diff --git a/analyzers/archive-analyzer.html b/analyzers/archive-analyzer.html index aab7add4a..acada5f73 100644 --- a/analyzers/archive-analyzer.html +++ b/analyzers/archive-analyzer.html @@ -1,13 +1,13 @@ - + dependency-check – Archive Analyzer @@ -59,9 +59,9 @@
  • Archive Analyzer
  • -
  • | Last Published: 2016-06-16
  • +
  • | Last Published: 2016-07-31
  • - Version: 1.4.0 + Version: 1.4.2
  • diff --git a/analyzers/assembly-analyzer.html b/analyzers/assembly-analyzer.html index 71843a75e..83b852012 100644 --- a/analyzers/assembly-analyzer.html +++ b/analyzers/assembly-analyzer.html @@ -1,13 +1,13 @@ - + dependency-check – Assembly Analyzer @@ -59,9 +59,9 @@
  • Assembly Analyzer
  • -
  • | Last Published: 2016-06-16
  • +
  • | Last Published: 2016-07-31
  • - Version: 1.4.0 + Version: 1.4.2
  • diff --git a/analyzers/autoconf.html b/analyzers/autoconf.html index f5071deb2..36e0207d8 100644 --- a/analyzers/autoconf.html +++ b/analyzers/autoconf.html @@ -1,13 +1,13 @@ - + dependency-check – Autoconf Analyzer @@ -59,9 +59,9 @@
  • Autoconf Analyzer
  • -
  • | Last Published: 2016-06-16
  • +
  • | Last Published: 2016-07-31
  • - Version: 1.4.0 + Version: 1.4.2
  • diff --git a/analyzers/central-analyzer.html b/analyzers/central-analyzer.html index 722eaab9b..80820bda2 100644 --- a/analyzers/central-analyzer.html +++ b/analyzers/central-analyzer.html @@ -1,13 +1,13 @@ - + dependency-check – Central Analyzer @@ -59,9 +59,9 @@
  • Central Analyzer
  • -
  • | Last Published: 2016-06-16
  • +
  • | Last Published: 2016-07-31
  • - Version: 1.4.0 + Version: 1.4.2
  • diff --git a/analyzers/cmake.html b/analyzers/cmake.html index a62fcacd4..306145b4a 100644 --- a/analyzers/cmake.html +++ b/analyzers/cmake.html @@ -1,13 +1,13 @@ - + dependency-check – CMake Analyzer @@ -59,9 +59,9 @@
  • CMake Analyzer
  • -
  • | Last Published: 2016-06-16
  • +
  • | Last Published: 2016-07-31
  • - Version: 1.4.0 + Version: 1.4.2
  • diff --git a/analyzers/composer-lock.html b/analyzers/composer-lock.html index 38b18d90e..368dac24a 100644 --- a/analyzers/composer-lock.html +++ b/analyzers/composer-lock.html @@ -1,13 +1,13 @@ - + dependency-check – Composer Lock Analyzer @@ -59,9 +59,9 @@
  • Composer Lock Analyzer
  • -
  • | Last Published: 2016-06-16
  • +
  • | Last Published: 2016-07-31
  • - Version: 1.4.0 + Version: 1.4.2
  • diff --git a/analyzers/index.html b/analyzers/index.html index 62722b1bf..801f29e13 100644 --- a/analyzers/index.html +++ b/analyzers/index.html @@ -1,13 +1,13 @@ - + dependency-check – File Type Analyzers @@ -59,9 +59,9 @@
  • File Type Analyzers
  • -
  • | Last Published: 2016-06-16
  • +
  • | Last Published: 2016-07-31
  • - Version: 1.4.0 + Version: 1.4.2
  • diff --git a/analyzers/jar-analyzer.html b/analyzers/jar-analyzer.html index e7d032d9a..fb89865e3 100644 --- a/analyzers/jar-analyzer.html +++ b/analyzers/jar-analyzer.html @@ -1,13 +1,13 @@ - + dependency-check – Jar Analyzer @@ -59,9 +59,9 @@
  • Jar Analyzer
  • -
  • | Last Published: 2016-06-16
  • +
  • | Last Published: 2016-07-31
  • - Version: 1.4.0 + Version: 1.4.2
  • diff --git a/analyzers/nexus-analyzer.html b/analyzers/nexus-analyzer.html index 32c9d4f3a..a6eee2e2f 100644 --- a/analyzers/nexus-analyzer.html +++ b/analyzers/nexus-analyzer.html @@ -1,13 +1,13 @@ - + dependency-check – Nexus Analyzer @@ -59,9 +59,9 @@
  • Nexus Analyzer
  • -
  • | Last Published: 2016-06-16
  • +
  • | Last Published: 2016-07-31
  • - Version: 1.4.0 + Version: 1.4.2
  • diff --git a/analyzers/nodejs.html b/analyzers/nodejs.html index 690dc0302..7faaa7eac 100644 --- a/analyzers/nodejs.html +++ b/analyzers/nodejs.html @@ -1,13 +1,13 @@ - + dependency-check – Node.js Analyzer @@ -59,9 +59,9 @@
  • Node.js Analyzer
  • -
  • | Last Published: 2016-06-16
  • +
  • | Last Published: 2016-07-31
  • - Version: 1.4.0 + Version: 1.4.2
  • diff --git a/analyzers/nuspec-analyzer.html b/analyzers/nuspec-analyzer.html index 4b0a40e24..de07e3c57 100644 --- a/analyzers/nuspec-analyzer.html +++ b/analyzers/nuspec-analyzer.html @@ -1,13 +1,13 @@ - + dependency-check – Nuspec Analyzer @@ -59,9 +59,9 @@
  • Nuspec Analyzer
  • -
  • | Last Published: 2016-06-16
  • +
  • | Last Published: 2016-07-31
  • - Version: 1.4.0 + Version: 1.4.2
  • diff --git a/analyzers/openssl.html b/analyzers/openssl.html index 11c188d3e..f6c6cfcfc 100644 --- a/analyzers/openssl.html +++ b/analyzers/openssl.html @@ -1,13 +1,13 @@ - + dependency-check – OpenSSL Analyzer @@ -59,9 +59,9 @@
  • OpenSSL Analyzer
  • -
  • | Last Published: 2016-06-16
  • +
  • | Last Published: 2016-07-31
  • - Version: 1.4.0 + Version: 1.4.2
  • diff --git a/analyzers/python.html b/analyzers/python.html index e8dee681f..1d91fb0f0 100644 --- a/analyzers/python.html +++ b/analyzers/python.html @@ -1,13 +1,13 @@ - + dependency-check – Python Analyzer @@ -59,9 +59,9 @@
  • Python Analyzer
  • -
  • | Last Published: 2016-06-16
  • +
  • | Last Published: 2016-07-31
  • - Version: 1.4.0 + Version: 1.4.2
  • diff --git a/analyzers/ruby-gemspec.html b/analyzers/ruby-gemspec.html index 6cf6d439e..e8e78db6c 100644 --- a/analyzers/ruby-gemspec.html +++ b/analyzers/ruby-gemspec.html @@ -1,13 +1,13 @@ - + dependency-check – Ruby Gemspec Analyzer @@ -59,9 +59,9 @@
  • Ruby Gemspec Analyzer
  • -
  • | Last Published: 2016-06-16
  • +
  • | Last Published: 2016-07-31
  • - Version: 1.4.0 + Version: 1.4.2
  • diff --git a/current.txt b/current.txt index e21e727f9..c9929e36a 100644 --- a/current.txt +++ b/current.txt @@ -1 +1 @@ -1.4.0 \ No newline at end of file +1.4.2 \ No newline at end of file diff --git a/data/cachenvd.html b/data/cachenvd.html index d743827cc..ef5f34e1b 100644 --- a/data/cachenvd.html +++ b/data/cachenvd.html @@ -1,13 +1,13 @@ - + dependency-check – Snapshotting the NVD @@ -59,9 +59,9 @@
  • Snapshotting the NVD
  • -
  • | Last Published: 2016-06-16
  • +
  • | Last Published: 2016-07-31
  • - Version: 1.4.0 + Version: 1.4.2
  • diff --git a/data/database.html b/data/database.html index 6e1856983..d85954cb5 100644 --- a/data/database.html +++ b/data/database.html @@ -1,13 +1,13 @@ - + dependency-check – Using a Database Server @@ -59,9 +59,9 @@
  • Using a Database Server
  • -
  • | Last Published: 2016-06-16
  • +
  • | Last Published: 2016-07-31
  • - Version: 1.4.0 + Version: 1.4.2
  • @@ -244,11 +244,12 @@

    Using a Database Server

    WARNING: This discusses an advanced setup and you may run into issues.

    Out of the box dependency-check uses a local H2 database. The location of the database file is configured using the data directory configuration option (see CLI).

    -

    Some organizations may want to use a more robust centralized database. Currently, H2 in server mode, MySQL, PostgreSQL, Oracle, and MS SQL Server have been tested. In general, the setup is done by creating a central database, setting up a single instance of dependency-check, which can connect to the Internet, that is run in update-only mode once a day. Then the other dependency-check clients can connect, using a read-only connection, to perform the analysis. Please note that if the clients are unable to access the Internet the analysis may result in a few false negatives; see the note about Central here.

    +

    Some organizations may want to use a more robust centralized database. Currently, H2 in server mode, MySQL, MariaDB, PostgreSQL, Oracle, and MS SQL Server have been tested. In general, the setup is done by creating a central database, setting up a single instance of dependency-check, which can connect to the Internet, that is run in update-only mode once a day. Then the other dependency-check clients can connect, using a read-only connection, to perform the analysis. Please note that if the clients are unable to access the Internet the analysis may result in a few false negatives; see the note about Central here.

    To setup a centralized database the following generalized steps can be used:

      -
    1. Create the database and tables using either one of the intialization scripts found here.
    2. +
    3. Create the database and tables using either initialize.sql + or one of the other initialization scripts found here.
    4. The account that the clients will connect using must have select granted on the tables. @@ -268,9 +269,52 @@
    5. The connection string, database user name, and the database user's password will also need to be configured.
    -

    Depending on the database being used, you may need to customize the dbStatements.properties. Alternatively to modifying the dbStatements.properties it is now possible to use a dialect file to support other databases. See dbStatements_h2.properties as an example.

    +

    Depending on the database being used, you may need to customize the dbStatements.properties. Alternatively to modifying the dbStatements.properties it is possible to use a dialect file to support other databases. See dbStatements_h2.properties as an example.

    Also, if using an external database you will need to manually upgrade the schema. See database upgrades for more information.

    -

    As always, feel free to open an issue or post a question to the dependency-check google group.

    +
    +

    Examples

    +

    The following example shows how to use the Maven plugin with MariaDB:

    + +
    +
    <project>
    +    <modelVersion>4.0.0</modelVersion>
    +    <groupId>dummy</groupId>
    +    <artifactId>dummy</artifactId>
    +    <version>1.0-SNAPSHOT</version>
    +    <build>
    +        <plugins>
    +            <plugin>
    +                <groupId>org.owasp</groupId>
    +                <artifactId>dependency-check-maven</artifactId>
    +                <version>1.4.2</version>
    +                <dependencies>
    +                    <dependency>
    +                        <groupId>org.mariadb.jdbc</groupId>
    +                        <artifactId>mariadb-java-client</artifactId>
    +                        <version>1.4.6</version>
    +                    </dependency>
    +                </dependencies>
    +                <configuration>
    +                    <databaseDriverName>org.mariadb.jdbc.Driver</databaseDriverName>
    +                    <connectionString>jdbc:mariadb://my.cvedb.host/cvedb</connectionString>
    +                    <databaseUser>depscan</databaseUser>
    +                    <databasePassword>NotReallyMyDbPassword</databasePassword>
    +                </configuration>
    +                <executions>
    +                    <execution>
    +                        <goals>
    +                            <goal>update-only</goal>
    +                        </goals>
    +                    </execution>
    +                </executions>
    +            </plugin>
    +        </plugins>
    +    </build>
    +</project>
    +
    +
    +

    Support

    +

    As always, feel free to open an issue or post a question to the dependency-check google group.

    diff --git a/data/index.html b/data/index.html index 157484ce9..af6a8d577 100644 --- a/data/index.html +++ b/data/index.html @@ -1,13 +1,13 @@ - + dependency-check – Internet Access Required @@ -59,9 +59,9 @@
  • Internet Access Required
  • -
  • | Last Published: 2016-06-16
  • +
  • | Last Published: 2016-07-31
  • - Version: 1.4.0 + Version: 1.4.2
  • diff --git a/data/mirrornvd.html b/data/mirrornvd.html index bbe3f485e..947695f96 100644 --- a/data/mirrornvd.html +++ b/data/mirrornvd.html @@ -1,13 +1,13 @@ - + dependency-check – Mirroring the NVD from NIST @@ -59,9 +59,9 @@
  • Mirroring the NVD from NIST
  • -
  • | Last Published: 2016-06-16
  • +
  • | Last Published: 2016-07-31
  • - Version: 1.4.0 + Version: 1.4.2
  • diff --git a/data/proxy.html b/data/proxy.html index 88659f7c3..e591d11ab 100644 --- a/data/proxy.html +++ b/data/proxy.html @@ -1,13 +1,13 @@ - + dependency-check – Proxy Configuration @@ -59,9 +59,9 @@
  • Proxy Configuration
  • -
  • | Last Published: 2016-06-16
  • +
  • | Last Published: 2016-07-31
  • - Version: 1.4.0 + Version: 1.4.2
  • diff --git a/data/upgrade.html b/data/upgrade.html index 57ae6b181..24153e06d 100644 --- a/data/upgrade.html +++ b/data/upgrade.html @@ -1,13 +1,13 @@ - + dependency-check – Database Upgrades @@ -59,9 +59,9 @@
  • Database Upgrades
  • -
  • | Last Published: 2016-06-16
  • +
  • | Last Published: 2016-07-31
  • - Version: 1.4.0 + Version: 1.4.2
  • diff --git a/dependency-analysis.html b/dependency-analysis.html index 579c2a355..603b636a2 100644 --- a/dependency-analysis.html +++ b/dependency-analysis.html @@ -1,13 +1,13 @@ - + dependency-check – @@ -59,9 +59,9 @@
  • -
  • | Last Published: 2016-06-16
  • +
  • | Last Published: 2016-07-31
  • - Version: 1.4.0 + Version: 1.4.2
  • diff --git a/dependency-check-ant/apidocs/allclasses-frame.html b/dependency-check-ant/apidocs/allclasses-frame.html index 2d007a06e..788c6c775 100644 --- a/dependency-check-ant/apidocs/allclasses-frame.html +++ b/dependency-check-ant/apidocs/allclasses-frame.html @@ -2,10 +2,10 @@ - + -All Classes (Dependency-Check Ant Task 1.4.0 API) - +All Classes (Dependency-Check Ant Task 1.4.2 API) + diff --git a/dependency-check-ant/apidocs/allclasses-noframe.html b/dependency-check-ant/apidocs/allclasses-noframe.html index 3c32881a4..0adbf1434 100644 --- a/dependency-check-ant/apidocs/allclasses-noframe.html +++ b/dependency-check-ant/apidocs/allclasses-noframe.html @@ -2,10 +2,10 @@ - + -All Classes (Dependency-Check Ant Task 1.4.0 API) - +All Classes (Dependency-Check Ant Task 1.4.2 API) + diff --git a/dependency-check-ant/apidocs/constant-values.html b/dependency-check-ant/apidocs/constant-values.html index 81be668ff..c144a8b19 100644 --- a/dependency-check-ant/apidocs/constant-values.html +++ b/dependency-check-ant/apidocs/constant-values.html @@ -2,10 +2,10 @@ - + -Constant Field Values (Dependency-Check Ant Task 1.4.0 API) - +Constant Field Values (Dependency-Check Ant Task 1.4.2 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-ant/apidocs/org/owasp/dependencycheck/ant/logging/package-summary.html b/dependency-check-ant/apidocs/org/owasp/dependencycheck/ant/logging/package-summary.html index 4122dca57..e7d8539af 100644 --- a/dependency-check-ant/apidocs/org/owasp/dependencycheck/ant/logging/package-summary.html +++ b/dependency-check-ant/apidocs/org/owasp/dependencycheck/ant/logging/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.ant.logging (Dependency-Check Ant Task 1.4.0 API) - +org.owasp.dependencycheck.ant.logging (Dependency-Check Ant Task 1.4.2 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,13 +13,13 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-ant/apidocs/org/owasp/dependencycheck/taskdefs/package-summary.html b/dependency-check-ant/apidocs/org/owasp/dependencycheck/taskdefs/package-summary.html index 32626b84c..9c06e7cf7 100644 --- a/dependency-check-ant/apidocs/org/owasp/dependencycheck/taskdefs/package-summary.html +++ b/dependency-check-ant/apidocs/org/owasp/dependencycheck/taskdefs/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.taskdefs (Dependency-Check Ant Task 1.4.0 API) - +org.owasp.dependencycheck.taskdefs (Dependency-Check Ant Task 1.4.2 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-ant/apidocs/org/slf4j/impl/package-summary.html b/dependency-check-ant/apidocs/org/slf4j/impl/package-summary.html index 2bc885b85..bdad23959 100644 --- a/dependency-check-ant/apidocs/org/slf4j/impl/package-summary.html +++ b/dependency-check-ant/apidocs/org/slf4j/impl/package-summary.html @@ -2,10 +2,10 @@ - + -org.slf4j.impl (Dependency-Check Ant Task 1.4.0 API) - +org.slf4j.impl (Dependency-Check Ant Task 1.4.2 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-ant/apidocs/overview-summary.html b/dependency-check-ant/apidocs/overview-summary.html index d19102b0c..af89d6683 100644 --- a/dependency-check-ant/apidocs/overview-summary.html +++ b/dependency-check-ant/apidocs/overview-summary.html @@ -2,10 +2,10 @@ - + -Overview (Dependency-Check Ant Task 1.4.0 API) - +Overview (Dependency-Check Ant Task 1.4.2 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ - + diff --git a/dependency-check-ant/cobertura/frame-summary-org.owasp.dependencycheck.taskdefs.html b/dependency-check-ant/cobertura/frame-summary-org.owasp.dependencycheck.taskdefs.html index 7c4a174af..a98879409 100644 --- a/dependency-check-ant/cobertura/frame-summary-org.owasp.dependencycheck.taskdefs.html +++ b/dependency-check-ant/cobertura/frame-summary-org.owasp.dependencycheck.taskdefs.html @@ -16,7 +16,7 @@ - +
    Package # Classes Line Coverage Branch Coverage Complexity
    org.owasp.dependencycheck.taskdefs4
    47%
    168/355
    50%
    40/80
    1.538
    org.owasp.dependencycheck.taskdefs4
    43%
    169/390
    40%
    40/100
    1.704
    - + diff --git a/dependency-check-ant/cobertura/frame-summary-org.slf4j.impl.html b/dependency-check-ant/cobertura/frame-summary-org.slf4j.impl.html index 842d8e428..6d495b900 100644 --- a/dependency-check-ant/cobertura/frame-summary-org.slf4j.impl.html +++ b/dependency-check-ant/cobertura/frame-summary-org.slf4j.impl.html @@ -37,6 +37,6 @@ var classTable = new SortableTable(document.getElementById("classResults"), ["String", "Percentage", "Percentage", "FormattedNumber"]); classTable.sort(0); - + diff --git a/dependency-check-ant/cobertura/frame-summary.html b/dependency-check-ant/cobertura/frame-summary.html index 7e2658471..fdc7eb515 100644 --- a/dependency-check-ant/cobertura/frame-summary.html +++ b/dependency-check-ant/cobertura/frame-summary.html @@ -16,9 +16,9 @@ - + - +
    Package # Classes Line Coverage Branch Coverage Complexity
    All Packages7
    46%
    218/472
    40%
    53/130
    1.566
    All Packages7
    43%
    219/507
    35%
    53/150
    1.687
    org.owasp.dependencycheck.ant.logging2
    35%
    37/104
    26%
    13/50
    1.735
    org.owasp.dependencycheck.taskdefs4
    47%
    168/355
    50%
    40/80
    1.538
    org.owasp.dependencycheck.taskdefs4
    43%
    169/390
    40%
    40/100
    1.704
    org.slf4j.impl1
    100%
    13/13
    N/A
    1
    @@ -27,6 +27,6 @@ var packageTable = new SortableTable(document.getElementById("packageResults"), ["String", "Number", "Percentage", "Percentage", "FormattedNumber"]); packageTable.sort(0); - + diff --git a/dependency-check-ant/cobertura/org.owasp.dependencycheck.ant.logging.AntLoggerAdapter.html b/dependency-check-ant/cobertura/org.owasp.dependencycheck.ant.logging.AntLoggerAdapter.html index 6cb7a0145..75abee2e4 100644 --- a/dependency-check-ant/cobertura/org.owasp.dependencycheck.ant.logging.AntLoggerAdapter.html +++ b/dependency-check-ant/cobertura/org.owasp.dependencycheck.ant.logging.AntLoggerAdapter.html @@ -103,9 +103,9 @@
          */
     43  
         public AntLoggerAdapter(Task task) {
    -  44  26
             super();
    -  45  26
             this.task = task;
    -  46  26
         }
    +  44  13
             super();
    +  45  13
             this.task = task;
    +  46  13
         }
     47  
     
     48   @@ -141,23 +141,23 @@
         @Override
     65  
         public void trace(String msg) {
    -  66  61
             if (task != null) {
    -  67  54
                 task.log(msg, Project.MSG_VERBOSE);
    +  66  32
             if (task != null) {
    +  67  27
                 task.log(msg, Project.MSG_VERBOSE);
     68  
             }
    -  69  61
         }
    +  69  32
         }
     70  
     
     71  
         @Override
     72  
         public void trace(String format, Object arg) {
    -  73  58
             if (task != null) {
    -  74  42
                 final FormattingTuple tp = MessageFormatter.format(format, arg);
    -  75  42
                 task.log(tp.getMessage(), Project.MSG_VERBOSE);
    +  73  29
             if (task != null) {
    +  74  21
                 final FormattingTuple tp = MessageFormatter.format(format, arg);
    +  75  21
                 task.log(tp.getMessage(), Project.MSG_VERBOSE);
     76  
             }
    -  77  58
         }
    +  77  29
         }
     78  
     
     79   @@ -199,7 +199,7 @@
         @Override
     103  
         public boolean isDebugEnabled() {
    -  104  20
             return true;
    +  104  10
             return true;
     105  
         }
     106   @@ -208,47 +208,47 @@
         @Override
     108  
         public void debug(String msg) {
    -  109  268
             if (task != null) {
    -  110  234
                 task.log(msg, Project.MSG_DEBUG);
    +  109  137
             if (task != null) {
    +  110  117
                 task.log(msg, Project.MSG_DEBUG);
     111  
             }
    -  112  268
         }
    +  112  137
         }
     113  
     
     114  
         @Override
     115  
         public void debug(String format, Object arg) {
    -  116  660
             if (task != null) {
    -  117  634
                 final FormattingTuple tp = MessageFormatter.format(format, arg);
    -  118  634
                 task.log(tp.getMessage(), Project.MSG_DEBUG);
    +  116  330
             if (task != null) {
    +  117  317
                 final FormattingTuple tp = MessageFormatter.format(format, arg);
    +  118  317
                 task.log(tp.getMessage(), Project.MSG_DEBUG);
     119  
             }
    -  120  660
         }
    +  120  330
         }
     121  
     
     122  
         @Override
     123  
         public void debug(String format, Object arg1, Object arg2) {
    -  124  50
             if (task != null) {
    -  125  38
                 final FormattingTuple tp = MessageFormatter.format(format, arg1, arg2);
    -  126  38
                 task.log(tp.getMessage(), Project.MSG_DEBUG);
    +  124  25
             if (task != null) {
    +  125  19
                 final FormattingTuple tp = MessageFormatter.format(format, arg1, arg2);
    +  126  19
                 task.log(tp.getMessage(), Project.MSG_DEBUG);
     127  
             }
    -  128  50
         }
    +  128  25
         }
     129  
     
     130  
         @Override
     131  
         public void debug(String format, Object... arguments) {
    -  132  4
             if (task != null) {
    -  133  4
                 final FormattingTuple tp = MessageFormatter.format(format, arguments);
    -  134  4
                 task.log(tp.getMessage(), Project.MSG_DEBUG);
    +  132  2
             if (task != null) {
    +  133  2
                 final FormattingTuple tp = MessageFormatter.format(format, arguments);
    +  134  2
                 task.log(tp.getMessage(), Project.MSG_DEBUG);
     135  
             }
    -  136  4
         }
    +  136  2
         }
     137  
     
     138   @@ -275,23 +275,23 @@
         @Override
     151  
         public void info(String msg) {
    -  152  12
             if (task != null) {
    -  153  12
                 task.log(msg, Project.MSG_INFO);
    +  152  6
             if (task != null) {
    +  153  6
                 task.log(msg, Project.MSG_INFO);
     154  
             }
    -  155  12
         }
    +  155  6
         }
     156  
     
     157  
         @Override
     158  
         public void info(String format, Object arg) {
    -  159  12
             if (task != null) {
    -  160  12
                 final FormattingTuple tp = MessageFormatter.format(format, arg);
    -  161  12
                 task.log(tp.getMessage(), Project.MSG_INFO);
    +  159  6
             if (task != null) {
    +  160  6
                 final FormattingTuple tp = MessageFormatter.format(format, arg);
    +  161  6
                 task.log(tp.getMessage(), Project.MSG_INFO);
     162  
             }
    -  163  12
         }
    +  163  6
         }
     164  
     
     165   @@ -465,6 +465,6 @@
     }
    - + diff --git a/dependency-check-ant/cobertura/org.owasp.dependencycheck.ant.logging.AntLoggerFactory.html b/dependency-check-ant/cobertura/org.owasp.dependencycheck.ant.logging.AntLoggerFactory.html index 982f58e7a..9e417d03c 100644 --- a/dependency-check-ant/cobertura/org.owasp.dependencycheck.ant.logging.AntLoggerFactory.html +++ b/dependency-check-ant/cobertura/org.owasp.dependencycheck.ant.logging.AntLoggerFactory.html @@ -99,9 +99,9 @@
          */
     41  
         public AntLoggerFactory(Task task) {
    -  42  26
             super();
    -  43  26
             this.antLoggerAdapter = new AntLoggerAdapter(task);
    -  44  26
         }
    +  42  13
             super();
    +  43  13
             this.antLoggerAdapter = new AntLoggerAdapter(task);
    +  44  13
         }
     45  
     
     46   @@ -120,13 +120,13 @@
         @Override
     53  
         public Logger getLogger(String name) {
    -  54  92
             return antLoggerAdapter;
    +  54  52
             return antLoggerAdapter;
     55  
         }
     56  
     }
    - + diff --git a/dependency-check-ant/cobertura/org.owasp.dependencycheck.taskdefs.Check.html b/dependency-check-ant/cobertura/org.owasp.dependencycheck.taskdefs.Check.html index 61ab76bc2..f946da362 100644 --- a/dependency-check-ant/cobertura/org.owasp.dependencycheck.taskdefs.Check.html +++ b/dependency-check-ant/cobertura/org.owasp.dependencycheck.taskdefs.Check.html @@ -12,8 +12,8 @@
     
    - - + +
    Classes in this File Line Coverage Branch Coverage Complexity
    Check
    53%
    123/232
    54%
    35/64
    1.647
    Check$ReportFormats
    100%
    7/7
    100%
    2/2
    1.647
    Check
    50%
    123/242
    48%
    35/72
    1.75
    Check$ReportFormats
    100%
    7/7
    100%
    2/2
    1.75
     
    @@ -59,33 +59,33 @@  20  
     import java.io.File;
     21   -
     import java.io.IOException;
    -  22  
     import java.util.List;
    -  23   +  22  
     import org.apache.tools.ant.BuildException;
    -  24   +  23  
     import org.apache.tools.ant.Project;
    -  25   +  24  
     import org.apache.tools.ant.types.EnumeratedAttribute;
    -  26   +  25  
     import org.apache.tools.ant.types.Reference;
    -  27   +  26  
     import org.apache.tools.ant.types.Resource;
    -  28   +  27  
     import org.apache.tools.ant.types.ResourceCollection;
    -  29   +  28  
     import org.apache.tools.ant.types.resources.FileProvider;
    -  30   +  29  
     import org.apache.tools.ant.types.resources.Resources;
    -  31   +  30  
     import org.owasp.dependencycheck.Engine;
    -  32   +  31  
     import org.owasp.dependencycheck.data.nvdcve.CveDB;
    -  33   +  32  
     import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
    -  34   +  33  
     import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties;
    +  34   +
     import org.owasp.dependencycheck.data.update.exception.UpdateException;
     35  
     import org.owasp.dependencycheck.dependency.Dependency;
     36   @@ -93,1700 +93,1724 @@  37  
     import org.owasp.dependencycheck.dependency.Vulnerability;
     38   -
     import org.owasp.dependencycheck.reporting.ReportGenerator;
    +
     import org.owasp.dependencycheck.exception.ExceptionCollection;
     39   -
     import org.owasp.dependencycheck.reporting.ReportGenerator.Format;
    +
     import org.owasp.dependencycheck.exception.ReportException;
     40   -
     import org.owasp.dependencycheck.utils.Settings;
    +
     import org.owasp.dependencycheck.reporting.ReportGenerator;
     41   -
     import org.slf4j.impl.StaticLoggerBinder;
    +
     import org.owasp.dependencycheck.reporting.ReportGenerator.Format;
     42   -
     
    +
     import org.owasp.dependencycheck.utils.Settings;
     43   -
     /**
    +
     import org.slf4j.impl.StaticLoggerBinder;
     44   -
      * An Ant task definition to execute dependency-check during an Ant build.
    +
     
     45   -
      *
    +
     /**
     46   -
      * @author Jeremy Long
    +
      * An Ant task definition to execute dependency-check during an Ant build.
     47   -
      */
    +
      *
     48   -
     public class Check extends Update {
    +
      * @author Jeremy Long
     49   -
     
    +
      */
     50   -
         /**
    +
     public class Check extends Update {
     51   -
          * System specific new line character.
    +
     
     52   -
          */
    -  53  2
         private static final String NEW_LINE = System.getProperty("line.separator", "\n").intern();
    +
         /**
    +  53   +
          * System specific new line character.
     54   -
     
    -  55   -
         /**
    +
          */
    +  55  1
         private static final String NEW_LINE = System.getProperty("line.separator", "\n").intern();
     56   -
          * Construct a new DependencyCheckTask.
    +
     
     57   -
          */
    +
         /**
     58   -
         public Check() {
    -  59  8
             super();
    +
          * Construct a new DependencyCheckTask.
    +  59   +
          */
     60   +
         public Check() {
    +  61  4
             super();
    +  62  
             // Call this before Dependency Check Core starts logging anything - this way, all SLF4J messages from
    -  61   +  63  
             // core end up coming through this tasks logger
    -  62  8
             StaticLoggerBinder.getSingleton().setTask(this);
    -  63  8
         }
    -  64   -
         //The following code was copied Apache Ant PathConvert
    -  65   -
         //BEGIN COPY from org.apache.tools.ant.taskdefs.PathConvert
    +  64  4
             StaticLoggerBinder.getSingleton().setTask(this);
    +  65  4
         }
     66   -
         /**
    +
         //The following code was copied Apache Ant PathConvert
     67   -
          * Path to be converted
    +
         //BEGIN COPY from org.apache.tools.ant.taskdefs.PathConvert
     68   -
          */
    -  69  8
         private Resources path = null;
    +
         /**
    +  69   +
          * Path to be converted
     70   -
         /**
    -  71   -
          * Reference to path/fileset to convert
    +
          */
    +  71  4
         private Resources path = null;
     72   -
          */
    -  73  8
         private Reference refid = null;
    +
         /**
    +  73   +
          * Reference to path/fileset to convert
     74   -
     
    -  75   -
         /**
    +
          */
    +  75  4
         private Reference refid = null;
     76   -
          * Add an arbitrary ResourceCollection.
    +
     
     77   -
          *
    +
         /**
     78   -
          * @param rc the ResourceCollection to add.
    +
          * Add an arbitrary ResourceCollection.
     79   -
          * @since Ant 1.7
    +
          *
     80   -
          */
    +
          * @param rc the ResourceCollection to add.
     81   +
          * @since Ant 1.7
    +  82   +
          */
    +  83  
         public void add(ResourceCollection rc) {
    -  82  8
             if (isReference()) {
    -  83  0
                 throw new BuildException("Nested elements are not allowed when using the refid attribute.");
    -  84   +  84  4
             if (isReference()) {
    +  85  0
                 throw new BuildException("Nested elements are not allowed when using the refid attribute.");
    +  86  
             }
    -  85  8
             getPath().add(rc);
    -  86  8
         }
    -  87   -
     
    -  88   -
         /**
    +  87  4
             getPath().add(rc);
    +  88  4
         }
     89   -
          * Returns the path. If the path has not been initialized yet, this class is
    +
     
     90   -
          * synchronized, and will instantiate the path object.
    +
         /**
     91   -
          *
    +
          * Returns the path. If the path has not been initialized yet, this class is
     92   -
          * @return the path
    +
          * synchronized, and will instantiate the path object.
     93   -
          */
    +
          *
     94   +
          * @return the path
    +  95   +
          */
    +  96  
         private synchronized Resources getPath() {
    -  95  8
             if (path == null) {
    -  96  6
                 path = new Resources(getProject());
    -  97  6
                 path.setCache(true);
    -  98   -
             }
    -  99  8
             return path;
    +  97  4
             if (path == null) {
    +  98  3
                 path = new Resources(getProject());
    +  99  3
                 path.setCache(true);
     100   -
         }
    -  101   -
     
    +
             }
    +  101  4
             return path;
     102   -
         /**
    -  103   -
          * Learn whether the refid attribute of this element been set.
    -  104   -
          *
    -  105   -
          * @return true if refid is valid.
    -  106   -
          */
    -  107   -
         public boolean isReference() {
    -  108  16
             return refid != null;
    -  109  
         }
    -  110   +  103  
     
    +  104   +
         /**
    +  105   +
          * Learn whether the refid attribute of this element been set.
    +  106   +
          *
    +  107   +
          * @return true if refid is valid.
    +  108   +
          */
    +  109   +
         public boolean isReference() {
    +  110  8
             return refid != null;
     111   -
         /**
    +
         }
     112   -
          * Add a reference to a Path, FileSet, DirSet, or FileList defined
    +
     
     113   -
          * elsewhere.
    +
         /**
     114   -
          *
    +
          * Add a reference to a Path, FileSet, DirSet, or FileList defined
     115   -
          * @param r the reference to a path, fileset, dirset or filelist.
    +
          * elsewhere.
     116   -
          */
    +
          *
     117   +
          * @param r the reference to a path, fileset, dirset or filelist.
    +  118   +
          */
    +  119  
         public void setRefid(Reference r) {
    -  118  0
             if (path != null) {
    -  119  0
                 throw new BuildException("Nested elements are not allowed when using the refid attribute.");
    -  120   +  120  0
             if (path != null) {
    +  121  0
                 throw new BuildException("Nested elements are not allowed when using the refid attribute.");
    +  122  
             }
    -  121  0
             refid = r;
    -  122  0
         }
    -  123   -
     
    -  124   -
         /**
    +  123  0
             refid = r;
    +  124  0
         }
     125   -
          * If this is a reference, this method will add the referenced resource
    -  126   -
          * collection to the collection of paths.
    -  127   -
          *
    -  128   -
          * @throws BuildException if the reference is not to a resource collection
    -  129   -
          */
    -  130   -
         private void dealWithReferences() throws BuildException {
    -  131  8
             if (isReference()) {
    -  132  0
                 final Object o = refid.getReferencedObject(getProject());
    -  133  0
                 if (!(o instanceof ResourceCollection)) {
    -  134  0
                     throw new BuildException("refid '" + refid.getRefId()
    -  135   -
                             + "' does not refer to a resource collection.");
    -  136   -
                 }
    -  137  0
                 getPath().add((ResourceCollection) o);
    -  138   -
             }
    -  139  8
         }
    -  140   -
         // END COPY from org.apache.tools.ant.taskdefs
    -  141   -
         /**
    -  142   -
          * The application name for the report.
    -  143   -
          *
    -  144   -
          * @deprecated use projectName instead.
    -  145   -
          */
    -  146  8
         @Deprecated
    -  147   -
         private String applicationName = null;
    -  148  
     
    -  149   +  126  
         /**
    -  150   -
          * Get the value of applicationName.
    -  151   +  127   +
          * If this is a reference, this method will add the referenced resource
    +  128   +
          * collection to the collection of paths.
    +  129  
          *
    +  130   +
          * @throws BuildException if the reference is not to a resource collection
    +  131   +
          */
    +  132   +
         private void dealWithReferences() throws BuildException {
    +  133  4
             if (isReference()) {
    +  134  0
                 final Object o = refid.getReferencedObject(getProject());
    +  135  0
                 if (!(o instanceof ResourceCollection)) {
    +  136  0
                     throw new BuildException("refid '" + refid.getRefId()
    +  137   +
                             + "' does not refer to a resource collection.");
    +  138   +
                 }
    +  139  0
                 getPath().add((ResourceCollection) o);
    +  140   +
             }
    +  141  4
         }
    +  142   +
         // END COPY from org.apache.tools.ant.taskdefs
    +  143   +
         /**
    +  144   +
          * The application name for the report.
    +  145   +
          *
    +  146   +
          * @deprecated use projectName instead.
    +  147   +
          */
    +  148  4
         @Deprecated
    +  149   +
         private String applicationName = null;
    +  150   +
     
    +  151   +
         /**
     152   -
          * @return the value of applicationName
    +
          * Get the value of applicationName.
     153  
          *
     154   -
          * @deprecated use projectName instead.
    +
          * @return the value of applicationName
     155   -
          */
    +
          *
     156   -
         @Deprecated
    -  157   -
         public String getApplicationName() {
    -  158  0
             return applicationName;
    -  159   -
         }
    -  160   -
     
    -  161   -
         /**
    -  162   -
          * Set the value of applicationName.
    -  163   -
          *
    -  164   -
          * @param applicationName new value of applicationName
    -  165  
          * @deprecated use projectName instead.
    +  157   +
          */
    +  158   +
         @Deprecated
    +  159   +
         public String getApplicationName() {
    +  160  0
             return applicationName;
    +  161   +
         }
    +  162   +
     
    +  163   +
         /**
    +  164   +
          * Set the value of applicationName.
    +  165   +
          *
     166   -
          */
    +
          * @param applicationName new value of applicationName
     167   -
         @Deprecated
    +
          * @deprecated use projectName instead.
     168   +
          */
    +  169   +
         @Deprecated
    +  170  
         public void setApplicationName(String applicationName) {
    -  169  8
             this.applicationName = applicationName;
    -  170  8
         }
    -  171   -
         /**
    -  172   -
          * The name of the project being analyzed.
    +  171  4
             this.applicationName = applicationName;
    +  172  4
         }
     173   -
          */
    -  174  8
         private String projectName = "dependency-check";
    +
         /**
    +  174   +
          * The name of the project being analyzed.
     175   -
     
    -  176   -
         /**
    +
          */
    +  176  4
         private String projectName = "dependency-check";
     177   -
          * Get the value of projectName.
    +
     
     178   -
          *
    +
         /**
     179   -
          * @return the value of projectName
    +
          * Get the value of projectName.
     180   -
          */
    +
          *
     181   +
          * @return the value of projectName
    +  182   +
          */
    +  183  
         public String getProjectName() {
    -  182  6
             if (applicationName != null) {
    -  183  6
                 log("Configuration 'applicationName' has been deprecated, please use 'projectName' instead", Project.MSG_WARN);
    -  184  6
                 if ("dependency-check".equals(projectName)) {
    -  185  6
                     projectName = applicationName;
    -  186   +  184  3
             if (applicationName != null) {
    +  185  3
                 log("Configuration 'applicationName' has been deprecated, please use 'projectName' instead", Project.MSG_WARN);
    +  186  3
                 if ("dependency-check".equals(projectName)) {
    +  187  3
                     projectName = applicationName;
    +  188  
                 }
    -  187   -
             }
    -  188  6
             return projectName;
     189   -
         }
    -  190   -
     
    +
             }
    +  190  3
             return projectName;
     191   -
         /**
    +
         }
     192   -
          * Set the value of projectName.
    +
     
     193   -
          *
    +
         /**
     194   -
          * @param projectName new value of projectName
    +
          * Set the value of projectName.
     195   -
          */
    +
          *
     196   +
          * @param projectName new value of projectName
    +  197   +
          */
    +  198  
         public void setProjectName(String projectName) {
    -  197  0
             this.projectName = projectName;
    -  198  0
         }
    -  199   -
     
    -  200   -
         /**
    +  199  0
             this.projectName = projectName;
    +  200  0
         }
     201   -
          * Specifies the destination directory for the generated Dependency-Check
    +
     
     202   -
          * report.
    +
         /**
     203   -
          */
    -  204  8
         private String reportOutputDirectory = ".";
    +
          * Specifies the destination directory for the generated Dependency-Check
    +  204   +
          * report.
     205   -
     
    -  206   -
         /**
    +
          */
    +  206  4
         private String reportOutputDirectory = ".";
     207   -
          * Get the value of reportOutputDirectory.
    +
     
     208   -
          *
    +
         /**
     209   -
          * @return the value of reportOutputDirectory
    +
          * Get the value of reportOutputDirectory.
     210   -
          */
    +
          *
     211   -
         public String getReportOutputDirectory() {
    -  212  0
             return reportOutputDirectory;
    +
          * @return the value of reportOutputDirectory
    +  212   +
          */
     213   -
         }
    -  214   -
     
    +
         public String getReportOutputDirectory() {
    +  214  0
             return reportOutputDirectory;
     215   -
         /**
    +
         }
     216   -
          * Set the value of reportOutputDirectory.
    +
     
     217   -
          *
    +
         /**
     218   -
          * @param reportOutputDirectory new value of reportOutputDirectory
    +
          * Set the value of reportOutputDirectory.
     219   -
          */
    +
          *
     220   +
          * @param reportOutputDirectory new value of reportOutputDirectory
    +  221   +
          */
    +  222  
         public void setReportOutputDirectory(String reportOutputDirectory) {
    -  221  8
             this.reportOutputDirectory = reportOutputDirectory;
    -  222  8
         }
    -  223   -
         /**
    -  224   -
          * Specifies if the build should be failed if a CVSS score above a specified
    +  223  4
             this.reportOutputDirectory = reportOutputDirectory;
    +  224  4
         }
     225   -
          * level is identified. The default is 11 which means since the CVSS scores
    +
         /**
     226   -
          * are 0-10, by default the build will never fail and the CVSS score is set
    +
          * Specifies if the build should be failed if a CVSS score above a specified
     227   -
          * to 11. The valid range for the fail build on CVSS is 0 to 11, where
    +
          * level is identified. The default is 11 which means since the CVSS scores
     228   -
          * anything above 10 will not cause the build to fail.
    +
          * are 0-10, by default the build will never fail and the CVSS score is set
     229   -
          */
    -  230  8
         private float failBuildOnCVSS = 11;
    +
          * to 11. The valid range for the fail build on CVSS is 0 to 11, where
    +  230   +
          * anything above 10 will not cause the build to fail.
     231   -
     
    -  232   -
         /**
    +
          */
    +  232  4
         private float failBuildOnCVSS = 11;
     233   -
          * Get the value of failBuildOnCVSS.
    +
     
     234   -
          *
    +
         /**
     235   -
          * @return the value of failBuildOnCVSS
    +
          * Get the value of failBuildOnCVSS.
     236   -
          */
    +
          *
     237   -
         public float getFailBuildOnCVSS() {
    -  238  0
             return failBuildOnCVSS;
    +
          * @return the value of failBuildOnCVSS
    +  238   +
          */
     239   -
         }
    -  240   -
     
    +
         public float getFailBuildOnCVSS() {
    +  240  0
             return failBuildOnCVSS;
     241   -
         /**
    +
         }
     242   -
          * Set the value of failBuildOnCVSS.
    +
     
     243   -
          *
    +
         /**
     244   -
          * @param failBuildOnCVSS new value of failBuildOnCVSS
    +
          * Set the value of failBuildOnCVSS.
     245   -
          */
    +
          *
     246   +
          * @param failBuildOnCVSS new value of failBuildOnCVSS
    +  247   +
          */
    +  248  
         public void setFailBuildOnCVSS(float failBuildOnCVSS) {
    -  247  2
             this.failBuildOnCVSS = failBuildOnCVSS;
    -  248  2
         }
    -  249   -
         /**
    -  250   -
          * Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not
    +  249  1
             this.failBuildOnCVSS = failBuildOnCVSS;
    +  250  1
         }
     251   -
          * recommended that this be turned to false. Default is true.
    +
         /**
     252   -
          */
    +
          * Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not
     253   -
         private Boolean autoUpdate;
    +
          * recommended that this be turned to false. Default is true.
     254   -
     
    +
          */
     255   -
         /**
    +
         private Boolean autoUpdate;
     256   -
          * Get the value of autoUpdate.
    +
     
     257   -
          *
    +
         /**
     258   -
          * @return the value of autoUpdate
    +
          * Get the value of autoUpdate.
     259   -
          */
    +
          *
     260   -
         public Boolean isAutoUpdate() {
    -  261  0
             return autoUpdate;
    +
          * @return the value of autoUpdate
    +  261   +
          */
     262   -
         }
    -  263   -
     
    +
         public Boolean isAutoUpdate() {
    +  263  0
             return autoUpdate;
     264   -
         /**
    +
         }
     265   -
          * Set the value of autoUpdate.
    +
     
     266   -
          *
    +
         /**
     267   -
          * @param autoUpdate new value of autoUpdate
    +
          * Set the value of autoUpdate.
     268   -
          */
    +
          *
     269   +
          * @param autoUpdate new value of autoUpdate
    +  270   +
          */
    +  271  
         public void setAutoUpdate(Boolean autoUpdate) {
    -  270  8
             this.autoUpdate = autoUpdate;
    -  271  8
         }
    -  272   -
         /**
    -  273   -
          * Whether only the update phase should be executed.
    +  272  4
             this.autoUpdate = autoUpdate;
    +  273  4
         }
     274   -
          *
    +
         /**
     275   -
          * @deprecated Use the update task instead
    +
          * Whether only the update phase should be executed.
     276   -
          */
    -  277  8
         @Deprecated
    +
          *
    +  277   +
          * @deprecated Use the update task instead
     278   -
         private boolean updateOnly = false;
    -  279   -
     
    +
          */
    +  279  4
         @Deprecated
     280   -
         /**
    +
         private boolean updateOnly = false;
     281   -
          * Get the value of updateOnly.
    +
     
     282   -
          *
    +
         /**
     283   -
          * @return the value of updateOnly
    +
          * Get the value of updateOnly.
     284   -
          * @deprecated Use the update task instead
    +
          *
     285   -
          */
    +
          * @return the value of updateOnly
     286   -
         @Deprecated
    -  287   -
         public boolean isUpdateOnly() {
    -  288  6
             return updateOnly;
    -  289   -
         }
    -  290   -
     
    -  291   -
         /**
    -  292   -
          * Set the value of updateOnly.
    -  293   -
          *
    -  294   -
          * @param updateOnly new value of updateOnly
    -  295  
          * @deprecated Use the update task instead
    -  296   +  287  
          */
    -  297   +  288  
         @Deprecated
    +  289   +
         public boolean isUpdateOnly() {
    +  290  3
             return updateOnly;
    +  291   +
         }
    +  292   +
     
    +  293   +
         /**
    +  294   +
          * Set the value of updateOnly.
    +  295   +
          *
    +  296   +
          * @param updateOnly new value of updateOnly
    +  297   +
          * @deprecated Use the update task instead
     298   +
          */
    +  299   +
         @Deprecated
    +  300  
         public void setUpdateOnly(boolean updateOnly) {
    -  299  0
             this.updateOnly = updateOnly;
    -  300  0
         }
    -  301   -
     
    -  302   -
         /**
    +  301  0
             this.updateOnly = updateOnly;
    +  302  0
         }
     303   -
          * The report format to be generated (HTML, XML, VULN, ALL). Default is
    +
     
     304   -
          * HTML.
    +
         /**
     305   -
          */
    -  306  8
         private String reportFormat = "HTML";
    +
          * The report format to be generated (HTML, XML, VULN, ALL). Default is
    +  306   +
          * HTML.
     307   -
     
    -  308   -
         /**
    +
          */
    +  308  4
         private String reportFormat = "HTML";
     309   -
          * Get the value of reportFormat.
    +
     
     310   -
          *
    +
         /**
     311   -
          * @return the value of reportFormat
    +
          * Get the value of reportFormat.
     312   -
          */
    +
          *
     313   -
         public String getReportFormat() {
    -  314  0
             return reportFormat;
    +
          * @return the value of reportFormat
    +  314   +
          */
     315   -
         }
    -  316   -
     
    +
         public String getReportFormat() {
    +  316  0
             return reportFormat;
     317   -
         /**
    +
         }
     318   -
          * Set the value of reportFormat.
    +
     
     319   -
          *
    +
         /**
     320   -
          * @param reportFormat new value of reportFormat
    +
          * Set the value of reportFormat.
     321   -
          */
    +
          *
     322   +
          * @param reportFormat new value of reportFormat
    +  323   +
          */
    +  324  
         public void setReportFormat(ReportFormats reportFormat) {
    -  323  8
             this.reportFormat = reportFormat.getValue();
    -  324  8
         }
    -  325   -
         /**
    -  326   -
          * The path to the suppression file.
    +  325  4
             this.reportFormat = reportFormat.getValue();
    +  326  4
         }
     327   -
          */
    +
         /**
     328   -
         private String suppressionFile;
    +
          * The path to the suppression file.
     329   -
     
    +
          */
     330   -
         /**
    +
         private String suppressionFile;
     331   -
          * Get the value of suppressionFile.
    +
     
     332   -
          *
    +
         /**
     333   -
          * @return the value of suppressionFile
    +
          * Get the value of suppressionFile.
     334   -
          */
    +
          *
     335   -
         public String getSuppressionFile() {
    -  336  0
             return suppressionFile;
    +
          * @return the value of suppressionFile
    +  336   +
          */
     337   -
         }
    -  338   -
     
    +
         public String getSuppressionFile() {
    +  338  0
             return suppressionFile;
     339   -
         /**
    +
         }
     340   -
          * Set the value of suppressionFile.
    +
     
     341   -
          *
    +
         /**
     342   -
          * @param suppressionFile new value of suppressionFile
    +
          * Set the value of suppressionFile.
     343   -
          */
    +
          *
     344   +
          * @param suppressionFile new value of suppressionFile
    +  345   +
          */
    +  346  
         public void setSuppressionFile(String suppressionFile) {
    -  345  0
             this.suppressionFile = suppressionFile;
    -  346  0
         }
    -  347   -
         /**
    -  348   -
          * flag indicating whether or not to show a summary of findings.
    +  347  0
             this.suppressionFile = suppressionFile;
    +  348  0
         }
     349   -
          */
    -  350  8
         private boolean showSummary = true;
    +
         /**
    +  350   +
          * flag indicating whether or not to show a summary of findings.
     351   -
     
    -  352   -
         /**
    +
          */
    +  352  4
         private boolean showSummary = true;
     353   -
          * Get the value of showSummary.
    +
     
     354   -
          *
    +
         /**
     355   -
          * @return the value of showSummary
    +
          * Get the value of showSummary.
     356   -
          */
    +
          *
     357   -
         public boolean isShowSummary() {
    -  358  0
             return showSummary;
    +
          * @return the value of showSummary
    +  358   +
          */
     359   -
         }
    -  360   -
     
    +
         public boolean isShowSummary() {
    +  360  0
             return showSummary;
     361   -
         /**
    +
         }
     362   -
          * Set the value of showSummary.
    +
     
     363   -
          *
    +
         /**
     364   -
          * @param showSummary new value of showSummary
    +
          * Set the value of showSummary.
     365   -
          */
    +
          *
     366   +
          * @param showSummary new value of showSummary
    +  367   +
          */
    +  368  
         public void setShowSummary(boolean showSummary) {
    -  367  0
             this.showSummary = showSummary;
    -  368  0
         }
    -  369   -
     
    -  370   -
         /**
    +  369  0
             this.showSummary = showSummary;
    +  370  0
         }
     371   -
          * Whether experimental analyzers are enabled.
    +
     
     372   -
          */
    +
         /**
     373   -
         private Boolean enableExperimental;
    +
          * Whether experimental analyzers are enabled.
     374   -
     
    +
          */
     375   -
         /**
    +
         private Boolean enableExperimental;
     376   -
          * Get the value of enableExperimental.
    +
     
     377   -
          *
    +
         /**
     378   -
          * @return the value of enableExperimental
    +
          * Get the value of enableExperimental.
     379   -
          */
    +
          *
     380   -
         public Boolean isEnableExperimental() {
    -  381  0
             return enableExperimental;
    +
          * @return the value of enableExperimental
    +  381   +
          */
     382   -
         }
    -  383   -
     
    +
         public Boolean isEnableExperimental() {
    +  383  0
             return enableExperimental;
     384   -
         /**
    +
         }
     385   -
          * Set the value of enableExperimental.
    +
     
     386   -
          *
    +
         /**
     387   -
          * @param enableExperimental new value of enableExperimental
    +
          * Set the value of enableExperimental.
     388   -
          */
    +
          *
     389   +
          * @param enableExperimental new value of enableExperimental
    +  390   +
          */
    +  391  
         public void setEnableExperimental(Boolean enableExperimental) {
    -  390  0
             this.enableExperimental = enableExperimental;
    -  391  0
         }
    -  392   -
     
    -  393   -
         /**
    +  392  0
             this.enableExperimental = enableExperimental;
    +  393  0
         }
     394   -
          * Whether or not the Jar Analyzer is enabled.
    +
     
     395   -
          */
    +
         /**
     396   -
         private Boolean jarAnalyzerEnabled;
    +
          * Whether or not the Jar Analyzer is enabled.
     397   -
     
    +
          */
     398   -
         /**
    +
         private Boolean jarAnalyzerEnabled;
     399   -
          * Returns whether or not the analyzer is enabled.
    +
     
     400   -
          *
    +
         /**
     401   -
          * @return true if the analyzer is enabled
    +
          * Returns whether or not the analyzer is enabled.
     402   -
          */
    +
          *
     403   -
         public Boolean isJarAnalyzerEnabled() {
    -  404  0
             return jarAnalyzerEnabled;
    +
          * @return true if the analyzer is enabled
    +  404   +
          */
     405   -
         }
    -  406   -
     
    +
         public Boolean isJarAnalyzerEnabled() {
    +  406  0
             return jarAnalyzerEnabled;
     407   -
         /**
    +
         }
     408   -
          * Sets whether or not the analyzer is enabled.
    +
     
     409   -
          *
    +
         /**
     410   -
          * @param jarAnalyzerEnabled the value of the new setting
    +
          * Sets whether or not the analyzer is enabled.
     411   -
          */
    +
          *
     412   +
          * @param jarAnalyzerEnabled the value of the new setting
    +  413   +
          */
    +  414  
         public void setJarAnalyzerEnabled(Boolean jarAnalyzerEnabled) {
    -  413  0
             this.jarAnalyzerEnabled = jarAnalyzerEnabled;
    -  414  0
         }
    -  415   -
         /**
    -  416   -
          * Whether or not the Archive Analyzer is enabled.
    +  415  0
             this.jarAnalyzerEnabled = jarAnalyzerEnabled;
    +  416  0
         }
     417   -
          */
    +
         /**
     418   -
         private Boolean archiveAnalyzerEnabled;
    +
          * Whether or not the Archive Analyzer is enabled.
     419   -
     
    +
          */
     420   -
         /**
    +
         private Boolean archiveAnalyzerEnabled;
     421   -
          * Returns whether or not the analyzer is enabled.
    +
     
     422   -
          *
    +
         /**
     423   -
          * @return true if the analyzer is enabled
    +
          * Returns whether or not the analyzer is enabled.
     424   -
          */
    +
          *
     425   -
         public Boolean isArchiveAnalyzerEnabled() {
    -  426  0
             return archiveAnalyzerEnabled;
    +
          * @return true if the analyzer is enabled
    +  426   +
          */
     427   -
         }
    -  428   -
         /**
    +
         public Boolean isArchiveAnalyzerEnabled() {
    +  428  0
             return archiveAnalyzerEnabled;
     429   -
          * Whether or not the .NET Assembly Analyzer is enabled.
    +
         }
     430   -
          */
    +
         /**
     431   -
         private Boolean assemblyAnalyzerEnabled;
    +
          * Whether or not the .NET Assembly Analyzer is enabled.
     432   -
     
    +
          */
     433   -
         /**
    +
         private Boolean assemblyAnalyzerEnabled;
     434   -
          * Sets whether or not the analyzer is enabled.
    +
     
     435   -
          *
    +
         /**
     436   -
          * @param archiveAnalyzerEnabled the value of the new setting
    +
          * Sets whether or not the analyzer is enabled.
     437   -
          */
    +
          *
     438   +
          * @param archiveAnalyzerEnabled the value of the new setting
    +  439   +
          */
    +  440  
         public void setArchiveAnalyzerEnabled(Boolean archiveAnalyzerEnabled) {
    -  439  0
             this.archiveAnalyzerEnabled = archiveAnalyzerEnabled;
    -  440  0
         }
    -  441   -
     
    -  442   -
         /**
    +  441  0
             this.archiveAnalyzerEnabled = archiveAnalyzerEnabled;
    +  442  0
         }
     443   -
          * Returns whether or not the analyzer is enabled.
    +
     
     444   -
          *
    +
         /**
     445   -
          * @return true if the analyzer is enabled
    -  446   -
          */
    -  447   -
         public Boolean isAssemblyAnalyzerEnabled() {
    -  448  0
             return assemblyAnalyzerEnabled;
    -  449   -
         }
    -  450   -
     
    -  451   -
         /**
    -  452   -
          * Sets whether or not the analyzer is enabled.
    -  453   -
          *
    -  454   -
          * @param assemblyAnalyzerEnabled the value of the new setting
    -  455   -
          */
    -  456   -
         public void setAssemblyAnalyzerEnabled(Boolean assemblyAnalyzerEnabled) {
    -  457  0
             this.assemblyAnalyzerEnabled = assemblyAnalyzerEnabled;
    -  458  0
         }
    -  459   -
         /**
    -  460   -
          * Whether or not the .NET Nuspec Analyzer is enabled.
    -  461   -
          */
    -  462   -
         private Boolean nuspecAnalyzerEnabled;
    -  463   -
     
    -  464   -
         /**
    -  465  
          * Returns whether or not the analyzer is enabled.
    -  466   +  446  
          *
    -  467   +  447  
          * @return true if the analyzer is enabled
    -  468   +  448  
          */
    -  469   -
         public Boolean isNuspecAnalyzerEnabled() {
    -  470  0
             return nuspecAnalyzerEnabled;
    -  471   +  449   +
         public Boolean isAssemblyAnalyzerEnabled() {
    +  450  0
             return assemblyAnalyzerEnabled;
    +  451  
         }
    -  472   +  452  
     
    -  473   +  453  
         /**
    -  474   +  454  
          * Sets whether or not the analyzer is enabled.
    +  455   +
          *
    +  456   +
          * @param assemblyAnalyzerEnabled the value of the new setting
    +  457   +
          */
    +  458   +
         public void setAssemblyAnalyzerEnabled(Boolean assemblyAnalyzerEnabled) {
    +  459  0
             this.assemblyAnalyzerEnabled = assemblyAnalyzerEnabled;
    +  460  0
         }
    +  461   +
         /**
    +  462   +
          * Whether or not the .NET Nuspec Analyzer is enabled.
    +  463   +
          */
    +  464   +
         private Boolean nuspecAnalyzerEnabled;
    +  465   +
     
    +  466   +
         /**
    +  467   +
          * Returns whether or not the analyzer is enabled.
    +  468   +
          *
    +  469   +
          * @return true if the analyzer is enabled
    +  470   +
          */
    +  471   +
         public Boolean isNuspecAnalyzerEnabled() {
    +  472  0
             return nuspecAnalyzerEnabled;
    +  473   +
         }
    +  474   +
     
     475   -
          *
    +
         /**
     476   -
          * @param nuspecAnalyzerEnabled the value of the new setting
    +
          * Sets whether or not the analyzer is enabled.
     477   -
          */
    +
          *
     478   +
          * @param nuspecAnalyzerEnabled the value of the new setting
    +  479   +
          */
    +  480  
         public void setNuspecAnalyzerEnabled(Boolean nuspecAnalyzerEnabled) {
    -  479  0
             this.nuspecAnalyzerEnabled = nuspecAnalyzerEnabled;
    -  480  0
         }
    -  481   -
         /**
    -  482   -
          * Whether or not the PHP Composer Analyzer is enabled.
    +  481  0
             this.nuspecAnalyzerEnabled = nuspecAnalyzerEnabled;
    +  482  0
         }
     483   -
          */
    +
         /**
     484   -
         private Boolean composerAnalyzerEnabled;
    +
          * Whether or not the PHP Composer Analyzer is enabled.
     485   -
     
    +
          */
     486   -
         /**
    +
         private Boolean composerAnalyzerEnabled;
     487   -
          * Get the value of composerAnalyzerEnabled.
    +
     
     488   -
          *
    +
         /**
     489   -
          * @return the value of composerAnalyzerEnabled
    +
          * Get the value of composerAnalyzerEnabled.
     490   -
          */
    +
          *
     491   -
         public Boolean isComposerAnalyzerEnabled() {
    -  492  0
             return composerAnalyzerEnabled;
    +
          * @return the value of composerAnalyzerEnabled
    +  492   +
          */
     493   -
         }
    -  494   -
     
    +
         public Boolean isComposerAnalyzerEnabled() {
    +  494  0
             return composerAnalyzerEnabled;
     495   -
         /**
    +
         }
     496   -
          * Set the value of composerAnalyzerEnabled.
    +
     
     497   -
          *
    +
         /**
     498   -
          * @param composerAnalyzerEnabled new value of composerAnalyzerEnabled
    +
          * Set the value of composerAnalyzerEnabled.
     499   -
          */
    +
          *
     500   +
          * @param composerAnalyzerEnabled new value of composerAnalyzerEnabled
    +  501   +
          */
    +  502  
         public void setComposerAnalyzerEnabled(Boolean composerAnalyzerEnabled) {
    -  501  0
             this.composerAnalyzerEnabled = composerAnalyzerEnabled;
    -  502  0
         }
    -  503   -
         /**
    -  504   -
          * Whether the autoconf analyzer should be enabled.
    +  503  0
             this.composerAnalyzerEnabled = composerAnalyzerEnabled;
    +  504  0
         }
     505   -
          */
    +
         /**
     506   -
         private Boolean autoconfAnalyzerEnabled;
    +
          * Whether the autoconf analyzer should be enabled.
     507   -
     
    +
          */
     508   -
         /**
    +
         private Boolean autoconfAnalyzerEnabled;
     509   -
          * Get the value of autoconfAnalyzerEnabled.
    +
     
     510   -
          *
    +
         /**
     511   -
          * @return the value of autoconfAnalyzerEnabled
    +
          * Get the value of autoconfAnalyzerEnabled.
     512   -
          */
    +
          *
     513   -
         public Boolean isAutoconfAnalyzerEnabled() {
    -  514  0
             return autoconfAnalyzerEnabled;
    +
          * @return the value of autoconfAnalyzerEnabled
    +  514   +
          */
     515   -
         }
    -  516   -
     
    +
         public Boolean isAutoconfAnalyzerEnabled() {
    +  516  0
             return autoconfAnalyzerEnabled;
     517   -
         /**
    +
         }
     518   -
          * Set the value of autoconfAnalyzerEnabled.
    +
     
     519   -
          *
    +
         /**
     520   -
          * @param autoconfAnalyzerEnabled new value of autoconfAnalyzerEnabled
    +
          * Set the value of autoconfAnalyzerEnabled.
     521   -
          */
    +
          *
     522   +
          * @param autoconfAnalyzerEnabled new value of autoconfAnalyzerEnabled
    +  523   +
          */
    +  524  
         public void setAutoconfAnalyzerEnabled(Boolean autoconfAnalyzerEnabled) {
    -  523  0
             this.autoconfAnalyzerEnabled = autoconfAnalyzerEnabled;
    -  524  0
         }
    -  525   -
         /**
    -  526   -
          * Whether the CMake analyzer should be enabled.
    +  525  0
             this.autoconfAnalyzerEnabled = autoconfAnalyzerEnabled;
    +  526  0
         }
     527   -
          */
    +
         /**
     528   -
         private Boolean cmakeAnalyzerEnabled;
    +
          * Whether the CMake analyzer should be enabled.
     529   -
     
    +
          */
     530   -
         /**
    +
         private Boolean cmakeAnalyzerEnabled;
     531   -
          * Get the value of cmakeAnalyzerEnabled.
    +
     
     532   -
          *
    +
         /**
     533   -
          * @return the value of cmakeAnalyzerEnabled
    +
          * Get the value of cmakeAnalyzerEnabled.
     534   -
          */
    +
          *
     535   -
         public Boolean isCMakeAnalyzerEnabled() {
    -  536  0
             return cmakeAnalyzerEnabled;
    +
          * @return the value of cmakeAnalyzerEnabled
    +  536   +
          */
     537   -
         }
    -  538   -
     
    +
         public Boolean isCMakeAnalyzerEnabled() {
    +  538  0
             return cmakeAnalyzerEnabled;
     539   -
         /**
    +
         }
     540   -
          * Set the value of cmakeAnalyzerEnabled.
    +
     
     541   -
          *
    +
         /**
     542   -
          * @param cmakeAnalyzerEnabled new value of cmakeAnalyzerEnabled
    +
          * Set the value of cmakeAnalyzerEnabled.
     543   -
          */
    +
          *
     544   +
          * @param cmakeAnalyzerEnabled new value of cmakeAnalyzerEnabled
    +  545   +
          */
    +  546  
         public void setCMakeAnalyzerEnabled(Boolean cmakeAnalyzerEnabled) {
    -  545  0
             this.cmakeAnalyzerEnabled = cmakeAnalyzerEnabled;
    -  546  0
         }
    -  547   -
         /**
    -  548   -
          * Whether or not the openssl analyzer is enabled.
    +  547  0
             this.cmakeAnalyzerEnabled = cmakeAnalyzerEnabled;
    +  548  0
         }
     549   -
          */
    +
         /**
     550   -
         private Boolean opensslAnalyzerEnabled;
    +
          * Whether or not the openssl analyzer is enabled.
     551   -
     
    +
          */
     552   -
         /**
    +
         private Boolean opensslAnalyzerEnabled;
     553   -
          * Get the value of opensslAnalyzerEnabled.
    +
     
     554   -
          *
    +
         /**
     555   -
          * @return the value of opensslAnalyzerEnabled
    +
          * Get the value of opensslAnalyzerEnabled.
     556   -
          */
    +
          *
     557   -
         public Boolean isOpensslAnalyzerEnabled() {
    -  558  0
             return opensslAnalyzerEnabled;
    +
          * @return the value of opensslAnalyzerEnabled
    +  558   +
          */
     559   -
         }
    -  560   -
     
    +
         public Boolean isOpensslAnalyzerEnabled() {
    +  560  0
             return opensslAnalyzerEnabled;
     561   -
         /**
    +
         }
     562   -
          * Set the value of opensslAnalyzerEnabled.
    +
     
     563   -
          *
    +
         /**
     564   -
          * @param opensslAnalyzerEnabled new value of opensslAnalyzerEnabled
    +
          * Set the value of opensslAnalyzerEnabled.
     565   -
          */
    +
          *
     566   +
          * @param opensslAnalyzerEnabled new value of opensslAnalyzerEnabled
    +  567   +
          */
    +  568  
         public void setOpensslAnalyzerEnabled(Boolean opensslAnalyzerEnabled) {
    -  567  0
             this.opensslAnalyzerEnabled = opensslAnalyzerEnabled;
    -  568  0
         }
    -  569   -
         /**
    -  570   -
          * Whether or not the Node.js Analyzer is enabled.
    +  569  0
             this.opensslAnalyzerEnabled = opensslAnalyzerEnabled;
    +  570  0
         }
     571   -
          */
    +
         /**
     572   -
         private Boolean nodeAnalyzerEnabled;
    +
          * Whether or not the Node.js Analyzer is enabled.
     573   -
     
    +
          */
     574   -
         /**
    +
         private Boolean nodeAnalyzerEnabled;
     575   -
          * Get the value of nodeAnalyzerEnabled.
    +
     
     576   -
          *
    +
         /**
     577   -
          * @return the value of nodeAnalyzerEnabled
    +
          * Get the value of nodeAnalyzerEnabled.
     578   -
          */
    +
          *
     579   -
         public Boolean isNodeAnalyzerEnabled() {
    -  580  0
             return nodeAnalyzerEnabled;
    +
          * @return the value of nodeAnalyzerEnabled
    +  580   +
          */
     581   -
         }
    -  582   -
     
    +
         public Boolean isNodeAnalyzerEnabled() {
    +  582  0
             return nodeAnalyzerEnabled;
     583   -
         /**
    +
         }
     584   -
          * Set the value of nodeAnalyzerEnabled.
    +
     
     585   -
          *
    +
         /**
     586   -
          * @param nodeAnalyzerEnabled new value of nodeAnalyzerEnabled
    +
          * Set the value of nodeAnalyzerEnabled.
     587   -
          */
    +
          *
     588   +
          * @param nodeAnalyzerEnabled new value of nodeAnalyzerEnabled
    +  589   +
          */
    +  590  
         public void setNodeAnalyzerEnabled(Boolean nodeAnalyzerEnabled) {
    -  589  0
             this.nodeAnalyzerEnabled = nodeAnalyzerEnabled;
    -  590  0
         }
    -  591   -
         /**
    -  592   -
          * Whether the ruby gemspec analyzer should be enabled.
    +  591  0
             this.nodeAnalyzerEnabled = nodeAnalyzerEnabled;
    +  592  0
         }
     593   -
          */
    +
         /**
     594   -
         private Boolean rubygemsAnalyzerEnabled;
    +
          * Whether the ruby gemspec analyzer should be enabled.
     595   -
     
    +
          */
     596   -
         /**
    +
         private Boolean rubygemsAnalyzerEnabled;
     597   -
          * Get the value of rubygemsAnalyzerEnabled.
    +
     
     598   -
          *
    +
         /**
     599   -
          * @return the value of rubygemsAnalyzerEnabled
    +
          * Get the value of rubygemsAnalyzerEnabled.
     600   -
          */
    +
          *
     601   -
         public Boolean isRubygemsAnalyzerEnabled() {
    -  602  0
             return rubygemsAnalyzerEnabled;
    +
          * @return the value of rubygemsAnalyzerEnabled
    +  602   +
          */
     603   -
         }
    -  604   -
     
    +
         public Boolean isRubygemsAnalyzerEnabled() {
    +  604  0
             return rubygemsAnalyzerEnabled;
     605   -
         /**
    +
         }
     606   -
          * Set the value of rubygemsAnalyzerEnabled.
    +
     
     607   -
          *
    +
         /**
     608   -
          * @param rubygemsAnalyzerEnabled new value of rubygemsAnalyzerEnabled
    +
          * Set the value of rubygemsAnalyzerEnabled.
     609   -
          */
    +
          *
     610   +
          * @param rubygemsAnalyzerEnabled new value of rubygemsAnalyzerEnabled
    +  611   +
          */
    +  612  
         public void setRubygemsAnalyzerEnabled(Boolean rubygemsAnalyzerEnabled) {
    -  611  0
             this.rubygemsAnalyzerEnabled = rubygemsAnalyzerEnabled;
    -  612  0
         }
    -  613   -
         /**
    -  614   -
          * Whether the python package analyzer should be enabled.
    +  613  0
             this.rubygemsAnalyzerEnabled = rubygemsAnalyzerEnabled;
    +  614  0
         }
     615   -
          */
    +
         /**
     616   -
         private Boolean pyPackageAnalyzerEnabled;
    +
          * Whether the python package analyzer should be enabled.
     617   -
     
    +
          */
     618   -
         /**
    +
         private Boolean pyPackageAnalyzerEnabled;
     619   -
          * Get the value of pyPackageAnalyzerEnabled.
    +
     
     620   -
          *
    +
         /**
     621   -
          * @return the value of pyPackageAnalyzerEnabled
    +
          * Get the value of pyPackageAnalyzerEnabled.
     622   -
          */
    +
          *
     623   -
         public Boolean isPyPackageAnalyzerEnabled() {
    -  624  0
             return pyPackageAnalyzerEnabled;
    +
          * @return the value of pyPackageAnalyzerEnabled
    +  624   +
          */
     625   -
         }
    -  626   -
     
    +
         public Boolean isPyPackageAnalyzerEnabled() {
    +  626  0
             return pyPackageAnalyzerEnabled;
     627   -
         /**
    +
         }
     628   -
          * Set the value of pyPackageAnalyzerEnabled.
    +
     
     629   -
          *
    +
         /**
     630   -
          * @param pyPackageAnalyzerEnabled new value of pyPackageAnalyzerEnabled
    +
          * Set the value of pyPackageAnalyzerEnabled.
     631   -
          */
    +
          *
     632   +
          * @param pyPackageAnalyzerEnabled new value of pyPackageAnalyzerEnabled
    +  633   +
          */
    +  634  
         public void setPyPackageAnalyzerEnabled(Boolean pyPackageAnalyzerEnabled) {
    -  633  0
             this.pyPackageAnalyzerEnabled = pyPackageAnalyzerEnabled;
    -  634  0
         }
    -  635   -
     
    -  636   -
         /**
    +  635  0
             this.pyPackageAnalyzerEnabled = pyPackageAnalyzerEnabled;
    +  636  0
         }
     637   -
          * Whether the python distribution analyzer should be enabled.
    +
     
     638   -
          */
    +
         /**
     639   -
         private Boolean pyDistributionAnalyzerEnabled;
    +
          * Whether the python distribution analyzer should be enabled.
     640   -
     
    +
          */
     641   -
         /**
    +
         private Boolean pyDistributionAnalyzerEnabled;
     642   -
          * Get the value of pyDistributionAnalyzerEnabled.
    +
     
     643   -
          *
    +
         /**
     644   -
          * @return the value of pyDistributionAnalyzerEnabled
    +
          * Get the value of pyDistributionAnalyzerEnabled.
     645   -
          */
    +
          *
     646   -
         public Boolean isPyDistributionAnalyzerEnabled() {
    -  647  0
             return pyDistributionAnalyzerEnabled;
    +
          * @return the value of pyDistributionAnalyzerEnabled
    +  647   +
          */
     648   -
         }
    -  649   -
     
    +
         public Boolean isPyDistributionAnalyzerEnabled() {
    +  649  0
             return pyDistributionAnalyzerEnabled;
     650   -
         /**
    +
         }
     651   -
          * Set the value of pyDistributionAnalyzerEnabled.
    +
     
     652   -
          *
    +
         /**
     653   -
          * @param pyDistributionAnalyzerEnabled new value of
    +
          * Set the value of pyDistributionAnalyzerEnabled.
     654   -
          * pyDistributionAnalyzerEnabled
    +
          *
     655   -
          */
    +
          * @param pyDistributionAnalyzerEnabled new value of
     656   +
          * pyDistributionAnalyzerEnabled
    +  657   +
          */
    +  658  
         public void setPyDistributionAnalyzerEnabled(Boolean pyDistributionAnalyzerEnabled) {
    -  657  0
             this.pyDistributionAnalyzerEnabled = pyDistributionAnalyzerEnabled;
    -  658  0
         }
    -  659   -
     
    -  660   -
         /**
    +  659  0
             this.pyDistributionAnalyzerEnabled = pyDistributionAnalyzerEnabled;
    +  660  0
         }
     661   -
          * Whether or not the central analyzer is enabled.
    +
     
     662   -
          */
    +
         /**
     663   -
         private Boolean centralAnalyzerEnabled;
    +
          * Whether or not the central analyzer is enabled.
     664   -
     
    +
          */
     665   -
         /**
    +
         private Boolean centralAnalyzerEnabled;
     666   -
          * Get the value of centralAnalyzerEnabled.
    +
     
     667   -
          *
    +
         /**
     668   -
          * @return the value of centralAnalyzerEnabled
    +
          * Get the value of centralAnalyzerEnabled.
     669   -
          */
    +
          *
     670   -
         public Boolean isCentralAnalyzerEnabled() {
    -  671  0
             return centralAnalyzerEnabled;
    +
          * @return the value of centralAnalyzerEnabled
    +  671   +
          */
     672   -
         }
    -  673   -
     
    +
         public Boolean isCentralAnalyzerEnabled() {
    +  673  0
             return centralAnalyzerEnabled;
     674   -
         /**
    +
         }
     675   -
          * Set the value of centralAnalyzerEnabled.
    +
     
     676   -
          *
    +
         /**
     677   -
          * @param centralAnalyzerEnabled new value of centralAnalyzerEnabled
    +
          * Set the value of centralAnalyzerEnabled.
     678   -
          */
    +
          *
     679   +
          * @param centralAnalyzerEnabled new value of centralAnalyzerEnabled
    +  680   +
          */
    +  681  
         public void setCentralAnalyzerEnabled(Boolean centralAnalyzerEnabled) {
    -  680  0
             this.centralAnalyzerEnabled = centralAnalyzerEnabled;
    -  681  0
         }
    -  682   -
     
    -  683   -
         /**
    +  682  0
             this.centralAnalyzerEnabled = centralAnalyzerEnabled;
    +  683  0
         }
     684   -
          * Whether or not the nexus analyzer is enabled.
    +
     
     685   -
          */
    +
         /**
     686   -
         private Boolean nexusAnalyzerEnabled;
    +
          * Whether or not the nexus analyzer is enabled.
     687   -
     
    +
          */
     688   -
         /**
    +
         private Boolean nexusAnalyzerEnabled;
     689   -
          * Get the value of nexusAnalyzerEnabled.
    +
     
     690   -
          *
    +
         /**
     691   -
          * @return the value of nexusAnalyzerEnabled
    +
          * Get the value of nexusAnalyzerEnabled.
     692   -
          */
    +
          *
     693   -
         public Boolean isNexusAnalyzerEnabled() {
    -  694  0
             return nexusAnalyzerEnabled;
    +
          * @return the value of nexusAnalyzerEnabled
    +  694   +
          */
     695   -
         }
    -  696   -
     
    +
         public Boolean isNexusAnalyzerEnabled() {
    +  696  0
             return nexusAnalyzerEnabled;
     697   -
         /**
    +
         }
     698   -
          * Set the value of nexusAnalyzerEnabled.
    +
     
     699   -
          *
    +
         /**
     700   -
          * @param nexusAnalyzerEnabled new value of nexusAnalyzerEnabled
    +
          * Set the value of nexusAnalyzerEnabled.
     701   -
          */
    +
          *
     702   +
          * @param nexusAnalyzerEnabled new value of nexusAnalyzerEnabled
    +  703   +
          */
    +  704  
         public void setNexusAnalyzerEnabled(Boolean nexusAnalyzerEnabled) {
    -  703  0
             this.nexusAnalyzerEnabled = nexusAnalyzerEnabled;
    -  704  0
         }
    -  705   -
     
    -  706   -
         /**
    +  705  0
             this.nexusAnalyzerEnabled = nexusAnalyzerEnabled;
    +  706  0
         }
     707   -
          * The URL of a Nexus server's REST API end point
    +
     
     708   -
          * (http://domain/nexus/service/local).
    +
         /**
     709   -
          */
    +
          * The URL of a Nexus server's REST API end point
     710   -
         private String nexusUrl;
    +
          * (http://domain/nexus/service/local).
     711   -
     
    +
          */
     712   -
         /**
    +
         private String nexusUrl;
     713   -
          * Get the value of nexusUrl.
    +
     
     714   -
          *
    +
         /**
     715   -
          * @return the value of nexusUrl
    +
          * Get the value of nexusUrl.
     716   -
          */
    +
          *
     717   -
         public String getNexusUrl() {
    -  718  0
             return nexusUrl;
    +
          * @return the value of nexusUrl
    +  718   +
          */
     719   -
         }
    -  720   -
     
    +
         public String getNexusUrl() {
    +  720  0
             return nexusUrl;
     721   -
         /**
    +
         }
     722   -
          * Set the value of nexusUrl.
    +
     
     723   -
          *
    +
         /**
     724   -
          * @param nexusUrl new value of nexusUrl
    +
          * Set the value of nexusUrl.
     725   -
          */
    +
          *
     726   +
          * @param nexusUrl new value of nexusUrl
    +  727   +
          */
    +  728  
         public void setNexusUrl(String nexusUrl) {
    -  727  0
             this.nexusUrl = nexusUrl;
    -  728  0
         }
    -  729   -
         /**
    -  730   -
          * Whether or not the defined proxy should be used when connecting to Nexus.
    +  729  0
             this.nexusUrl = nexusUrl;
    +  730  0
         }
     731   -
          */
    +
         /**
     732   -
         private Boolean nexusUsesProxy;
    +
          * Whether or not the defined proxy should be used when connecting to Nexus.
     733   -
     
    +
          */
     734   -
         /**
    +
         private Boolean nexusUsesProxy;
     735   -
          * Get the value of nexusUsesProxy.
    +
     
     736   -
          *
    +
         /**
     737   -
          * @return the value of nexusUsesProxy
    +
          * Get the value of nexusUsesProxy.
     738   -
          */
    +
          *
     739   -
         public Boolean isNexusUsesProxy() {
    -  740  0
             return nexusUsesProxy;
    +
          * @return the value of nexusUsesProxy
    +  740   +
          */
     741   -
         }
    -  742   -
     
    +
         public Boolean isNexusUsesProxy() {
    +  742  0
             return nexusUsesProxy;
     743   -
         /**
    +
         }
     744   -
          * Set the value of nexusUsesProxy.
    +
     
     745   -
          *
    +
         /**
     746   -
          * @param nexusUsesProxy new value of nexusUsesProxy
    +
          * Set the value of nexusUsesProxy.
     747   -
          */
    +
          *
     748   +
          * @param nexusUsesProxy new value of nexusUsesProxy
    +  749   +
          */
    +  750  
         public void setNexusUsesProxy(Boolean nexusUsesProxy) {
    -  749  0
             this.nexusUsesProxy = nexusUsesProxy;
    -  750  0
         }
    -  751   -
     
    -  752   -
         /**
    +  751  0
             this.nexusUsesProxy = nexusUsesProxy;
    +  752  0
         }
     753   -
          * Additional ZIP File extensions to add analyze. This should be a
    +
     
     754   -
          * comma-separated list of file extensions to treat like ZIP files.
    +
         /**
     755   -
          */
    +
          * Additional ZIP File extensions to add analyze. This should be a
     756   -
         private String zipExtensions;
    +
          * comma-separated list of file extensions to treat like ZIP files.
     757   -
     
    +
          */
     758   -
         /**
    +
         private String zipExtensions;
     759   -
          * Get the value of zipExtensions.
    +
     
     760   -
          *
    +
         /**
     761   -
          * @return the value of zipExtensions
    +
          * Get the value of zipExtensions.
     762   -
          */
    +
          *
     763   -
         public String getZipExtensions() {
    -  764  0
             return zipExtensions;
    +
          * @return the value of zipExtensions
    +  764   +
          */
     765   -
         }
    -  766   -
     
    +
         public String getZipExtensions() {
    +  766  0
             return zipExtensions;
     767   -
         /**
    -  768   -
          * Set the value of zipExtensions.
    -  769   -
          *
    -  770   -
          * @param zipExtensions new value of zipExtensions
    -  771   -
          */
    -  772   -
         public void setZipExtensions(String zipExtensions) {
    -  773  0
             this.zipExtensions = zipExtensions;
    -  774  0
         }
    -  775   -
     
    -  776   -
         /**
    -  777   -
          * The path to Mono for .NET assembly analysis on non-windows systems.
    -  778   -
          */
    -  779   -
         private String pathToMono;
    -  780   -
     
    -  781   -
         /**
    -  782   -
          * Get the value of pathToMono.
    -  783   -
          *
    -  784   -
          * @return the value of pathToMono
    -  785   -
          */
    -  786   -
         public String getPathToMono() {
    -  787  0
             return pathToMono;
    -  788  
         }
    -  789   +  768  
     
    -  790   +  769  
         /**
    -  791   -
          * Set the value of pathToMono.
    -  792   +  770   +
          * Set the value of zipExtensions.
    +  771  
          *
    -  793   -
          * @param pathToMono new value of pathToMono
    -  794   +  772   +
          * @param zipExtensions new value of zipExtensions
    +  773  
          */
    -  795   -
         public void setPathToMono(String pathToMono) {
    -  796  0
             this.pathToMono = pathToMono;
    -  797  0
         }
    -  798   +  774   +
         public void setZipExtensions(String zipExtensions) {
    +  775  0
             this.zipExtensions = zipExtensions;
    +  776  0
         }
    +  777  
     
    -  799   -
         @Override
    +  778   +
         /**
    +  779   +
          * The path to Mono for .NET assembly analysis on non-windows systems.
    +  780   +
          */
    +  781   +
         private String pathToMono;
    +  782   +
     
    +  783   +
         /**
    +  784   +
          * Get the value of pathToMono.
    +  785   +
          *
    +  786   +
          * @return the value of pathToMono
    +  787   +
          */
    +  788   +
         public String getPathToMono() {
    +  789  0
             return pathToMono;
    +  790   +
         }
    +  791   +
     
    +  792   +
         /**
    +  793   +
          * Set the value of pathToMono.
    +  794   +
          *
    +  795   +
          * @param pathToMono new value of pathToMono
    +  796   +
          */
    +  797   +
         public void setPathToMono(String pathToMono) {
    +  798  0
             this.pathToMono = pathToMono;
    +  799  0
         }
     800   +
     
    +  801   +
         @Override
    +  802  
         public void execute() throws BuildException {
    -  801  8
             dealWithReferences();
    -  802  8
             validateConfiguration();
    -  803  6
             populateSettings();
    -  804  6
             Engine engine = null;
    -  805   +  803  4
             dealWithReferences();
    +  804  4
             validateConfiguration();
    +  805  3
             populateSettings();
    +  806  3
             Engine engine = null;
    +  807  
             try {
    -  806  6
                 engine = new Engine(Check.class.getClassLoader());
    -  807  6
                 if (isUpdateOnly()) {
    -  808  0
                     log("Deprecated 'UpdateOnly' property set; please use the UpdateTask instead", Project.MSG_WARN);
    -  809  0
                     engine.doUpdates();
    -  810   -
                 } else {
    +  808  3
                 engine = new Engine(Check.class.getClassLoader());
    +  809  3
                 if (isUpdateOnly()) {
    +  810  0
                     log("Deprecated 'UpdateOnly' property set; please use the UpdateTask instead", Project.MSG_WARN);
     811  
                     try {
    -  812  6
                         for (Resource resource : path) {
    -  813  10
                             final FileProvider provider = resource.as(FileProvider.class);
    -  814  10
                             if (provider != null) {
    -  815  10
                                 final File file = provider.getFile();
    -  816  10
                                 if (file != null && file.exists()) {
    -  817  8
                                     engine.scan(file);
    -  818   -
                                 }
    +  812  0
                         engine.doUpdates();
    +  813  0
                     } catch (UpdateException ex) {
    +  814  0
                         if (this.isFailOnError()) {
    +  815  0
                             throw new BuildException(ex);
    +  816   +
                         }
    +  817  0
                         log(ex.getMessage(), Project.MSG_ERR);
    +  818  0
                     }
     819   +
                 } else {
    +  820  3
                     for (Resource resource : path) {
    +  821  5
                         final FileProvider provider = resource.as(FileProvider.class);
    +  822  5
                         if (provider != null) {
    +  823  5
                             final File file = provider.getFile();
    +  824  5
                             if (file != null && file.exists()) {
    +  825  4
                                 engine.scan(file);
    +  826  
                             }
    -  820  10
                         }
    -  821   +  827   +
                         }
    +  828  5
                     }
    +  829  
     
    -  822  6
                         engine.analyzeDependencies();
    -  823  6
                         DatabaseProperties prop = null;
    -  824  6
                         CveDB cve = null;
    -  825   -
                         try {
    -  826  6
                             cve = new CveDB();
    -  827  6
                             cve.open();
    -  828  6
                             prop = cve.getDatabaseProperties();
    -  829  0
                         } catch (DatabaseException ex) {
    -  830  0
                             log("Unable to retrieve DB Properties", ex, Project.MSG_DEBUG);
    -  831   -
                         } finally {
    -  832  6
                             if (cve != null) {
    -  833  6
                                 cve.close();
    -  834   -
                             }
    +  830   +
                     try {
    +  831  3
                         engine.analyzeDependencies();
    +  832  0
                     } catch (ExceptionCollection ex) {
    +  833  0
                         if (this.isFailOnError()) {
    +  834  0
                             throw new BuildException(ex);
     835  
                         }
    -  836  6
                         final ReportGenerator reporter = new ReportGenerator(getProjectName(), engine.getDependencies(), engine.getAnalyzers(), prop);
    -  837  6
                         reporter.generateReports(reportOutputDirectory, reportFormat);
    -  838   -
     
    -  839  6
                         if (this.failBuildOnCVSS <= 10) {
    -  840  0
                             checkForFailure(engine.getDependencies());
    -  841   +  836  3
                     }
    +  837  3
                     DatabaseProperties prop = null;
    +  838  3
                     CveDB cve = null;
    +  839   +
                     try {
    +  840  3
                         cve = new CveDB();
    +  841  3
                         cve.open();
    +  842  3
                         prop = cve.getDatabaseProperties();
    +  843  0
                     } catch (DatabaseException ex) {
    +  844  0
                         log("Unable to retrieve DB Properties", ex, Project.MSG_DEBUG);
    +  845   +
                     } finally {
    +  846  3
                         if (cve != null) {
    +  847  3
                             cve.close();
    +  848  
                         }
    -  842  6
                         if (this.showSummary) {
    -  843  6
                             showSummary(engine.getDependencies());
    -  844   -
                         }
    -  845  0
                     } catch (IOException ex) {
    -  846  0
                         log("Unable to generate dependency-check report", ex, Project.MSG_DEBUG);
    -  847  0
                         throw new BuildException("Unable to generate dependency-check report", ex);
    -  848  0
                     } catch (Exception ex) {
    -  849  0
                         log("An exception occurred; unable to continue task", ex, Project.MSG_DEBUG);
    -  850  0
                         throw new BuildException("An exception occurred; unable to continue task", ex);
    -  851  6
                     }
    +  849   +
                     }
    +  850  3
                     final ReportGenerator reporter = new ReportGenerator(getProjectName(), engine.getDependencies(), engine.getAnalyzers(), prop);
    +  851  3
                     reporter.generateReports(reportOutputDirectory, reportFormat);
     852   -
                 }
    -  853  0
             } catch (DatabaseException ex) {
    -  854  0
                 log("Unable to connect to the dependency-check database; analysis has stopped", ex, Project.MSG_ERR);
    +
     
    +  853  3
                     if (this.failBuildOnCVSS <= 10) {
    +  854  0
                         checkForFailure(engine.getDependencies());
     855   -
             } finally {
    -  856  6
                 Settings.cleanup(true);
    -  857  6
                 if (engine != null) {
    -  858  6
                     engine.cleanup();
    +
                     }
    +  856  3
                     if (this.showSummary) {
    +  857  3
                         showSummary(engine.getDependencies());
    +  858   +
                     }
     859  
                 }
    -  860   -
             }
    -  861  6
         }
    -  862   -
     
    -  863   -
         /**
    +  860  0
             } catch (DatabaseException ex) {
    +  861  0
                 final String msg = "Unable to connect to the dependency-check database; analysis has stopped";
    +  862  0
                 if (this.isFailOnError()) {
    +  863  0
                     throw new BuildException(msg, ex);
     864   -
          * Validate the configuration to ensure the parameters have been properly
    -  865   -
          * configured/initialized.
    -  866   -
          *
    -  867   -
          * @throws BuildException if the task was not configured correctly.
    -  868   -
          */
    -  869   -
         private void validateConfiguration() throws BuildException {
    -  870  8
             if (path == null) {
    -  871  2
                 throw new BuildException("No project dependencies have been defined to analyze.");
    +
                 }
    +  865  0
                 log(msg, ex, Project.MSG_ERR);
    +  866  0
             } catch (ReportException ex) {
    +  867  0
                 final String msg = "Unable to generate the dependency-check report";
    +  868  0
                 if (this.isFailOnError()) {
    +  869  0
                     throw new BuildException(msg, ex);
    +  870   +
                 }
    +  871  0
                 log(msg, ex, Project.MSG_ERR);
     872   -
             }
    -  873  6
             if (failBuildOnCVSS < 0 || failBuildOnCVSS > 11) {
    -  874  0
                 throw new BuildException("Invalid configuration, failBuildOnCVSS must be between 0 and 11.");
    -  875   -
             }
    -  876  6
         }
    +
             } finally {
    +  873  3
                 Settings.cleanup(true);
    +  874  3
                 if (engine != null) {
    +  875  3
                     engine.cleanup();
    +  876   +
                 }
     877   -
     
    -  878   -
         /**
    +
             }
    +  878  3
         }
     879   -
          * Takes the properties supplied and updates the dependency-check settings.
    +
     
     880   -
          * Additionally, this sets the system properties required to change the
    +
         /**
     881   -
          * proxy server, port, and connection timeout.
    +
          * Validate the configuration to ensure the parameters have been properly
     882   -
          *
    +
          * configured/initialized.
     883   -
          * @throws BuildException thrown when an invalid setting is configured.
    +
          *
     884   -
          */
    +
          * @throws BuildException if the task was not configured correctly.
     885   -
         @Override
    +
          */
     886   +
         private void validateConfiguration() throws BuildException {
    +  887  4
             if (path == null) {
    +  888  1
                 throw new BuildException("No project dependencies have been defined to analyze.");
    +  889   +
             }
    +  890  3
             if (failBuildOnCVSS < 0 || failBuildOnCVSS > 11) {
    +  891  0
                 throw new BuildException("Invalid configuration, failBuildOnCVSS must be between 0 and 11.");
    +  892   +
             }
    +  893  3
         }
    +  894   +
     
    +  895   +
         /**
    +  896   +
          * Takes the properties supplied and updates the dependency-check settings.
    +  897   +
          * Additionally, this sets the system properties required to change the
    +  898   +
          * proxy server, port, and connection timeout.
    +  899   +
          *
    +  900   +
          * @throws BuildException thrown when an invalid setting is configured.
    +  901   +
          */
    +  902   +
         @Override
    +  903  
         protected void populateSettings() throws BuildException {
    -  887  6
             super.populateSettings();
    -  888  6
             Settings.setBooleanIfNotNull(Settings.KEYS.AUTO_UPDATE, autoUpdate);
    -  889  6
             Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile);
    -  890  6
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, enableExperimental);
    -  891  6
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_JAR_ENABLED, jarAnalyzerEnabled);
    -  892  6
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, pyDistributionAnalyzerEnabled);
    -  893  6
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, pyPackageAnalyzerEnabled);
    -  894  6
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED, rubygemsAnalyzerEnabled);
    -  895  6
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, opensslAnalyzerEnabled);
    -  896  6
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CMAKE_ENABLED, cmakeAnalyzerEnabled);
    -  897  6
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_AUTOCONF_ENABLED, autoconfAnalyzerEnabled);
    -  898  6
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED, composerAnalyzerEnabled);
    -  899  6
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED, nodeAnalyzerEnabled);
    -  900  6
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, nuspecAnalyzerEnabled);
    -  901  6
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, centralAnalyzerEnabled);
    -  902  6
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled);
    -  903  6
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, archiveAnalyzerEnabled);
    -  904  6
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, assemblyAnalyzerEnabled);
    -  905  6
             Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl);
    -  906  6
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy);
    -  907  6
             Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions);
    -  908  6
             Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono);
    -  909  6
         }
    -  910   +  904  3
             super.populateSettings();
    +  905  3
             Settings.setBooleanIfNotNull(Settings.KEYS.AUTO_UPDATE, autoUpdate);
    +  906  3
             Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile);
    +  907  3
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, enableExperimental);
    +  908  3
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_JAR_ENABLED, jarAnalyzerEnabled);
    +  909  3
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, pyDistributionAnalyzerEnabled);
    +  910  3
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, pyPackageAnalyzerEnabled);
    +  911  3
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED, rubygemsAnalyzerEnabled);
    +  912  3
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, opensslAnalyzerEnabled);
    +  913  3
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CMAKE_ENABLED, cmakeAnalyzerEnabled);
    +  914  3
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_AUTOCONF_ENABLED, autoconfAnalyzerEnabled);
    +  915  3
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED, composerAnalyzerEnabled);
    +  916  3
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED, nodeAnalyzerEnabled);
    +  917  3
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, nuspecAnalyzerEnabled);
    +  918  3
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, centralAnalyzerEnabled);
    +  919  3
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled);
    +  920  3
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, archiveAnalyzerEnabled);
    +  921  3
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, assemblyAnalyzerEnabled);
    +  922  3
             Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl);
    +  923  3
             Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy);
    +  924  3
             Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions);
    +  925  3
             Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono);
    +  926  3
         }
    +  927  
     
    -  911   -
         /**
    -  912   -
          * Checks to see if a vulnerability has been identified with a CVSS score
    -  913   -
          * that is above the threshold set in the configuration.
    -  914   -
          *
    -  915   -
          * @param dependencies the list of dependency objects
    -  916   -
          * @throws BuildException thrown if a CVSS score is found that is higher
    -  917   -
          * then the threshold set
    -  918   -
          */
    -  919   -
         private void checkForFailure(List<Dependency> dependencies) throws BuildException {
    -  920  0
             final StringBuilder ids = new StringBuilder();
    -  921  0
             for (Dependency d : dependencies) {
    -  922  0
                 for (Vulnerability v : d.getVulnerabilities()) {
    -  923  0
                     if (v.getCvssScore() >= failBuildOnCVSS) {
    -  924  0
                         if (ids.length() == 0) {
    -  925  0
                             ids.append(v.getName());
    -  926   -
                         } else {
    -  927  0
                             ids.append(", ").append(v.getName());
     928   -
                         }
    +
         /**
     929   -
                     }
    -  930  0
                 }
    -  931  0
             }
    -  932  0
             if (ids.length() > 0) {
    -  933  0
                 final String msg = String.format("%n%nDependency-Check Failure:%n"
    -  934   -
                         + "One or more dependencies were identified with vulnerabilities that have a CVSS score greater then '%.1f': %s%n"
    -  935  0
                         + "See the dependency-check report for more details.%n%n", failBuildOnCVSS, ids.toString());
    -  936  0
                 throw new BuildException(msg);
    -  937   -
             }
    -  938  0
         }
    -  939   -
     
    -  940   -
         /**
    -  941   -
          * Generates a warning message listing a summary of dependencies and their
    -  942   -
          * associated CPE and CVE entries.
    -  943   +
          * Checks to see if a vulnerability has been identified with a CVSS score
    +  930   +
          * that is above the threshold set in the configuration.
    +  931  
          *
    -  944   -
          * @param dependencies a list of dependency objects
    -  945   +  932   +
          * @param dependencies the list of dependency objects
    +  933   +
          * @throws BuildException thrown if a CVSS score is found that is higher
    +  934   +
          * then the threshold set
    +  935  
          */
    -  946   -
         private void showSummary(List<Dependency> dependencies) {
    -  947  6
             final StringBuilder summary = new StringBuilder();
    -  948  6
             for (Dependency d : dependencies) {
    -  949  10
                 boolean firstEntry = true;
    -  950  10
                 final StringBuilder ids = new StringBuilder();
    -  951  10
                 for (Vulnerability v : d.getVulnerabilities()) {
    -  952  36
                     if (firstEntry) {
    -  953  8
                         firstEntry = false;
    -  954   -
                     } else {
    -  955  28
                         ids.append(", ");
    -  956   -
                     }
    -  957  36
                     ids.append(v.getName());
    -  958  36
                 }
    -  959  10
                 if (ids.length() > 0) {
    -  960  8
                     summary.append(d.getFileName()).append(" (");
    -  961  8
                     firstEntry = true;
    -  962  8
                     for (Identifier id : d.getIdentifiers()) {
    -  963  30
                         if (firstEntry) {
    -  964  8
                             firstEntry = false;
    -  965   +  936   +
         private void checkForFailure(List<Dependency> dependencies) throws BuildException {
    +  937  0
             final StringBuilder ids = new StringBuilder();
    +  938  0
             for (Dependency d : dependencies) {
    +  939  0
                 for (Vulnerability v : d.getVulnerabilities()) {
    +  940  0
                     if (v.getCvssScore() >= failBuildOnCVSS) {
    +  941  0
                         if (ids.length() == 0) {
    +  942  0
                             ids.append(v.getName());
    +  943  
                         } else {
    -  966  22
                             summary.append(", ");
    -  967   +  944  0
                             ids.append(", ").append(v.getName());
    +  945  
                         }
    -  968  30
                         summary.append(id.getValue());
    -  969  30
                     }
    -  970  8
                     summary.append(") : ").append(ids).append(NEW_LINE);
    -  971   -
                 }
    -  972  10
             }
    -  973  6
             if (summary.length() > 0) {
    -  974  12
                 final String msg = String.format("%n%n"
    -  975   -
                         + "One or more dependencies were identified with known vulnerabilities:%n%n%s"
    -  976  6
                         + "%n%nSee the dependency-check report for more details.%n%n", summary.toString());
    -  977  6
                 log(msg, Project.MSG_WARN);
    -  978   +  946   +
                     }
    +  947  0
                 }
    +  948  0
             }
    +  949  0
             if (ids.length() > 0) {
    +  950  0
                 final String msg = String.format("%n%nDependency-Check Failure:%n"
    +  951   +
                         + "One or more dependencies were identified with vulnerabilities that have a CVSS score greater then '%.1f': %s%n"
    +  952  0
                         + "See the dependency-check report for more details.%n%n", failBuildOnCVSS, ids.toString());
    +  953  0
                 throw new BuildException(msg);
    +  954  
             }
    -  979  6
         }
    -  980   +  955  0
         }
    +  956  
     
    -  981   +  957  
         /**
    -  982   -
          * An enumeration of supported report formats: "ALL", "HTML", "XML", "VULN",
    -  983   -
          * etc..
    -  984   +  958   +
          * Generates a warning message listing a summary of dependencies and their
    +  959   +
          * associated CPE and CVE entries.
    +  960   +
          *
    +  961   +
          * @param dependencies a list of dependency objects
    +  962  
          */
    -  985  8
         public static class ReportFormats extends EnumeratedAttribute {
    -  986   -
     
    -  987   -
             /**
    +  963   +
         private void showSummary(List<Dependency> dependencies) {
    +  964  3
             final StringBuilder summary = new StringBuilder();
    +  965  3
             for (Dependency d : dependencies) {
    +  966  5
                 boolean firstEntry = true;
    +  967  5
                 final StringBuilder ids = new StringBuilder();
    +  968  5
                 for (Vulnerability v : d.getVulnerabilities()) {
    +  969  18
                     if (firstEntry) {
    +  970  4
                         firstEntry = false;
    +  971   +
                     } else {
    +  972  14
                         ids.append(", ");
    +  973   +
                     }
    +  974  18
                     ids.append(v.getName());
    +  975  18
                 }
    +  976  5
                 if (ids.length() > 0) {
    +  977  4
                     summary.append(d.getFileName()).append(" (");
    +  978  4
                     firstEntry = true;
    +  979  4
                     for (Identifier id : d.getIdentifiers()) {
    +  980  15
                         if (firstEntry) {
    +  981  4
                             firstEntry = false;
    +  982   +
                         } else {
    +  983  11
                             summary.append(", ");
    +  984   +
                         }
    +  985  15
                         summary.append(id.getValue());
    +  986  15
                     }
    +  987  4
                     summary.append(") : ").append(ids).append(NEW_LINE);
     988   -
              * Returns the list of values for the report format.
    -  989   -
              *
    -  990   -
              * @return the list of values for the report format
    -  991   -
              */
    -  992   -
             @Override
    -  993   -
             public String[] getValues() {
    -  994  8
                 int i = 0;
    -  995  8
                 final Format[] formats = Format.values();
    -  996  8
                 final String[] values = new String[formats.length];
    -  997  40
                 for (Format format : formats) {
    -  998  32
                     values[i++] = format.name();
    -  999  
                 }
    -  1000  8
                 return values;
    -  1001   +  989  5
             }
    +  990  3
             if (summary.length() > 0) {
    +  991  6
                 final String msg = String.format("%n%n"
    +  992   +
                         + "One or more dependencies were identified with known vulnerabilities:%n%n%s"
    +  993  3
                         + "%n%nSee the dependency-check report for more details.%n%n", summary.toString());
    +  994  3
                 log(msg, Project.MSG_WARN);
    +  995  
             }
    -  1002   -
         }
    +  996  3
         }
    +  997   +
     
    +  998   +
         /**
    +  999   +
          * An enumeration of supported report formats: "ALL", "HTML", "XML", "VULN",
    +  1000   +
          * etc..
    +  1001   +
          */
    +  1002  4
         public static class ReportFormats extends EnumeratedAttribute {
     1003   +
     
    +  1004   +
             /**
    +  1005   +
              * Returns the list of values for the report format.
    +  1006   +
              *
    +  1007   +
              * @return the list of values for the report format
    +  1008   +
              */
    +  1009   +
             @Override
    +  1010   +
             public String[] getValues() {
    +  1011  4
                 int i = 0;
    +  1012  4
                 final Format[] formats = Format.values();
    +  1013  4
                 final String[] values = new String[formats.length];
    +  1014  20
                 for (Format format : formats) {
    +  1015  16
                     values[i++] = format.name();
    +  1016   +
                 }
    +  1017  4
                 return values;
    +  1018   +
             }
    +  1019   +
         }
    +  1020  
     }
    - + diff --git a/dependency-check-ant/cobertura/org.owasp.dependencycheck.taskdefs.Purge.html b/dependency-check-ant/cobertura/org.owasp.dependencycheck.taskdefs.Purge.html index edf8c1e15..72d1befa9 100644 --- a/dependency-check-ant/cobertura/org.owasp.dependencycheck.taskdefs.Purge.html +++ b/dependency-check-ant/cobertura/org.owasp.dependencycheck.taskdefs.Purge.html @@ -12,7 +12,7 @@
     
    - +
    Classes in this File Line Coverage Branch Coverage Complexity
    Purge
    47%
    18/38
    25%
    2/8
    2.4
    Purge
    34%
    19/55
    12%
    2/16
    3.143
     
    @@ -105,13 +105,13 @@
          */
     44  
         public Purge() {
    -  45  8
             super();
    +  45  4
             super();
     46  
             // Call this before Dependency Check Core starts logging anything - this way, all SLF4J messages from
     47  
             // core end up coming through this tasks logger
    -  48  8
             StaticLoggerBinder.getSingleton().setTask(this);
    -  49  8
         }
    +  48  4
             StaticLoggerBinder.getSingleton().setTask(this);
    +  49  4
         }
     50  
     
     51   @@ -120,7 +120,7 @@
          * The location of the data directory that contains
     53  
          */
    -  54  8
         private String dataDirectory = null;
    +  54  4
         private String dataDirectory = null;
     55  
     
     56   @@ -157,84 +157,153 @@  73  
     
     74   -
         @Override
    -  75   -
         public void execute() throws BuildException {
    -  76  0
             populateSettings();
    -  77   -
             File db;
    -  78   -
             try {
    -  79  0
                 db = new File(Settings.getDataDirectory(), "dc.h2.db");
    -  80  0
                 if (db.exists()) {
    -  81  0
                     if (db.delete()) {
    -  82  0
                         log("Database file purged; local copy of the NVD has been removed", Project.MSG_INFO);
    -  83   -
                     } else {
    -  84  0
                         log(String.format("Unable to delete '%s'; please delete the file manually", db.getAbsolutePath()), Project.MSG_ERR);
    -  85   -
                     }
    -  86   -
                 } else {
    -  87  0
                     log(String.format("Unable to purge database; the database file does not exists: %s", db.getAbsolutePath()), Project.MSG_ERR);
    -  88   -
                 }
    -  89  0
             } catch (IOException ex) {
    -  90  0
                 log("Unable to delete the database", Project.MSG_ERR);
    -  91   -
             } finally {
    -  92  0
                 Settings.cleanup(true);
    -  93  0
             }
    -  94  0
         }
    -  95   -
     
    -  96  
         /**
    -  97   -
          * Takes the properties supplied and updates the dependency-check settings. Additionally, this sets the system properties
    -  98   -
          * required to change the proxy server, port, and connection timeout.
    -  99   +  75   +
          * Indicates if dependency-check should fail the build if an exception
    +  76   +
          * occurs.
    +  77  
          */
    -  100   -
         protected void populateSettings() {
    -  101  6
             Settings.initialize();
    -  102  6
             InputStream taskProperties = null;
    -  103   +  78  4
         private boolean failOnError = true;
    +  79   +
     
    +  80   +
         /**
    +  81   +
          * Get the value of failOnError.
    +  82   +
          *
    +  83   +
          * @return the value of failOnError
    +  84   +
          */
    +  85   +
         public boolean isFailOnError() {
    +  86  0
             return failOnError;
    +  87   +
         }
    +  88   +
     
    +  89   +
         /**
    +  90   +
          * Set the value of failOnError.
    +  91   +
          *
    +  92   +
          * @param failOnError new value of failOnError
    +  93   +
          */
    +  94   +
         public void setFailOnError(boolean failOnError) {
    +  95  0
             this.failOnError = failOnError;
    +  96  0
         }
    +  97   +
     
    +  98   +
         @Override
    +  99   +
         public void execute() throws BuildException {
    +  100  0
             populateSettings();
    +  101   +
             File db;
    +  102  
             try {
    -  104  6
                 taskProperties = this.getClass().getClassLoader().getResourceAsStream(PROPERTIES_FILE);
    -  105  6
                 Settings.mergeProperties(taskProperties);
    -  106  0
             } catch (IOException ex) {
    -  107  0
                 log("Unable to load the dependency-check ant task.properties file.", ex, Project.MSG_WARN);
    -  108   -
             } finally {
    -  109  6
                 if (taskProperties != null) {
    -  110   -
                     try {
    -  111  6
                         taskProperties.close();
    -  112  0
                     } catch (IOException ex) {
    -  113  0
                         log("", ex, Project.MSG_DEBUG);
    -  114  6
                     }
    -  115   +  103  0
                 db = new File(Settings.getDataDirectory(), "dc.h2.db");
    +  104  0
                 if (db.exists()) {
    +  105  0
                     if (db.delete()) {
    +  106  0
                         log("Database file purged; local copy of the NVD has been removed", Project.MSG_INFO);
    +  107   +
                     } else {
    +  108  0
                         final String msg = String.format("Unable to delete '%s'; please delete the file manually", db.getAbsolutePath());
    +  109  0
                         if (this.failOnError) {
    +  110  0
                             throw new BuildException(msg);
    +  111   +
                         }
    +  112  0
                         log(msg, Project.MSG_ERR);
    +  113  0
                     }
    +  114   +
                 } else {
    +  115  0
                     final String msg = String.format("Unable to purge database; the database file does not exists: %s", db.getAbsolutePath());
    +  116  0
                     if (this.failOnError) {
    +  117  0
                         throw new BuildException(msg);
    +  118   +
                     }
    +  119  0
                     log(msg, Project.MSG_ERR);
    +  120  
                 }
    -  116   -
             }
    -  117  6
             if (dataDirectory != null) {
    -  118  0
                 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory);
    -  119   -
             } else {
    -  120  6
                 final File jarPath = new File(Purge.class.getProtectionDomain().getCodeSource().getLocation().getPath());
    -  121  6
                 final File base = jarPath.getParentFile();
    -  122  6
                 final String sub = Settings.getString(Settings.KEYS.DATA_DIRECTORY);
    -  123  6
                 final File dataDir = new File(base, sub);
    -  124  6
                 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath());
    +  121  0
             } catch (IOException ex) {
    +  122  0
                 final String msg = "Unable to delete the database";
    +  123  0
                 if (this.failOnError) {
    +  124  0
                     throw new BuildException(msg);
     125   -
             }
    -  126  6
         }
    +
                 }
    +  126  0
                 log(msg, Project.MSG_ERR);
     127   +
             } finally {
    +  128  0
                 Settings.cleanup(true);
    +  129  0
             }
    +  130  0
         }
    +  131   +
     
    +  132   +
         /**
    +  133   +
          * Takes the properties supplied and updates the dependency-check settings.
    +  134   +
          * Additionally, this sets the system properties required to change the
    +  135   +
          * proxy server, port, and connection timeout.
    +  136   +
          *
    +  137   +
          * @throws BuildException thrown if the properties file cannot be read.
    +  138   +
          */
    +  139   +
         protected void populateSettings() throws BuildException {
    +  140  3
             Settings.initialize();
    +  141  3
             InputStream taskProperties = null;
    +  142   +
             try {
    +  143  3
                 taskProperties = this.getClass().getClassLoader().getResourceAsStream(PROPERTIES_FILE);
    +  144  3
                 Settings.mergeProperties(taskProperties);
    +  145  0
             } catch (IOException ex) {
    +  146  0
                 final String msg = "Unable to load the dependency-check ant task.properties file.";
    +  147  0
                 if (this.failOnError) {
    +  148  0
                     throw new BuildException(msg, ex);
    +  149   +
                 }
    +  150  0
                 log(msg, ex, Project.MSG_WARN);
    +  151   +
             } finally {
    +  152  3
                 if (taskProperties != null) {
    +  153   +
                     try {
    +  154  3
                         taskProperties.close();
    +  155  0
                     } catch (IOException ex) {
    +  156  0
                         log("", ex, Project.MSG_DEBUG);
    +  157  3
                     }
    +  158   +
                 }
    +  159   +
             }
    +  160  3
             if (dataDirectory != null) {
    +  161  0
                 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory);
    +  162   +
             } else {
    +  163  3
                 final File jarPath = new File(Purge.class.getProtectionDomain().getCodeSource().getLocation().getPath());
    +  164  3
                 final File base = jarPath.getParentFile();
    +  165  3
                 final String sub = Settings.getString(Settings.KEYS.DATA_DIRECTORY);
    +  166  3
                 final File dataDir = new File(base, sub);
    +  167  3
                 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath());
    +  168   +
             }
    +  169  3
         }
    +  170  
     }
    - + diff --git a/dependency-check-ant/cobertura/org.owasp.dependencycheck.taskdefs.Update.html b/dependency-check-ant/cobertura/org.owasp.dependencycheck.taskdefs.Update.html index 474e7ce83..2a5018171 100644 --- a/dependency-check-ant/cobertura/org.owasp.dependencycheck.taskdefs.Update.html +++ b/dependency-check-ant/cobertura/org.owasp.dependencycheck.taskdefs.Update.html @@ -12,7 +12,7 @@
     
    - +
    Classes in this File Line Coverage Branch Coverage Complexity
    Update
    25%
    20/78
    16%
    1/6
    1.182
    Update
    23%
    20/86
    10%
    1/10
    1.303
     
    @@ -58,763 +58,787 @@  20  
     import org.apache.tools.ant.BuildException;
     21   -
     import org.owasp.dependencycheck.Engine;
    +
     import org.apache.tools.ant.Project;
     22   -
     import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
    +
     import org.owasp.dependencycheck.Engine;
     23   -
     import org.owasp.dependencycheck.utils.Settings;
    +
     import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
     24   -
     import org.slf4j.impl.StaticLoggerBinder;
    +
     import org.owasp.dependencycheck.data.update.exception.UpdateException;
     25   -
     
    +
     import org.owasp.dependencycheck.utils.Settings;
     26   -
     /**
    +
     import org.slf4j.impl.StaticLoggerBinder;
     27   -
      * An Ant task definition to execute dependency-check update. This will download the latest data from the National Vulnerability
    +
     
     28   -
      * Database (NVD) and store a copy in the local database.
    +
     /**
     29   -
      *
    +
      * An Ant task definition to execute dependency-check update. This will download
     30   -
      * @author Jeremy Long
    +
      * the latest data from the National Vulnerability Database (NVD) and store a
     31   -
      */
    +
      * copy in the local database.
     32   -
     public class Update extends Purge {
    +
      *
     33   -
     
    +
      * @author Jeremy Long
     34   -
         /**
    +
      */
     35   -
          * Construct a new UpdateTask.
    +
     public class Update extends Purge {
     36   -
          */
    +
     
     37   -
         public Update() {
    -  38  8
             super();
    +
         /**
    +  38   +
          * Construct a new UpdateTask.
     39   -
             // Call this before Dependency Check Core starts logging anything - this way, all SLF4J messages from
    +
          */
     40   -
             // core end up coming through this tasks logger
    -  41  8
             StaticLoggerBinder.getSingleton().setTask(this);
    -  42  8
         }
    +
         public Update() {
    +  41  4
             super();
    +  42   +
             // Call this before Dependency Check Core starts logging anything - this way, all SLF4J messages from
     43   -
     
    -  44   -
         /**
    -  45   -
          * The Proxy Server.
    +
             // core end up coming through this tasks logger
    +  44  4
             StaticLoggerBinder.getSingleton().setTask(this);
    +  45  4
         }
     46   -
          */
    +
     
     47   -
         private String proxyServer;
    +
         /**
     48   -
     
    +
          * The Proxy Server.
     49   -
         /**
    +
          */
     50   -
          * Get the value of proxyServer.
    +
         private String proxyServer;
     51   -
          *
    +
     
     52   -
          * @return the value of proxyServer
    +
         /**
     53   -
          */
    +
          * Get the value of proxyServer.
     54   -
         public String getProxyServer() {
    -  55  0
             return proxyServer;
    +
          *
    +  55   +
          * @return the value of proxyServer
     56   -
         }
    +
          */
     57   -
     
    -  58   -
         /**
    +
         public String getProxyServer() {
    +  58  0
             return proxyServer;
     59   -
          * Set the value of proxyServer.
    +
         }
     60   -
          *
    +
     
     61   -
          * @param server new value of proxyServer
    +
         /**
     62   -
          */
    +
          * Set the value of proxyServer.
     63   -
         public void setProxyServer(String server) {
    -  64  0
             this.proxyServer = server;
    -  65  0
         }
    +
          *
    +  64   +
          * @param server new value of proxyServer
    +  65   +
          */
     66   -
     
    -  67   -
         /**
    -  68   -
          * The Proxy Port.
    +
         public void setProxyServer(String server) {
    +  67  0
             this.proxyServer = server;
    +  68  0
         }
     69   -
          */
    +
     
     70   -
         private String proxyPort;
    +
         /**
     71   -
     
    +
          * The Proxy Port.
     72   -
         /**
    +
          */
     73   -
          * Get the value of proxyPort.
    +
         private String proxyPort;
     74   -
          *
    +
     
     75   -
          * @return the value of proxyPort
    +
         /**
     76   -
          */
    +
          * Get the value of proxyPort.
     77   -
         public String getProxyPort() {
    -  78  0
             return proxyPort;
    +
          *
    +  78   +
          * @return the value of proxyPort
     79   -
         }
    +
          */
     80   -
     
    -  81   -
         /**
    +
         public String getProxyPort() {
    +  81  0
             return proxyPort;
     82   -
          * Set the value of proxyPort.
    +
         }
     83   -
          *
    +
     
     84   -
          * @param proxyPort new value of proxyPort
    +
         /**
     85   -
          */
    +
          * Set the value of proxyPort.
     86   -
         public void setProxyPort(String proxyPort) {
    -  87  0
             this.proxyPort = proxyPort;
    -  88  0
         }
    +
          *
    +  87   +
          * @param proxyPort new value of proxyPort
    +  88   +
          */
     89   -
         /**
    -  90   -
          * The Proxy username.
    -  91   -
          */
    +
         public void setProxyPort(String proxyPort) {
    +  90  0
             this.proxyPort = proxyPort;
    +  91  0
         }
     92   -
         private String proxyUsername;
    +
         /**
     93   -
     
    +
          * The Proxy username.
     94   -
         /**
    +
          */
     95   -
          * Get the value of proxyUsername.
    +
         private String proxyUsername;
     96   -
          *
    +
     
     97   -
          * @return the value of proxyUsername
    +
         /**
     98   -
          */
    +
          * Get the value of proxyUsername.
     99   -
         public String getProxyUsername() {
    -  100  0
             return proxyUsername;
    +
          *
    +  100   +
          * @return the value of proxyUsername
     101   -
         }
    +
          */
     102   -
     
    -  103   -
         /**
    +
         public String getProxyUsername() {
    +  103  0
             return proxyUsername;
     104   -
          * Set the value of proxyUsername.
    +
         }
     105   -
          *
    +
     
     106   -
          * @param proxyUsername new value of proxyUsername
    +
         /**
     107   -
          */
    +
          * Set the value of proxyUsername.
     108   -
         public void setProxyUsername(String proxyUsername) {
    -  109  0
             this.proxyUsername = proxyUsername;
    -  110  0
         }
    +
          *
    +  109   +
          * @param proxyUsername new value of proxyUsername
    +  110   +
          */
     111   -
         /**
    -  112   -
          * The Proxy password.
    -  113   -
          */
    +
         public void setProxyUsername(String proxyUsername) {
    +  112  0
             this.proxyUsername = proxyUsername;
    +  113  0
         }
     114   -
         private String proxyPassword;
    +
         /**
     115   -
     
    +
          * The Proxy password.
     116   -
         /**
    +
          */
     117   -
          * Get the value of proxyPassword.
    +
         private String proxyPassword;
     118   -
          *
    +
     
     119   -
          * @return the value of proxyPassword
    +
         /**
     120   -
          */
    +
          * Get the value of proxyPassword.
     121   -
         public String getProxyPassword() {
    -  122  0
             return proxyPassword;
    +
          *
    +  122   +
          * @return the value of proxyPassword
     123   -
         }
    +
          */
     124   -
     
    -  125   -
         /**
    +
         public String getProxyPassword() {
    +  125  0
             return proxyPassword;
     126   -
          * Set the value of proxyPassword.
    +
         }
     127   -
          *
    +
     
     128   -
          * @param proxyPassword new value of proxyPassword
    +
         /**
     129   -
          */
    +
          * Set the value of proxyPassword.
     130   -
         public void setProxyPassword(String proxyPassword) {
    -  131  0
             this.proxyPassword = proxyPassword;
    -  132  0
         }
    +
          *
    +  131   +
          * @param proxyPassword new value of proxyPassword
    +  132   +
          */
     133   -
         /**
    -  134   -
          * The Connection Timeout.
    -  135   -
          */
    +
         public void setProxyPassword(String proxyPassword) {
    +  134  0
             this.proxyPassword = proxyPassword;
    +  135  0
         }
     136   -
         private String connectionTimeout;
    +
         /**
     137   -
     
    +
          * The Connection Timeout.
     138   -
         /**
    +
          */
     139   -
          * Get the value of connectionTimeout.
    +
         private String connectionTimeout;
     140   -
          *
    +
     
     141   -
          * @return the value of connectionTimeout
    +
         /**
     142   -
          */
    +
          * Get the value of connectionTimeout.
     143   -
         public String getConnectionTimeout() {
    -  144  0
             return connectionTimeout;
    +
          *
    +  144   +
          * @return the value of connectionTimeout
     145   -
         }
    +
          */
     146   -
     
    -  147   -
         /**
    +
         public String getConnectionTimeout() {
    +  147  0
             return connectionTimeout;
     148   -
          * Set the value of connectionTimeout.
    +
         }
     149   -
          *
    +
     
     150   -
          * @param connectionTimeout new value of connectionTimeout
    +
         /**
     151   -
          */
    +
          * Set the value of connectionTimeout.
     152   -
         public void setConnectionTimeout(String connectionTimeout) {
    -  153  0
             this.connectionTimeout = connectionTimeout;
    -  154  0
         }
    +
          *
    +  153   +
          * @param connectionTimeout new value of connectionTimeout
    +  154   +
          */
     155   -
         /**
    -  156   -
          * The database driver name; such as org.h2.Driver.
    -  157   -
          */
    +
         public void setConnectionTimeout(String connectionTimeout) {
    +  156  0
             this.connectionTimeout = connectionTimeout;
    +  157  0
         }
     158   -
         private String databaseDriverName;
    +
         /**
     159   -
     
    +
          * The database driver name; such as org.h2.Driver.
     160   -
         /**
    +
          */
     161   -
          * Get the value of databaseDriverName.
    +
         private String databaseDriverName;
     162   -
          *
    +
     
     163   -
          * @return the value of databaseDriverName
    +
         /**
     164   -
          */
    +
          * Get the value of databaseDriverName.
     165   -
         public String getDatabaseDriverName() {
    -  166  0
             return databaseDriverName;
    +
          *
    +  166   +
          * @return the value of databaseDriverName
     167   -
         }
    +
          */
     168   -
     
    -  169   -
         /**
    +
         public String getDatabaseDriverName() {
    +  169  0
             return databaseDriverName;
     170   -
          * Set the value of databaseDriverName.
    +
         }
     171   -
          *
    +
     
     172   -
          * @param databaseDriverName new value of databaseDriverName
    +
         /**
     173   -
          */
    +
          * Set the value of databaseDriverName.
     174   -
         public void setDatabaseDriverName(String databaseDriverName) {
    -  175  0
             this.databaseDriverName = databaseDriverName;
    -  176  0
         }
    +
          *
    +  175   +
          * @param databaseDriverName new value of databaseDriverName
    +  176   +
          */
     177   -
     
    -  178   -
         /**
    -  179   -
          * The path to the database driver JAR file if it is not on the class path.
    +
         public void setDatabaseDriverName(String databaseDriverName) {
    +  178  0
             this.databaseDriverName = databaseDriverName;
    +  179  0
         }
     180   -
          */
    +
     
     181   -
         private String databaseDriverPath;
    +
         /**
     182   -
     
    +
          * The path to the database driver JAR file if it is not on the class path.
     183   -
         /**
    +
          */
     184   -
          * Get the value of databaseDriverPath.
    +
         private String databaseDriverPath;
     185   -
          *
    +
     
     186   -
          * @return the value of databaseDriverPath
    +
         /**
     187   -
          */
    +
          * Get the value of databaseDriverPath.
     188   -
         public String getDatabaseDriverPath() {
    -  189  0
             return databaseDriverPath;
    +
          *
    +  189   +
          * @return the value of databaseDriverPath
     190   -
         }
    +
          */
     191   -
     
    -  192   -
         /**
    +
         public String getDatabaseDriverPath() {
    +  192  0
             return databaseDriverPath;
     193   -
          * Set the value of databaseDriverPath.
    +
         }
     194   -
          *
    +
     
     195   -
          * @param databaseDriverPath new value of databaseDriverPath
    +
         /**
     196   -
          */
    +
          * Set the value of databaseDriverPath.
     197   -
         public void setDatabaseDriverPath(String databaseDriverPath) {
    -  198  0
             this.databaseDriverPath = databaseDriverPath;
    -  199  0
         }
    +
          *
    +  198   +
          * @param databaseDriverPath new value of databaseDriverPath
    +  199   +
          */
     200   -
         /**
    -  201   -
          * The database connection string.
    -  202   -
          */
    +
         public void setDatabaseDriverPath(String databaseDriverPath) {
    +  201  0
             this.databaseDriverPath = databaseDriverPath;
    +  202  0
         }
     203   -
         private String connectionString;
    +
         /**
     204   -
     
    +
          * The database connection string.
     205   -
         /**
    +
          */
     206   -
          * Get the value of connectionString.
    +
         private String connectionString;
     207   -
          *
    +
     
     208   -
          * @return the value of connectionString
    +
         /**
     209   -
          */
    +
          * Get the value of connectionString.
     210   -
         public String getConnectionString() {
    -  211  0
             return connectionString;
    +
          *
    +  211   +
          * @return the value of connectionString
     212   -
         }
    +
          */
     213   -
     
    -  214   -
         /**
    +
         public String getConnectionString() {
    +  214  0
             return connectionString;
     215   -
          * Set the value of connectionString.
    +
         }
     216   -
          *
    +
     
     217   -
          * @param connectionString new value of connectionString
    +
         /**
     218   -
          */
    +
          * Set the value of connectionString.
     219   -
         public void setConnectionString(String connectionString) {
    -  220  0
             this.connectionString = connectionString;
    -  221  0
         }
    +
          *
    +  220   +
          * @param connectionString new value of connectionString
    +  221   +
          */
     222   -
         /**
    -  223   -
          * The user name for connecting to the database.
    -  224   -
          */
    +
         public void setConnectionString(String connectionString) {
    +  223  0
             this.connectionString = connectionString;
    +  224  0
         }
     225   -
         private String databaseUser;
    +
         /**
     226   -
     
    +
          * The user name for connecting to the database.
     227   -
         /**
    +
          */
     228   -
          * Get the value of databaseUser.
    +
         private String databaseUser;
     229   -
          *
    +
     
     230   -
          * @return the value of databaseUser
    +
         /**
     231   -
          */
    +
          * Get the value of databaseUser.
     232   -
         public String getDatabaseUser() {
    -  233  0
             return databaseUser;
    +
          *
    +  233   +
          * @return the value of databaseUser
     234   -
         }
    +
          */
     235   -
     
    -  236   -
         /**
    +
         public String getDatabaseUser() {
    +  236  0
             return databaseUser;
     237   -
          * Set the value of databaseUser.
    +
         }
     238   -
          *
    +
     
     239   -
          * @param databaseUser new value of databaseUser
    +
         /**
     240   -
          */
    +
          * Set the value of databaseUser.
     241   -
         public void setDatabaseUser(String databaseUser) {
    -  242  0
             this.databaseUser = databaseUser;
    -  243  0
         }
    +
          *
    +  242   +
          * @param databaseUser new value of databaseUser
    +  243   +
          */
     244   -
     
    -  245   -
         /**
    -  246   -
          * The password to use when connecting to the database.
    +
         public void setDatabaseUser(String databaseUser) {
    +  245  0
             this.databaseUser = databaseUser;
    +  246  0
         }
     247   -
          */
    +
     
     248   -
         private String databasePassword;
    +
         /**
     249   -
     
    +
          * The password to use when connecting to the database.
     250   -
         /**
    +
          */
     251   -
          * Get the value of databasePassword.
    +
         private String databasePassword;
     252   -
          *
    +
     
     253   -
          * @return the value of databasePassword
    +
         /**
     254   -
          */
    +
          * Get the value of databasePassword.
     255   -
         public String getDatabasePassword() {
    -  256  0
             return databasePassword;
    +
          *
    +  256   +
          * @return the value of databasePassword
     257   -
         }
    +
          */
     258   -
     
    -  259   -
         /**
    +
         public String getDatabasePassword() {
    +  259  0
             return databasePassword;
     260   -
          * Set the value of databasePassword.
    +
         }
     261   -
          *
    +
     
     262   -
          * @param databasePassword new value of databasePassword
    +
         /**
     263   -
          */
    +
          * Set the value of databasePassword.
     264   -
         public void setDatabasePassword(String databasePassword) {
    -  265  0
             this.databasePassword = databasePassword;
    -  266  0
         }
    +
          *
    +  265   +
          * @param databasePassword new value of databasePassword
    +  266   +
          */
     267   -
     
    -  268   -
         /**
    -  269   -
          * The url for the modified NVD CVE (1.2 schema).
    +
         public void setDatabasePassword(String databasePassword) {
    +  268  0
             this.databasePassword = databasePassword;
    +  269  0
         }
     270   -
          */
    +
     
     271   -
         private String cveUrl12Modified;
    +
         /**
     272   -
     
    +
          * The url for the modified NVD CVE (1.2 schema).
     273   -
         /**
    +
          */
     274   -
          * Get the value of cveUrl12Modified.
    +
         private String cveUrl12Modified;
     275   -
          *
    +
     
     276   -
          * @return the value of cveUrl12Modified
    +
         /**
     277   -
          */
    +
          * Get the value of cveUrl12Modified.
     278   -
         public String getCveUrl12Modified() {
    -  279  0
             return cveUrl12Modified;
    +
          *
    +  279   +
          * @return the value of cveUrl12Modified
     280   -
         }
    +
          */
     281   -
     
    -  282   -
         /**
    +
         public String getCveUrl12Modified() {
    +  282  0
             return cveUrl12Modified;
     283   -
          * Set the value of cveUrl12Modified.
    +
         }
     284   -
          *
    +
     
     285   -
          * @param cveUrl12Modified new value of cveUrl12Modified
    +
         /**
     286   -
          */
    +
          * Set the value of cveUrl12Modified.
     287   -
         public void setCveUrl12Modified(String cveUrl12Modified) {
    -  288  0
             this.cveUrl12Modified = cveUrl12Modified;
    -  289  0
         }
    +
          *
    +  288   +
          * @param cveUrl12Modified new value of cveUrl12Modified
    +  289   +
          */
     290   -
     
    -  291   -
         /**
    -  292   -
          * The url for the modified NVD CVE (2.0 schema).
    +
         public void setCveUrl12Modified(String cveUrl12Modified) {
    +  291  0
             this.cveUrl12Modified = cveUrl12Modified;
    +  292  0
         }
     293   -
          */
    +
     
     294   -
         private String cveUrl20Modified;
    +
         /**
     295   -
     
    +
          * The url for the modified NVD CVE (2.0 schema).
     296   -
         /**
    +
          */
     297   -
          * Get the value of cveUrl20Modified.
    +
         private String cveUrl20Modified;
     298   -
          *
    +
     
     299   -
          * @return the value of cveUrl20Modified
    +
         /**
     300   -
          */
    +
          * Get the value of cveUrl20Modified.
     301   -
         public String getCveUrl20Modified() {
    -  302  0
             return cveUrl20Modified;
    +
          *
    +  302   +
          * @return the value of cveUrl20Modified
     303   -
         }
    +
          */
     304   -
     
    -  305   -
         /**
    +
         public String getCveUrl20Modified() {
    +  305  0
             return cveUrl20Modified;
     306   -
          * Set the value of cveUrl20Modified.
    +
         }
     307   -
          *
    +
     
     308   -
          * @param cveUrl20Modified new value of cveUrl20Modified
    +
         /**
     309   -
          */
    +
          * Set the value of cveUrl20Modified.
     310   -
         public void setCveUrl20Modified(String cveUrl20Modified) {
    -  311  0
             this.cveUrl20Modified = cveUrl20Modified;
    -  312  0
         }
    +
          *
    +  311   +
          * @param cveUrl20Modified new value of cveUrl20Modified
    +  312   +
          */
     313   -
     
    -  314   -
         /**
    -  315   -
          * Base Data Mirror URL for CVE 1.2.
    +
         public void setCveUrl20Modified(String cveUrl20Modified) {
    +  314  0
             this.cveUrl20Modified = cveUrl20Modified;
    +  315  0
         }
     316   -
          */
    +
     
     317   -
         private String cveUrl12Base;
    +
         /**
     318   -
     
    +
          * Base Data Mirror URL for CVE 1.2.
     319   -
         /**
    +
          */
     320   -
          * Get the value of cveUrl12Base.
    +
         private String cveUrl12Base;
     321   -
          *
    +
     
     322   -
          * @return the value of cveUrl12Base
    +
         /**
     323   -
          */
    +
          * Get the value of cveUrl12Base.
     324   -
         public String getCveUrl12Base() {
    -  325  0
             return cveUrl12Base;
    +
          *
    +  325   +
          * @return the value of cveUrl12Base
     326   -
         }
    +
          */
     327   -
     
    -  328   -
         /**
    +
         public String getCveUrl12Base() {
    +  328  0
             return cveUrl12Base;
     329   -
          * Set the value of cveUrl12Base.
    +
         }
     330   -
          *
    +
     
     331   -
          * @param cveUrl12Base new value of cveUrl12Base
    +
         /**
     332   -
          */
    +
          * Set the value of cveUrl12Base.
     333   -
         public void setCveUrl12Base(String cveUrl12Base) {
    -  334  0
             this.cveUrl12Base = cveUrl12Base;
    -  335  0
         }
    +
          *
    +  334   +
          * @param cveUrl12Base new value of cveUrl12Base
    +  335   +
          */
     336   -
     
    -  337   -
         /**
    -  338   -
          * Data Mirror URL for CVE 2.0.
    +
         public void setCveUrl12Base(String cveUrl12Base) {
    +  337  0
             this.cveUrl12Base = cveUrl12Base;
    +  338  0
         }
     339   -
          */
    +
     
     340   -
         private String cveUrl20Base;
    +
         /**
     341   -
     
    +
          * Data Mirror URL for CVE 2.0.
     342   -
         /**
    +
          */
     343   -
          * Get the value of cveUrl20Base.
    +
         private String cveUrl20Base;
     344   -
          *
    +
     
     345   -
          * @return the value of cveUrl20Base
    +
         /**
     346   -
          */
    +
          * Get the value of cveUrl20Base.
     347   -
         public String getCveUrl20Base() {
    -  348  0
             return cveUrl20Base;
    +
          *
    +  348   +
          * @return the value of cveUrl20Base
     349   -
         }
    +
          */
     350   -
     
    -  351   -
         /**
    +
         public String getCveUrl20Base() {
    +  351  0
             return cveUrl20Base;
     352   -
          * Set the value of cveUrl20Base.
    -  353   -
          *
    -  354   -
          * @param cveUrl20Base new value of cveUrl20Base
    -  355   -
          */
    -  356   -
         public void setCveUrl20Base(String cveUrl20Base) {
    -  357  0
             this.cveUrl20Base = cveUrl20Base;
    -  358  0
         }
    -  359   -
     
    -  360   -
         /**
    -  361   -
          * The number of hours to wait before re-checking for updates.
    -  362   -
          */
    -  363   -
         private Integer cveValidForHours;
    -  364   -
     
    -  365   -
         /**
    -  366   -
          * Get the value of cveValidForHours.
    -  367   -
          *
    -  368   -
          * @return the value of cveValidForHours
    -  369   -
          */
    -  370   -
         public Integer getCveValidForHours() {
    -  371  0
             return cveValidForHours;
    -  372  
         }
    +  353   +
     
    +  354   +
         /**
    +  355   +
          * Set the value of cveUrl20Base.
    +  356   +
          *
    +  357   +
          * @param cveUrl20Base new value of cveUrl20Base
    +  358   +
          */
    +  359   +
         public void setCveUrl20Base(String cveUrl20Base) {
    +  360  0
             this.cveUrl20Base = cveUrl20Base;
    +  361  0
         }
    +  362   +
     
    +  363   +
         /**
    +  364   +
          * The number of hours to wait before re-checking for updates.
    +  365   +
          */
    +  366   +
         private Integer cveValidForHours;
    +  367   +
     
    +  368   +
         /**
    +  369   +
          * Get the value of cveValidForHours.
    +  370   +
          *
    +  371   +
          * @return the value of cveValidForHours
    +  372   +
          */
     373   -
     
    -  374   -
         /**
    +
         public Integer getCveValidForHours() {
    +  374  0
             return cveValidForHours;
     375   -
          * Set the value of cveValidForHours.
    +
         }
     376   -
          *
    +
     
     377   -
          * @param cveValidForHours new value of cveValidForHours
    +
         /**
     378   -
          */
    +
          * Set the value of cveValidForHours.
     379   -
         public void setCveValidForHours(Integer cveValidForHours) {
    -  380  0
             this.cveValidForHours = cveValidForHours;
    -  381  0
         }
    +
          *
    +  380   +
          * @param cveValidForHours new value of cveValidForHours
    +  381   +
          */
     382   -
     
    -  383   -
         /**
    -  384   -
          * Executes the update by initializing the settings, downloads the NVD XML data, and then processes the data storing it in the
    +
         public void setCveValidForHours(Integer cveValidForHours) {
    +  383  0
             this.cveValidForHours = cveValidForHours;
    +  384  0
         }
     385   -
          * local database.
    -  386   -
          *
    -  387   -
          * @throws BuildException thrown if a connection to the local database cannot be made.
    -  388   -
          */
    -  389   -
         @Override
    -  390   -
         public void execute() throws BuildException {
    -  391  0
             populateSettings();
    -  392  0
             Engine engine = null;
    -  393   -
             try {
    -  394  0
                 engine = new Engine(Update.class.getClassLoader());
    -  395  0
                 engine.doUpdates();
    -  396  0
             } catch (DatabaseException ex) {
    -  397  0
                 throw new BuildException("Unable to connect to the dependency-check database; unable to update the NVD data", ex);
    -  398   -
             } finally {
    -  399  0
                 Settings.cleanup(true);
    -  400  0
                 if (engine != null) {
    -  401  0
                     engine.cleanup();
    -  402   -
                 }
    -  403   -
             }
    -  404  0
         }
    -  405  
     
    -  406   +  386  
         /**
    -  407   -
          * Takes the properties supplied and updates the dependency-check settings. Additionally, this sets the system properties
    -  408   -
          * required to change the proxy server, port, and connection timeout.
    -  409   +  387   +
          * Executes the update by initializing the settings, downloads the NVD XML
    +  388   +
          * data, and then processes the data storing it in the local database.
    +  389  
          *
    -  410   -
          * @throws BuildException thrown when an invalid setting is configured.
    -  411   +  390   +
          * @throws BuildException thrown if a connection to the local database
    +  391   +
          * cannot be made.
    +  392  
          */
    -  412   +  393  
         @Override
    -  413   -
         protected void populateSettings() throws BuildException {
    -  414  6
             super.populateSettings();
    -  415  6
             Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_SERVER, proxyServer);
    -  416  6
             Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PORT, proxyPort);
    -  417  6
             Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_USERNAME, proxyUsername);
    -  418  6
             Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PASSWORD, proxyPassword);
    -  419  6
             Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout);
    -  420  6
             Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName);
    -  421  6
             Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath);
    -  422  6
             Settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString);
    -  423  6
             Settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser);
    -  424  6
             Settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword);
    -  425  6
             Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_12_URL, cveUrl12Modified);
    -  426  6
             Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_20_URL, cveUrl20Modified);
    -  427  6
             Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_1_2, cveUrl12Base);
    -  428  6
             Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_2_0, cveUrl20Base);
    -  429  6
             if (cveValidForHours != null) {
    -  430  0
                 if (cveValidForHours >= 0) {
    -  431  0
                     Settings.setInt(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, cveValidForHours);
    -  432   -
                 } else {
    -  433  0
                     throw new BuildException("Invalid setting: `cpeValidForHours` must be 0 or greater");
    -  434   +  394   +
         public void execute() throws BuildException {
    +  395  0
             populateSettings();
    +  396  0
             Engine engine = null;
    +  397   +
             try {
    +  398  0
                 engine = new Engine(Update.class.getClassLoader());
    +  399   +
                 try {
    +  400  0
                     engine.doUpdates();
    +  401  0
                 } catch (UpdateException ex) {
    +  402  0
                     if (this.isFailOnError()) {
    +  403  0
                         throw new BuildException(ex);
    +  404   +
                     }
    +  405  0
                     log(ex.getMessage(), Project.MSG_ERR);
    +  406  0
                 }
    +  407  0
             } catch (DatabaseException ex) {
    +  408  0
                 final String msg = "Unable to connect to the dependency-check database; unable to update the NVD data";
    +  409  0
                 if (this.isFailOnError()) {
    +  410  0
                     throw new BuildException(msg, ex);
    +  411  
                 }
    -  435   +  412  0
                 log(msg, Project.MSG_ERR);
    +  413   +
             } finally {
    +  414  0
                 Settings.cleanup(true);
    +  415  0
                 if (engine != null) {
    +  416  0
                     engine.cleanup();
    +  417   +
                 }
    +  418  
             }
    -  436  6
         }
    -  437   +  419  0
         }
    +  420   +
     
    +  421   +
         /**
    +  422   +
          * Takes the properties supplied and updates the dependency-check settings.
    +  423   +
          * Additionally, this sets the system properties required to change the
    +  424   +
          * proxy server, port, and connection timeout.
    +  425   +
          *
    +  426   +
          * @throws BuildException thrown when an invalid setting is configured.
    +  427   +
          */
    +  428   +
         @Override
    +  429   +
         protected void populateSettings() throws BuildException {
    +  430  3
             super.populateSettings();
    +  431  3
             Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_SERVER, proxyServer);
    +  432  3
             Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PORT, proxyPort);
    +  433  3
             Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_USERNAME, proxyUsername);
    +  434  3
             Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PASSWORD, proxyPassword);
    +  435  3
             Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout);
    +  436  3
             Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName);
    +  437  3
             Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath);
    +  438  3
             Settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString);
    +  439  3
             Settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser);
    +  440  3
             Settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword);
    +  441  3
             Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_12_URL, cveUrl12Modified);
    +  442  3
             Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_20_URL, cveUrl20Modified);
    +  443  3
             Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_1_2, cveUrl12Base);
    +  444  3
             Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_2_0, cveUrl20Base);
    +  445  3
             if (cveValidForHours != null) {
    +  446  0
                 if (cveValidForHours >= 0) {
    +  447  0
                     Settings.setInt(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, cveValidForHours);
    +  448   +
                 } else {
    +  449  0
                     throw new BuildException("Invalid setting: `cpeValidForHours` must be 0 or greater");
    +  450   +
                 }
    +  451   +
             }
    +  452  3
         }
    +  453  
     }
    - + diff --git a/dependency-check-ant/cobertura/org.slf4j.impl.StaticLoggerBinder.html b/dependency-check-ant/cobertura/org.slf4j.impl.StaticLoggerBinder.html index 3b263a180..d25b986ee 100644 --- a/dependency-check-ant/cobertura/org.slf4j.impl.StaticLoggerBinder.html +++ b/dependency-check-ant/cobertura/org.slf4j.impl.StaticLoggerBinder.html @@ -93,7 +93,7 @@
          * The unique instance of this class
     38  
          */
    -  39  2
         private static final StaticLoggerBinder SINGLETON = new StaticLoggerBinder();
    +  39  1
         private static final StaticLoggerBinder SINGLETON = new StaticLoggerBinder();
     40  
     
     41   @@ -108,7 +108,7 @@
          */
     46  
         public static final StaticLoggerBinder getSingleton() {
    -  47  120
             return SINGLETON;
    +  47  66
             return SINGLETON;
     48  
         }
     49   @@ -121,7 +121,7 @@
          * the task as a delegate
     53  
          */
    -  54  2
         private Task task = null;
    +  54  1
         private Task task = null;
     55  
     
     56   @@ -136,9 +136,9 @@
          */
     61  
         public void setTask(Task task) {
    -  62  24
             this.task = task;
    -  63  24
             loggerFactory = new AntLoggerFactory(task);
    -  64  24
         }
    +  62  12
             this.task = task;
    +  63  12
             loggerFactory = new AntLoggerFactory(task);
    +  64  12
         }
     65  
     
     66   @@ -155,7 +155,7 @@
         //CSOFF: StaticVariableName
     72  
         //CSOFF: VisibilityModifier
    -  73  2
         public static String REQUESTED_API_VERSION = "1.7.12"; // final
    +  73  1
         public static String REQUESTED_API_VERSION = "1.7.12"; // final
     74  
         //CSON: VisibilityModifier
     75   @@ -168,7 +168,7 @@
          * The logger factory class string.
     79  
          */
    -  80  2
         private static final String LOGGER_FACTORY_CLASS = AntLoggerFactory.class.getName();
    +  80  1
         private static final String LOGGER_FACTORY_CLASS = AntLoggerFactory.class.getName();
     81  
     
     82   @@ -189,9 +189,9 @@
          * Constructs a new static logger binder.
     90  
          */
    -  91  2
         private StaticLoggerBinder() {
    -  92  2
             loggerFactory = new AntLoggerFactory(task);
    -  93  2
         }
    +  91  1
         private StaticLoggerBinder() {
    +  92  1
             loggerFactory = new AntLoggerFactory(task);
    +  93  1
         }
     94  
     
     95   @@ -208,7 +208,7 @@
         @Override
     101  
         public ILoggerFactory getLoggerFactory() {
    -  102  92
             return loggerFactory;
    +  102  52
             return loggerFactory;
     103  
         }
     104   @@ -227,13 +227,13 @@
         @Override
     111  
         public String getLoggerFactoryClassStr() {
    -  112  2
             return LOGGER_FACTORY_CLASS;
    +  112  1
             return LOGGER_FACTORY_CLASS;
     113  
         }
     114  
     }
    - + diff --git a/dependency-check-ant/config-purge.html b/dependency-check-ant/config-purge.html index 997b4f2f8..a7149aee0 100644 --- a/dependency-check-ant/config-purge.html +++ b/dependency-check-ant/config-purge.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Configuration @@ -52,7 +52,7 @@ @@ -180,6 +180,15 @@ data + + + +failOnError + +Whether the build should fail if there is an error executing the purge + +true + diff --git a/dependency-check-ant/config-update.html b/dependency-check-ant/config-update.html index d65e31734..2a78af02c 100644 --- a/dependency-check-ant/config-update.html +++ b/dependency-check-ant/config-update.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Configuration @@ -52,7 +52,7 @@ @@ -216,6 +216,15 @@   + + + +failOnError + +Whether the build should fail if there is an error executing the update + +true +

    Advanced Configuration

    diff --git a/dependency-check-ant/configuration.html b/dependency-check-ant/configuration.html index 27ea1ccc3..9c6f9a4a6 100644 --- a/dependency-check-ant/configuration.html +++ b/dependency-check-ant/configuration.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Configuration @@ -52,7 +52,7 @@ @@ -216,6 +216,15 @@ +failOnError + +Whether the build should fail if there is an error executing the dependency-check analysis + +true + + + + projectName The name of the project being scanned. @@ -223,7 +232,7 @@ Dependency-Check - + reportFormat @@ -232,7 +241,7 @@ HTML - + reportOutputDirectory @@ -241,7 +250,7 @@ ‘target’ - + suppressionFile @@ -250,7 +259,7 @@   - + proxyServer @@ -259,7 +268,7 @@   - + proxyPort @@ -268,7 +277,7 @@   - + proxyUsername @@ -277,7 +286,7 @@   - + proxyPassword @@ -286,7 +295,7 @@   - + connectionTimeout @@ -295,7 +304,7 @@   - + enableExperimental diff --git a/dependency-check-ant/dependency-analysis.html b/dependency-check-ant/dependency-analysis.html index 869c3ca7f..bd8506db7 100644 --- a/dependency-check-ant/dependency-analysis.html +++ b/dependency-check-ant/dependency-analysis.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Dependencies Report @@ -52,7 +52,7 @@ @@ -239,7 +239,7 @@ org.owasp dependency-check-core -1.4.0 +1.4.2 compile jar @@ -247,7 +247,7 @@ org.owasp dependency-check-utils -1.4.0 +1.4.2 compile jar @@ -255,7 +255,7 @@ org.owasp dependency-check-core -1.4.0 +1.4.2 test tests test-jar diff --git a/dependency-check-ant/dependency-updates-report.html b/dependency-check-ant/dependency-updates-report.html index ca16efbef..d81165dbc 100644 --- a/dependency-check-ant/dependency-updates-report.html +++ b/dependency-check-ant/dependency-updates-report.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Dependency Updates Report @@ -52,7 +52,7 @@ @@ -230,7 +230,7 @@ # of dependencies using the latest version available -24 +25 # of dependencies where the next version available is smaller than an incremental version update @@ -238,7 +238,7 @@ # of dependencies where the next version available is an incremental version update -1 +0 # of dependencies where the next version available is a minor version update @@ -398,7 +398,7 @@ org.apache.commons commons-compress -1.11 +1.12 jar @@ -578,24 +578,24 @@ org.jmockit jmockit -1.22 +1.24 test jar -1.23 +1.25 - + org.jsoup jsoup -1.9.1 +1.9.2 jar -1.9.2 + @@ -665,7 +665,7 @@ org.owasp dependency-check-core -1.4.0 +1.4.2 compile jar @@ -677,7 +677,7 @@ org.owasp dependency-check-utils -1.4.0 +1.4.2 compile jar @@ -984,7 +984,7 @@ commons-compress Current Version -1.11 +1.12 Scope @@ -1047,7 +1047,7 @@ jar Newer versions -4.8.0 Next Minor
    4.8.1
    4.9.0
    4.9.1
    4.10.0
    4.10.1
    4.10.2
    4.10.3
    4.10.4 Latest Minor
    5.0.0 Next Major
    5.1.0
    5.2.0
    5.2.1
    5.3.0
    5.3.1
    5.3.2
    5.4.0
    5.4.1
    5.5.0
    5.5.1
    6.0.0
    6.0.1 Latest Major +4.8.0 Next Minor
    4.8.1
    4.9.0
    4.9.1
    4.10.0
    4.10.1
    4.10.2
    4.10.3
    4.10.4 Latest Minor
    5.0.0 Next Major
    5.1.0
    5.2.0
    5.2.1
    5.3.0
    5.3.1
    5.3.2
    5.4.0
    5.4.1
    5.5.0
    5.5.1
    5.5.2
    6.0.0
    6.0.1
    6.1.0 Latest Major

    org.apache.lucene:lucene-core

    @@ -1074,7 +1074,7 @@ -
    jar
    Newer versions4.8.0 Next Minor
    4.8.1
    4.9.0
    4.9.1
    4.10.0
    4.10.1
    4.10.2
    4.10.3
    4.10.4 Latest Minor
    5.0.0 Next Major
    5.1.0
    5.2.0
    5.2.1
    5.3.0
    5.3.1
    5.3.2
    5.4.0
    5.4.1
    5.5.0
    5.5.1
    6.0.0
    6.0.1 Latest Major
    +4.8.0 Next Minor
    4.8.1
    4.9.0
    4.9.1
    4.10.0
    4.10.1
    4.10.2
    4.10.3
    4.10.4 Latest Minor
    5.0.0 Next Major
    5.1.0
    5.2.0
    5.2.1
    5.3.0
    5.3.1
    5.3.2
    5.4.0
    5.4.1
    5.5.0
    5.5.1
    5.5.2
    6.0.0
    6.0.1
    6.1.0 Latest Major

    org.apache.lucene:lucene-queryparser

    @@ -1101,7 +1101,7 @@ -
    jar
    Newer versions4.8.0 Next Minor
    4.8.1
    4.9.0
    4.9.1
    4.10.0
    4.10.1
    4.10.2
    4.10.3
    4.10.4 Latest Minor
    5.0.0 Next Major
    5.1.0
    5.2.0
    5.2.1
    5.3.0
    5.3.1
    5.3.2
    5.4.0
    5.4.1
    5.5.0
    5.5.1
    6.0.0
    6.0.1 Latest Major
    +4.8.0 Next Minor
    4.8.1
    4.9.0
    4.9.1
    4.10.0
    4.10.1
    4.10.2
    4.10.3
    4.10.4 Latest Minor
    5.0.0 Next Major
    5.1.0
    5.2.0
    5.2.1
    5.3.0
    5.3.1
    5.3.2
    5.4.0
    5.4.1
    5.5.0
    5.5.1
    5.5.2
    6.0.0
    6.0.1
    6.1.0 Latest Major

    org.apache.lucene:lucene-test-framework

    @@ -1128,7 +1128,7 @@ -
    jar
    Newer versions4.8.0 Next Minor
    4.8.1
    4.9.0
    4.9.1
    4.10.0
    4.10.1
    4.10.2
    4.10.3
    4.10.4 Latest Minor
    5.0.0 Next Major
    5.1.0
    5.2.0
    5.2.1
    5.3.0
    5.3.1
    5.3.2
    5.4.0
    5.4.1
    5.5.0
    5.5.1
    6.0.0
    6.0.1 Latest Major
    +4.8.0 Next Minor
    4.8.1
    4.9.0
    4.9.1
    4.10.0
    4.10.1
    4.10.2
    4.10.3
    4.10.4 Latest Minor
    5.0.0 Next Major
    5.1.0
    5.2.0
    5.2.1
    5.3.0
    5.3.1
    5.3.2
    5.4.0
    5.4.1
    5.5.0
    5.5.1
    5.5.2
    6.0.0
    6.0.1
    6.1.0 Latest Major

    org.apache.maven:maven-core

    @@ -1359,7 +1359,7 @@ - + @@ -1371,13 +1371,13 @@ -
    jmockit
    Current Version1.22
    1.24
    Scope test
    jar
    Newer versions1.23 Next Minor
    1.24 Latest Minor
    +1.25 Next Minor

    org.jsoup:jsoup

    - + @@ -1386,7 +1386,7 @@ - + @@ -1395,10 +1395,7 @@ - - - -
    Status There is at least one newer incremental version available. Incremental updates are typically passive.
     No newer versions available.
    Group Id org.jsoup
    jsoup
    Current Version1.9.1
    1.9.2
    Scope
    Typejar
    Newer versions1.9.2 Next Incremental
    +jar

    org.owasp:dependency-check-core

    @@ -1413,7 +1410,7 @@ - + @@ -1437,7 +1434,7 @@ - + diff --git a/dependency-check-ant/findbugs.html b/dependency-check-ant/findbugs.html index 62f02f09e..6a633008f 100644 --- a/dependency-check-ant/findbugs.html +++ b/dependency-check-ant/findbugs.html @@ -1,13 +1,13 @@ - + dependency-check-ant – FindBugs Bug Detector Report @@ -52,7 +52,7 @@ @@ -264,7 +264,7 @@ - +
    dependency-check-core
    Current Version1.4.0
    1.4.2
    Scope compile
    dependency-check-utils
    Current Version1.4.0
    1.4.2
    Scope compile
    Inconsistent synchronization of org.owasp.dependencycheck.taskdefs.Check.path; locked 44% of time MT_CORRECTNESS IS2_INCONSISTENT_SYNC870887 Medium
    diff --git a/dependency-check-ant/index.html b/dependency-check-ant/index.html index 70d962843..ae431870a 100644 --- a/dependency-check-ant/index.html +++ b/dependency-check-ant/index.html @@ -1,13 +1,13 @@ - + dependency-check-ant – About @@ -52,7 +52,7 @@ @@ -150,7 +150,7 @@
      -
    1. Download dependency-check-ant from bintray here.
    2. +
    3. Download dependency-check-ant from bintray here.
    4. Unzip the archive
    5. diff --git a/dependency-check-ant/integration.html b/dependency-check-ant/integration.html index 76e088e8a..73e98d56f 100644 --- a/dependency-check-ant/integration.html +++ b/dependency-check-ant/integration.html @@ -1,13 +1,13 @@ - + dependency-check-ant – CI Management @@ -52,7 +52,7 @@ diff --git a/dependency-check-ant/issue-tracking.html b/dependency-check-ant/issue-tracking.html index 378db0cc3..f2cf2bdda 100644 --- a/dependency-check-ant/issue-tracking.html +++ b/dependency-check-ant/issue-tracking.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Issue Management @@ -52,7 +52,7 @@ diff --git a/dependency-check-ant/license.html b/dependency-check-ant/license.html index 4c298a65d..a720c353f 100644 --- a/dependency-check-ant/license.html +++ b/dependency-check-ant/license.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Project Licenses @@ -52,7 +52,7 @@ diff --git a/dependency-check-ant/mail-lists.html b/dependency-check-ant/mail-lists.html index ce7c4c66f..4824edfef 100644 --- a/dependency-check-ant/mail-lists.html +++ b/dependency-check-ant/mail-lists.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Project Mailing Lists @@ -52,7 +52,7 @@ diff --git a/dependency-check-ant/plugin-updates-report.html b/dependency-check-ant/plugin-updates-report.html index c41d3ed4c..fcac7e5d5 100644 --- a/dependency-check-ant/plugin-updates-report.html +++ b/dependency-check-ant/plugin-updates-report.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Plugin Updates Report @@ -52,7 +52,7 @@ @@ -230,7 +230,7 @@ # of plugins using the latest version available -18 +19 # of plugins where the next version available is smaller than an incremental version update @@ -246,7 +246,7 @@ # of plugins where the next version available is a major version update -1 +0 # of plugins where a dependencies section containes a dependency with an updated version @@ -368,7 +368,7 @@ org.apache.maven.plugins maven-jar-plugin -3.0.0 +3.0.2 @@ -378,7 +378,7 @@ org.apache.maven.plugins maven-javadoc-plugin -2.10.3 +2.10.4 @@ -415,14 +415,14 @@ - + org.apache.maven.plugins maven-source-plugin -2.4 +3.0.1 + -3.0.0 @@ -634,7 +634,7 @@ maven-jar-plugin Current Version -3.0.0 +3.0.2

      Plugin org.apache.maven.plugins:maven-javadoc-plugin

      @@ -649,7 +649,7 @@ -
      maven-javadoc-plugin
      Current Version2.10.3
      +2.10.4

      Plugin org.apache.maven.plugins:maven-release-plugin

      @@ -700,7 +700,7 @@
      - + @@ -709,10 +709,7 @@ - - - -
      Status There is at least one newer major version available. Major updates are rarely passive.
       No newer versions available.
      Group Id org.apache.maven.plugins
      maven-source-plugin
      Current Version2.4
      Newer versions3.0.0 Next Major
      +3.0.1

      Plugin org.apache.maven.plugins:maven-surefire-plugin

      diff --git a/dependency-check-ant/project-info.html b/dependency-check-ant/project-info.html index 183cda180..52eee0113 100644 --- a/dependency-check-ant/project-info.html +++ b/dependency-check-ant/project-info.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Project Information @@ -52,7 +52,7 @@ diff --git a/dependency-check-ant/project-reports.html b/dependency-check-ant/project-reports.html index d2a0f70fc..e0b1d2343 100644 --- a/dependency-check-ant/project-reports.html +++ b/dependency-check-ant/project-reports.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Generated Reports @@ -52,7 +52,7 @@ diff --git a/dependency-check-ant/project-summary.html b/dependency-check-ant/project-summary.html index cfbe4f71c..bbd602b98 100644 --- a/dependency-check-ant/project-summary.html +++ b/dependency-check-ant/project-summary.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Project Summary @@ -52,7 +52,7 @@ @@ -238,7 +238,7 @@ - + diff --git a/dependency-check-ant/source-repository.html b/dependency-check-ant/source-repository.html index 8ac1dcba0..1250faa72 100644 --- a/dependency-check-ant/source-repository.html +++ b/dependency-check-ant/source-repository.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Source Code Management @@ -52,7 +52,7 @@ diff --git a/dependency-check-ant/surefire-report.html b/dependency-check-ant/surefire-report.html index d54168ed6..153eccf3f 100644 --- a/dependency-check-ant/surefire-report.html +++ b/dependency-check-ant/surefire-report.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Surefire Report @@ -52,7 +52,7 @@ @@ -259,7 +259,7 @@ function toggleDisplay(elementId) { -
      dependency-check-ant
      Version1.4.0
      1.4.2
      Type jar
      0 0 100%16.843

      +16.967

      Note: failures are anticipated and checked for with assertions while errors are unanticipated.


      Package List

      @@ -280,7 +280,7 @@ function toggleDisplay(elementId) { 0 0 100% -16.843
      +16.967

      Note: package statistics are not computed recursively, they only sum up all of its testsuites numbers.

      org.owasp.dependencycheck.taskdefs

      @@ -302,7 +302,7 @@ function toggleDisplay(elementId) { 0 0 100% -16.843

      +16.967

      Test Cases

      [Summary] [Package List] [Test Cases]

      @@ -312,19 +312,19 @@ function toggleDisplay(elementId) { testGetFailBuildOnCVSS -0.402 +0.454 testAddDirSet -7.583 +7.177 testAddFileSet -4.888 +4.975 testAddFileList -3.884

      +4.258
      diff --git a/dependency-check-ant/taglist.html b/dependency-check-ant/taglist.html index f81456efa..ea957f8cb 100644 --- a/dependency-check-ant/taglist.html +++ b/dependency-check-ant/taglist.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Tag List report @@ -52,7 +52,7 @@ diff --git a/dependency-check-ant/team-list.html b/dependency-check-ant/team-list.html index 38b0559b4..846133cc7 100644 --- a/dependency-check-ant/team-list.html +++ b/dependency-check-ant/team-list.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Project Team @@ -52,7 +52,7 @@ diff --git a/dependency-check-ant/xref-test/index.html b/dependency-check-ant/xref-test/index.html index 87b737854..a6c03eb1f 100644 --- a/dependency-check-ant/xref-test/index.html +++ b/dependency-check-ant/xref-test/index.html @@ -4,7 +4,7 @@ - Dependency-Check Ant Task 1.4.0 Reference + Dependency-Check Ant Task 1.4.2 Reference diff --git a/dependency-check-ant/xref-test/org/owasp/dependencycheck/taskdefs/package-frame.html b/dependency-check-ant/xref-test/org/owasp/dependencycheck/taskdefs/package-frame.html index 106e7d141..2165a446e 100644 --- a/dependency-check-ant/xref-test/org/owasp/dependencycheck/taskdefs/package-frame.html +++ b/dependency-check-ant/xref-test/org/owasp/dependencycheck/taskdefs/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Ant Task 1.4.0 Reference Package org.owasp.dependencycheck.taskdefs + Dependency-Check Ant Task 1.4.2 Reference Package org.owasp.dependencycheck.taskdefs diff --git a/dependency-check-ant/xref-test/org/owasp/dependencycheck/taskdefs/package-summary.html b/dependency-check-ant/xref-test/org/owasp/dependencycheck/taskdefs/package-summary.html index e0c2c2c73..a3b1934f2 100644 --- a/dependency-check-ant/xref-test/org/owasp/dependencycheck/taskdefs/package-summary.html +++ b/dependency-check-ant/xref-test/org/owasp/dependencycheck/taskdefs/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Ant Task 1.4.0 Reference Package org.owasp.dependencycheck.taskdefs + Dependency-Check Ant Task 1.4.2 Reference Package org.owasp.dependencycheck.taskdefs diff --git a/dependency-check-ant/xref-test/overview-frame.html b/dependency-check-ant/xref-test/overview-frame.html index 815bfa189..a9ab11169 100644 --- a/dependency-check-ant/xref-test/overview-frame.html +++ b/dependency-check-ant/xref-test/overview-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Ant Task 1.4.0 Reference + Dependency-Check Ant Task 1.4.2 Reference diff --git a/dependency-check-ant/xref-test/overview-summary.html b/dependency-check-ant/xref-test/overview-summary.html index 9be5448cb..43107983f 100644 --- a/dependency-check-ant/xref-test/overview-summary.html +++ b/dependency-check-ant/xref-test/overview-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Ant Task 1.4.0 Reference + Dependency-Check Ant Task 1.4.2 Reference @@ -24,7 +24,7 @@ -

      Dependency-Check Ant Task 1.4.0 Reference

      +

      Dependency-Check Ant Task 1.4.2 Reference

      diff --git a/dependency-check-ant/xref/index.html b/dependency-check-ant/xref/index.html index 87b737854..a6c03eb1f 100644 --- a/dependency-check-ant/xref/index.html +++ b/dependency-check-ant/xref/index.html @@ -4,7 +4,7 @@ - Dependency-Check Ant Task 1.4.0 Reference + Dependency-Check Ant Task 1.4.2 Reference diff --git a/dependency-check-ant/xref/org/owasp/dependencycheck/ant/logging/package-frame.html b/dependency-check-ant/xref/org/owasp/dependencycheck/ant/logging/package-frame.html index f96519771..ae86307de 100644 --- a/dependency-check-ant/xref/org/owasp/dependencycheck/ant/logging/package-frame.html +++ b/dependency-check-ant/xref/org/owasp/dependencycheck/ant/logging/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Ant Task 1.4.0 Reference Package org.owasp.dependencycheck.ant.logging + Dependency-Check Ant Task 1.4.2 Reference Package org.owasp.dependencycheck.ant.logging diff --git a/dependency-check-ant/xref/org/owasp/dependencycheck/ant/logging/package-summary.html b/dependency-check-ant/xref/org/owasp/dependencycheck/ant/logging/package-summary.html index b47da75a0..d61fa2b55 100644 --- a/dependency-check-ant/xref/org/owasp/dependencycheck/ant/logging/package-summary.html +++ b/dependency-check-ant/xref/org/owasp/dependencycheck/ant/logging/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Ant Task 1.4.0 Reference Package org.owasp.dependencycheck.ant.logging + Dependency-Check Ant Task 1.4.2 Reference Package org.owasp.dependencycheck.ant.logging diff --git a/dependency-check-ant/xref/org/owasp/dependencycheck/taskdefs/Check.html b/dependency-check-ant/xref/org/owasp/dependencycheck/taskdefs/Check.html index 2c447834d..4d625b854 100644 --- a/dependency-check-ant/xref/org/owasp/dependencycheck/taskdefs/Check.html +++ b/dependency-check-ant/xref/org/owasp/dependencycheck/taskdefs/Check.html @@ -26,989 +26,1006 @@ 18package org.owasp.dependencycheck.taskdefs; 1920import java.io.File; -21import java.io.IOException; -22import java.util.List; -23import org.apache.tools.ant.BuildException; -24import org.apache.tools.ant.Project; -25import org.apache.tools.ant.types.EnumeratedAttribute; -26import org.apache.tools.ant.types.Reference; -27import org.apache.tools.ant.types.Resource; -28import org.apache.tools.ant.types.ResourceCollection; -29import org.apache.tools.ant.types.resources.FileProvider; -30import org.apache.tools.ant.types.resources.Resources; -31import org.owasp.dependencycheck.Engine; -32import org.owasp.dependencycheck.data.nvdcve.CveDB; -33import org.owasp.dependencycheck.data.nvdcve.DatabaseException; -34import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties; +21import java.util.List; +22import org.apache.tools.ant.BuildException; +23import org.apache.tools.ant.Project; +24import org.apache.tools.ant.types.EnumeratedAttribute; +25import org.apache.tools.ant.types.Reference; +26import org.apache.tools.ant.types.Resource; +27import org.apache.tools.ant.types.ResourceCollection; +28import org.apache.tools.ant.types.resources.FileProvider; +29import org.apache.tools.ant.types.resources.Resources; +30import org.owasp.dependencycheck.Engine; +31import org.owasp.dependencycheck.data.nvdcve.CveDB; +32import org.owasp.dependencycheck.data.nvdcve.DatabaseException; +33import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties; +34import org.owasp.dependencycheck.data.update.exception.UpdateException; 35import org.owasp.dependencycheck.dependency.Dependency; 36import org.owasp.dependencycheck.dependency.Identifier; 37import org.owasp.dependencycheck.dependency.Vulnerability; -38import org.owasp.dependencycheck.reporting.ReportGenerator; -39import org.owasp.dependencycheck.reporting.ReportGenerator.Format; -40import org.owasp.dependencycheck.utils.Settings; -41import org.slf4j.impl.StaticLoggerBinder; -42 -43/** -44 * An Ant task definition to execute dependency-check during an Ant build. -45 * -46 * @author Jeremy Long -47 */ -48publicclassCheckextendsUpdate { -49 -50/** -51 * System specific new line character. -52 */ -53privatestaticfinal String NEW_LINE = System.getProperty("line.separator", "\n").intern(); -54 -55/** -56 * Construct a new DependencyCheckTask. -57 */ -58publicCheck() { -59super(); -60// Call this before Dependency Check Core starts logging anything - this way, all SLF4J messages from -61// core end up coming through this tasks logger -62 StaticLoggerBinder.getSingleton().setTask(this); -63 } -64//The following code was copied Apache Ant PathConvert -65//BEGIN COPY from org.apache.tools.ant.taskdefs.PathConvert -66/** -67 * Path to be converted -68 */ -69private Resources path = null; -70/** -71 * Reference to path/fileset to convert -72 */ -73private Reference refid = null; -74 -75/** -76 * Add an arbitrary ResourceCollection. -77 * -78 * @param rc the ResourceCollection to add. -79 * @since Ant 1.7 -80 */ -81publicvoid add(ResourceCollection rc) { -82if (isReference()) { -83thrownew BuildException("Nested elements are not allowed when using the refid attribute."); -84 } -85 getPath().add(rc); -86 } -87 -88/** -89 * Returns the path. If the path has not been initialized yet, this class is -90 * synchronized, and will instantiate the path object. -91 * -92 * @return the path -93 */ -94privatesynchronized Resources getPath() { -95if (path == null) { -96 path = new Resources(getProject()); -97 path.setCache(true); -98 } -99return path; -100 } -101 -102/** -103 * Learn whether the refid attribute of this element been set. -104 * -105 * @return true if refid is valid. -106 */ -107publicboolean isReference() { -108return refid != null; -109 } -110 -111/** -112 * Add a reference to a Path, FileSet, DirSet, or FileList defined -113 * elsewhere. -114 * -115 * @param r the reference to a path, fileset, dirset or filelist. -116 */ -117publicvoid setRefid(Reference r) { -118if (path != null) { -119thrownew BuildException("Nested elements are not allowed when using the refid attribute."); -120 } -121 refid = r; -122 } -123 -124/** -125 * If this is a reference, this method will add the referenced resource -126 * collection to the collection of paths. -127 * -128 * @throws BuildException if the reference is not to a resource collection -129 */ -130privatevoid dealWithReferences() throws BuildException { -131if (isReference()) { -132final Object o = refid.getReferencedObject(getProject()); -133if (!(o instanceof ResourceCollection)) { -134thrownew BuildException("refid '" + refid.getRefId() -135 + "' does not refer to a resource collection."); -136 } -137 getPath().add((ResourceCollection) o); -138 } -139 } -140// END COPY from org.apache.tools.ant.taskdefs -141/** -142 * The application name for the report. -143 * -144 * @deprecated use projectName instead. -145 */ -146 @Deprecated -147private String applicationName = null; -148 -149/** -150 * Get the value of applicationName. -151 * -152 * @return the value of applicationName +38import org.owasp.dependencycheck.exception.ExceptionCollection; +39import org.owasp.dependencycheck.exception.ReportException; +40import org.owasp.dependencycheck.reporting.ReportGenerator; +41import org.owasp.dependencycheck.reporting.ReportGenerator.Format; +42import org.owasp.dependencycheck.utils.Settings; +43import org.slf4j.impl.StaticLoggerBinder; +44 +45/** +46 * An Ant task definition to execute dependency-check during an Ant build. +47 * +48 * @author Jeremy Long +49 */ +50publicclassCheckextendsUpdate { +51 +52/** +53 * System specific new line character. +54 */ +55privatestaticfinal String NEW_LINE = System.getProperty("line.separator", "\n").intern(); +56 +57/** +58 * Construct a new DependencyCheckTask. +59 */ +60publicCheck() { +61super(); +62// Call this before Dependency Check Core starts logging anything - this way, all SLF4J messages from +63// core end up coming through this tasks logger +64 StaticLoggerBinder.getSingleton().setTask(this); +65 } +66//The following code was copied Apache Ant PathConvert +67//BEGIN COPY from org.apache.tools.ant.taskdefs.PathConvert +68/** +69 * Path to be converted +70 */ +71private Resources path = null; +72/** +73 * Reference to path/fileset to convert +74 */ +75private Reference refid = null; +76 +77/** +78 * Add an arbitrary ResourceCollection. +79 * +80 * @param rc the ResourceCollection to add. +81 * @since Ant 1.7 +82 */ +83publicvoid add(ResourceCollection rc) { +84if (isReference()) { +85thrownew BuildException("Nested elements are not allowed when using the refid attribute."); +86 } +87 getPath().add(rc); +88 } +89 +90/** +91 * Returns the path. If the path has not been initialized yet, this class is +92 * synchronized, and will instantiate the path object. +93 * +94 * @return the path +95 */ +96privatesynchronized Resources getPath() { +97if (path == null) { +98 path = new Resources(getProject()); +99 path.setCache(true); +100 } +101return path; +102 } +103 +104/** +105 * Learn whether the refid attribute of this element been set. +106 * +107 * @return true if refid is valid. +108 */ +109publicboolean isReference() { +110return refid != null; +111 } +112 +113/** +114 * Add a reference to a Path, FileSet, DirSet, or FileList defined +115 * elsewhere. +116 * +117 * @param r the reference to a path, fileset, dirset or filelist. +118 */ +119publicvoid setRefid(Reference r) { +120if (path != null) { +121thrownew BuildException("Nested elements are not allowed when using the refid attribute."); +122 } +123 refid = r; +124 } +125 +126/** +127 * If this is a reference, this method will add the referenced resource +128 * collection to the collection of paths. +129 * +130 * @throws BuildException if the reference is not to a resource collection +131 */ +132privatevoid dealWithReferences() throws BuildException { +133if (isReference()) { +134final Object o = refid.getReferencedObject(getProject()); +135if (!(o instanceof ResourceCollection)) { +136thrownew BuildException("refid '" + refid.getRefId() +137 + "' does not refer to a resource collection."); +138 } +139 getPath().add((ResourceCollection) o); +140 } +141 } +142// END COPY from org.apache.tools.ant.taskdefs +143/** +144 * The application name for the report. +145 * +146 * @deprecated use projectName instead. +147 */ +148 @Deprecated +149private String applicationName = null; +150 +151/** +152 * Get the value of applicationName.153 * -154 * @deprecated use projectName instead. -155 */ -156 @Deprecated -157public String getApplicationName() { -158return applicationName; -159 } -160 -161/** -162 * Set the value of applicationName. -163 * -164 * @param applicationName new value of applicationName -165 * @deprecated use projectName instead. -166 */ -167 @Deprecated -168publicvoid setApplicationName(String applicationName) { -169this.applicationName = applicationName; -170 } -171/** -172 * The name of the project being analyzed. -173 */ -174private String projectName = "dependency-check"; -175 -176/** -177 * Get the value of projectName. -178 * -179 * @return the value of projectName -180 */ -181public String getProjectName() { -182if (applicationName != null) { -183 log("Configuration 'applicationName' has been deprecated, please use 'projectName' instead", Project.MSG_WARN); -184if ("dependency-check".equals(projectName)) { -185 projectName = applicationName; -186 } -187 } -188return projectName; -189 } -190 -191/** -192 * Set the value of projectName. -193 * -194 * @param projectName new value of projectName -195 */ -196publicvoid setProjectName(String projectName) { -197this.projectName = projectName; -198 } -199 -200/** -201 * Specifies the destination directory for the generated Dependency-Check -202 * report. -203 */ -204private String reportOutputDirectory = "."; -205 -206/** -207 * Get the value of reportOutputDirectory. -208 * -209 * @return the value of reportOutputDirectory -210 */ -211public String getReportOutputDirectory() { -212return reportOutputDirectory; -213 } -214 -215/** -216 * Set the value of reportOutputDirectory. -217 * -218 * @param reportOutputDirectory new value of reportOutputDirectory -219 */ -220publicvoid setReportOutputDirectory(String reportOutputDirectory) { -221this.reportOutputDirectory = reportOutputDirectory; -222 } -223/** -224 * Specifies if the build should be failed if a CVSS score above a specified -225 * level is identified. The default is 11 which means since the CVSS scores -226 * are 0-10, by default the build will never fail and the CVSS score is set -227 * to 11. The valid range for the fail build on CVSS is 0 to 11, where -228 * anything above 10 will not cause the build to fail. -229 */ -230privatefloat failBuildOnCVSS = 11; -231 -232/** -233 * Get the value of failBuildOnCVSS. -234 * -235 * @return the value of failBuildOnCVSS -236 */ -237publicfloat getFailBuildOnCVSS() { -238return failBuildOnCVSS; -239 } -240 -241/** -242 * Set the value of failBuildOnCVSS. -243 * -244 * @param failBuildOnCVSS new value of failBuildOnCVSS -245 */ -246publicvoid setFailBuildOnCVSS(float failBuildOnCVSS) { -247this.failBuildOnCVSS = failBuildOnCVSS; -248 } -249/** -250 * Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not -251 * recommended that this be turned to false. Default is true. -252 */ -253private Boolean autoUpdate; -254 -255/** -256 * Get the value of autoUpdate. -257 * -258 * @return the value of autoUpdate -259 */ -260public Boolean isAutoUpdate() { -261return autoUpdate; -262 } -263 -264/** -265 * Set the value of autoUpdate. -266 * -267 * @param autoUpdate new value of autoUpdate -268 */ -269publicvoid setAutoUpdate(Boolean autoUpdate) { -270this.autoUpdate = autoUpdate; -271 } -272/** -273 * Whether only the update phase should be executed. -274 * -275 * @deprecated Use the update task instead -276 */ -277 @Deprecated -278privateboolean updateOnly = false; -279 -280/** -281 * Get the value of updateOnly. -282 * -283 * @return the value of updateOnly -284 * @deprecated Use the update task instead -285 */ -286 @Deprecated -287publicboolean isUpdateOnly() { -288return updateOnly; -289 } -290 -291/** -292 * Set the value of updateOnly. -293 * -294 * @param updateOnly new value of updateOnly -295 * @deprecated Use the update task instead -296 */ -297 @Deprecated -298publicvoid setUpdateOnly(boolean updateOnly) { -299this.updateOnly = updateOnly; -300 } -301 -302/** -303 * The report format to be generated (HTML, XML, VULN, ALL). Default is -304 * HTML. -305 */ -306private String reportFormat = "HTML"; -307 -308/** -309 * Get the value of reportFormat. -310 * -311 * @return the value of reportFormat -312 */ -313public String getReportFormat() { -314return reportFormat; -315 } -316 -317/** -318 * Set the value of reportFormat. -319 * -320 * @param reportFormat new value of reportFormat -321 */ -322publicvoid setReportFormat(ReportFormats reportFormat) { -323this.reportFormat = reportFormat.getValue(); -324 } -325/** -326 * The path to the suppression file. -327 */ -328private String suppressionFile; -329 -330/** -331 * Get the value of suppressionFile. -332 * -333 * @return the value of suppressionFile -334 */ -335public String getSuppressionFile() { -336return suppressionFile; -337 } -338 -339/** -340 * Set the value of suppressionFile. -341 * -342 * @param suppressionFile new value of suppressionFile -343 */ -344publicvoid setSuppressionFile(String suppressionFile) { -345this.suppressionFile = suppressionFile; -346 } -347/** -348 * flag indicating whether or not to show a summary of findings. -349 */ -350privateboolean showSummary = true; -351 -352/** -353 * Get the value of showSummary. -354 * -355 * @return the value of showSummary -356 */ -357publicboolean isShowSummary() { -358return showSummary; -359 } -360 -361/** -362 * Set the value of showSummary. -363 * -364 * @param showSummary new value of showSummary -365 */ -366publicvoid setShowSummary(boolean showSummary) { -367this.showSummary = showSummary; -368 } -369 -370/** -371 * Whether experimental analyzers are enabled. -372 */ -373private Boolean enableExperimental; -374 -375/** -376 * Get the value of enableExperimental. -377 * -378 * @return the value of enableExperimental -379 */ -380public Boolean isEnableExperimental() { -381return enableExperimental; -382 } -383 -384/** -385 * Set the value of enableExperimental. -386 * -387 * @param enableExperimental new value of enableExperimental -388 */ -389publicvoid setEnableExperimental(Boolean enableExperimental) { -390this.enableExperimental = enableExperimental; -391 } -392 -393/** -394 * Whether or not the Jar Analyzer is enabled. -395 */ -396private Boolean jarAnalyzerEnabled; -397 -398/** -399 * Returns whether or not the analyzer is enabled. -400 * -401 * @return true if the analyzer is enabled -402 */ -403public Boolean isJarAnalyzerEnabled() { -404return jarAnalyzerEnabled; -405 } -406 -407/** -408 * Sets whether or not the analyzer is enabled. -409 * -410 * @param jarAnalyzerEnabled the value of the new setting -411 */ -412publicvoid setJarAnalyzerEnabled(Boolean jarAnalyzerEnabled) { -413this.jarAnalyzerEnabled = jarAnalyzerEnabled; -414 } -415/** -416 * Whether or not the Archive Analyzer is enabled. -417 */ -418private Boolean archiveAnalyzerEnabled; -419 -420/** -421 * Returns whether or not the analyzer is enabled. -422 * -423 * @return true if the analyzer is enabled -424 */ -425public Boolean isArchiveAnalyzerEnabled() { -426return archiveAnalyzerEnabled; -427 } -428/** -429 * Whether or not the .NET Assembly Analyzer is enabled. -430 */ -431private Boolean assemblyAnalyzerEnabled; -432 -433/** -434 * Sets whether or not the analyzer is enabled. -435 * -436 * @param archiveAnalyzerEnabled the value of the new setting -437 */ -438publicvoid setArchiveAnalyzerEnabled(Boolean archiveAnalyzerEnabled) { -439this.archiveAnalyzerEnabled = archiveAnalyzerEnabled; -440 } -441 -442/** -443 * Returns whether or not the analyzer is enabled. -444 * -445 * @return true if the analyzer is enabled -446 */ -447public Boolean isAssemblyAnalyzerEnabled() { -448return assemblyAnalyzerEnabled; -449 } -450 -451/** -452 * Sets whether or not the analyzer is enabled. -453 * -454 * @param assemblyAnalyzerEnabled the value of the new setting -455 */ -456publicvoid setAssemblyAnalyzerEnabled(Boolean assemblyAnalyzerEnabled) { -457this.assemblyAnalyzerEnabled = assemblyAnalyzerEnabled; -458 } -459/** -460 * Whether or not the .NET Nuspec Analyzer is enabled. -461 */ -462private Boolean nuspecAnalyzerEnabled; -463 -464/** -465 * Returns whether or not the analyzer is enabled. -466 * -467 * @return true if the analyzer is enabled -468 */ -469public Boolean isNuspecAnalyzerEnabled() { -470return nuspecAnalyzerEnabled; -471 } -472 -473/** -474 * Sets whether or not the analyzer is enabled. -475 * -476 * @param nuspecAnalyzerEnabled the value of the new setting -477 */ -478publicvoid setNuspecAnalyzerEnabled(Boolean nuspecAnalyzerEnabled) { -479this.nuspecAnalyzerEnabled = nuspecAnalyzerEnabled; -480 } -481/** -482 * Whether or not the PHP Composer Analyzer is enabled. -483 */ -484private Boolean composerAnalyzerEnabled; -485 -486/** -487 * Get the value of composerAnalyzerEnabled. -488 * -489 * @return the value of composerAnalyzerEnabled -490 */ -491public Boolean isComposerAnalyzerEnabled() { -492return composerAnalyzerEnabled; -493 } -494 -495/** -496 * Set the value of composerAnalyzerEnabled. -497 * -498 * @param composerAnalyzerEnabled new value of composerAnalyzerEnabled -499 */ -500publicvoid setComposerAnalyzerEnabled(Boolean composerAnalyzerEnabled) { -501this.composerAnalyzerEnabled = composerAnalyzerEnabled; -502 } -503/** -504 * Whether the autoconf analyzer should be enabled. -505 */ -506private Boolean autoconfAnalyzerEnabled; -507 -508/** -509 * Get the value of autoconfAnalyzerEnabled. -510 * -511 * @return the value of autoconfAnalyzerEnabled -512 */ -513public Boolean isAutoconfAnalyzerEnabled() { -514return autoconfAnalyzerEnabled; -515 } -516 -517/** -518 * Set the value of autoconfAnalyzerEnabled. -519 * -520 * @param autoconfAnalyzerEnabled new value of autoconfAnalyzerEnabled -521 */ -522publicvoid setAutoconfAnalyzerEnabled(Boolean autoconfAnalyzerEnabled) { -523this.autoconfAnalyzerEnabled = autoconfAnalyzerEnabled; -524 } -525/** -526 * Whether the CMake analyzer should be enabled. -527 */ -528private Boolean cmakeAnalyzerEnabled; -529 -530/** -531 * Get the value of cmakeAnalyzerEnabled. -532 * -533 * @return the value of cmakeAnalyzerEnabled -534 */ -535public Boolean isCMakeAnalyzerEnabled() { -536return cmakeAnalyzerEnabled; -537 } -538 -539/** -540 * Set the value of cmakeAnalyzerEnabled. -541 * -542 * @param cmakeAnalyzerEnabled new value of cmakeAnalyzerEnabled -543 */ -544publicvoid setCMakeAnalyzerEnabled(Boolean cmakeAnalyzerEnabled) { -545this.cmakeAnalyzerEnabled = cmakeAnalyzerEnabled; -546 } -547/** -548 * Whether or not the openssl analyzer is enabled. -549 */ -550private Boolean opensslAnalyzerEnabled; -551 -552/** -553 * Get the value of opensslAnalyzerEnabled. -554 * -555 * @return the value of opensslAnalyzerEnabled -556 */ -557public Boolean isOpensslAnalyzerEnabled() { -558return opensslAnalyzerEnabled; -559 } -560 -561/** -562 * Set the value of opensslAnalyzerEnabled. -563 * -564 * @param opensslAnalyzerEnabled new value of opensslAnalyzerEnabled -565 */ -566publicvoid setOpensslAnalyzerEnabled(Boolean opensslAnalyzerEnabled) { -567this.opensslAnalyzerEnabled = opensslAnalyzerEnabled; -568 } -569/** -570 * Whether or not the Node.js Analyzer is enabled. -571 */ -572private Boolean nodeAnalyzerEnabled; -573 -574/** -575 * Get the value of nodeAnalyzerEnabled. -576 * -577 * @return the value of nodeAnalyzerEnabled -578 */ -579public Boolean isNodeAnalyzerEnabled() { -580return nodeAnalyzerEnabled; -581 } -582 -583/** -584 * Set the value of nodeAnalyzerEnabled. -585 * -586 * @param nodeAnalyzerEnabled new value of nodeAnalyzerEnabled -587 */ -588publicvoid setNodeAnalyzerEnabled(Boolean nodeAnalyzerEnabled) { -589this.nodeAnalyzerEnabled = nodeAnalyzerEnabled; -590 } -591/** -592 * Whether the ruby gemspec analyzer should be enabled. -593 */ -594private Boolean rubygemsAnalyzerEnabled; -595 -596/** -597 * Get the value of rubygemsAnalyzerEnabled. -598 * -599 * @return the value of rubygemsAnalyzerEnabled -600 */ -601public Boolean isRubygemsAnalyzerEnabled() { -602return rubygemsAnalyzerEnabled; -603 } -604 -605/** -606 * Set the value of rubygemsAnalyzerEnabled. -607 * -608 * @param rubygemsAnalyzerEnabled new value of rubygemsAnalyzerEnabled -609 */ -610publicvoid setRubygemsAnalyzerEnabled(Boolean rubygemsAnalyzerEnabled) { -611this.rubygemsAnalyzerEnabled = rubygemsAnalyzerEnabled; -612 } -613/** -614 * Whether the python package analyzer should be enabled. -615 */ -616private Boolean pyPackageAnalyzerEnabled; -617 -618/** -619 * Get the value of pyPackageAnalyzerEnabled. -620 * -621 * @return the value of pyPackageAnalyzerEnabled -622 */ -623public Boolean isPyPackageAnalyzerEnabled() { -624return pyPackageAnalyzerEnabled; -625 } -626 -627/** -628 * Set the value of pyPackageAnalyzerEnabled. -629 * -630 * @param pyPackageAnalyzerEnabled new value of pyPackageAnalyzerEnabled -631 */ -632publicvoid setPyPackageAnalyzerEnabled(Boolean pyPackageAnalyzerEnabled) { -633this.pyPackageAnalyzerEnabled = pyPackageAnalyzerEnabled; -634 } -635 -636/** -637 * Whether the python distribution analyzer should be enabled. -638 */ -639private Boolean pyDistributionAnalyzerEnabled; -640 -641/** -642 * Get the value of pyDistributionAnalyzerEnabled. -643 * -644 * @return the value of pyDistributionAnalyzerEnabled -645 */ -646public Boolean isPyDistributionAnalyzerEnabled() { -647return pyDistributionAnalyzerEnabled; -648 } -649 -650/** -651 * Set the value of pyDistributionAnalyzerEnabled. -652 * -653 * @param pyDistributionAnalyzerEnabled new value of -654 * pyDistributionAnalyzerEnabled -655 */ -656publicvoid setPyDistributionAnalyzerEnabled(Boolean pyDistributionAnalyzerEnabled) { -657this.pyDistributionAnalyzerEnabled = pyDistributionAnalyzerEnabled; -658 } -659 -660/** -661 * Whether or not the central analyzer is enabled. -662 */ -663private Boolean centralAnalyzerEnabled; -664 -665/** -666 * Get the value of centralAnalyzerEnabled. -667 * -668 * @return the value of centralAnalyzerEnabled -669 */ -670public Boolean isCentralAnalyzerEnabled() { -671return centralAnalyzerEnabled; -672 } -673 -674/** -675 * Set the value of centralAnalyzerEnabled. -676 * -677 * @param centralAnalyzerEnabled new value of centralAnalyzerEnabled -678 */ -679publicvoid setCentralAnalyzerEnabled(Boolean centralAnalyzerEnabled) { -680this.centralAnalyzerEnabled = centralAnalyzerEnabled; -681 } -682 -683/** -684 * Whether or not the nexus analyzer is enabled. -685 */ -686private Boolean nexusAnalyzerEnabled; -687 -688/** -689 * Get the value of nexusAnalyzerEnabled. -690 * -691 * @return the value of nexusAnalyzerEnabled -692 */ -693public Boolean isNexusAnalyzerEnabled() { -694return nexusAnalyzerEnabled; -695 } -696 -697/** -698 * Set the value of nexusAnalyzerEnabled. -699 * -700 * @param nexusAnalyzerEnabled new value of nexusAnalyzerEnabled -701 */ -702publicvoid setNexusAnalyzerEnabled(Boolean nexusAnalyzerEnabled) { -703this.nexusAnalyzerEnabled = nexusAnalyzerEnabled; -704 } -705 -706/** -707 * The URL of a Nexus server's REST API end point -708 * (http://domain/nexus/service/local). -709 */ -710private String nexusUrl; -711 -712/** -713 * Get the value of nexusUrl. -714 * -715 * @return the value of nexusUrl -716 */ -717public String getNexusUrl() { -718return nexusUrl; -719 } -720 -721/** -722 * Set the value of nexusUrl. -723 * -724 * @param nexusUrl new value of nexusUrl -725 */ -726publicvoid setNexusUrl(String nexusUrl) { -727this.nexusUrl = nexusUrl; -728 } -729/** -730 * Whether or not the defined proxy should be used when connecting to Nexus. -731 */ -732private Boolean nexusUsesProxy; -733 -734/** -735 * Get the value of nexusUsesProxy. -736 * -737 * @return the value of nexusUsesProxy -738 */ -739public Boolean isNexusUsesProxy() { -740return nexusUsesProxy; -741 } -742 -743/** -744 * Set the value of nexusUsesProxy. -745 * -746 * @param nexusUsesProxy new value of nexusUsesProxy -747 */ -748publicvoid setNexusUsesProxy(Boolean nexusUsesProxy) { -749this.nexusUsesProxy = nexusUsesProxy; -750 } -751 -752/** -753 * Additional ZIP File extensions to add analyze. This should be a -754 * comma-separated list of file extensions to treat like ZIP files. -755 */ -756private String zipExtensions; -757 -758/** -759 * Get the value of zipExtensions. -760 * -761 * @return the value of zipExtensions -762 */ -763public String getZipExtensions() { -764return zipExtensions; -765 } -766 -767/** -768 * Set the value of zipExtensions. -769 * -770 * @param zipExtensions new value of zipExtensions -771 */ -772publicvoid setZipExtensions(String zipExtensions) { -773this.zipExtensions = zipExtensions; -774 } -775 -776/** -777 * The path to Mono for .NET assembly analysis on non-windows systems. -778 */ -779private String pathToMono; -780 -781/** -782 * Get the value of pathToMono. -783 * -784 * @return the value of pathToMono -785 */ -786public String getPathToMono() { -787return pathToMono; -788 } -789 -790/** -791 * Set the value of pathToMono. -792 * -793 * @param pathToMono new value of pathToMono -794 */ -795publicvoid setPathToMono(String pathToMono) { -796this.pathToMono = pathToMono; -797 } -798 -799 @Override -800publicvoid execute() throws BuildException { -801 dealWithReferences(); -802 validateConfiguration(); -803 populateSettings(); -804 Engine engine = null; -805try { -806 engine = new Engine(Check.class.getClassLoader()); -807if (isUpdateOnly()) { -808 log("Deprecated 'UpdateOnly' property set; please use the UpdateTask instead", Project.MSG_WARN); -809 engine.doUpdates(); -810 } else { +154 * @return the value of applicationName +155 * +156 * @deprecated use projectName instead. +157 */ +158 @Deprecated +159public String getApplicationName() { +160return applicationName; +161 } +162 +163/** +164 * Set the value of applicationName. +165 * +166 * @param applicationName new value of applicationName +167 * @deprecated use projectName instead. +168 */ +169 @Deprecated +170publicvoid setApplicationName(String applicationName) { +171this.applicationName = applicationName; +172 } +173/** +174 * The name of the project being analyzed. +175 */ +176private String projectName = "dependency-check"; +177 +178/** +179 * Get the value of projectName. +180 * +181 * @return the value of projectName +182 */ +183public String getProjectName() { +184if (applicationName != null) { +185 log("Configuration 'applicationName' has been deprecated, please use 'projectName' instead", Project.MSG_WARN); +186if ("dependency-check".equals(projectName)) { +187 projectName = applicationName; +188 } +189 } +190return projectName; +191 } +192 +193/** +194 * Set the value of projectName. +195 * +196 * @param projectName new value of projectName +197 */ +198publicvoid setProjectName(String projectName) { +199this.projectName = projectName; +200 } +201 +202/** +203 * Specifies the destination directory for the generated Dependency-Check +204 * report. +205 */ +206private String reportOutputDirectory = "."; +207 +208/** +209 * Get the value of reportOutputDirectory. +210 * +211 * @return the value of reportOutputDirectory +212 */ +213public String getReportOutputDirectory() { +214return reportOutputDirectory; +215 } +216 +217/** +218 * Set the value of reportOutputDirectory. +219 * +220 * @param reportOutputDirectory new value of reportOutputDirectory +221 */ +222publicvoid setReportOutputDirectory(String reportOutputDirectory) { +223this.reportOutputDirectory = reportOutputDirectory; +224 } +225/** +226 * Specifies if the build should be failed if a CVSS score above a specified +227 * level is identified. The default is 11 which means since the CVSS scores +228 * are 0-10, by default the build will never fail and the CVSS score is set +229 * to 11. The valid range for the fail build on CVSS is 0 to 11, where +230 * anything above 10 will not cause the build to fail. +231 */ +232privatefloat failBuildOnCVSS = 11; +233 +234/** +235 * Get the value of failBuildOnCVSS. +236 * +237 * @return the value of failBuildOnCVSS +238 */ +239publicfloat getFailBuildOnCVSS() { +240return failBuildOnCVSS; +241 } +242 +243/** +244 * Set the value of failBuildOnCVSS. +245 * +246 * @param failBuildOnCVSS new value of failBuildOnCVSS +247 */ +248publicvoid setFailBuildOnCVSS(float failBuildOnCVSS) { +249this.failBuildOnCVSS = failBuildOnCVSS; +250 } +251/** +252 * Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not +253 * recommended that this be turned to false. Default is true. +254 */ +255private Boolean autoUpdate; +256 +257/** +258 * Get the value of autoUpdate. +259 * +260 * @return the value of autoUpdate +261 */ +262public Boolean isAutoUpdate() { +263return autoUpdate; +264 } +265 +266/** +267 * Set the value of autoUpdate. +268 * +269 * @param autoUpdate new value of autoUpdate +270 */ +271publicvoid setAutoUpdate(Boolean autoUpdate) { +272this.autoUpdate = autoUpdate; +273 } +274/** +275 * Whether only the update phase should be executed. +276 * +277 * @deprecated Use the update task instead +278 */ +279 @Deprecated +280privateboolean updateOnly = false; +281 +282/** +283 * Get the value of updateOnly. +284 * +285 * @return the value of updateOnly +286 * @deprecated Use the update task instead +287 */ +288 @Deprecated +289publicboolean isUpdateOnly() { +290return updateOnly; +291 } +292 +293/** +294 * Set the value of updateOnly. +295 * +296 * @param updateOnly new value of updateOnly +297 * @deprecated Use the update task instead +298 */ +299 @Deprecated +300publicvoid setUpdateOnly(boolean updateOnly) { +301this.updateOnly = updateOnly; +302 } +303 +304/** +305 * The report format to be generated (HTML, XML, VULN, ALL). Default is +306 * HTML. +307 */ +308private String reportFormat = "HTML"; +309 +310/** +311 * Get the value of reportFormat. +312 * +313 * @return the value of reportFormat +314 */ +315public String getReportFormat() { +316return reportFormat; +317 } +318 +319/** +320 * Set the value of reportFormat. +321 * +322 * @param reportFormat new value of reportFormat +323 */ +324publicvoid setReportFormat(ReportFormats reportFormat) { +325this.reportFormat = reportFormat.getValue(); +326 } +327/** +328 * The path to the suppression file. +329 */ +330private String suppressionFile; +331 +332/** +333 * Get the value of suppressionFile. +334 * +335 * @return the value of suppressionFile +336 */ +337public String getSuppressionFile() { +338return suppressionFile; +339 } +340 +341/** +342 * Set the value of suppressionFile. +343 * +344 * @param suppressionFile new value of suppressionFile +345 */ +346publicvoid setSuppressionFile(String suppressionFile) { +347this.suppressionFile = suppressionFile; +348 } +349/** +350 * flag indicating whether or not to show a summary of findings. +351 */ +352privateboolean showSummary = true; +353 +354/** +355 * Get the value of showSummary. +356 * +357 * @return the value of showSummary +358 */ +359publicboolean isShowSummary() { +360return showSummary; +361 } +362 +363/** +364 * Set the value of showSummary. +365 * +366 * @param showSummary new value of showSummary +367 */ +368publicvoid setShowSummary(boolean showSummary) { +369this.showSummary = showSummary; +370 } +371 +372/** +373 * Whether experimental analyzers are enabled. +374 */ +375private Boolean enableExperimental; +376 +377/** +378 * Get the value of enableExperimental. +379 * +380 * @return the value of enableExperimental +381 */ +382public Boolean isEnableExperimental() { +383return enableExperimental; +384 } +385 +386/** +387 * Set the value of enableExperimental. +388 * +389 * @param enableExperimental new value of enableExperimental +390 */ +391publicvoid setEnableExperimental(Boolean enableExperimental) { +392this.enableExperimental = enableExperimental; +393 } +394 +395/** +396 * Whether or not the Jar Analyzer is enabled. +397 */ +398private Boolean jarAnalyzerEnabled; +399 +400/** +401 * Returns whether or not the analyzer is enabled. +402 * +403 * @return true if the analyzer is enabled +404 */ +405public Boolean isJarAnalyzerEnabled() { +406return jarAnalyzerEnabled; +407 } +408 +409/** +410 * Sets whether or not the analyzer is enabled. +411 * +412 * @param jarAnalyzerEnabled the value of the new setting +413 */ +414publicvoid setJarAnalyzerEnabled(Boolean jarAnalyzerEnabled) { +415this.jarAnalyzerEnabled = jarAnalyzerEnabled; +416 } +417/** +418 * Whether or not the Archive Analyzer is enabled. +419 */ +420private Boolean archiveAnalyzerEnabled; +421 +422/** +423 * Returns whether or not the analyzer is enabled. +424 * +425 * @return true if the analyzer is enabled +426 */ +427public Boolean isArchiveAnalyzerEnabled() { +428return archiveAnalyzerEnabled; +429 } +430/** +431 * Whether or not the .NET Assembly Analyzer is enabled. +432 */ +433private Boolean assemblyAnalyzerEnabled; +434 +435/** +436 * Sets whether or not the analyzer is enabled. +437 * +438 * @param archiveAnalyzerEnabled the value of the new setting +439 */ +440publicvoid setArchiveAnalyzerEnabled(Boolean archiveAnalyzerEnabled) { +441this.archiveAnalyzerEnabled = archiveAnalyzerEnabled; +442 } +443 +444/** +445 * Returns whether or not the analyzer is enabled. +446 * +447 * @return true if the analyzer is enabled +448 */ +449public Boolean isAssemblyAnalyzerEnabled() { +450return assemblyAnalyzerEnabled; +451 } +452 +453/** +454 * Sets whether or not the analyzer is enabled. +455 * +456 * @param assemblyAnalyzerEnabled the value of the new setting +457 */ +458publicvoid setAssemblyAnalyzerEnabled(Boolean assemblyAnalyzerEnabled) { +459this.assemblyAnalyzerEnabled = assemblyAnalyzerEnabled; +460 } +461/** +462 * Whether or not the .NET Nuspec Analyzer is enabled. +463 */ +464private Boolean nuspecAnalyzerEnabled; +465 +466/** +467 * Returns whether or not the analyzer is enabled. +468 * +469 * @return true if the analyzer is enabled +470 */ +471public Boolean isNuspecAnalyzerEnabled() { +472return nuspecAnalyzerEnabled; +473 } +474 +475/** +476 * Sets whether or not the analyzer is enabled. +477 * +478 * @param nuspecAnalyzerEnabled the value of the new setting +479 */ +480publicvoid setNuspecAnalyzerEnabled(Boolean nuspecAnalyzerEnabled) { +481this.nuspecAnalyzerEnabled = nuspecAnalyzerEnabled; +482 } +483/** +484 * Whether or not the PHP Composer Analyzer is enabled. +485 */ +486private Boolean composerAnalyzerEnabled; +487 +488/** +489 * Get the value of composerAnalyzerEnabled. +490 * +491 * @return the value of composerAnalyzerEnabled +492 */ +493public Boolean isComposerAnalyzerEnabled() { +494return composerAnalyzerEnabled; +495 } +496 +497/** +498 * Set the value of composerAnalyzerEnabled. +499 * +500 * @param composerAnalyzerEnabled new value of composerAnalyzerEnabled +501 */ +502publicvoid setComposerAnalyzerEnabled(Boolean composerAnalyzerEnabled) { +503this.composerAnalyzerEnabled = composerAnalyzerEnabled; +504 } +505/** +506 * Whether the autoconf analyzer should be enabled. +507 */ +508private Boolean autoconfAnalyzerEnabled; +509 +510/** +511 * Get the value of autoconfAnalyzerEnabled. +512 * +513 * @return the value of autoconfAnalyzerEnabled +514 */ +515public Boolean isAutoconfAnalyzerEnabled() { +516return autoconfAnalyzerEnabled; +517 } +518 +519/** +520 * Set the value of autoconfAnalyzerEnabled. +521 * +522 * @param autoconfAnalyzerEnabled new value of autoconfAnalyzerEnabled +523 */ +524publicvoid setAutoconfAnalyzerEnabled(Boolean autoconfAnalyzerEnabled) { +525this.autoconfAnalyzerEnabled = autoconfAnalyzerEnabled; +526 } +527/** +528 * Whether the CMake analyzer should be enabled. +529 */ +530private Boolean cmakeAnalyzerEnabled; +531 +532/** +533 * Get the value of cmakeAnalyzerEnabled. +534 * +535 * @return the value of cmakeAnalyzerEnabled +536 */ +537public Boolean isCMakeAnalyzerEnabled() { +538return cmakeAnalyzerEnabled; +539 } +540 +541/** +542 * Set the value of cmakeAnalyzerEnabled. +543 * +544 * @param cmakeAnalyzerEnabled new value of cmakeAnalyzerEnabled +545 */ +546publicvoid setCMakeAnalyzerEnabled(Boolean cmakeAnalyzerEnabled) { +547this.cmakeAnalyzerEnabled = cmakeAnalyzerEnabled; +548 } +549/** +550 * Whether or not the openssl analyzer is enabled. +551 */ +552private Boolean opensslAnalyzerEnabled; +553 +554/** +555 * Get the value of opensslAnalyzerEnabled. +556 * +557 * @return the value of opensslAnalyzerEnabled +558 */ +559public Boolean isOpensslAnalyzerEnabled() { +560return opensslAnalyzerEnabled; +561 } +562 +563/** +564 * Set the value of opensslAnalyzerEnabled. +565 * +566 * @param opensslAnalyzerEnabled new value of opensslAnalyzerEnabled +567 */ +568publicvoid setOpensslAnalyzerEnabled(Boolean opensslAnalyzerEnabled) { +569this.opensslAnalyzerEnabled = opensslAnalyzerEnabled; +570 } +571/** +572 * Whether or not the Node.js Analyzer is enabled. +573 */ +574private Boolean nodeAnalyzerEnabled; +575 +576/** +577 * Get the value of nodeAnalyzerEnabled. +578 * +579 * @return the value of nodeAnalyzerEnabled +580 */ +581public Boolean isNodeAnalyzerEnabled() { +582return nodeAnalyzerEnabled; +583 } +584 +585/** +586 * Set the value of nodeAnalyzerEnabled. +587 * +588 * @param nodeAnalyzerEnabled new value of nodeAnalyzerEnabled +589 */ +590publicvoid setNodeAnalyzerEnabled(Boolean nodeAnalyzerEnabled) { +591this.nodeAnalyzerEnabled = nodeAnalyzerEnabled; +592 } +593/** +594 * Whether the ruby gemspec analyzer should be enabled. +595 */ +596private Boolean rubygemsAnalyzerEnabled; +597 +598/** +599 * Get the value of rubygemsAnalyzerEnabled. +600 * +601 * @return the value of rubygemsAnalyzerEnabled +602 */ +603public Boolean isRubygemsAnalyzerEnabled() { +604return rubygemsAnalyzerEnabled; +605 } +606 +607/** +608 * Set the value of rubygemsAnalyzerEnabled. +609 * +610 * @param rubygemsAnalyzerEnabled new value of rubygemsAnalyzerEnabled +611 */ +612publicvoid setRubygemsAnalyzerEnabled(Boolean rubygemsAnalyzerEnabled) { +613this.rubygemsAnalyzerEnabled = rubygemsAnalyzerEnabled; +614 } +615/** +616 * Whether the python package analyzer should be enabled. +617 */ +618private Boolean pyPackageAnalyzerEnabled; +619 +620/** +621 * Get the value of pyPackageAnalyzerEnabled. +622 * +623 * @return the value of pyPackageAnalyzerEnabled +624 */ +625public Boolean isPyPackageAnalyzerEnabled() { +626return pyPackageAnalyzerEnabled; +627 } +628 +629/** +630 * Set the value of pyPackageAnalyzerEnabled. +631 * +632 * @param pyPackageAnalyzerEnabled new value of pyPackageAnalyzerEnabled +633 */ +634publicvoid setPyPackageAnalyzerEnabled(Boolean pyPackageAnalyzerEnabled) { +635this.pyPackageAnalyzerEnabled = pyPackageAnalyzerEnabled; +636 } +637 +638/** +639 * Whether the python distribution analyzer should be enabled. +640 */ +641private Boolean pyDistributionAnalyzerEnabled; +642 +643/** +644 * Get the value of pyDistributionAnalyzerEnabled. +645 * +646 * @return the value of pyDistributionAnalyzerEnabled +647 */ +648public Boolean isPyDistributionAnalyzerEnabled() { +649return pyDistributionAnalyzerEnabled; +650 } +651 +652/** +653 * Set the value of pyDistributionAnalyzerEnabled. +654 * +655 * @param pyDistributionAnalyzerEnabled new value of +656 * pyDistributionAnalyzerEnabled +657 */ +658publicvoid setPyDistributionAnalyzerEnabled(Boolean pyDistributionAnalyzerEnabled) { +659this.pyDistributionAnalyzerEnabled = pyDistributionAnalyzerEnabled; +660 } +661 +662/** +663 * Whether or not the central analyzer is enabled. +664 */ +665private Boolean centralAnalyzerEnabled; +666 +667/** +668 * Get the value of centralAnalyzerEnabled. +669 * +670 * @return the value of centralAnalyzerEnabled +671 */ +672public Boolean isCentralAnalyzerEnabled() { +673return centralAnalyzerEnabled; +674 } +675 +676/** +677 * Set the value of centralAnalyzerEnabled. +678 * +679 * @param centralAnalyzerEnabled new value of centralAnalyzerEnabled +680 */ +681publicvoid setCentralAnalyzerEnabled(Boolean centralAnalyzerEnabled) { +682this.centralAnalyzerEnabled = centralAnalyzerEnabled; +683 } +684 +685/** +686 * Whether or not the nexus analyzer is enabled. +687 */ +688private Boolean nexusAnalyzerEnabled; +689 +690/** +691 * Get the value of nexusAnalyzerEnabled. +692 * +693 * @return the value of nexusAnalyzerEnabled +694 */ +695public Boolean isNexusAnalyzerEnabled() { +696return nexusAnalyzerEnabled; +697 } +698 +699/** +700 * Set the value of nexusAnalyzerEnabled. +701 * +702 * @param nexusAnalyzerEnabled new value of nexusAnalyzerEnabled +703 */ +704publicvoid setNexusAnalyzerEnabled(Boolean nexusAnalyzerEnabled) { +705this.nexusAnalyzerEnabled = nexusAnalyzerEnabled; +706 } +707 +708/** +709 * The URL of a Nexus server's REST API end point +710 * (http://domain/nexus/service/local). +711 */ +712private String nexusUrl; +713 +714/** +715 * Get the value of nexusUrl. +716 * +717 * @return the value of nexusUrl +718 */ +719public String getNexusUrl() { +720return nexusUrl; +721 } +722 +723/** +724 * Set the value of nexusUrl. +725 * +726 * @param nexusUrl new value of nexusUrl +727 */ +728publicvoid setNexusUrl(String nexusUrl) { +729this.nexusUrl = nexusUrl; +730 } +731/** +732 * Whether or not the defined proxy should be used when connecting to Nexus. +733 */ +734private Boolean nexusUsesProxy; +735 +736/** +737 * Get the value of nexusUsesProxy. +738 * +739 * @return the value of nexusUsesProxy +740 */ +741public Boolean isNexusUsesProxy() { +742return nexusUsesProxy; +743 } +744 +745/** +746 * Set the value of nexusUsesProxy. +747 * +748 * @param nexusUsesProxy new value of nexusUsesProxy +749 */ +750publicvoid setNexusUsesProxy(Boolean nexusUsesProxy) { +751this.nexusUsesProxy = nexusUsesProxy; +752 } +753 +754/** +755 * Additional ZIP File extensions to add analyze. This should be a +756 * comma-separated list of file extensions to treat like ZIP files. +757 */ +758private String zipExtensions; +759 +760/** +761 * Get the value of zipExtensions. +762 * +763 * @return the value of zipExtensions +764 */ +765public String getZipExtensions() { +766return zipExtensions; +767 } +768 +769/** +770 * Set the value of zipExtensions. +771 * +772 * @param zipExtensions new value of zipExtensions +773 */ +774publicvoid setZipExtensions(String zipExtensions) { +775this.zipExtensions = zipExtensions; +776 } +777 +778/** +779 * The path to Mono for .NET assembly analysis on non-windows systems. +780 */ +781private String pathToMono; +782 +783/** +784 * Get the value of pathToMono. +785 * +786 * @return the value of pathToMono +787 */ +788public String getPathToMono() { +789return pathToMono; +790 } +791 +792/** +793 * Set the value of pathToMono. +794 * +795 * @param pathToMono new value of pathToMono +796 */ +797publicvoid setPathToMono(String pathToMono) { +798this.pathToMono = pathToMono; +799 } +800 +801 @Override +802publicvoid execute() throws BuildException { +803 dealWithReferences(); +804 validateConfiguration(); +805 populateSettings(); +806 Engine engine = null; +807try { +808 engine = new Engine(Check.class.getClassLoader()); +809if (isUpdateOnly()) { +810 log("Deprecated 'UpdateOnly' property set; please use the UpdateTask instead", Project.MSG_WARN); 811try { -812for (Resource resource : path) { -813final FileProvider provider = resource.as(FileProvider.class); -814if (provider != null) { -815final File file = provider.getFile(); -816if (file != null && file.exists()) { -817 engine.scan(file); -818 } -819 } -820 } -821 -822 engine.analyzeDependencies(); -823 DatabaseProperties prop = null; -824 CveDB cve = null; -825try { -826 cve = new CveDB(); -827 cve.open(); -828 prop = cve.getDatabaseProperties(); -829 } catch (DatabaseException ex) { -830 log("Unable to retrieve DB Properties", ex, Project.MSG_DEBUG); -831 } finally { -832if (cve != null) { -833 cve.close(); -834 } +812 engine.doUpdates(); +813 } catch (UpdateException ex) { +814if (this.isFailOnError()) { +815thrownew BuildException(ex); +816 } +817 log(ex.getMessage(), Project.MSG_ERR); +818 } +819 } else { +820for (Resource resource : path) { +821final FileProvider provider = resource.as(FileProvider.class); +822if (provider != null) { +823final File file = provider.getFile(); +824if (file != null && file.exists()) { +825 engine.scan(file); +826 } +827 } +828 } +829 +830try { +831 engine.analyzeDependencies(); +832 } catch (ExceptionCollection ex) { +833if (this.isFailOnError()) { +834thrownew BuildException(ex); 835 } -836final ReportGenerator reporter = new ReportGenerator(getProjectName(), engine.getDependencies(), engine.getAnalyzers(), prop); -837 reporter.generateReports(reportOutputDirectory, reportFormat); -838 -839if (this.failBuildOnCVSS <= 10) { -840 checkForFailure(engine.getDependencies()); -841 } -842if (this.showSummary) { -843 showSummary(engine.getDependencies()); -844 } -845 } catch (IOException ex) { -846 log("Unable to generate dependency-check report", ex, Project.MSG_DEBUG); -847thrownew BuildException("Unable to generate dependency-check report", ex); -848 } catch (Exception ex) { -849 log("An exception occurred; unable to continue task", ex, Project.MSG_DEBUG); -850thrownew BuildException("An exception occurred; unable to continue task", ex); -851 } -852 } -853 } catch (DatabaseException ex) { -854 log("Unable to connect to the dependency-check database; analysis has stopped", ex, Project.MSG_ERR); -855 } finally { -856 Settings.cleanup(true); -857if (engine != null) { -858 engine.cleanup(); +836 } +837 DatabaseProperties prop = null; +838 CveDB cve = null; +839try { +840 cve = new CveDB(); +841 cve.open(); +842 prop = cve.getDatabaseProperties(); +843 } catch (DatabaseException ex) { +844 log("Unable to retrieve DB Properties", ex, Project.MSG_DEBUG); +845 } finally { +846if (cve != null) { +847 cve.close(); +848 } +849 } +850final ReportGenerator reporter = new ReportGenerator(getProjectName(), engine.getDependencies(), engine.getAnalyzers(), prop); +851 reporter.generateReports(reportOutputDirectory, reportFormat); +852 +853if (this.failBuildOnCVSS <= 10) { +854 checkForFailure(engine.getDependencies()); +855 } +856if (this.showSummary) { +857 showSummary(engine.getDependencies()); +858 } 859 } -860 } -861 } -862 -863/** -864 * Validate the configuration to ensure the parameters have been properly -865 * configured/initialized. -866 * -867 * @throws BuildException if the task was not configured correctly. -868 */ -869privatevoid validateConfiguration() throws BuildException { -870if (path == null) { -871thrownew BuildException("No project dependencies have been defined to analyze."); -872 } -873if (failBuildOnCVSS < 0 || failBuildOnCVSS > 11) { -874thrownew BuildException("Invalid configuration, failBuildOnCVSS must be between 0 and 11."); -875 } -876 } -877 -878/** -879 * Takes the properties supplied and updates the dependency-check settings. -880 * Additionally, this sets the system properties required to change the -881 * proxy server, port, and connection timeout. -882 * -883 * @throws BuildException thrown when an invalid setting is configured. -884 */ -885 @Override -886protectedvoid populateSettings() throws BuildException { -887super.populateSettings(); -888 Settings.setBooleanIfNotNull(Settings.KEYS.AUTO_UPDATE, autoUpdate); -889 Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile); -890 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, enableExperimental); -891 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_JAR_ENABLED, jarAnalyzerEnabled); -892 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, pyDistributionAnalyzerEnabled); -893 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, pyPackageAnalyzerEnabled); -894 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED, rubygemsAnalyzerEnabled); -895 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, opensslAnalyzerEnabled); -896 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CMAKE_ENABLED, cmakeAnalyzerEnabled); -897 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_AUTOCONF_ENABLED, autoconfAnalyzerEnabled); -898 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED, composerAnalyzerEnabled); -899 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED, nodeAnalyzerEnabled); -900 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, nuspecAnalyzerEnabled); -901 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, centralAnalyzerEnabled); -902 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled); -903 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, archiveAnalyzerEnabled); -904 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, assemblyAnalyzerEnabled); -905 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl); -906 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy); -907 Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions); -908 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono); -909 } -910 -911/** -912 * Checks to see if a vulnerability has been identified with a CVSS score -913 * that is above the threshold set in the configuration. -914 * -915 * @param dependencies the list of dependency objects -916 * @throws BuildException thrown if a CVSS score is found that is higher -917 * then the threshold set -918 */ -919privatevoid checkForFailure(List<Dependency> dependencies) throws BuildException { -920final StringBuilder ids = new StringBuilder(); -921for (Dependency d : dependencies) { -922for (Vulnerability v : d.getVulnerabilities()) { -923if (v.getCvssScore() >= failBuildOnCVSS) { -924if (ids.length() == 0) { -925 ids.append(v.getName()); -926 } else { -927 ids.append(", ").append(v.getName()); -928 } -929 } -930 } -931 } -932if (ids.length() > 0) { -933final String msg = String.format("%n%nDependency-Check Failure:%n" -934 + "One or more dependencies were identified with vulnerabilities that have a CVSS score greater then '%.1f': %s%n" -935 + "See the dependency-check report for more details.%n%n", failBuildOnCVSS, ids.toString()); -936thrownew BuildException(msg); -937 } -938 } -939 -940/** -941 * Generates a warning message listing a summary of dependencies and their -942 * associated CPE and CVE entries. -943 * -944 * @param dependencies a list of dependency objects -945 */ -946privatevoid showSummary(List<Dependency> dependencies) { -947final StringBuilder summary = new StringBuilder(); -948for (Dependency d : dependencies) { -949boolean firstEntry = true; -950final StringBuilder ids = new StringBuilder(); -951for (Vulnerability v : d.getVulnerabilities()) { -952if (firstEntry) { -953 firstEntry = false; -954 } else { -955 ids.append(", "); -956 } -957 ids.append(v.getName()); -958 } -959if (ids.length() > 0) { -960 summary.append(d.getFileName()).append(" ("); -961 firstEntry = true; -962for (Identifier id : d.getIdentifiers()) { -963if (firstEntry) { -964 firstEntry = false; -965 } else { -966 summary.append(", "); -967 } -968 summary.append(id.getValue()); -969 } -970 summary.append(") : ").append(ids).append(NEW_LINE); -971 } -972 } -973if (summary.length() > 0) { -974final String msg = String.format("%n%n" -975 + "One or more dependencies were identified with known vulnerabilities:%n%n%s" -976 + "%n%nSee the dependency-check report for more details.%n%n", summary.toString()); -977 log(msg, Project.MSG_WARN); -978 } -979 } -980 -981/** -982 * An enumeration of supported report formats: "ALL", "HTML", "XML", "VULN", -983 * etc.. -984 */ -985publicstaticclassReportFormatsextends EnumeratedAttribute { -986 -987/** -988 * Returns the list of values for the report format. -989 * -990 * @return the list of values for the report format -991 */ -992 @Override -993public String[] getValues() { -994int i = 0; -995final Format[] formats = Format.values(); -996final String[] values = new String[formats.length]; -997for (Format format : formats) { -998 values[i++] = format.name(); -999 } -1000return values; -1001 } -1002 } -1003 } +860 } catch (DatabaseException ex) { +861final String msg = "Unable to connect to the dependency-check database; analysis has stopped"; +862if (this.isFailOnError()) { +863thrownew BuildException(msg, ex); +864 } +865 log(msg, ex, Project.MSG_ERR); +866 } catch (ReportException ex) { +867final String msg = "Unable to generate the dependency-check report"; +868if (this.isFailOnError()) { +869thrownew BuildException(msg, ex); +870 } +871 log(msg, ex, Project.MSG_ERR); +872 } finally { +873 Settings.cleanup(true); +874if (engine != null) { +875 engine.cleanup(); +876 } +877 } +878 } +879 +880/** +881 * Validate the configuration to ensure the parameters have been properly +882 * configured/initialized. +883 * +884 * @throws BuildException if the task was not configured correctly. +885 */ +886privatevoid validateConfiguration() throws BuildException { +887if (path == null) { +888thrownew BuildException("No project dependencies have been defined to analyze."); +889 } +890if (failBuildOnCVSS < 0 || failBuildOnCVSS > 11) { +891thrownew BuildException("Invalid configuration, failBuildOnCVSS must be between 0 and 11."); +892 } +893 } +894 +895/** +896 * Takes the properties supplied and updates the dependency-check settings. +897 * Additionally, this sets the system properties required to change the +898 * proxy server, port, and connection timeout. +899 * +900 * @throws BuildException thrown when an invalid setting is configured. +901 */ +902 @Override +903protectedvoid populateSettings() throws BuildException { +904super.populateSettings(); +905 Settings.setBooleanIfNotNull(Settings.KEYS.AUTO_UPDATE, autoUpdate); +906 Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile); +907 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, enableExperimental); +908 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_JAR_ENABLED, jarAnalyzerEnabled); +909 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, pyDistributionAnalyzerEnabled); +910 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, pyPackageAnalyzerEnabled); +911 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED, rubygemsAnalyzerEnabled); +912 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, opensslAnalyzerEnabled); +913 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CMAKE_ENABLED, cmakeAnalyzerEnabled); +914 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_AUTOCONF_ENABLED, autoconfAnalyzerEnabled); +915 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED, composerAnalyzerEnabled); +916 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED, nodeAnalyzerEnabled); +917 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, nuspecAnalyzerEnabled); +918 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, centralAnalyzerEnabled); +919 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled); +920 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, archiveAnalyzerEnabled); +921 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, assemblyAnalyzerEnabled); +922 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl); +923 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy); +924 Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions); +925 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono); +926 } +927 +928/** +929 * Checks to see if a vulnerability has been identified with a CVSS score +930 * that is above the threshold set in the configuration. +931 * +932 * @param dependencies the list of dependency objects +933 * @throws BuildException thrown if a CVSS score is found that is higher +934 * then the threshold set +935 */ +936privatevoid checkForFailure(List<Dependency> dependencies) throws BuildException { +937final StringBuilder ids = new StringBuilder(); +938for (Dependency d : dependencies) { +939for (Vulnerability v : d.getVulnerabilities()) { +940if (v.getCvssScore() >= failBuildOnCVSS) { +941if (ids.length() == 0) { +942 ids.append(v.getName()); +943 } else { +944 ids.append(", ").append(v.getName()); +945 } +946 } +947 } +948 } +949if (ids.length() > 0) { +950final String msg = String.format("%n%nDependency-Check Failure:%n" +951 + "One or more dependencies were identified with vulnerabilities that have a CVSS score greater then '%.1f': %s%n" +952 + "See the dependency-check report for more details.%n%n", failBuildOnCVSS, ids.toString()); +953thrownew BuildException(msg); +954 } +955 } +956 +957/** +958 * Generates a warning message listing a summary of dependencies and their +959 * associated CPE and CVE entries. +960 * +961 * @param dependencies a list of dependency objects +962 */ +963privatevoid showSummary(List<Dependency> dependencies) { +964final StringBuilder summary = new StringBuilder(); +965for (Dependency d : dependencies) { +966boolean firstEntry = true; +967final StringBuilder ids = new StringBuilder(); +968for (Vulnerability v : d.getVulnerabilities()) { +969if (firstEntry) { +970 firstEntry = false; +971 } else { +972 ids.append(", "); +973 } +974 ids.append(v.getName()); +975 } +976if (ids.length() > 0) { +977 summary.append(d.getFileName()).append(" ("); +978 firstEntry = true; +979for (Identifier id : d.getIdentifiers()) { +980if (firstEntry) { +981 firstEntry = false; +982 } else { +983 summary.append(", "); +984 } +985 summary.append(id.getValue()); +986 } +987 summary.append(") : ").append(ids).append(NEW_LINE); +988 } +989 } +990if (summary.length() > 0) { +991final String msg = String.format("%n%n" +992 + "One or more dependencies were identified with known vulnerabilities:%n%n%s" +993 + "%n%nSee the dependency-check report for more details.%n%n", summary.toString()); +994 log(msg, Project.MSG_WARN); +995 } +996 } +997 +998/** +999 * An enumeration of supported report formats: "ALL", "HTML", "XML", "VULN", +1000 * etc.. +1001 */ +1002publicstaticclassReportFormatsextends EnumeratedAttribute { +1003 +1004/** +1005 * Returns the list of values for the report format. +1006 * +1007 * @return the list of values for the report format +1008 */ +1009 @Override +1010public String[] getValues() { +1011int i = 0; +1012final Format[] formats = Format.values(); +1013final String[] values = new String[formats.length]; +1014for (Format format : formats) { +1015 values[i++] = format.name(); +1016 } +1017return values; +1018 } +1019 } +1020 }
      diff --git a/dependency-check-ant/xref/org/owasp/dependencycheck/taskdefs/Purge.html b/dependency-check-ant/xref/org/owasp/dependencycheck/taskdefs/Purge.html index 35abcc910..967c6577a 100644 --- a/dependency-check-ant/xref/org/owasp/dependencycheck/taskdefs/Purge.html +++ b/dependency-check-ant/xref/org/owasp/dependencycheck/taskdefs/Purge.html @@ -79,60 +79,103 @@ 71this.dataDirectory = dataDirectory; 72 } 73 -74 @Override -75publicvoid execute() throws BuildException { -76 populateSettings(); -77 File db; -78try { -79 db = new File(Settings.getDataDirectory(), "dc.h2.db"); -80if (db.exists()) { -81if (db.delete()) { -82 log("Database file purged; local copy of the NVD has been removed", Project.MSG_INFO); -83 } else { -84 log(String.format("Unable to delete '%s'; please delete the file manually", db.getAbsolutePath()), Project.MSG_ERR); -85 } -86 } else { -87 log(String.format("Unable to purge database; the database file does not exists: %s", db.getAbsolutePath()), Project.MSG_ERR); -88 } -89 } catch (IOException ex) { -90 log("Unable to delete the database", Project.MSG_ERR); -91 } finally { -92 Settings.cleanup(true); -93 } -94 } -95 -96/** -97 * Takes the properties supplied and updates the dependency-check settings. Additionally, this sets the system properties -98 * required to change the proxy server, port, and connection timeout. -99 */ -100protectedvoid populateSettings() { -101 Settings.initialize(); -102 InputStream taskProperties = null; -103try { -104 taskProperties = this.getClass().getClassLoader().getResourceAsStream(PROPERTIES_FILE); -105 Settings.mergeProperties(taskProperties); -106 } catch (IOException ex) { -107 log("Unable to load the dependency-check ant task.properties file.", ex, Project.MSG_WARN); -108 } finally { -109if (taskProperties != null) { -110try { -111 taskProperties.close(); -112 } catch (IOException ex) { -113 log("", ex, Project.MSG_DEBUG); -114 } -115 } -116 } -117if (dataDirectory != null) { -118 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory); -119 } else { -120final File jarPath = new File(Purge.class.getProtectionDomain().getCodeSource().getLocation().getPath()); -121final File base = jarPath.getParentFile(); -122final String sub = Settings.getString(Settings.KEYS.DATA_DIRECTORY); -123final File dataDir = new File(base, sub); -124 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath()); -125 } -126 } -127 } +74/** +75 * Indicates if dependency-check should fail the build if an exception +76 * occurs. +77 */ +78privateboolean failOnError = true; +79 +80/** +81 * Get the value of failOnError. +82 * +83 * @return the value of failOnError +84 */ +85publicboolean isFailOnError() { +86return failOnError; +87 } +88 +89/** +90 * Set the value of failOnError. +91 * +92 * @param failOnError new value of failOnError +93 */ +94publicvoid setFailOnError(boolean failOnError) { +95this.failOnError = failOnError; +96 } +97 +98 @Override +99publicvoid execute() throws BuildException { +100 populateSettings(); +101 File db; +102try { +103 db = new File(Settings.getDataDirectory(), "dc.h2.db"); +104if (db.exists()) { +105if (db.delete()) { +106 log("Database file purged; local copy of the NVD has been removed", Project.MSG_INFO); +107 } else { +108final String msg = String.format("Unable to delete '%s'; please delete the file manually", db.getAbsolutePath()); +109if (this.failOnError) { +110thrownew BuildException(msg); +111 } +112 log(msg, Project.MSG_ERR); +113 } +114 } else { +115final String msg = String.format("Unable to purge database; the database file does not exists: %s", db.getAbsolutePath()); +116if (this.failOnError) { +117thrownew BuildException(msg); +118 } +119 log(msg, Project.MSG_ERR); +120 } +121 } catch (IOException ex) { +122final String msg = "Unable to delete the database"; +123if (this.failOnError) { +124thrownew BuildException(msg); +125 } +126 log(msg, Project.MSG_ERR); +127 } finally { +128 Settings.cleanup(true); +129 } +130 } +131 +132/** +133 * Takes the properties supplied and updates the dependency-check settings. +134 * Additionally, this sets the system properties required to change the +135 * proxy server, port, and connection timeout. +136 * +137 * @throws BuildException thrown if the properties file cannot be read. +138 */ +139protectedvoid populateSettings() throws BuildException { +140 Settings.initialize(); +141 InputStream taskProperties = null; +142try { +143 taskProperties = this.getClass().getClassLoader().getResourceAsStream(PROPERTIES_FILE); +144 Settings.mergeProperties(taskProperties); +145 } catch (IOException ex) { +146final String msg = "Unable to load the dependency-check ant task.properties file."; +147if (this.failOnError) { +148thrownew BuildException(msg, ex); +149 } +150 log(msg, ex, Project.MSG_WARN); +151 } finally { +152if (taskProperties != null) { +153try { +154 taskProperties.close(); +155 } catch (IOException ex) { +156 log("", ex, Project.MSG_DEBUG); +157 } +158 } +159 } +160if (dataDirectory != null) { +161 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory); +162 } else { +163final File jarPath = new File(Purge.class.getProtectionDomain().getCodeSource().getLocation().getPath()); +164final File base = jarPath.getParentFile(); +165final String sub = Settings.getString(Settings.KEYS.DATA_DIRECTORY); +166final File dataDir = new File(base, sub); +167 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath()); +168 } +169 } +170 }
      diff --git a/dependency-check-ant/xref/org/owasp/dependencycheck/taskdefs/Update.html b/dependency-check-ant/xref/org/owasp/dependencycheck/taskdefs/Update.html index ebe54bd74..1f0d074cb 100644 --- a/dependency-check-ant/xref/org/owasp/dependencycheck/taskdefs/Update.html +++ b/dependency-check-ant/xref/org/owasp/dependencycheck/taskdefs/Update.html @@ -26,423 +26,439 @@ 18package org.owasp.dependencycheck.taskdefs; 1920import org.apache.tools.ant.BuildException; -21import org.owasp.dependencycheck.Engine; -22import org.owasp.dependencycheck.data.nvdcve.DatabaseException; -23import org.owasp.dependencycheck.utils.Settings; -24import org.slf4j.impl.StaticLoggerBinder; -25 -26/** -27 * An Ant task definition to execute dependency-check update. This will download the latest data from the National Vulnerability -28 * Database (NVD) and store a copy in the local database. -29 * -30 * @author Jeremy Long -31 */ -32publicclassUpdateextendsPurge { -33 -34/** -35 * Construct a new UpdateTask. -36 */ -37publicUpdate() { -38super(); -39// Call this before Dependency Check Core starts logging anything - this way, all SLF4J messages from -40// core end up coming through this tasks logger -41 StaticLoggerBinder.getSingleton().setTask(this); -42 } -43 -44/** -45 * The Proxy Server. -46 */ -47private String proxyServer; -48 -49/** -50 * Get the value of proxyServer. -51 * -52 * @return the value of proxyServer -53 */ -54public String getProxyServer() { -55return proxyServer; -56 } -57 -58/** -59 * Set the value of proxyServer. -60 * -61 * @param server new value of proxyServer -62 */ -63publicvoid setProxyServer(String server) { -64this.proxyServer = server; -65 } -66 -67/** -68 * The Proxy Port. -69 */ -70private String proxyPort; -71 -72/** -73 * Get the value of proxyPort. -74 * -75 * @return the value of proxyPort -76 */ -77public String getProxyPort() { -78return proxyPort; -79 } -80 -81/** -82 * Set the value of proxyPort. -83 * -84 * @param proxyPort new value of proxyPort -85 */ -86publicvoid setProxyPort(String proxyPort) { -87this.proxyPort = proxyPort; -88 } -89/** -90 * The Proxy username. -91 */ -92private String proxyUsername; -93 -94/** -95 * Get the value of proxyUsername. -96 * -97 * @return the value of proxyUsername -98 */ -99public String getProxyUsername() { -100return proxyUsername; -101 } -102 -103/** -104 * Set the value of proxyUsername. -105 * -106 * @param proxyUsername new value of proxyUsername -107 */ -108publicvoid setProxyUsername(String proxyUsername) { -109this.proxyUsername = proxyUsername; -110 } -111/** -112 * The Proxy password. -113 */ -114private String proxyPassword; -115 -116/** -117 * Get the value of proxyPassword. -118 * -119 * @return the value of proxyPassword -120 */ -121public String getProxyPassword() { -122return proxyPassword; -123 } -124 -125/** -126 * Set the value of proxyPassword. -127 * -128 * @param proxyPassword new value of proxyPassword -129 */ -130publicvoid setProxyPassword(String proxyPassword) { -131this.proxyPassword = proxyPassword; -132 } -133/** -134 * The Connection Timeout. -135 */ -136private String connectionTimeout; -137 -138/** -139 * Get the value of connectionTimeout. -140 * -141 * @return the value of connectionTimeout -142 */ -143public String getConnectionTimeout() { -144return connectionTimeout; -145 } -146 -147/** -148 * Set the value of connectionTimeout. -149 * -150 * @param connectionTimeout new value of connectionTimeout -151 */ -152publicvoid setConnectionTimeout(String connectionTimeout) { -153this.connectionTimeout = connectionTimeout; -154 } -155/** -156 * The database driver name; such as org.h2.Driver. -157 */ -158private String databaseDriverName; -159 -160/** -161 * Get the value of databaseDriverName. -162 * -163 * @return the value of databaseDriverName -164 */ -165public String getDatabaseDriverName() { -166return databaseDriverName; -167 } -168 -169/** -170 * Set the value of databaseDriverName. -171 * -172 * @param databaseDriverName new value of databaseDriverName -173 */ -174publicvoid setDatabaseDriverName(String databaseDriverName) { -175this.databaseDriverName = databaseDriverName; -176 } -177 -178/** -179 * The path to the database driver JAR file if it is not on the class path. -180 */ -181private String databaseDriverPath; -182 -183/** -184 * Get the value of databaseDriverPath. -185 * -186 * @return the value of databaseDriverPath -187 */ -188public String getDatabaseDriverPath() { -189return databaseDriverPath; -190 } -191 -192/** -193 * Set the value of databaseDriverPath. -194 * -195 * @param databaseDriverPath new value of databaseDriverPath -196 */ -197publicvoid setDatabaseDriverPath(String databaseDriverPath) { -198this.databaseDriverPath = databaseDriverPath; -199 } -200/** -201 * The database connection string. -202 */ -203private String connectionString; -204 -205/** -206 * Get the value of connectionString. -207 * -208 * @return the value of connectionString -209 */ -210public String getConnectionString() { -211return connectionString; -212 } -213 -214/** -215 * Set the value of connectionString. -216 * -217 * @param connectionString new value of connectionString -218 */ -219publicvoid setConnectionString(String connectionString) { -220this.connectionString = connectionString; -221 } -222/** -223 * The user name for connecting to the database. -224 */ -225private String databaseUser; -226 -227/** -228 * Get the value of databaseUser. -229 * -230 * @return the value of databaseUser -231 */ -232public String getDatabaseUser() { -233return databaseUser; -234 } -235 -236/** -237 * Set the value of databaseUser. -238 * -239 * @param databaseUser new value of databaseUser -240 */ -241publicvoid setDatabaseUser(String databaseUser) { -242this.databaseUser = databaseUser; -243 } -244 -245/** -246 * The password to use when connecting to the database. -247 */ -248private String databasePassword; -249 -250/** -251 * Get the value of databasePassword. -252 * -253 * @return the value of databasePassword -254 */ -255public String getDatabasePassword() { -256return databasePassword; -257 } -258 -259/** -260 * Set the value of databasePassword. -261 * -262 * @param databasePassword new value of databasePassword -263 */ -264publicvoid setDatabasePassword(String databasePassword) { -265this.databasePassword = databasePassword; -266 } -267 -268/** -269 * The url for the modified NVD CVE (1.2 schema). -270 */ -271private String cveUrl12Modified; -272 -273/** -274 * Get the value of cveUrl12Modified. -275 * -276 * @return the value of cveUrl12Modified -277 */ -278public String getCveUrl12Modified() { -279return cveUrl12Modified; -280 } -281 -282/** -283 * Set the value of cveUrl12Modified. -284 * -285 * @param cveUrl12Modified new value of cveUrl12Modified -286 */ -287publicvoid setCveUrl12Modified(String cveUrl12Modified) { -288this.cveUrl12Modified = cveUrl12Modified; -289 } -290 -291/** -292 * The url for the modified NVD CVE (2.0 schema). -293 */ -294private String cveUrl20Modified; -295 -296/** -297 * Get the value of cveUrl20Modified. -298 * -299 * @return the value of cveUrl20Modified -300 */ -301public String getCveUrl20Modified() { -302return cveUrl20Modified; -303 } -304 -305/** -306 * Set the value of cveUrl20Modified. -307 * -308 * @param cveUrl20Modified new value of cveUrl20Modified -309 */ -310publicvoid setCveUrl20Modified(String cveUrl20Modified) { -311this.cveUrl20Modified = cveUrl20Modified; -312 } -313 -314/** -315 * Base Data Mirror URL for CVE 1.2. -316 */ -317private String cveUrl12Base; -318 -319/** -320 * Get the value of cveUrl12Base. -321 * -322 * @return the value of cveUrl12Base -323 */ -324public String getCveUrl12Base() { -325return cveUrl12Base; -326 } -327 -328/** -329 * Set the value of cveUrl12Base. -330 * -331 * @param cveUrl12Base new value of cveUrl12Base -332 */ -333publicvoid setCveUrl12Base(String cveUrl12Base) { -334this.cveUrl12Base = cveUrl12Base; -335 } -336 -337/** -338 * Data Mirror URL for CVE 2.0. -339 */ -340private String cveUrl20Base; -341 -342/** -343 * Get the value of cveUrl20Base. -344 * -345 * @return the value of cveUrl20Base -346 */ -347public String getCveUrl20Base() { -348return cveUrl20Base; -349 } -350 -351/** -352 * Set the value of cveUrl20Base. -353 * -354 * @param cveUrl20Base new value of cveUrl20Base -355 */ -356publicvoid setCveUrl20Base(String cveUrl20Base) { -357this.cveUrl20Base = cveUrl20Base; -358 } -359 -360/** -361 * The number of hours to wait before re-checking for updates. -362 */ -363private Integer cveValidForHours; -364 -365/** -366 * Get the value of cveValidForHours. -367 * -368 * @return the value of cveValidForHours -369 */ -370public Integer getCveValidForHours() { -371return cveValidForHours; -372 } -373 -374/** -375 * Set the value of cveValidForHours. -376 * -377 * @param cveValidForHours new value of cveValidForHours -378 */ -379publicvoid setCveValidForHours(Integer cveValidForHours) { -380this.cveValidForHours = cveValidForHours; -381 } -382 -383/** -384 * Executes the update by initializing the settings, downloads the NVD XML data, and then processes the data storing it in the -385 * local database. -386 * -387 * @throws BuildException thrown if a connection to the local database cannot be made. -388 */ -389 @Override -390publicvoid execute() throws BuildException { -391 populateSettings(); -392 Engine engine = null; -393try { -394 engine = new Engine(Update.class.getClassLoader()); -395 engine.doUpdates(); -396 } catch (DatabaseException ex) { -397thrownew BuildException("Unable to connect to the dependency-check database; unable to update the NVD data", ex); -398 } finally { -399 Settings.cleanup(true); -400if (engine != null) { -401 engine.cleanup(); -402 } -403 } -404 } -405 -406/** -407 * Takes the properties supplied and updates the dependency-check settings. Additionally, this sets the system properties -408 * required to change the proxy server, port, and connection timeout. -409 * -410 * @throws BuildException thrown when an invalid setting is configured. -411 */ -412 @Override -413protectedvoid populateSettings() throws BuildException { -414super.populateSettings(); -415 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_SERVER, proxyServer); -416 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PORT, proxyPort); -417 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_USERNAME, proxyUsername); -418 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PASSWORD, proxyPassword); -419 Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout); -420 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName); -421 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath); -422 Settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString); -423 Settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser); -424 Settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword); -425 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_12_URL, cveUrl12Modified); -426 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_20_URL, cveUrl20Modified); -427 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_1_2, cveUrl12Base); -428 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_2_0, cveUrl20Base); -429if (cveValidForHours != null) { -430if (cveValidForHours >= 0) { -431 Settings.setInt(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, cveValidForHours); -432 } else { -433thrownew BuildException("Invalid setting: `cpeValidForHours` must be 0 or greater"); -434 } -435 } -436 } -437 } +21import org.apache.tools.ant.Project; +22import org.owasp.dependencycheck.Engine; +23import org.owasp.dependencycheck.data.nvdcve.DatabaseException; +24import org.owasp.dependencycheck.data.update.exception.UpdateException; +25import org.owasp.dependencycheck.utils.Settings; +26import org.slf4j.impl.StaticLoggerBinder; +27 +28/** +29 * An Ant task definition to execute dependency-check update. This will download +30 * the latest data from the National Vulnerability Database (NVD) and store a +31 * copy in the local database. +32 * +33 * @author Jeremy Long +34 */ +35publicclassUpdateextendsPurge { +36 +37/** +38 * Construct a new UpdateTask. +39 */ +40publicUpdate() { +41super(); +42// Call this before Dependency Check Core starts logging anything - this way, all SLF4J messages from +43// core end up coming through this tasks logger +44 StaticLoggerBinder.getSingleton().setTask(this); +45 } +46 +47/** +48 * The Proxy Server. +49 */ +50private String proxyServer; +51 +52/** +53 * Get the value of proxyServer. +54 * +55 * @return the value of proxyServer +56 */ +57public String getProxyServer() { +58return proxyServer; +59 } +60 +61/** +62 * Set the value of proxyServer. +63 * +64 * @param server new value of proxyServer +65 */ +66publicvoid setProxyServer(String server) { +67this.proxyServer = server; +68 } +69 +70/** +71 * The Proxy Port. +72 */ +73private String proxyPort; +74 +75/** +76 * Get the value of proxyPort. +77 * +78 * @return the value of proxyPort +79 */ +80public String getProxyPort() { +81return proxyPort; +82 } +83 +84/** +85 * Set the value of proxyPort. +86 * +87 * @param proxyPort new value of proxyPort +88 */ +89publicvoid setProxyPort(String proxyPort) { +90this.proxyPort = proxyPort; +91 } +92/** +93 * The Proxy username. +94 */ +95private String proxyUsername; +96 +97/** +98 * Get the value of proxyUsername. +99 * +100 * @return the value of proxyUsername +101 */ +102public String getProxyUsername() { +103return proxyUsername; +104 } +105 +106/** +107 * Set the value of proxyUsername. +108 * +109 * @param proxyUsername new value of proxyUsername +110 */ +111publicvoid setProxyUsername(String proxyUsername) { +112this.proxyUsername = proxyUsername; +113 } +114/** +115 * The Proxy password. +116 */ +117private String proxyPassword; +118 +119/** +120 * Get the value of proxyPassword. +121 * +122 * @return the value of proxyPassword +123 */ +124public String getProxyPassword() { +125return proxyPassword; +126 } +127 +128/** +129 * Set the value of proxyPassword. +130 * +131 * @param proxyPassword new value of proxyPassword +132 */ +133publicvoid setProxyPassword(String proxyPassword) { +134this.proxyPassword = proxyPassword; +135 } +136/** +137 * The Connection Timeout. +138 */ +139private String connectionTimeout; +140 +141/** +142 * Get the value of connectionTimeout. +143 * +144 * @return the value of connectionTimeout +145 */ +146public String getConnectionTimeout() { +147return connectionTimeout; +148 } +149 +150/** +151 * Set the value of connectionTimeout. +152 * +153 * @param connectionTimeout new value of connectionTimeout +154 */ +155publicvoid setConnectionTimeout(String connectionTimeout) { +156this.connectionTimeout = connectionTimeout; +157 } +158/** +159 * The database driver name; such as org.h2.Driver. +160 */ +161private String databaseDriverName; +162 +163/** +164 * Get the value of databaseDriverName. +165 * +166 * @return the value of databaseDriverName +167 */ +168public String getDatabaseDriverName() { +169return databaseDriverName; +170 } +171 +172/** +173 * Set the value of databaseDriverName. +174 * +175 * @param databaseDriverName new value of databaseDriverName +176 */ +177publicvoid setDatabaseDriverName(String databaseDriverName) { +178this.databaseDriverName = databaseDriverName; +179 } +180 +181/** +182 * The path to the database driver JAR file if it is not on the class path. +183 */ +184private String databaseDriverPath; +185 +186/** +187 * Get the value of databaseDriverPath. +188 * +189 * @return the value of databaseDriverPath +190 */ +191public String getDatabaseDriverPath() { +192return databaseDriverPath; +193 } +194 +195/** +196 * Set the value of databaseDriverPath. +197 * +198 * @param databaseDriverPath new value of databaseDriverPath +199 */ +200publicvoid setDatabaseDriverPath(String databaseDriverPath) { +201this.databaseDriverPath = databaseDriverPath; +202 } +203/** +204 * The database connection string. +205 */ +206private String connectionString; +207 +208/** +209 * Get the value of connectionString. +210 * +211 * @return the value of connectionString +212 */ +213public String getConnectionString() { +214return connectionString; +215 } +216 +217/** +218 * Set the value of connectionString. +219 * +220 * @param connectionString new value of connectionString +221 */ +222publicvoid setConnectionString(String connectionString) { +223this.connectionString = connectionString; +224 } +225/** +226 * The user name for connecting to the database. +227 */ +228private String databaseUser; +229 +230/** +231 * Get the value of databaseUser. +232 * +233 * @return the value of databaseUser +234 */ +235public String getDatabaseUser() { +236return databaseUser; +237 } +238 +239/** +240 * Set the value of databaseUser. +241 * +242 * @param databaseUser new value of databaseUser +243 */ +244publicvoid setDatabaseUser(String databaseUser) { +245this.databaseUser = databaseUser; +246 } +247 +248/** +249 * The password to use when connecting to the database. +250 */ +251private String databasePassword; +252 +253/** +254 * Get the value of databasePassword. +255 * +256 * @return the value of databasePassword +257 */ +258public String getDatabasePassword() { +259return databasePassword; +260 } +261 +262/** +263 * Set the value of databasePassword. +264 * +265 * @param databasePassword new value of databasePassword +266 */ +267publicvoid setDatabasePassword(String databasePassword) { +268this.databasePassword = databasePassword; +269 } +270 +271/** +272 * The url for the modified NVD CVE (1.2 schema). +273 */ +274private String cveUrl12Modified; +275 +276/** +277 * Get the value of cveUrl12Modified. +278 * +279 * @return the value of cveUrl12Modified +280 */ +281public String getCveUrl12Modified() { +282return cveUrl12Modified; +283 } +284 +285/** +286 * Set the value of cveUrl12Modified. +287 * +288 * @param cveUrl12Modified new value of cveUrl12Modified +289 */ +290publicvoid setCveUrl12Modified(String cveUrl12Modified) { +291this.cveUrl12Modified = cveUrl12Modified; +292 } +293 +294/** +295 * The url for the modified NVD CVE (2.0 schema). +296 */ +297private String cveUrl20Modified; +298 +299/** +300 * Get the value of cveUrl20Modified. +301 * +302 * @return the value of cveUrl20Modified +303 */ +304public String getCveUrl20Modified() { +305return cveUrl20Modified; +306 } +307 +308/** +309 * Set the value of cveUrl20Modified. +310 * +311 * @param cveUrl20Modified new value of cveUrl20Modified +312 */ +313publicvoid setCveUrl20Modified(String cveUrl20Modified) { +314this.cveUrl20Modified = cveUrl20Modified; +315 } +316 +317/** +318 * Base Data Mirror URL for CVE 1.2. +319 */ +320private String cveUrl12Base; +321 +322/** +323 * Get the value of cveUrl12Base. +324 * +325 * @return the value of cveUrl12Base +326 */ +327public String getCveUrl12Base() { +328return cveUrl12Base; +329 } +330 +331/** +332 * Set the value of cveUrl12Base. +333 * +334 * @param cveUrl12Base new value of cveUrl12Base +335 */ +336publicvoid setCveUrl12Base(String cveUrl12Base) { +337this.cveUrl12Base = cveUrl12Base; +338 } +339 +340/** +341 * Data Mirror URL for CVE 2.0. +342 */ +343private String cveUrl20Base; +344 +345/** +346 * Get the value of cveUrl20Base. +347 * +348 * @return the value of cveUrl20Base +349 */ +350public String getCveUrl20Base() { +351return cveUrl20Base; +352 } +353 +354/** +355 * Set the value of cveUrl20Base. +356 * +357 * @param cveUrl20Base new value of cveUrl20Base +358 */ +359publicvoid setCveUrl20Base(String cveUrl20Base) { +360this.cveUrl20Base = cveUrl20Base; +361 } +362 +363/** +364 * The number of hours to wait before re-checking for updates. +365 */ +366private Integer cveValidForHours; +367 +368/** +369 * Get the value of cveValidForHours. +370 * +371 * @return the value of cveValidForHours +372 */ +373public Integer getCveValidForHours() { +374return cveValidForHours; +375 } +376 +377/** +378 * Set the value of cveValidForHours. +379 * +380 * @param cveValidForHours new value of cveValidForHours +381 */ +382publicvoid setCveValidForHours(Integer cveValidForHours) { +383this.cveValidForHours = cveValidForHours; +384 } +385 +386/** +387 * Executes the update by initializing the settings, downloads the NVD XML +388 * data, and then processes the data storing it in the local database. +389 * +390 * @throws BuildException thrown if a connection to the local database +391 * cannot be made. +392 */ +393 @Override +394publicvoid execute() throws BuildException { +395 populateSettings(); +396 Engine engine = null; +397try { +398 engine = new Engine(Update.class.getClassLoader()); +399try { +400 engine.doUpdates(); +401 } catch (UpdateException ex) { +402if (this.isFailOnError()) { +403thrownew BuildException(ex); +404 } +405 log(ex.getMessage(), Project.MSG_ERR); +406 } +407 } catch (DatabaseException ex) { +408final String msg = "Unable to connect to the dependency-check database; unable to update the NVD data"; +409if (this.isFailOnError()) { +410thrownew BuildException(msg, ex); +411 } +412 log(msg, Project.MSG_ERR); +413 } finally { +414 Settings.cleanup(true); +415if (engine != null) { +416 engine.cleanup(); +417 } +418 } +419 } +420 +421/** +422 * Takes the properties supplied and updates the dependency-check settings. +423 * Additionally, this sets the system properties required to change the +424 * proxy server, port, and connection timeout. +425 * +426 * @throws BuildException thrown when an invalid setting is configured. +427 */ +428 @Override +429protectedvoid populateSettings() throws BuildException { +430super.populateSettings(); +431 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_SERVER, proxyServer); +432 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PORT, proxyPort); +433 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_USERNAME, proxyUsername); +434 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PASSWORD, proxyPassword); +435 Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout); +436 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName); +437 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath); +438 Settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString); +439 Settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser); +440 Settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword); +441 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_12_URL, cveUrl12Modified); +442 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_20_URL, cveUrl20Modified); +443 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_1_2, cveUrl12Base); +444 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_2_0, cveUrl20Base); +445if (cveValidForHours != null) { +446if (cveValidForHours >= 0) { +447 Settings.setInt(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, cveValidForHours); +448 } else { +449thrownew BuildException("Invalid setting: `cpeValidForHours` must be 0 or greater"); +450 } +451 } +452 } +453 }
      diff --git a/dependency-check-ant/xref/org/owasp/dependencycheck/taskdefs/package-frame.html b/dependency-check-ant/xref/org/owasp/dependencycheck/taskdefs/package-frame.html index b63485c6d..74f9d9c4c 100644 --- a/dependency-check-ant/xref/org/owasp/dependencycheck/taskdefs/package-frame.html +++ b/dependency-check-ant/xref/org/owasp/dependencycheck/taskdefs/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Ant Task 1.4.0 Reference Package org.owasp.dependencycheck.taskdefs + Dependency-Check Ant Task 1.4.2 Reference Package org.owasp.dependencycheck.taskdefs diff --git a/dependency-check-ant/xref/org/owasp/dependencycheck/taskdefs/package-summary.html b/dependency-check-ant/xref/org/owasp/dependencycheck/taskdefs/package-summary.html index 82c23676f..20dbdc8cf 100644 --- a/dependency-check-ant/xref/org/owasp/dependencycheck/taskdefs/package-summary.html +++ b/dependency-check-ant/xref/org/owasp/dependencycheck/taskdefs/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Ant Task 1.4.0 Reference Package org.owasp.dependencycheck.taskdefs + Dependency-Check Ant Task 1.4.2 Reference Package org.owasp.dependencycheck.taskdefs diff --git a/dependency-check-ant/xref/org/slf4j/impl/package-frame.html b/dependency-check-ant/xref/org/slf4j/impl/package-frame.html index b74e9fb84..fd362348d 100644 --- a/dependency-check-ant/xref/org/slf4j/impl/package-frame.html +++ b/dependency-check-ant/xref/org/slf4j/impl/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Ant Task 1.4.0 Reference Package org.slf4j.impl + Dependency-Check Ant Task 1.4.2 Reference Package org.slf4j.impl diff --git a/dependency-check-ant/xref/org/slf4j/impl/package-summary.html b/dependency-check-ant/xref/org/slf4j/impl/package-summary.html index 1474d553a..01dd2fbda 100644 --- a/dependency-check-ant/xref/org/slf4j/impl/package-summary.html +++ b/dependency-check-ant/xref/org/slf4j/impl/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Ant Task 1.4.0 Reference Package org.slf4j.impl + Dependency-Check Ant Task 1.4.2 Reference Package org.slf4j.impl diff --git a/dependency-check-ant/xref/overview-frame.html b/dependency-check-ant/xref/overview-frame.html index e51b8b623..b7e15bc6a 100644 --- a/dependency-check-ant/xref/overview-frame.html +++ b/dependency-check-ant/xref/overview-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Ant Task 1.4.0 Reference + Dependency-Check Ant Task 1.4.2 Reference diff --git a/dependency-check-ant/xref/overview-summary.html b/dependency-check-ant/xref/overview-summary.html index 744480468..73645d9c9 100644 --- a/dependency-check-ant/xref/overview-summary.html +++ b/dependency-check-ant/xref/overview-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Ant Task 1.4.0 Reference + Dependency-Check Ant Task 1.4.2 Reference @@ -24,7 +24,7 @@ -

      Dependency-Check Ant Task 1.4.0 Reference

      +

      Dependency-Check Ant Task 1.4.2 Reference

      diff --git a/dependency-check-cli/apidocs/allclasses-frame.html b/dependency-check-cli/apidocs/allclasses-frame.html index 6a7938eab..a610559fb 100644 --- a/dependency-check-cli/apidocs/allclasses-frame.html +++ b/dependency-check-cli/apidocs/allclasses-frame.html @@ -2,10 +2,10 @@ - + -All Classes (Dependency-Check Command Line 1.4.0 API) - +All Classes (Dependency-Check Command Line 1.4.2 API) + diff --git a/dependency-check-cli/apidocs/allclasses-noframe.html b/dependency-check-cli/apidocs/allclasses-noframe.html index 876d89003..00b750b10 100644 --- a/dependency-check-cli/apidocs/allclasses-noframe.html +++ b/dependency-check-cli/apidocs/allclasses-noframe.html @@ -2,10 +2,10 @@ - + -All Classes (Dependency-Check Command Line 1.4.0 API) - +All Classes (Dependency-Check Command Line 1.4.2 API) + diff --git a/dependency-check-cli/apidocs/constant-values.html b/dependency-check-cli/apidocs/constant-values.html index 08f9fc6d1..bff536f38 100644 --- a/dependency-check-cli/apidocs/constant-values.html +++ b/dependency-check-cli/apidocs/constant-values.html @@ -2,10 +2,10 @@ - + -Constant Field Values (Dependency-Check Command Line 1.4.0 API) - +Constant Field Values (Dependency-Check Command Line 1.4.2 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-cli/apidocs/org/owasp/dependencycheck/package-summary.html b/dependency-check-cli/apidocs/org/owasp/dependencycheck/package-summary.html index 76e02745f..462c44742 100644 --- a/dependency-check-cli/apidocs/org/owasp/dependencycheck/package-summary.html +++ b/dependency-check-cli/apidocs/org/owasp/dependencycheck/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck (Dependency-Check Command Line 1.4.0 API) - +org.owasp.dependencycheck (Dependency-Check Command Line 1.4.2 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ - + diff --git a/dependency-check-cli/cobertura/frame-summary.html b/dependency-check-cli/cobertura/frame-summary.html index fed446866..8054f27da 100644 --- a/dependency-check-cli/cobertura/frame-summary.html +++ b/dependency-check-cli/cobertura/frame-summary.html @@ -16,8 +16,8 @@
      - - + +
      Package # Classes Line Coverage Branch Coverage Complexity
      All Packages4
      45%
      288/631
      19%
      56/284
      2.92
      org.owasp.dependencycheck4
      45%
      288/631
      19%
      56/284
      2.92
      All Packages4
      42%
      287/672
      18%
      56/296
      3.147
      org.owasp.dependencycheck4
      42%
      287/672
      18%
      56/296
      3.147
      - + diff --git a/dependency-check-cli/cobertura/org.owasp.dependencycheck.App.html b/dependency-check-cli/cobertura/org.owasp.dependencycheck.App.html index acdd31361..969f91068 100644 --- a/dependency-check-cli/cobertura/org.owasp.dependencycheck.App.html +++ b/dependency-check-cli/cobertura/org.owasp.dependencycheck.App.html @@ -12,7 +12,7 @@
       
      - +
      Classes in this File Line Coverage Branch Coverage Complexity
      App
      10%
      27/256
      9%
      10/104
      7.75
      App
      8%
      26/297
      8%
      10/116
      9.875
       
      @@ -96,561 +96,668 @@  39  
       import ch.qos.logback.core.FileAppender;
       40   -
       import org.slf4j.impl.StaticLoggerBinder;
      +
       import org.owasp.dependencycheck.data.update.exception.UpdateException;
       41   -
       
      +
       import org.owasp.dependencycheck.exception.ExceptionCollection;
       42   -
       /**
      +
       import org.owasp.dependencycheck.exception.ReportException;
       43   -
        * The command line interface for the DependencyCheck application.
      +
       import org.owasp.dependencycheck.utils.InvalidSettingException;
       44   -
        *
      +
       import org.slf4j.impl.StaticLoggerBinder;
       45   -
        * @author Jeremy Long
      +
       
       46   -
        */
      -  47  4
       public class App {
      +
       /**
      +  47   +
        * The command line interface for the DependencyCheck application.
       48   -
       
      +
        *
       49   -
           /**
      +
        * @author Jeremy Long
       50   -
            * The logger.
      -  51   -
            */
      -  52  2
           private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
      +
        */
      +  51  2
       public class App {
      +  52   +
       
       53   -
       
      +
           /**
       54   -
           /**
      +
            * The logger.
       55   -
            * The main method for the application.
      -  56   -
            *
      +
            */
      +  56  1
           private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
       57   -
            * @param args the command line arguments
      +
       
       58   -
            */
      +
           /**
       59   -
           public static void main(String[] args) {
      +
            * The main method for the application.
       60   -
               try {
      -  61  0
                   Settings.initialize();
      -  62  0
                   final App app = new App();
      -  63  0
                   app.run(args);
      -  64   -
               } finally {
      -  65  0
                   Settings.cleanup(true);
      -  66  0
               }
      -  67  0
           }
      -  68   -
       
      -  69   -
           /**
      -  70   -
            * Main CLI entry-point into the application.
      -  71  
            *
      -  72   +  61  
            * @param args the command line arguments
      -  73   +  62  
            */
      -  74   -
           public void run(String[] args) {
      -  75  0
               final CliParser cli = new CliParser();
      +  63   +
           public static void main(String[] args) {
      +  64  0
               int exitCode = 0;
      +  65   +
               try {
      +  66  0
                   Settings.initialize();
      +  67  0
                   final App app = new App();
      +  68  0
                   exitCode = app.run(args);
      +  69  0
                   LOGGER.debug("Exit code: " + exitCode);
      +  70   +
               } finally {
      +  71  0
                   Settings.cleanup(true);
      +  72  0
               }
      +  73  0
               System.exit(exitCode);
      +  74  0
           }
      +  75   +
       
       76   -
       
      +
           /**
       77   +
            * Main CLI entry-point into the application.
      +  78   +
            *
      +  79   +
            * @param args the command line arguments
      +  80   +
            * @return the exit code to return
      +  81   +
            */
      +  82   +
           public int run(String[] args) {
      +  83  0
               int exitCode = 0;
      +  84  0
               final CliParser cli = new CliParser();
      +  85   +
       
      +  86  
               try {
      -  78  0
                   cli.parse(args);
      -  79  0
               } catch (FileNotFoundException ex) {
      -  80  0
                   System.err.println(ex.getMessage());
      -  81  0
                   cli.printHelp();
      -  82  0
                   return;
      -  83  0
               } catch (ParseException ex) {
      -  84  0
                   System.err.println(ex.getMessage());
      -  85  0
                   cli.printHelp();
      -  86  0
                   return;
      -  87  0
               }
      -  88   +  87  0
                   cli.parse(args);
      +  88  0
               } catch (FileNotFoundException ex) {
      +  89  0
                   System.err.println(ex.getMessage());
      +  90  0
                   cli.printHelp();
      +  91  0
                   return -1;
      +  92  0
               } catch (ParseException ex) {
      +  93  0
                   System.err.println(ex.getMessage());
      +  94  0
                   cli.printHelp();
      +  95  0
                   return -2;
      +  96  0
               }
      +  97  
       
      -  89  0
               if (cli.getVerboseLog() != null) {
      -  90  0
                   prepareLogger(cli.getVerboseLog());
      -  91   +  98  0
               if (cli.getVerboseLog() != null) {
      +  99  0
                   prepareLogger(cli.getVerboseLog());
      +  100  
               }
      -  92   +  101  
       
      -  93  0
               if (cli.isPurge()) {
      -  94  0
                   if (cli.getConnectionString() != null) {
      -  95  0
                       LOGGER.error("Unable to purge the database when using a non-default connection string");
      -  96   -
                   } else {
      -  97  0
                       populateSettings(cli);
      -  98   -
                       File db;
      -  99   -
                       try {
      -  100  0
                           db = new File(Settings.getDataDirectory(), "dc.h2.db");
      -  101  0
                           if (db.exists()) {
      -  102  0
                               if (db.delete()) {
      -  103  0
                                   LOGGER.info("Database file purged; local copy of the NVD has been removed");
      -  104   -
                               } else {
      -  105  0
                                   LOGGER.error("Unable to delete '{}'; please delete the file manually", db.getAbsolutePath());
      +  102  0
               if (cli.isPurge()) {
      +  103  0
                   if (cli.getConnectionString() != null) {
      +  104  0
                       LOGGER.error("Unable to purge the database when using a non-default connection string");
      +  105  0
                       exitCode = -3;
       106   -
                               }
      +
                   } else {
       107   +
                       try {
      +  108  0
                           populateSettings(cli);
      +  109  0
                       } catch (InvalidSettingException ex) {
      +  110  0
                           LOGGER.error(ex.getMessage());
      +  111  0
                           LOGGER.debug("Error loading properties file", ex);
      +  112  0
                           exitCode = -4;
      +  113  0
                       }
      +  114   +
                       File db;
      +  115   +
                       try {
      +  116  0
                           db = new File(Settings.getDataDirectory(), "dc.h2.db");
      +  117  0
                           if (db.exists()) {
      +  118  0
                               if (db.delete()) {
      +  119  0
                                   LOGGER.info("Database file purged; local copy of the NVD has been removed");
      +  120   +
                               } else {
      +  121  0
                                   LOGGER.error("Unable to delete '{}'; please delete the file manually", db.getAbsolutePath());
      +  122  0
                                   exitCode = -5;
      +  123   +
                               }
      +  124  
                           } else {
      -  108  0
                               LOGGER.error("Unable to purge database; the database file does not exists: {}", db.getAbsolutePath());
      -  109   -
                           }
      -  110  0
                       } catch (IOException ex) {
      -  111  0
                           LOGGER.error("Unable to delete the database");
      -  112  0
                       }
      -  113   -
                   }
      -  114  0
               } else if (cli.isGetVersion()) {
      -  115  0
                   cli.printVersionInfo();
      -  116  0
               } else if (cli.isUpdateOnly()) {
      -  117  0
                   populateSettings(cli);
      -  118  0
                   runUpdateOnly();
      -  119  0
               } else if (cli.isRunScan()) {
      -  120  0
                   populateSettings(cli);
      -  121   -
                   try {
      -  122  0
                       runScan(cli.getReportDirectory(), cli.getReportFormat(), cli.getProjectName(), cli.getScanFiles(),
      -  123  0
                               cli.getExcludeList(), cli.getSymLinkDepth());
      -  124  0
                   } catch (InvalidScanPathException ex) {
      -  125  0
                       LOGGER.error("An invalid scan path was detected; unable to scan '//*' paths");
      -  126  0
                   }
      +  125  0
                               LOGGER.error("Unable to purge database; the database file does not exists: {}", db.getAbsolutePath());
      +  126  0
                               exitCode = -6;
       127   -
               } else {
      -  128  0
                   cli.printHelp();
      -  129   -
               }
      -  130  0
           }
      -  131   -
       
      +
                           }
      +  128  0
                       } catch (IOException ex) {
      +  129  0
                           LOGGER.error("Unable to delete the database");
      +  130  0
                           exitCode = -7;
      +  131  0
                       }
       132   -
           /**
      -  133   -
            * Scans the specified directories and writes the dependency reports to the reportDirectory.
      -  134   -
            *
      -  135   -
            * @param reportDirectory the path to the directory where the reports will be written
      +
                   }
      +  133  0
               } else if (cli.isGetVersion()) {
      +  134  0
                   cli.printVersionInfo();
      +  135  0
               } else if (cli.isUpdateOnly()) {
       136   -
            * @param outputFormat the output format of the report
      -  137   -
            * @param applicationName the application name for the report
      -  138   -
            * @param files the files/directories to scan
      -  139   -
            * @param excludes the patterns for files/directories to exclude
      -  140   -
            * @param symLinkDepth the depth that symbolic links will be followed
      -  141   -
            *
      -  142   -
            * @throws InvalidScanPathException thrown if the path to scan starts with "//"
      +
                   try {
      +  137  0
                       populateSettings(cli);
      +  138  0
                   } catch (InvalidSettingException ex) {
      +  139  0
                       LOGGER.error(ex.getMessage());
      +  140  0
                       LOGGER.debug("Error loading properties file", ex);
      +  141  0
                       exitCode = -4;
      +  142  0
                   }
       143   -
            */
      -  144   -
           private void runScan(String reportDirectory, String outputFormat, String applicationName, String[] files,
      -  145   -
                   String[] excludes, int symLinkDepth) throws InvalidScanPathException {
      -  146  0
               Engine engine = null;
      -  147   -
               try {
      -  148  0
                   engine = new Engine();
      -  149  0
                   final List<String> antStylePaths = new ArrayList<String>();
      -  150  0
                   for (String file : files) {
      -  151  0
                       final String antPath = ensureCanonicalPath(file);
      -  152  0
                       antStylePaths.add(antPath);
      +
                   try {
      +  144  0
                       runUpdateOnly();
      +  145  0
                   } catch (UpdateException ex) {
      +  146  0
                       LOGGER.error(ex.getMessage());
      +  147  0
                       exitCode = -8;
      +  148  0
                   } catch (DatabaseException ex) {
      +  149  0
                       LOGGER.error(ex.getMessage());
      +  150  0
                       exitCode = -9;
      +  151  0
                   }
      +  152  0
               } else if (cli.isRunScan()) {
       153   -
                   }
      -  154   -
       
      -  155  0
                   final Set<File> paths = new HashSet<File>();
      -  156  0
                   for (String file : antStylePaths) {
      -  157  0
                       LOGGER.debug("Scanning {}", file);
      -  158  0
                       final DirectoryScanner scanner = new DirectoryScanner();
      -  159  0
                       String include = file.replace('\\', '/');
      +
                   try {
      +  154  0
                       populateSettings(cli);
      +  155  0
                   } catch (InvalidSettingException ex) {
      +  156  0
                       LOGGER.error(ex.getMessage());
      +  157  0
                       LOGGER.debug("Error loading properties file", ex);
      +  158  0
                       exitCode = -4;
      +  159  0
                   }
       160   -
                       File baseDir;
      -  161   -
       
      -  162  0
                       if (include.startsWith("//")) {
      -  163  0
                           throw new InvalidScanPathException("Unable to scan paths specified by //");
      -  164   -
                       } else {
      -  165  0
                           final int pos = getLastFileSeparator(include);
      -  166  0
                           final String tmpBase = include.substring(0, pos);
      -  167  0
                           final String tmpInclude = include.substring(pos + 1);
      -  168  0
                           if (tmpInclude.indexOf('*') >= 0 || tmpInclude.indexOf('?') >= 0
      -  169  0
                                   || (new File(include)).isFile()) {
      -  170  0
                               baseDir = new File(tmpBase);
      -  171  0
                               include = tmpInclude;
      -  172   -
                           } else {
      -  173  0
                               baseDir = new File(tmpBase, tmpInclude);
      -  174  0
                               include = "**/*";
      -  175   -
                           }
      +
                   try {
      +  161  0
                       runScan(cli.getReportDirectory(), cli.getReportFormat(), cli.getProjectName(), cli.getScanFiles(),
      +  162  0
                               cli.getExcludeList(), cli.getSymLinkDepth());
      +  163  0
                   } catch (InvalidScanPathException ex) {
      +  164  0
                       LOGGER.error("An invalid scan path was detected; unable to scan '//*' paths");
      +  165  0
                       exitCode = -10;
      +  166  0
                   } catch (DatabaseException ex) {
      +  167  0
                       LOGGER.error(ex.getMessage());
      +  168  0
                       exitCode = -11;
      +  169  0
                   } catch (ReportException ex) {
      +  170  0
                       LOGGER.error(ex.getMessage());
      +  171  0
                       exitCode = -12;
      +  172  0
                   } catch (ExceptionCollection ex) {
      +  173  0
                       if (ex.isFatal()) {
      +  174  0
                           exitCode = -13;
      +  175  0
                           LOGGER.error("One or more fatal errors occured");
       176   -
                       }
      -  177   -
                       //LOGGER.debug("baseDir: {}", baseDir);
      +
                       } else {
      +  177  0
                           exitCode = -14;
       178   -
                       //LOGGER.debug("include: {}", include);
      -  179  0
                       scanner.setBasedir(baseDir);
      -  180  0
                       final String[] includes = {include};
      -  181  0
                       scanner.setIncludes(includes);
      -  182  0
                       scanner.setMaxLevelsOfSymlinks(symLinkDepth);
      -  183  0
                       if (symLinkDepth <= 0) {
      -  184  0
                           scanner.setFollowSymlinks(false);
      +
                       }
      +  179  0
                       for (Throwable e : ex.getExceptions()) {
      +  180  0
                           LOGGER.error(e.getMessage());
      +  181  0
                       }
      +  182  0
                   }
      +  183   +
               } else {
      +  184  0
                   cli.printHelp();
       185   -
                       }
      -  186  0
                       if (excludes != null && excludes.length > 0) {
      -  187  0
                           scanner.addExcludes(excludes);
      +
               }
      +  186  0
               return exitCode;
      +  187   +
           }
       188   -
                       }
      -  189  0
                       scanner.scan();
      -  190  0
                       if (scanner.getIncludedFilesCount() > 0) {
      -  191  0
                           for (String s : scanner.getIncludedFiles()) {
      -  192  0
                               final File f = new File(baseDir, s);
      -  193  0
                               LOGGER.debug("Found file {}", f.toString());
      -  194  0
                               paths.add(f);
      -  195   -
                           }
      -  196   -
                       }
      -  197  0
                   }
      -  198  0
                   engine.scan(paths);
      -  199  
       
      -  200  0
                   engine.analyzeDependencies();
      -  201  0
                   final List<Dependency> dependencies = engine.getDependencies();
      -  202  0
                   DatabaseProperties prop = null;
      -  203  0
                   CveDB cve = null;
      -  204   -
                   try {
      -  205  0
                       cve = new CveDB();
      -  206  0
                       cve.open();
      -  207  0
                       prop = cve.getDatabaseProperties();
      -  208  0
                   } catch (DatabaseException ex) {
      -  209  0
                       LOGGER.debug("Unable to retrieve DB Properties", ex);
      -  210   -
                   } finally {
      -  211  0
                       if (cve != null) {
      -  212  0
                           cve.close();
      -  213   -
                       }
      -  214   -
                   }
      -  215  0
                   final ReportGenerator report = new ReportGenerator(applicationName, dependencies, engine.getAnalyzers(), prop);
      -  216   -
                   try {
      -  217  0
                       report.generateReports(reportDirectory, outputFormat);
      -  218  0
                   } catch (IOException ex) {
      -  219  0
                       LOGGER.error("There was an IO error while attempting to generate the report.");
      -  220  0
                       LOGGER.debug("", ex);
      -  221  0
                   } catch (Throwable ex) {
      -  222  0
                       LOGGER.error("There was an error while attempting to generate the report.");
      -  223  0
                       LOGGER.debug("", ex);
      -  224  0
                   }
      -  225  0
               } catch (DatabaseException ex) {
      -  226  0
                   LOGGER.error("Unable to connect to the dependency-check database; analysis has stopped");
      -  227  0
                   LOGGER.debug("", ex);
      -  228   -
               } finally {
      -  229  0
                   if (engine != null) {
      -  230  0
                       engine.cleanup();
      -  231   -
                   }
      -  232   -
               }
      -  233  0
           }
      -  234   -
       
      -  235   +  189  
           /**
      -  236   -
            * Only executes the update phase of dependency-check.
      -  237   -
            */
      -  238   -
           private void runUpdateOnly() {
      -  239  0
               Engine engine = null;
      -  240   -
               try {
      -  241  0
                   engine = new Engine();
      -  242  0
                   engine.doUpdates();
      -  243  0
               } catch (DatabaseException ex) {
      -  244  0
                   LOGGER.error("Unable to connect to the dependency-check database; analysis has stopped");
      -  245  0
                   LOGGER.debug("", ex);
      -  246   -
               } finally {
      -  247  0
                   if (engine != null) {
      -  248  0
                       engine.cleanup();
      -  249   -
                   }
      -  250   -
               }
      -  251  0
           }
      -  252   -
       
      -  253   -
           /**
      -  254   -
            * Updates the global Settings.
      -  255   +  190   +
            * Scans the specified directories and writes the dependency reports to the
      +  191   +
            * reportDirectory.
      +  192  
            *
      -  256   -
            * @param cli a reference to the CLI Parser that contains the command line arguments used to set the corresponding settings in
      -  257   -
            * the core engine.
      -  258   +  193   +
            * @param reportDirectory the path to the directory where the reports will
      +  194   +
            * be written
      +  195   +
            * @param outputFormat the output format of the report
      +  196   +
            * @param applicationName the application name for the report
      +  197   +
            * @param files the files/directories to scan
      +  198   +
            * @param excludes the patterns for files/directories to exclude
      +  199   +
            * @param symLinkDepth the depth that symbolic links will be followed
      +  200   +
            *
      +  201   +
            * @throws InvalidScanPathException thrown if the path to scan starts with
      +  202   +
            * "//"
      +  203   +
            * @throws ReportException thrown when the report cannot be generated
      +  204   +
            * @throws DatabaseException thrown when there is an error connecting to the
      +  205   +
            * database
      +  206   +
            * @throws ExceptionCollection thrown when an exception occurs during
      +  207   +
            * analysis; there may be multiple exceptions contained within the
      +  208   +
            * collection.
      +  209  
            */
      +  210   +
           private void runScan(String reportDirectory, String outputFormat, String applicationName, String[] files,
      +  211   +
                   String[] excludes, int symLinkDepth) throws InvalidScanPathException, DatabaseException, ExceptionCollection, ReportException {
      +  212  0
               Engine engine = null;
      +  213   +
               try {
      +  214  0
                   engine = new Engine();
      +  215  0
                   final List<String> antStylePaths = new ArrayList<String>();
      +  216  0
                   for (String file : files) {
      +  217  0
                       final String antPath = ensureCanonicalPath(file);
      +  218  0
                       antStylePaths.add(antPath);
      +  219   +
                   }
      +  220   +
       
      +  221  0
                   final Set<File> paths = new HashSet<File>();
      +  222  0
                   for (String file : antStylePaths) {
      +  223  0
                       LOGGER.debug("Scanning {}", file);
      +  224  0
                       final DirectoryScanner scanner = new DirectoryScanner();
      +  225  0
                       String include = file.replace('\\', '/');
      +  226   +
                       File baseDir;
      +  227   +
       
      +  228  0
                       if (include.startsWith("//")) {
      +  229  0
                           throw new InvalidScanPathException("Unable to scan paths specified by //");
      +  230   +
                       } else {
      +  231  0
                           final int pos = getLastFileSeparator(include);
      +  232  0
                           final String tmpBase = include.substring(0, pos);
      +  233  0
                           final String tmpInclude = include.substring(pos + 1);
      +  234  0
                           if (tmpInclude.indexOf('*') >= 0 || tmpInclude.indexOf('?') >= 0
      +  235  0
                                   || (new File(include)).isFile()) {
      +  236  0
                               baseDir = new File(tmpBase);
      +  237  0
                               include = tmpInclude;
      +  238   +
                           } else {
      +  239  0
                               baseDir = new File(tmpBase, tmpInclude);
      +  240  0
                               include = "**/*";
      +  241   +
                           }
      +  242   +
                       }
      +  243  0
                       scanner.setBasedir(baseDir);
      +  244  0
                       final String[] includes = {include};
      +  245  0
                       scanner.setIncludes(includes);
      +  246  0
                       scanner.setMaxLevelsOfSymlinks(symLinkDepth);
      +  247  0
                       if (symLinkDepth <= 0) {
      +  248  0
                           scanner.setFollowSymlinks(false);
      +  249   +
                       }
      +  250  0
                       if (excludes != null && excludes.length > 0) {
      +  251  0
                           scanner.addExcludes(excludes);
      +  252   +
                       }
      +  253  0
                       scanner.scan();
      +  254  0
                       if (scanner.getIncludedFilesCount() > 0) {
      +  255  0
                           for (String s : scanner.getIncludedFiles()) {
      +  256  0
                               final File f = new File(baseDir, s);
      +  257  0
                               LOGGER.debug("Found file {}", f.toString());
      +  258  0
                               paths.add(f);
       259   -
           private void populateSettings(CliParser cli) {
      +
                           }
       260   +
                       }
      +  261  0
                   }
      +  262  0
                   engine.scan(paths);
      +  263  
       
      -  261  0
               final boolean autoUpdate = cli.isAutoUpdate();
      -  262  0
               final String connectionTimeout = cli.getConnectionTimeout();
      -  263  0
               final String proxyServer = cli.getProxyServer();
      -  264  0
               final String proxyPort = cli.getProxyPort();
      -  265  0
               final String proxyUser = cli.getProxyUsername();
      -  266  0
               final String proxyPass = cli.getProxyPassword();
      -  267  0
               final String dataDirectory = cli.getDataDirectory();
      -  268  0
               final File propertiesFile = cli.getPropertiesFile();
      -  269  0
               final String suppressionFile = cli.getSuppressionFile();
      -  270  0
               final String nexusUrl = cli.getNexusUrl();
      -  271  0
               final String databaseDriverName = cli.getDatabaseDriverName();
      -  272  0
               final String databaseDriverPath = cli.getDatabaseDriverPath();
      -  273  0
               final String connectionString = cli.getConnectionString();
      -  274  0
               final String databaseUser = cli.getDatabaseUser();
      -  275  0
               final String databasePassword = cli.getDatabasePassword();
      -  276  0
               final String additionalZipExtensions = cli.getAdditionalZipExtensions();
      -  277  0
               final String pathToMono = cli.getPathToMono();
      -  278  0
               final String cveMod12 = cli.getModifiedCve12Url();
      -  279  0
               final String cveMod20 = cli.getModifiedCve20Url();
      -  280  0
               final String cveBase12 = cli.getBaseCve12Url();
      -  281  0
               final String cveBase20 = cli.getBaseCve20Url();
      -  282  0
               final Integer cveValidForHours = cli.getCveValidForHours();
      -  283  0
               final boolean experimentalEnabled = cli.isExperimentalEnabled();
      +  264  0
                   ExceptionCollection exCol = null;
      +  265   +
                   try {
      +  266  0
                       engine.analyzeDependencies();
      +  267  0
                   } catch (ExceptionCollection ex) {
      +  268  0
                       if (ex.isFatal()) {
      +  269  0
                           throw ex;
      +  270   +
                       }
      +  271  0
                       exCol = ex;
      +  272  0
                   }
      +  273  0
                   final List<Dependency> dependencies = engine.getDependencies();
      +  274  0
                   DatabaseProperties prop = null;
      +  275  0
                   CveDB cve = null;
      +  276   +
                   try {
      +  277  0
                       cve = new CveDB();
      +  278  0
                       cve.open();
      +  279  0
                       prop = cve.getDatabaseProperties();
      +  280   +
                   } finally {
      +  281  0
                       if (cve != null) {
      +  282  0
                           cve.close();
      +  283   +
                       }
       284   -
       
      -  285  0
               if (propertiesFile != null) {
      +
                   }
      +  285  0
                   final ReportGenerator report = new ReportGenerator(applicationName, dependencies, engine.getAnalyzers(), prop);
       286  
                   try {
      -  287  0
                       Settings.mergeProperties(propertiesFile);
      -  288  0
                   } catch (FileNotFoundException ex) {
      -  289  0
                       LOGGER.error("Unable to load properties file '{}'", propertiesFile.getPath());
      -  290  0
                       LOGGER.debug("", ex);
      -  291  0
                   } catch (IOException ex) {
      -  292  0
                       LOGGER.error("Unable to find properties file '{}'", propertiesFile.getPath());
      -  293  0
                       LOGGER.debug("", ex);
      -  294  0
                   }
      -  295   -
               }
      -  296   -
               // We have to wait until we've merged the properties before attempting to set whether we use
      -  297   -
               // the proxy for Nexus since it could be disabled in the properties, but not explicitly stated
      +  287  0
                       report.generateReports(reportDirectory, outputFormat);
      +  288  0
                   } catch (ReportException ex) {
      +  289  0
                       if (exCol != null) {
      +  290  0
                           exCol.addException(ex);
      +  291  0
                           throw exCol;
      +  292   +
                       } else {
      +  293  0
                           throw ex;
      +  294   +
                       }
      +  295  0
                   }
      +  296  0
                   if (exCol != null && exCol.getExceptions().size()>0) {
      +  297  0
                       throw exCol;
       298   -
               // on the command line
      -  299  0
               final boolean nexusUsesProxy = cli.isNexusUsesProxy();
      -  300  0
               if (dataDirectory != null) {
      -  301  0
                   Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory);
      -  302  0
               } else if (System.getProperty("basedir") != null) {
      -  303  0
                   final File dataDir = new File(System.getProperty("basedir"), "data");
      -  304  0
                   Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath());
      -  305  0
               } else {
      -  306  0
                   final File jarPath = new File(App.class.getProtectionDomain().getCodeSource().getLocation().getPath());
      -  307  0
                   final File base = jarPath.getParentFile();
      -  308  0
                   final String sub = Settings.getString(Settings.KEYS.DATA_DIRECTORY);
      -  309  0
                   final File dataDir = new File(base, sub);
      -  310  0
                   Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath());
      -  311   -
               }
      -  312  0
               Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate);
      -  313  0
               Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_SERVER, proxyServer);
      -  314  0
               Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PORT, proxyPort);
      -  315  0
               Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_USERNAME, proxyUser);
      -  316  0
               Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PASSWORD, proxyPass);
      -  317  0
               Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout);
      -  318  0
               Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile);
      -  319  0
               Settings.setIntIfNotNull(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, cveValidForHours);
      -  320   -
       
      -  321   -
               //File Type Analyzer Settings
      -  322  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, experimentalEnabled);
      -  323  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_JAR_ENABLED, !cli.isJarDisabled());
      -  324  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, !cli.isArchiveDisabled());
      -  325  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, !cli.isPythonDistributionDisabled());
      -  326  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, !cli.isPythonPackageDisabled());
      -  327  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_AUTOCONF_ENABLED, !cli.isAutoconfDisabled());
      -  328  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_CMAKE_ENABLED, !cli.isCmakeDisabled());
      -  329  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, !cli.isNuspecDisabled());
      -  330  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, !cli.isAssemblyDisabled());
      -  331  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_ENABLED, !cli.isBundleAuditDisabled());
      -  332  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, !cli.isOpenSSLDisabled());
      -  333  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED, !cli.isComposerDisabled());
      -  334  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED, !cli.isNodeJsDisabled());
      -  335  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED, !cli.isRubyGemspecDisabled());
      -  336  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, !cli.isCentralDisabled());
      -  337  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, !cli.isNexusDisabled());
      -  338   -
       
      -  339  0
               Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH, cli.getPathToBundleAudit());
      -  340  0
               Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl);
      -  341  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy);
      -  342  0
               Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName);
      -  343  0
               Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath);
      -  344  0
               Settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString);
      -  345  0
               Settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser);
      -  346  0
               Settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword);
      -  347  0
               Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, additionalZipExtensions);
      -  348  0
               Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono);
      -  349  0
               if (cveBase12 != null && !cveBase12.isEmpty()) {
      -  350  0
                   Settings.setString(Settings.KEYS.CVE_SCHEMA_1_2, cveBase12);
      -  351  0
                   Settings.setString(Settings.KEYS.CVE_SCHEMA_2_0, cveBase20);
      -  352  0
                   Settings.setString(Settings.KEYS.CVE_MODIFIED_12_URL, cveMod12);
      -  353  0
                   Settings.setString(Settings.KEYS.CVE_MODIFIED_20_URL, cveMod20);
      -  354   -
               }
      -  355  0
           }
      -  356   -
       
      -  357   -
           /**
      -  358   -
            * Creates a file appender and adds it to logback.
      -  359   -
            *
      -  360   -
            * @param verboseLog the path to the verbose log file
      -  361   -
            */
      -  362   -
           private void prepareLogger(String verboseLog) {
      -  363  0
               final StaticLoggerBinder loggerBinder = StaticLoggerBinder.getSingleton();
      -  364  0
               final LoggerContext context = (LoggerContext) loggerBinder.getLoggerFactory();
      -  365   -
       
      -  366  0
               final PatternLayoutEncoder encoder = new PatternLayoutEncoder();
      -  367  0
               encoder.setPattern("%d %C:%L%n%-5level - %msg%n");
      -  368  0
               encoder.setContext(context);
      -  369  0
               encoder.start();
      -  370  0
               final FileAppender fa = new FileAppender();
      -  371  0
               fa.setAppend(true);
      -  372  0
               fa.setEncoder(encoder);
      -  373  0
               fa.setContext(context);
      -  374  0
               fa.setFile(verboseLog);
      -  375  0
               final File f = new File(verboseLog);
      -  376  0
               String name = f.getName();
      -  377  0
               final int i = name.lastIndexOf('.');
      -  378  0
               if (i > 1) {
      -  379  0
                   name = name.substring(0, i);
      -  380   -
               }
      -  381  0
               fa.setName(name);
      -  382  0
               fa.start();
      -  383  0
               final ch.qos.logback.classic.Logger rootLogger = context.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME);
      -  384  0
               rootLogger.addAppender(fa);
      -  385  0
           }
      -  386   -
       
      -  387   -
           /**
      -  388   -
            * Takes a path and resolves it to be a canonical &amp; absolute path. The caveats are that this method will take an Ant style
      -  389   -
            * file selector path (../someDir/**\/*.jar) and convert it to an absolute/canonical path (at least to the left of the first *
      -  390   -
            * or ?).
      -  391   -
            *
      -  392   -
            * @param path the path to canonicalize
      -  393   -
            * @return the canonical path
      -  394   -
            */
      -  395   -
           protected String ensureCanonicalPath(String path) {
      -  396  4
               String basePath = null;
      -  397  4
               String wildCards = null;
      -  398  4
               final String file = path.replace('\\', '/');
      -  399  4
               if (file.contains("*") || file.contains("?")) {
      -  400   -
       
      -  401  2
                   int pos = getLastFileSeparator(file);
      -  402  2
                   if (pos < 0) {
      -  403  0
                       return file;
      -  404  
                   }
      -  405  2
                   pos += 1;
      -  406  2
                   basePath = file.substring(0, pos);
      -  407  2
                   wildCards = file.substring(pos);
      -  408  2
               } else {
      -  409  2
                   basePath = file;
      -  410   +  299   +
               } finally {
      +  300  0
                   if (engine != null) {
      +  301  0
                       engine.cleanup();
      +  302   +
                   }
      +  303  
               }
      +  304   +
               
      +  305  0
           }
      +  306   +
       
      +  307   +
           /**
      +  308   +
            * Only executes the update phase of dependency-check.
      +  309   +
            *
      +  310   +
            * @throws UpdateException thrown if there is an error updating
      +  311   +
            * @throws DatabaseException thrown if a fatal error occurred and a
      +  312   +
            * connection to the database could not be established
      +  313   +
            */
      +  314   +
           private void runUpdateOnly() throws UpdateException, DatabaseException {
      +  315  0
               Engine engine = null;
      +  316   +
               try {
      +  317  0
                   engine = new Engine();
      +  318  0
                   engine.doUpdates();
      +  319   +
               } finally {
      +  320  0
                   if (engine != null) {
      +  321  0
                       engine.cleanup();
      +  322   +
                   }
      +  323   +
               }
      +  324  0
           }
      +  325   +
       
      +  326   +
           /**
      +  327   +
            * Updates the global Settings.
      +  328   +
            *
      +  329   +
            * @param cli a reference to the CLI Parser that contains the command line
      +  330   +
            * arguments used to set the corresponding settings in the core engine.
      +  331   +
            *
      +  332   +
            * @throws InvalidSettingException thrown when a user defined properties
      +  333   +
            * file is unable to be loaded.
      +  334   +
            */
      +  335   +
           private void populateSettings(CliParser cli) throws InvalidSettingException {
      +  336  0
               final boolean autoUpdate = cli.isAutoUpdate();
      +  337  0
               final String connectionTimeout = cli.getConnectionTimeout();
      +  338  0
               final String proxyServer = cli.getProxyServer();
      +  339  0
               final String proxyPort = cli.getProxyPort();
      +  340  0
               final String proxyUser = cli.getProxyUsername();
      +  341  0
               final String proxyPass = cli.getProxyPassword();
      +  342  0
               final String dataDirectory = cli.getDataDirectory();
      +  343  0
               final File propertiesFile = cli.getPropertiesFile();
      +  344  0
               final String suppressionFile = cli.getSuppressionFile();
      +  345  0
               final String nexusUrl = cli.getNexusUrl();
      +  346  0
               final String databaseDriverName = cli.getDatabaseDriverName();
      +  347  0
               final String databaseDriverPath = cli.getDatabaseDriverPath();
      +  348  0
               final String connectionString = cli.getConnectionString();
      +  349  0
               final String databaseUser = cli.getDatabaseUser();
      +  350  0
               final String databasePassword = cli.getDatabasePassword();
      +  351  0
               final String additionalZipExtensions = cli.getAdditionalZipExtensions();
      +  352  0
               final String pathToMono = cli.getPathToMono();
      +  353  0
               final String cveMod12 = cli.getModifiedCve12Url();
      +  354  0
               final String cveMod20 = cli.getModifiedCve20Url();
      +  355  0
               final String cveBase12 = cli.getBaseCve12Url();
      +  356  0
               final String cveBase20 = cli.getBaseCve20Url();
      +  357  0
               final Integer cveValidForHours = cli.getCveValidForHours();
      +  358  0
               final boolean experimentalEnabled = cli.isExperimentalEnabled();
      +  359   +
       
      +  360  0
               if (propertiesFile != null) {
      +  361   +
                   try {
      +  362  0
                       Settings.mergeProperties(propertiesFile);
      +  363  0
                   } catch (FileNotFoundException ex) {
      +  364  0
                       throw new InvalidSettingException("Unable to find properties file '" + propertiesFile.getPath() + "'", ex);
      +  365  0
                   } catch (IOException ex) {
      +  366  0
                       throw new InvalidSettingException("Error reading properties file '" + propertiesFile.getPath() + "'", ex);
      +  367  0
                   }
      +  368   +
               }
      +  369   +
               // We have to wait until we've merged the properties before attempting to set whether we use
      +  370   +
               // the proxy for Nexus since it could be disabled in the properties, but not explicitly stated
      +  371   +
               // on the command line
      +  372  0
               final boolean nexusUsesProxy = cli.isNexusUsesProxy();
      +  373  0
               if (dataDirectory != null) {
      +  374  0
                   Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory);
      +  375  0
               } else if (System.getProperty("basedir") != null) {
      +  376  0
                   final File dataDir = new File(System.getProperty("basedir"), "data");
      +  377  0
                   Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath());
      +  378  0
               } else {
      +  379  0
                   final File jarPath = new File(App.class.getProtectionDomain().getCodeSource().getLocation().getPath());
      +  380  0
                   final File base = jarPath.getParentFile();
      +  381  0
                   final String sub = Settings.getString(Settings.KEYS.DATA_DIRECTORY);
      +  382  0
                   final File dataDir = new File(base, sub);
      +  383  0
                   Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath());
      +  384   +
               }
      +  385  0
               Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate);
      +  386  0
               Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_SERVER, proxyServer);
      +  387  0
               Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PORT, proxyPort);
      +  388  0
               Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_USERNAME, proxyUser);
      +  389  0
               Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PASSWORD, proxyPass);
      +  390  0
               Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout);
      +  391  0
               Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile);
      +  392  0
               Settings.setIntIfNotNull(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, cveValidForHours);
      +  393   +
       
      +  394   +
               //File Type Analyzer Settings
      +  395  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, experimentalEnabled);
      +  396  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_JAR_ENABLED, !cli.isJarDisabled());
      +  397  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, !cli.isArchiveDisabled());
      +  398  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, !cli.isPythonDistributionDisabled());
      +  399  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, !cli.isPythonPackageDisabled());
      +  400  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_AUTOCONF_ENABLED, !cli.isAutoconfDisabled());
      +  401  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_CMAKE_ENABLED, !cli.isCmakeDisabled());
      +  402  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, !cli.isNuspecDisabled());
      +  403  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, !cli.isAssemblyDisabled());
      +  404  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_ENABLED, !cli.isBundleAuditDisabled());
      +  405  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, !cli.isOpenSSLDisabled());
      +  406  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED, !cli.isComposerDisabled());
      +  407  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED, !cli.isNodeJsDisabled());
      +  408  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED, !cli.isRubyGemspecDisabled());
      +  409  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, !cli.isCentralDisabled());
      +  410  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, !cli.isNexusDisabled());
       411  
       
      -  412  4
               File f = new File(basePath);
      -  413   -
               try {
      -  414  4
                   f = f.getCanonicalFile();
      -  415  4
                   if (wildCards != null) {
      -  416  2
                       f = new File(f, wildCards);
      -  417   -
                   }
      -  418  0
               } catch (IOException ex) {
      -  419  0
                   LOGGER.warn("Invalid path '{}' was provided.", path);
      -  420  0
                   LOGGER.debug("Invalid path provided", ex);
      -  421  4
               }
      -  422  4
               return f.getAbsolutePath().replace('\\', '/');
      -  423   -
           }
      -  424   -
       
      -  425   -
           /**
      -  426   -
            * Returns the position of the last file separator.
      +  412  0
               Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH, cli.getPathToBundleAudit());
      +  413  0
               Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl);
      +  414  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy);
      +  415  0
               Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName);
      +  416  0
               Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath);
      +  417  0
               Settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString);
      +  418  0
               Settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser);
      +  419  0
               Settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword);
      +  420  0
               Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, additionalZipExtensions);
      +  421  0
               Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono);
      +  422  0
               if (cveBase12 != null && !cveBase12.isEmpty()) {
      +  423  0
                   Settings.setString(Settings.KEYS.CVE_SCHEMA_1_2, cveBase12);
      +  424  0
                   Settings.setString(Settings.KEYS.CVE_SCHEMA_2_0, cveBase20);
      +  425  0
                   Settings.setString(Settings.KEYS.CVE_MODIFIED_12_URL, cveMod12);
      +  426  0
                   Settings.setString(Settings.KEYS.CVE_MODIFIED_20_URL, cveMod20);
       427   -
            *
      -  428   -
            * @param file a file path
      -  429   -
            * @return the position of the last file separator
      -  430   -
            */
      -  431   -
           private int getLastFileSeparator(String file) {
      -  432  2
               if (file.contains("*") || file.contains("?")) {
      -  433  2
                   int p1 = file.indexOf('*');
      -  434  2
                   int p2 = file.indexOf('?');
      -  435  2
                   p1 = p1 > 0 ? p1 : file.length();
      -  436  2
                   p2 = p2 > 0 ? p2 : file.length();
      -  437  2
                   int pos = p1 < p2 ? p1 : p2;
      -  438  2
                   pos = file.lastIndexOf('/', pos);
      -  439  2
                   return pos;
      -  440   -
               } else {
      -  441  0
                   return file.lastIndexOf('/');
      -  442  
               }
      -  443   +  428  0
           }
      +  429   +
       
      +  430   +
           /**
      +  431   +
            * Creates a file appender and adds it to logback.
      +  432   +
            *
      +  433   +
            * @param verboseLog the path to the verbose log file
      +  434   +
            */
      +  435   +
           private void prepareLogger(String verboseLog) {
      +  436  0
               final StaticLoggerBinder loggerBinder = StaticLoggerBinder.getSingleton();
      +  437  0
               final LoggerContext context = (LoggerContext) loggerBinder.getLoggerFactory();
      +  438   +
       
      +  439  0
               final PatternLayoutEncoder encoder = new PatternLayoutEncoder();
      +  440  0
               encoder.setPattern("%d %C:%L%n%-5level - %msg%n");
      +  441  0
               encoder.setContext(context);
      +  442  0
               encoder.start();
      +  443  0
               final FileAppender fa = new FileAppender();
      +  444  0
               fa.setAppend(true);
      +  445  0
               fa.setEncoder(encoder);
      +  446  0
               fa.setContext(context);
      +  447  0
               fa.setFile(verboseLog);
      +  448  0
               final File f = new File(verboseLog);
      +  449  0
               String name = f.getName();
      +  450  0
               final int i = name.lastIndexOf('.');
      +  451  0
               if (i > 1) {
      +  452  0
                   name = name.substring(0, i);
      +  453   +
               }
      +  454  0
               fa.setName(name);
      +  455  0
               fa.start();
      +  456  0
               final ch.qos.logback.classic.Logger rootLogger = context.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME);
      +  457  0
               rootLogger.addAppender(fa);
      +  458  0
           }
      +  459   +
       
      +  460   +
           /**
      +  461   +
            * Takes a path and resolves it to be a canonical &amp; absolute path. The
      +  462   +
            * caveats are that this method will take an Ant style file selector path
      +  463   +
            * (../someDir/**\/*.jar) and convert it to an absolute/canonical path (at
      +  464   +
            * least to the left of the first * or ?).
      +  465   +
            *
      +  466   +
            * @param path the path to canonicalize
      +  467   +
            * @return the canonical path
      +  468   +
            */
      +  469   +
           protected String ensureCanonicalPath(String path) {
      +  470   +
               String basePath;
      +  471  2
               String wildCards = null;
      +  472  2
               final String file = path.replace('\\', '/');
      +  473  2
               if (file.contains("*") || file.contains("?")) {
      +  474   +
       
      +  475  1
                   int pos = getLastFileSeparator(file);
      +  476  1
                   if (pos < 0) {
      +  477  0
                       return file;
      +  478   +
                   }
      +  479  1
                   pos += 1;
      +  480  1
                   basePath = file.substring(0, pos);
      +  481  1
                   wildCards = file.substring(pos);
      +  482  1
               } else {
      +  483  1
                   basePath = file;
      +  484   +
               }
      +  485   +
       
      +  486  2
               File f = new File(basePath);
      +  487   +
               try {
      +  488  2
                   f = f.getCanonicalFile();
      +  489  2
                   if (wildCards != null) {
      +  490  1
                       f = new File(f, wildCards);
      +  491   +
                   }
      +  492  0
               } catch (IOException ex) {
      +  493  0
                   LOGGER.warn("Invalid path '{}' was provided.", path);
      +  494  0
                   LOGGER.debug("Invalid path provided", ex);
      +  495  2
               }
      +  496  2
               return f.getAbsolutePath().replace('\\', '/');
      +  497  
           }
      -  444   +  498   +
       
      +  499   +
           /**
      +  500   +
            * Returns the position of the last file separator.
      +  501   +
            *
      +  502   +
            * @param file a file path
      +  503   +
            * @return the position of the last file separator
      +  504   +
            */
      +  505   +
           private int getLastFileSeparator(String file) {
      +  506  1
               if (file.contains("*") || file.contains("?")) {
      +  507  1
                   int p1 = file.indexOf('*');
      +  508  1
                   int p2 = file.indexOf('?');
      +  509  1
                   p1 = p1 > 0 ? p1 : file.length();
      +  510  1
                   p2 = p2 > 0 ? p2 : file.length();
      +  511  1
                   int pos = p1 < p2 ? p1 : p2;
      +  512  1
                   pos = file.lastIndexOf('/', pos);
      +  513  1
                   return pos;
      +  514   +
               } else {
      +  515  0
                   return file.lastIndexOf('/');
      +  516   +
               }
      +  517   +
           }
      +  518  
       }
      - + diff --git a/dependency-check-cli/cobertura/org.owasp.dependencycheck.CliParser.html b/dependency-check-cli/cobertura/org.owasp.dependencycheck.CliParser.html index 0a3ad314f..80577c16f 100644 --- a/dependency-check-cli/cobertura/org.owasp.dependencycheck.CliParser.html +++ b/dependency-check-cli/cobertura/org.owasp.dependencycheck.CliParser.html @@ -100,7 +100,7 @@
        * @author Jeremy Long
       41  
        */
      -  42  18
       public final class CliParser {
      +  42  9
       public final class CliParser {
       43  
       
       44   @@ -109,7 +109,7 @@
            * The logger.
       46  
            */
      -  47  2
           private static final Logger LOGGER = LoggerFactory.getLogger(CliParser.class);
      +  47  1
           private static final Logger LOGGER = LoggerFactory.getLogger(CliParser.class);
       48  
           /**
       49   @@ -124,7 +124,7 @@
            * Indicates whether the arguments are valid.
       54  
            */
      -  55  18
           private boolean isValid = true;
      +  55  9
           private boolean isValid = true;
       56  
       
       57   @@ -145,14 +145,14 @@
            */
       65  
           public void parse(String[] args) throws FileNotFoundException, ParseException {
      -  66  18
               line = parseArgs(args);
      +  66  9
               line = parseArgs(args);
       67  
       
      -  68  14
               if (line != null) {
      -  69  14
                   validateArgs();
      +  68  7
               if (line != null) {
      +  69  7
                   validateArgs();
       70  
               }
      -  71  12
           }
      +  71  6
           }
       72  
       
       73   @@ -171,9 +171,9 @@
            */
       80  
           private CommandLine parseArgs(String[] args) throws ParseException {
      -  81  18
               final CommandLineParser parser = new DefaultParser();
      -  82  18
               final Options options = createCommandLineOptions();
      -  83  18
               return parser.parse(options, args);
      +  81  9
               final CommandLineParser parser = new DefaultParser();
      +  82  9
               final Options options = createCommandLineOptions();
      +  83  9
               return parser.parse(options, args);
       84  
           }
       85   @@ -196,9 +196,9 @@
            */
       94  
           private void validateArgs() throws FileNotFoundException, ParseException {
      -  95  14
               if (isUpdateOnly() || isRunScan()) {
      -  96  4
                   final String value = line.getOptionValue(ARGUMENT.CVE_VALID_FOR_HOURS);
      -  97  4
                   if (value != null) {
      +  95  7
               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);
      @@ -213,18 +213,18 @@
                   }
       107  
               }
      -  108  14
               if (isRunScan()) {
      -  109  4
                   validatePathExists(getScanFiles(), ARGUMENT.SCAN);
      -  110  2
                   validatePathExists(getReportDirectory(), ARGUMENT.OUT);
      -  111  2
                   if (getPathToMono() != null) {
      +  108  7
               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  2
                   if (!line.hasOption(ARGUMENT.APP_NAME) && !line.hasOption(ARGUMENT.PROJECT)) {
      +  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  2
                   if (line.hasOption(ARGUMENT.OUTPUT_FORMAT)) {
      +  117  1
                   if (line.hasOption(ARGUMENT.OUTPUT_FORMAT)) {
       118  0
                       final String format = line.getOptionValue(ARGUMENT.OUTPUT_FORMAT);
       119  
                       try {
      @@ -237,13 +237,13 @@  125  0
                       }
       126  
                   }
      -  127  2
                   if ((getBaseCve12Url() != null || getBaseCve20Url() != null || getModifiedCve12Url() != null || getModifiedCve20Url() != null)
      +  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  2
                   if (line.hasOption((ARGUMENT.SYM_LINK_DEPTH))) {
      +  132  1
                   if (line.hasOption((ARGUMENT.SYM_LINK_DEPTH))) {
       133  
                       try {
       134  0
                           final int i = Integer.parseInt(line.getOptionValue(ARGUMENT.SYM_LINK_DEPTH));
      @@ -258,7 +258,7 @@
                   }
       142  
               }
      -  143  12
           }
      +  143  6
           }
       144  
       
       145   @@ -283,11 +283,11 @@
            */
       155  
           private void validatePathExists(String[] paths, String optType) throws FileNotFoundException {
      -  156  6
               for (String path : paths) {
      -  157  4
                   validatePathExists(path, optType);
      +  156  3
               for (String path : paths) {
      +  157  2
                   validatePathExists(path, optType);
       158  
               }
      -  159  2
           }
      +  159  1
           }
       160  
       
       161   @@ -312,15 +312,15 @@
            */
       171  
           private void validatePathExists(String path, String argumentName) throws FileNotFoundException {
      -  172  6
               if (path == null) {
      +  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  6
               } else if (!path.contains("*") && !path.contains("?")) {
      -  177  6
                   File f = new File(path);
      -  178  6
                   if ("o".equalsIgnoreCase(argumentName.substring(0, 1)) && !"ALL".equalsIgnoreCase(this.getReportFormat())) {
      -  179  2
                       final String checkPath = path.toLowerCase();
      -  180  2
                       if (checkPath.endsWith(".html") || checkPath.endsWith(".xml") || checkPath.endsWith(".htm")) {
      +  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   @@ -333,19 +333,19 @@
                           }
       189  
                       }
      -  190  2
                   } else if (!f.exists()) {
      -  191  2
                       isValid = false;
      -  192  2
                       final String msg = String.format("Invalid '%s' argument: '%s'", argumentName, path);
      -  193  2
                       throw new FileNotFoundException(msg);
      +  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  4
               } else if (path.startsWith("//") || path.startsWith("\\\\")) {
      +  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  
               }
      -  200  4
           }
      +  200  2
           }
       201  
       
       202   @@ -364,11 +364,11 @@
           @SuppressWarnings("static-access")
       209  
           private Options createCommandLineOptions() {
      -  210  18
               final Options options = new Options();
      -  211  18
               addStandardOptions(options);
      -  212  18
               addAdvancedOptions(options);
      -  213  18
               addDeprecatedOptions(options);
      -  214  18
               return options;
      +  210  9
               final Options options = new Options();
      +  211  9
               addStandardOptions(options);
      +  212  9
               addAdvancedOptions(options);
      +  213  9
               addDeprecatedOptions(options);
      +  214  9
               return options;
       215  
           }
       216   @@ -389,112 +389,112 @@
           @SuppressWarnings("static-access")
       224  
           private void addStandardOptions(final Options options) throws IllegalArgumentException {
      -  225  22
               final Option help = new Option(ARGUMENT.HELP_SHORT, ARGUMENT.HELP, false,
      +  225  11
               final Option help = new Option(ARGUMENT.HELP_SHORT, ARGUMENT.HELP, false,
       226  
                       "Print this message.");
       227  
       
      -  228  22
               final Option advancedHelp = Option.builder().longOpt(ARGUMENT.ADVANCED_HELP)
      -  229  22
                       .desc("Print the advanced help message.").build();
      +  228  11
               final Option advancedHelp = Option.builder().longOpt(ARGUMENT.ADVANCED_HELP)
      +  229  11
                       .desc("Print the advanced help message.").build();
       230  
       
      -  231  22
               final Option version = new Option(ARGUMENT.VERSION_SHORT, ARGUMENT.VERSION,
      +  231  11
               final Option version = new Option(ARGUMENT.VERSION_SHORT, ARGUMENT.VERSION,
       232  
                       false, "Print the version information.");
       233  
       
      -  234  22
               final Option noUpdate = new Option(ARGUMENT.DISABLE_AUTO_UPDATE_SHORT, ARGUMENT.DISABLE_AUTO_UPDATE,
      +  234  11
               final Option noUpdate = new Option(ARGUMENT.DISABLE_AUTO_UPDATE_SHORT, ARGUMENT.DISABLE_AUTO_UPDATE,
       235  
                       false, "Disables the automatic updating of the CPE data.");
       236  
       
      -  237  22
               final Option projectName = Option.builder().hasArg().argName("name").longOpt(ARGUMENT.PROJECT)
      -  238  22
                       .desc("The name of the project being scanned. This is a required argument.")
      -  239  22
                       .build();
      +  237  11
               final Option projectName = Option.builder().hasArg().argName("name").longOpt(ARGUMENT.PROJECT)
      +  238  11
                       .desc("The name of the project being scanned. This is a required argument.")
      +  239  11
                       .build();
       240  
       
      -  241  22
               final Option path = Option.builder(ARGUMENT.SCAN_SHORT).argName("path").hasArg().longOpt(ARGUMENT.SCAN)
      -  242  22
                       .desc("The path to scan - this option can be specified multiple times. Ant style"
      +  241  11
               final Option path = Option.builder(ARGUMENT.SCAN_SHORT).argName("path").hasArg().longOpt(ARGUMENT.SCAN)
      +  242  11
                       .desc("The path to scan - this option can be specified multiple times. Ant style"
       243  
                               + " paths are supported (e.g. path/**/*.jar).")
      -  244  22
                       .build();
      +  244  11
                       .build();
       245  
       
      -  246  22
               final Option excludes = Option.builder().argName("pattern").hasArg().longOpt(ARGUMENT.EXCLUDE)
      -  247  22
                       .desc("Specify and exclusion pattern. This option can be specified multiple times"
      +  246  11
               final Option excludes = Option.builder().argName("pattern").hasArg().longOpt(ARGUMENT.EXCLUDE)
      +  247  11
                       .desc("Specify and exclusion pattern. This option can be specified multiple times"
       248  
                               + " and it accepts Ant style excludsions.")
      -  249  22
                       .build();
      +  249  11
                       .build();
       250  
       
      -  251  22
               final Option props = Option.builder(ARGUMENT.PROP_SHORT).argName("file").hasArg().longOpt(ARGUMENT.PROP)
      -  252  22
                       .desc("A property file to load.")
      -  253  22
                       .build();
      +  251  11
               final Option props = Option.builder(ARGUMENT.PROP_SHORT).argName("file").hasArg().longOpt(ARGUMENT.PROP)
      +  252  11
                       .desc("A property file to load.")
      +  253  11
                       .build();
       254  
       
      -  255  22
               final Option out = Option.builder(ARGUMENT.OUT_SHORT).argName("path").hasArg().longOpt(ARGUMENT.OUT)
      -  256  22
                       .desc("The folder to write reports to. This defaults to the current directory. "
      +  255  11
               final Option out = Option.builder(ARGUMENT.OUT_SHORT).argName("path").hasArg().longOpt(ARGUMENT.OUT)
      +  256  11
                       .desc("The folder to write reports to. This defaults to the current directory. "
       257  
                               + "It is possible to set this to a specific file name if the format argument is not set to ALL.")
      -  258  22
                       .build();
      +  258  11
                       .build();
       259  
       
      -  260  22
               final Option outputFormat = Option.builder(ARGUMENT.OUTPUT_FORMAT_SHORT).argName("format").hasArg().longOpt(ARGUMENT.OUTPUT_FORMAT)
      -  261  22
                       .desc("The output format to write to (XML, HTML, VULN, ALL). The default is HTML.")
      -  262  22
                       .build();
      +  260  11
               final Option outputFormat = Option.builder(ARGUMENT.OUTPUT_FORMAT_SHORT).argName("format").hasArg().longOpt(ARGUMENT.OUTPUT_FORMAT)
      +  261  11
                       .desc("The output format to write to (XML, HTML, VULN, ALL). The default is HTML.")
      +  262  11
                       .build();
       263  
       
      -  264  22
               final Option verboseLog = Option.builder(ARGUMENT.VERBOSE_LOG_SHORT).argName("file").hasArg().longOpt(ARGUMENT.VERBOSE_LOG)
      -  265  22
                       .desc("The file path to write verbose logging information.")
      -  266  22
                       .build();
      +  264  11
               final Option verboseLog = Option.builder(ARGUMENT.VERBOSE_LOG_SHORT).argName("file").hasArg().longOpt(ARGUMENT.VERBOSE_LOG)
      +  265  11
                       .desc("The file path to write verbose logging information.")
      +  266  11
                       .build();
       267  
       
      -  268  22
               final Option symLinkDepth = Option.builder().argName("depth").hasArg().longOpt(ARGUMENT.SYM_LINK_DEPTH)
      -  269  22
                       .desc("Sets how deep nested symbolic links will be followed; 0 indicates symbolic links will not be followed.")
      -  270  22
                       .build();
      +  268  11
               final Option symLinkDepth = Option.builder().argName("depth").hasArg().longOpt(ARGUMENT.SYM_LINK_DEPTH)
      +  269  11
                       .desc("Sets how deep nested symbolic links will be followed; 0 indicates symbolic links will not be followed.")
      +  270  11
                       .build();
       271  
       
      -  272  22
               final Option suppressionFile = Option.builder().argName("file").hasArg().longOpt(ARGUMENT.SUPPRESSION_FILE)
      -  273  22
                       .desc("The file path to the suppression XML file.")
      -  274  22
                       .build();
      +  272  11
               final Option suppressionFile = Option.builder().argName("file").hasArg().longOpt(ARGUMENT.SUPPRESSION_FILE)
      +  273  11
                       .desc("The file path to the suppression XML file.")
      +  274  11
                       .build();
       275  
       
      -  276  22
               final Option cveValidForHours = Option.builder().argName("hours").hasArg().longOpt(ARGUMENT.CVE_VALID_FOR_HOURS)
      -  277  22
                       .desc("The number of hours to wait before checking for new updates from the NVD.")
      -  278  22
                       .build();
      +  276  11
               final Option cveValidForHours = Option.builder().argName("hours").hasArg().longOpt(ARGUMENT.CVE_VALID_FOR_HOURS)
      +  277  11
                       .desc("The number of hours to wait before checking for new updates from the NVD.")
      +  278  11
                       .build();
       279  
       
      -  280  22
               final Option experimentalEnabled = Option.builder().longOpt(ARGUMENT.EXPERIMENTAL)
      -  281  22
                       .desc("Enables the experimental analzers.")
      -  282  22
                       .build();
      +  280  11
               final Option experimentalEnabled = Option.builder().longOpt(ARGUMENT.EXPERIMENTAL)
      +  281  11
                       .desc("Enables the experimental analzers.")
      +  282  11
                       .build();
       283  
       
       284  
               //This is an option group because it can be specified more then once.
      -  285  22
               final OptionGroup og = new OptionGroup();
      -  286  22
               og.addOption(path);
      +  285  11
               final OptionGroup og = new OptionGroup();
      +  286  11
               og.addOption(path);
       287  
       
      -  288  22
               final OptionGroup exog = new OptionGroup();
      -  289  22
               exog.addOption(excludes);
      +  288  11
               final OptionGroup exog = new OptionGroup();
      +  289  11
               exog.addOption(excludes);
       290  
       
      -  291  22
               options.addOptionGroup(og)
      -  292  22
                       .addOptionGroup(exog)
      -  293  22
                       .addOption(projectName)
      -  294  22
                       .addOption(out)
      -  295  22
                       .addOption(outputFormat)
      -  296  22
                       .addOption(version)
      -  297  22
                       .addOption(help)
      -  298  22
                       .addOption(advancedHelp)
      -  299  22
                       .addOption(noUpdate)
      -  300  22
                       .addOption(symLinkDepth)
      -  301  22
                       .addOption(props)
      -  302  22
                       .addOption(verboseLog)
      -  303  22
                       .addOption(suppressionFile)
      -  304  22
                       .addOption(cveValidForHours)
      -  305  22
                       .addOption(experimentalEnabled);
      -  306  22
           }
      +  291  11
               options.addOptionGroup(og)
      +  292  11
                       .addOptionGroup(exog)
      +  293  11
                       .addOption(projectName)
      +  294  11
                       .addOption(out)
      +  295  11
                       .addOption(outputFormat)
      +  296  11
                       .addOption(version)
      +  297  11
                       .addOption(help)
      +  298  11
                       .addOption(advancedHelp)
      +  299  11
                       .addOption(noUpdate)
      +  300  11
                       .addOption(symLinkDepth)
      +  301  11
                       .addOption(props)
      +  302  11
                       .addOption(verboseLog)
      +  303  11
                       .addOption(suppressionFile)
      +  304  11
                       .addOption(cveValidForHours)
      +  305  11
                       .addOption(experimentalEnabled);
      +  306  11
           }
       307  
       
       308   @@ -519,198 +519,198 @@
           private void addAdvancedOptions(final Options options) throws IllegalArgumentException {
       318  
       
      -  319  18
               final Option cve12Base = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.CVE_BASE_12)
      -  320  18
                       .desc("Base URL for each year’s CVE 1.2, the %d will be replaced with the year. ")
      -  321  18
                       .build();
      +  319  9
               final Option cve12Base = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.CVE_BASE_12)
      +  320  9
                       .desc("Base URL for each year’s CVE 1.2, the %d will be replaced with the year. ")
      +  321  9
                       .build();
       322  
       
      -  323  18
               final Option cve20Base = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.CVE_BASE_20)
      -  324  18
                       .desc("Base URL for each year’s CVE 2.0, the %d will be replaced with the year.")
      -  325  18
                       .build();
      +  323  9
               final Option cve20Base = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.CVE_BASE_20)
      +  324  9
                       .desc("Base URL for each year’s CVE 2.0, the %d will be replaced with the year.")
      +  325  9
                       .build();
       326  
       
      -  327  18
               final Option cve12Modified = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.CVE_MOD_12)
      -  328  18
                       .desc("URL for the modified CVE 1.2.")
      -  329  18
                       .build();
      +  327  9
               final Option cve12Modified = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.CVE_MOD_12)
      +  328  9
                       .desc("URL for the modified CVE 1.2.")
      +  329  9
                       .build();
       330  
       
      -  331  18
               final Option cve20Modified = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.CVE_MOD_20)
      -  332  18
                       .desc("URL for the modified CVE 2.0.")
      -  333  18
                       .build();
      +  331  9
               final Option cve20Modified = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.CVE_MOD_20)
      +  332  9
                       .desc("URL for the modified CVE 2.0.")
      +  333  9
                       .build();
       334  
       
      -  335  18
               final Option updateOnly = Option.builder().longOpt(ARGUMENT.UPDATE_ONLY)
      -  336  18
                       .desc("Only update the local NVD data cache; no scan will be executed.").build();
      +  335  9
               final Option updateOnly = Option.builder().longOpt(ARGUMENT.UPDATE_ONLY)
      +  336  9
                       .desc("Only update the local NVD data cache; no scan will be executed.").build();
       337  
       
      -  338  18
               final Option data = Option.builder(ARGUMENT.DATA_DIRECTORY_SHORT).argName("path").hasArg().longOpt(ARGUMENT.DATA_DIRECTORY)
      -  339  18
                       .desc("The location of the H2 Database file. This option should generally not be set.")
      -  340  18
                       .build();
      +  338  9
               final Option data = Option.builder(ARGUMENT.DATA_DIRECTORY_SHORT).argName("path").hasArg().longOpt(ARGUMENT.DATA_DIRECTORY)
      +  339  9
                       .desc("The location of the H2 Database file. This option should generally not be set.")
      +  340  9
                       .build();
       341  
       
      -  342  18
               final Option nexusUrl = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.NEXUS_URL)
      -  343  18
                       .desc("The url to the Nexus Server's REST API Endpoint (http://domain/nexus/service/local). "
      -  344  18
                               + "If not set the Nexus Analyzer will be disabled.").build();
      +  342  9
               final Option nexusUrl = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.NEXUS_URL)
      +  343  9
                       .desc("The url to the Nexus Server's REST API Endpoint (http://domain/nexus/service/local). "
      +  344  9
                               + "If not set the Nexus Analyzer will be disabled.").build();
       345  
       
      -  346  18
               final Option nexusUsesProxy = Option.builder().argName("true/false").hasArg().longOpt(ARGUMENT.NEXUS_USES_PROXY)
      -  347  18
                       .desc("Whether or not the configured proxy should be used when connecting to Nexus.")
      -  348  18
                       .build();
      +  346  9
               final Option nexusUsesProxy = Option.builder().argName("true/false").hasArg().longOpt(ARGUMENT.NEXUS_USES_PROXY)
      +  347  9
                       .desc("Whether or not the configured proxy should be used when connecting to Nexus.")
      +  348  9
                       .build();
       349  
       
      -  350  18
               final Option additionalZipExtensions = Option.builder().argName("extensions").hasArg()
      -  351  18
                       .longOpt(ARGUMENT.ADDITIONAL_ZIP_EXTENSIONS)
      -  352  18
                       .desc("A comma separated list of additional extensions to be scanned as ZIP files "
      -  353  18
                               + "(ZIP, EAR, WAR are already treated as zip files)").build();
      +  350  9
               final Option additionalZipExtensions = Option.builder().argName("extensions").hasArg()
      +  351  9
                       .longOpt(ARGUMENT.ADDITIONAL_ZIP_EXTENSIONS)
      +  352  9
                       .desc("A comma separated list of additional extensions to be scanned as ZIP files "
      +  353  9
                               + "(ZIP, EAR, WAR are already treated as zip files)").build();
       354  
       
      -  355  18
               final Option pathToMono = Option.builder().argName("path").hasArg().longOpt(ARGUMENT.PATH_TO_MONO)
      -  356  18
                       .desc("The path to Mono for .NET Assembly analysis on non-windows systems.")
      -  357  18
                       .build();
      +  355  9
               final Option pathToMono = Option.builder().argName("path").hasArg().longOpt(ARGUMENT.PATH_TO_MONO)
      +  356  9
                       .desc("The path to Mono for .NET Assembly analysis on non-windows systems.")
      +  357  9
                       .build();
       358  
       
      -  359  18
               final Option pathToBundleAudit = Option.builder().argName("path").hasArg()
      -  360  18
                       .longOpt(ARGUMENT.PATH_TO_BUNDLE_AUDIT)
      -  361  18
                       .desc("The path to bundle-audit for Gem bundle analysis.").build();
      +  359  9
               final Option pathToBundleAudit = Option.builder().argName("path").hasArg()
      +  360  9
                       .longOpt(ARGUMENT.PATH_TO_BUNDLE_AUDIT)
      +  361  9
                       .desc("The path to bundle-audit for Gem bundle analysis.").build();
       362  
       
      -  363  18
               final Option connectionTimeout = Option.builder(ARGUMENT.CONNECTION_TIMEOUT_SHORT).argName("timeout").hasArg()
      -  364  18
                       .longOpt(ARGUMENT.CONNECTION_TIMEOUT).desc("The connection timeout (in milliseconds) to use when downloading resources.")
      -  365  18
                       .build();
      +  363  9
               final Option connectionTimeout = Option.builder(ARGUMENT.CONNECTION_TIMEOUT_SHORT).argName("timeout").hasArg()
      +  364  9
                       .longOpt(ARGUMENT.CONNECTION_TIMEOUT).desc("The connection timeout (in milliseconds) to use when downloading resources.")
      +  365  9
                       .build();
       366  
       
      -  367  18
               final Option proxyServer = Option.builder().argName("server").hasArg().longOpt(ARGUMENT.PROXY_SERVER)
      -  368  18
                       .desc("The proxy server to use when downloading resources.").build();
      +  367  9
               final Option proxyServer = Option.builder().argName("server").hasArg().longOpt(ARGUMENT.PROXY_SERVER)
      +  368  9
                       .desc("The proxy server to use when downloading resources.").build();
       369  
       
      -  370  18
               final Option proxyPort = Option.builder().argName("port").hasArg().longOpt(ARGUMENT.PROXY_PORT)
      -  371  18
                       .desc("The proxy port to use when downloading resources.").build();
      +  370  9
               final Option proxyPort = Option.builder().argName("port").hasArg().longOpt(ARGUMENT.PROXY_PORT)
      +  371  9
                       .desc("The proxy port to use when downloading resources.").build();
       372  
       
      -  373  18
               final Option proxyUsername = Option.builder().argName("user").hasArg().longOpt(ARGUMENT.PROXY_USERNAME)
      -  374  18
                       .desc("The proxy username to use when downloading resources.").build();
      +  373  9
               final Option proxyUsername = Option.builder().argName("user").hasArg().longOpt(ARGUMENT.PROXY_USERNAME)
      +  374  9
                       .desc("The proxy username to use when downloading resources.").build();
       375  
       
      -  376  18
               final Option proxyPassword = Option.builder().argName("pass").hasArg().longOpt(ARGUMENT.PROXY_PASSWORD)
      -  377  18
                       .desc("The proxy password to use when downloading resources.").build();
      +  376  9
               final Option proxyPassword = Option.builder().argName("pass").hasArg().longOpt(ARGUMENT.PROXY_PASSWORD)
      +  377  9
                       .desc("The proxy password to use when downloading resources.").build();
       378  
       
      -  379  18
               final Option connectionString = Option.builder().argName("connStr").hasArg().longOpt(ARGUMENT.CONNECTION_STRING)
      -  380  18
                       .desc("The connection string to the database.").build();
      +  379  9
               final Option connectionString = Option.builder().argName("connStr").hasArg().longOpt(ARGUMENT.CONNECTION_STRING)
      +  380  9
                       .desc("The connection string to the database.").build();
       381  
       
      -  382  18
               final Option dbUser = Option.builder().argName("user").hasArg().longOpt(ARGUMENT.DB_NAME)
      -  383  18
                       .desc("The username used to connect to the database.").build();
      +  382  9
               final Option dbUser = Option.builder().argName("user").hasArg().longOpt(ARGUMENT.DB_NAME)
      +  383  9
                       .desc("The username used to connect to the database.").build();
       384  
       
      -  385  18
               final Option dbPassword = Option.builder().argName("password").hasArg().longOpt(ARGUMENT.DB_PASSWORD)
      -  386  18
                       .desc("The password for connecting to the database.").build();
      +  385  9
               final Option dbPassword = Option.builder().argName("password").hasArg().longOpt(ARGUMENT.DB_PASSWORD)
      +  386  9
                       .desc("The password for connecting to the database.").build();
       387  
       
      -  388  18
               final Option dbDriver = Option.builder().argName("driver").hasArg().longOpt(ARGUMENT.DB_DRIVER)
      -  389  18
                       .desc("The database driver name.").build();
      +  388  9
               final Option dbDriver = Option.builder().argName("driver").hasArg().longOpt(ARGUMENT.DB_DRIVER)
      +  389  9
                       .desc("The database driver name.").build();
       390  
       
      -  391  18
               final Option dbDriverPath = Option.builder().argName("path").hasArg().longOpt(ARGUMENT.DB_DRIVER_PATH)
      -  392  18
                       .desc("The path to the database driver; note, this does not need to be set unless the JAR is outside of the classpath.")
      -  393  18
                       .build();
      +  391  9
               final Option dbDriverPath = Option.builder().argName("path").hasArg().longOpt(ARGUMENT.DB_DRIVER_PATH)
      +  392  9
                       .desc("The path to the database driver; note, this does not need to be set unless the JAR is outside of the classpath.")
      +  393  9
                       .build();
       394  
       
      -  395  18
               final Option disableJarAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_JAR)
      -  396  18
                       .desc("Disable the Jar Analyzer.").build();
      +  395  9
               final Option disableJarAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_JAR)
      +  396  9
                       .desc("Disable the Jar Analyzer.").build();
       397  
       
      -  398  18
               final Option disableArchiveAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_ARCHIVE)
      -  399  18
                       .desc("Disable the Archive Analyzer.").build();
      +  398  9
               final Option disableArchiveAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_ARCHIVE)
      +  399  9
                       .desc("Disable the Archive Analyzer.").build();
       400  
       
      -  401  18
               final Option disableNuspecAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_NUSPEC)
      -  402  18
                       .desc("Disable the Nuspec Analyzer.").build();
      +  401  9
               final Option disableNuspecAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_NUSPEC)
      +  402  9
                       .desc("Disable the Nuspec Analyzer.").build();
       403  
       
      -  404  18
               final Option disableAssemblyAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_ASSEMBLY)
      -  405  18
                       .desc("Disable the .NET Assembly Analyzer.").build();
      +  404  9
               final Option disableAssemblyAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_ASSEMBLY)
      +  405  9
                       .desc("Disable the .NET Assembly Analyzer.").build();
       406  
       
      -  407  18
               final Option disablePythonDistributionAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_PY_DIST)
      -  408  18
                       .desc("Disable the Python Distribution Analyzer.").build();
      +  407  9
               final Option disablePythonDistributionAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_PY_DIST)
      +  408  9
                       .desc("Disable the Python Distribution Analyzer.").build();
       409  
       
      -  410  18
               final Option disablePythonPackageAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_PY_PKG)
      -  411  18
                       .desc("Disable the Python Package Analyzer.").build();
      +  410  9
               final Option disablePythonPackageAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_PY_PKG)
      +  411  9
                       .desc("Disable the Python Package Analyzer.").build();
       412  
       
      -  413  18
               final Option disableComposerAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_COMPOSER)
      -  414  18
                       .desc("Disable the PHP Composer Analyzer.").build();
      +  413  9
               final Option disableComposerAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_COMPOSER)
      +  414  9
                       .desc("Disable the PHP Composer Analyzer.").build();
       415  
       
      -  416  18
               final Option disableAutoconfAnalyzer = Option.builder()
      -  417  18
                       .longOpt(ARGUMENT.DISABLE_AUTOCONF)
      -  418  18
                       .desc("Disable the Autoconf Analyzer.").build();
      +  416  9
               final Option disableAutoconfAnalyzer = Option.builder()
      +  417  9
                       .longOpt(ARGUMENT.DISABLE_AUTOCONF)
      +  418  9
                       .desc("Disable the Autoconf Analyzer.").build();
       419  
       
      -  420  18
               final Option disableOpenSSLAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_OPENSSL)
      -  421  18
                       .desc("Disable the OpenSSL Analyzer.").build();
      -  422  18
               final Option disableCmakeAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_CMAKE)
      -  423  18
                       .desc("Disable the Cmake Analyzer.").build();
      +  420  9
               final Option disableOpenSSLAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_OPENSSL)
      +  421  9
                       .desc("Disable the OpenSSL Analyzer.").build();
      +  422  9
               final Option disableCmakeAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_CMAKE)
      +  423  9
                       .desc("Disable the Cmake Analyzer.").build();
       424  
       
      -  425  18
               final Option disableCentralAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_CENTRAL)
      -  426  18
                       .desc("Disable the Central Analyzer. If this analyzer is disabled it is likely you also want to disable "
      -  427  18
                               + "the Nexus Analyzer.").build();
      +  425  9
               final Option disableCentralAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_CENTRAL)
      +  426  9
                       .desc("Disable the Central Analyzer. If this analyzer is disabled it is likely you also want to disable "
      +  427  9
                               + "the Nexus Analyzer.").build();
       428  
       
      -  429  18
               final Option disableNexusAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_NEXUS)
      -  430  18
                       .desc("Disable the Nexus Analyzer.").build();
      +  429  9
               final Option disableNexusAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_NEXUS)
      +  430  9
                       .desc("Disable the Nexus Analyzer.").build();
       431  
       
      -  432  18
               final Option purge = Option.builder().longOpt(ARGUMENT.PURGE_NVD)
      -  433  18
                       .desc("Purges the local NVD data cache")
      -  434  18
                       .build();
      +  432  9
               final Option purge = Option.builder().longOpt(ARGUMENT.PURGE_NVD)
      +  433  9
                       .desc("Purges the local NVD data cache")
      +  434  9
                       .build();
       435  
       
      -  436  18
               options.addOption(updateOnly)
      -  437  18
                       .addOption(cve12Base)
      -  438  18
                       .addOption(cve20Base)
      -  439  18
                       .addOption(cve12Modified)
      -  440  18
                       .addOption(cve20Modified)
      -  441  18
                       .addOption(proxyPort)
      -  442  18
                       .addOption(proxyServer)
      -  443  18
                       .addOption(proxyUsername)
      -  444  18
                       .addOption(proxyPassword)
      -  445  18
                       .addOption(connectionTimeout)
      -  446  18
                       .addOption(connectionString)
      -  447  18
                       .addOption(dbUser)
      -  448  18
                       .addOption(data)
      -  449  18
                       .addOption(dbPassword)
      -  450  18
                       .addOption(dbDriver)
      -  451  18
                       .addOption(dbDriverPath)
      -  452  18
                       .addOption(disableJarAnalyzer)
      -  453  18
                       .addOption(disableArchiveAnalyzer)
      -  454  18
                       .addOption(disableAssemblyAnalyzer)
      -  455  18
                       .addOption(pathToBundleAudit)
      -  456  18
                       .addOption(disablePythonDistributionAnalyzer)
      -  457  18
                       .addOption(disableCmakeAnalyzer)
      -  458  18
                       .addOption(disablePythonPackageAnalyzer)
      -  459  36
                       .addOption(Option.builder().longOpt(ARGUMENT.DISABLE_RUBYGEMS)
      -  460  18
                               .desc("Disable the Ruby Gemspec Analyzer.").build())
      -  461  36
                       .addOption(Option.builder().longOpt(ARGUMENT.DISABLE_BUNDLE_AUDIT)
      -  462  18
                               .desc("Disable the Ruby Bundler-Audit Analyzer.").build())
      -  463  18
                       .addOption(disableAutoconfAnalyzer)
      -  464  18
                       .addOption(disableComposerAnalyzer)
      -  465  18
                       .addOption(disableOpenSSLAnalyzer)
      -  466  18
                       .addOption(disableNuspecAnalyzer)
      -  467  18
                       .addOption(disableCentralAnalyzer)
      -  468  18
                       .addOption(disableNexusAnalyzer)
      -  469  36
                       .addOption(Option.builder().longOpt(ARGUMENT.DISABLE_NODE_JS)
      -  470  18
                               .desc("Disable the Node.js Package Analyzer.").build())
      -  471  18
                       .addOption(nexusUrl)
      -  472  18
                       .addOption(nexusUsesProxy)
      -  473  18
                       .addOption(additionalZipExtensions)
      -  474  18
                       .addOption(pathToMono)
      -  475  18
                       .addOption(pathToBundleAudit)
      -  476  18
                       .addOption(purge);
      -  477  18
           }
      +  436  9
               options.addOption(updateOnly)
      +  437  9
                       .addOption(cve12Base)
      +  438  9
                       .addOption(cve20Base)
      +  439  9
                       .addOption(cve12Modified)
      +  440  9
                       .addOption(cve20Modified)
      +  441  9
                       .addOption(proxyPort)
      +  442  9
                       .addOption(proxyServer)
      +  443  9
                       .addOption(proxyUsername)
      +  444  9
                       .addOption(proxyPassword)
      +  445  9
                       .addOption(connectionTimeout)
      +  446  9
                       .addOption(connectionString)
      +  447  9
                       .addOption(dbUser)
      +  448  9
                       .addOption(data)
      +  449  9
                       .addOption(dbPassword)
      +  450  9
                       .addOption(dbDriver)
      +  451  9
                       .addOption(dbDriverPath)
      +  452  9
                       .addOption(disableJarAnalyzer)
      +  453  9
                       .addOption(disableArchiveAnalyzer)
      +  454  9
                       .addOption(disableAssemblyAnalyzer)
      +  455  9
                       .addOption(pathToBundleAudit)
      +  456  9
                       .addOption(disablePythonDistributionAnalyzer)
      +  457  9
                       .addOption(disableCmakeAnalyzer)
      +  458  9
                       .addOption(disablePythonPackageAnalyzer)
      +  459  18
                       .addOption(Option.builder().longOpt(ARGUMENT.DISABLE_RUBYGEMS)
      +  460  9
                               .desc("Disable the Ruby Gemspec Analyzer.").build())
      +  461  18
                       .addOption(Option.builder().longOpt(ARGUMENT.DISABLE_BUNDLE_AUDIT)
      +  462  9
                               .desc("Disable the Ruby Bundler-Audit Analyzer.").build())
      +  463  9
                       .addOption(disableAutoconfAnalyzer)
      +  464  9
                       .addOption(disableComposerAnalyzer)
      +  465  9
                       .addOption(disableOpenSSLAnalyzer)
      +  466  9
                       .addOption(disableNuspecAnalyzer)
      +  467  9
                       .addOption(disableCentralAnalyzer)
      +  468  9
                       .addOption(disableNexusAnalyzer)
      +  469  18
                       .addOption(Option.builder().longOpt(ARGUMENT.DISABLE_NODE_JS)
      +  470  9
                               .desc("Disable the Node.js Package Analyzer.").build())
      +  471  9
                       .addOption(nexusUrl)
      +  472  9
                       .addOption(nexusUsesProxy)
      +  473  9
                       .addOption(additionalZipExtensions)
      +  474  9
                       .addOption(pathToMono)
      +  475  9
                       .addOption(pathToBundleAudit)
      +  476  9
                       .addOption(purge);
      +  477  9
           }
       478  
       
       479   @@ -737,17 +737,17 @@
           private void addDeprecatedOptions(final Options options) throws IllegalArgumentException {
       490  
       
      -  491  18
               final Option proxyServer = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.PROXY_URL)
      -  492  18
                       .desc("The proxy url argument is deprecated, use proxyserver instead.")
      -  493  18
                       .build();
      -  494  18
               final Option appName = Option.builder(ARGUMENT.APP_NAME_SHORT).argName("name").hasArg().longOpt(ARGUMENT.APP_NAME)
      -  495  18
                       .desc("The name of the project being scanned.")
      -  496  18
                       .build();
      +  491  9
               final Option proxyServer = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.PROXY_URL)
      +  492  9
                       .desc("The proxy url argument is deprecated, use proxyserver instead.")
      +  493  9
                       .build();
      +  494  9
               final Option appName = Option.builder(ARGUMENT.APP_NAME_SHORT).argName("name").hasArg().longOpt(ARGUMENT.APP_NAME)
      +  495  9
                       .desc("The name of the project being scanned.")
      +  496  9
                       .build();
       497  
       
      -  498  18
               options.addOption(proxyServer);
      -  499  18
               options.addOption(appName);
      -  500  18
           }
      +  498  9
               options.addOption(proxyServer);
      +  499  9
               options.addOption(appName);
      +  500  9
           }
       501  
       
       502   @@ -762,7 +762,7 @@
            */
       507  
           public boolean isGetVersion() {
      -  508  14
               return (line != null) && line.hasOption(ARGUMENT.VERSION);
      +  508  7
               return (line != null) && line.hasOption(ARGUMENT.VERSION);
       509  
           }
       510   @@ -779,7 +779,7 @@
            */
       516  
           public boolean isGetHelp() {
      -  517  14
               return (line != null) && line.hasOption(ARGUMENT.HELP);
      +  517  7
               return (line != null) && line.hasOption(ARGUMENT.HELP);
       518  
           }
       519   @@ -796,7 +796,7 @@
            */
       525  
           public boolean isRunScan() {
      -  526  42
               return (line != null) && isValid && line.hasOption(ARGUMENT.SCAN);
      +  526  21
               return (line != null) && isValid && line.hasOption(ARGUMENT.SCAN);
       527  
           }
       528   @@ -1188,23 +1188,23 @@
            */
       737  
           public void printHelp() {
      -  738  4
               final HelpFormatter formatter = new HelpFormatter();
      -  739  4
               final Options options = new Options();
      -  740  4
               addStandardOptions(options);
      -  741  4
               if (line != null && line.hasOption(ARGUMENT.ADVANCED_HELP)) {
      +  738  2
               final HelpFormatter formatter = new HelpFormatter();
      +  739  2
               final Options options = new Options();
      +  740  2
               addStandardOptions(options);
      +  741  2
               if (line != null && line.hasOption(ARGUMENT.ADVANCED_HELP)) {
       742  0
                   addAdvancedOptions(options);
       743  
               }
      -  744  8
               final String helpMsg = String.format("%n%s"
      +  744  4
               final String helpMsg = String.format("%n%s"
       745  
                       + " can be used to identify if there are any known CVE vulnerabilities in libraries utilized by an application. "
       746  
                       + "%s will automatically update required data from the Internet, such as the CVE and CPE data files from nvd.nist.gov.%n%n",
      -  747  4
                       Settings.getString("application.name", "DependencyCheck"),
      -  748  4
                       Settings.getString("application.name", "DependencyCheck"));
      +  747  2
                       Settings.getString("application.name", "DependencyCheck"),
      +  748  2
                       Settings.getString("application.name", "DependencyCheck"));
       749  
       
      -  750  4
               formatter.printHelp(Settings.getString("application.name", "DependencyCheck"),
      +  750  2
               formatter.printHelp(Settings.getString("application.name", "DependencyCheck"),
       751  
                       helpMsg,
       752   @@ -1213,7 +1213,7 @@
                       "",
       754  
                       true);
      -  755  4
           }
      +  755  2
           }
       756  
       
       757   @@ -1230,7 +1230,7 @@
            */
       763  
           public String[] getScanFiles() {
      -  764  6
               return line.getOptionValues(ARGUMENT.SCAN);
      +  764  3
               return line.getOptionValues(ARGUMENT.SCAN);
       765  
           }
       766   @@ -1268,7 +1268,7 @@
            */
       783  
           public String getReportDirectory() {
      -  784  2
               return line.getOptionValue(ARGUMENT.OUT, ".");
      +  784  1
               return line.getOptionValue(ARGUMENT.OUT, ".");
       785  
           }
       786   @@ -1287,7 +1287,7 @@
            */
       793  
           public String getPathToMono() {
      -  794  2
               return line.getOptionValue(ARGUMENT.PATH_TO_MONO);
      +  794  1
               return line.getOptionValue(ARGUMENT.PATH_TO_MONO);
       795  
           }
       796   @@ -1323,7 +1323,7 @@
            */
       812  
           public String getReportFormat() {
      -  813  2
               return line.getOptionValue(ARGUMENT.OUTPUT_FORMAT, "HTML");
      +  813  1
               return line.getOptionValue(ARGUMENT.OUTPUT_FORMAT, "HTML");
       814  
           }
       815   @@ -1364,7 +1364,7 @@
            */
       836  
           public String getBaseCve12Url() {
      -  837  2
               return line.getOptionValue(ARGUMENT.CVE_BASE_12);
      +  837  1
               return line.getOptionValue(ARGUMENT.CVE_BASE_12);
       838  
           }
       839   @@ -1381,7 +1381,7 @@
            */
       845  
           public String getBaseCve20Url() {
      -  846  2
               return line.getOptionValue(ARGUMENT.CVE_BASE_20);
      +  846  1
               return line.getOptionValue(ARGUMENT.CVE_BASE_20);
       847  
           }
       848   @@ -1398,7 +1398,7 @@
            */
       854  
           public String getModifiedCve12Url() {
      -  855  2
               return line.getOptionValue(ARGUMENT.CVE_MOD_12);
      +  855  1
               return line.getOptionValue(ARGUMENT.CVE_MOD_12);
       856  
           }
       857   @@ -1415,7 +1415,7 @@
            */
       863  
           public String getModifiedCve20Url() {
      -  864  2
               return line.getOptionValue(ARGUMENT.CVE_MOD_20);
      +  864  1
               return line.getOptionValue(ARGUMENT.CVE_MOD_20);
       865  
           }
       866   @@ -1605,11 +1605,11 @@
            */
       967  
           public void printVersionInfo() {
      -  968  4
               final String version = String.format("%s version %s",
      -  969  2
                       Settings.getString(Settings.KEYS.APPLICATION_VAME, "dependency-check"),
      -  970  2
                       Settings.getString(Settings.KEYS.APPLICATION_VERSION, "Unknown"));
      -  971  2
               System.out.println(version);
      -  972  2
           }
      +  968  2
               final String version = String.format("%s version %s",
      +  969  1
                       Settings.getString(Settings.KEYS.APPLICATION_VAME, "dependency-check"),
      +  970  1
                       Settings.getString(Settings.KEYS.APPLICATION_VERSION, "Unknown"));
      +  971  1
               System.out.println(version);
      +  972  1
           }
       973  
       
       974   @@ -1647,7 +1647,7 @@
            */
       991  
           public boolean isUpdateOnly() {
      -  992  14
               return line != null && line.hasOption(ARGUMENT.UPDATE_ONLY);
      +  992  7
               return line != null && line.hasOption(ARGUMENT.UPDATE_ONLY);
       993  
           }
       994   @@ -2431,6 +2431,6 @@
       }
      - + diff --git a/dependency-check-cli/cobertura/org.owasp.dependencycheck.InvalidScanPathException.html b/dependency-check-cli/cobertura/org.owasp.dependencycheck.InvalidScanPathException.html index 055f5d9b7..377cc9ad4 100644 --- a/dependency-check-cli/cobertura/org.owasp.dependencycheck.InvalidScanPathException.html +++ b/dependency-check-cli/cobertura/org.owasp.dependencycheck.InvalidScanPathException.html @@ -143,6 +143,6 @@
       }
      - + diff --git a/dependency-check-cli/dependency-analysis.html b/dependency-check-cli/dependency-analysis.html index f54078dd6..ccde04a4d 100644 --- a/dependency-check-cli/dependency-analysis.html +++ b/dependency-check-cli/dependency-analysis.html @@ -1,13 +1,13 @@ - + dependency-check-cli – Dependencies Report @@ -52,7 +52,7 @@ @@ -254,7 +254,7 @@ org.owasp dependency-check-core -1.4.0 +1.4.2 compile jar @@ -262,7 +262,7 @@ org.owasp dependency-check-utils -1.4.0 +1.4.2 compile jar diff --git a/dependency-check-cli/dependency-updates-report.html b/dependency-check-cli/dependency-updates-report.html index 20642290d..b7c7f82fe 100644 --- a/dependency-check-cli/dependency-updates-report.html +++ b/dependency-check-cli/dependency-updates-report.html @@ -1,13 +1,13 @@ - + dependency-check-cli – Dependency Updates Report @@ -52,7 +52,7 @@ @@ -237,7 +237,7 @@ # of dependencies using the latest version available -24 +25 # of dependencies where the next version available is smaller than an incremental version update @@ -245,7 +245,7 @@ # of dependencies where the next version available is an incremental version update -1 +0 # of dependencies where the next version available is a minor version update @@ -405,7 +405,7 @@ org.apache.commons commons-compress -1.11 +1.12 jar @@ -585,24 +585,24 @@ org.jmockit jmockit -1.22 +1.24 test jar -1.23 +1.25 - + org.jsoup jsoup -1.9.1 +1.9.2 jar -1.9.2 + @@ -672,7 +672,7 @@ org.owasp dependency-check-core -1.4.0 +1.4.2 compile jar @@ -684,7 +684,7 @@ org.owasp dependency-check-utils -1.4.0 +1.4.2 compile jar @@ -991,7 +991,7 @@ commons-compress Current Version -1.11 +1.12 Scope @@ -1054,7 +1054,7 @@ jar Newer versions -4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      6.0.0
      6.0.1 Latest Major +4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      5.5.2
      6.0.0
      6.0.1
      6.1.0 Latest Major

      org.apache.lucene:lucene-core

      @@ -1081,7 +1081,7 @@ -
      jar
      Newer versions4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      6.0.0
      6.0.1 Latest Major
      +4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      5.5.2
      6.0.0
      6.0.1
      6.1.0 Latest Major

      org.apache.lucene:lucene-queryparser

      @@ -1108,7 +1108,7 @@ -
      jar
      Newer versions4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      6.0.0
      6.0.1 Latest Major
      +4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      5.5.2
      6.0.0
      6.0.1
      6.1.0 Latest Major

      org.apache.lucene:lucene-test-framework

      @@ -1135,7 +1135,7 @@ -
      jar
      Newer versions4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      6.0.0
      6.0.1 Latest Major
      +4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      5.5.2
      6.0.0
      6.0.1
      6.1.0 Latest Major

      org.apache.maven:maven-core

      @@ -1366,7 +1366,7 @@ - + @@ -1378,13 +1378,13 @@ -
      jmockit
      Current Version1.22
      1.24
      Scope test
      jar
      Newer versions1.23 Next Minor
      1.24 Latest Minor
      +1.25 Next Minor

      org.jsoup:jsoup

      - + @@ -1393,7 +1393,7 @@ - + @@ -1402,10 +1402,7 @@ - - - -
      Status There is at least one newer incremental version available. Incremental updates are typically passive.
       No newer versions available.
      Group Id org.jsoup
      jsoup
      Current Version1.9.1
      1.9.2
      Scope
      Typejar
      Newer versions1.9.2 Next Incremental
      +jar

      org.owasp:dependency-check-core

      @@ -1420,7 +1417,7 @@ - + @@ -1444,7 +1441,7 @@ - + diff --git a/dependency-check-cli/findbugs.html b/dependency-check-cli/findbugs.html index c2380889f..510e324b9 100644 --- a/dependency-check-cli/findbugs.html +++ b/dependency-check-cli/findbugs.html @@ -1,13 +1,13 @@ - + dependency-check-cli – FindBugs Bug Detector Report @@ -52,7 +52,7 @@ diff --git a/dependency-check-cli/index.html b/dependency-check-cli/index.html index c095bd697..b20d3ce7d 100644 --- a/dependency-check-cli/index.html +++ b/dependency-check-cli/index.html @@ -1,13 +1,13 @@ - + dependency-check-cli – About @@ -52,7 +52,7 @@ @@ -147,7 +147,7 @@

      About

      OWASP dependency-check-cli is an command line tool that uses dependency-check-core to detect publicly disclosed vulnerabilities associated with the scanned project dependencies. The tool will generate a report listing the dependency, any identified Common Platform Enumeration (CPE) identifiers, and the associated Common Vulnerability and Exposure (CVE) entries.

      Installation & Usage

      -

      Download the dependency-check command line tool here. Extract the zip file to a location on your computer and put the ‘bin’ directory into the path environment variable. On *nix systems you will likely need to make the shell script executable:

      +

      Download the dependency-check command line tool here. Extract the zip file to a location on your computer and put the ‘bin’ directory into the path environment variable. On *nix systems you will likely need to make the shell script executable:

      $ chmod +777 dependency-check.sh
      diff --git a/dependency-check-cli/integration.html b/dependency-check-cli/integration.html
      index 053b9fc48..f0eb2ab2c 100644
      --- a/dependency-check-cli/integration.html
      +++ b/dependency-check-cli/integration.html
      @@ -1,13 +1,13 @@
       
       
       
         
           
           
      -    
      +    
           
           dependency-check-cli – CI Management
           
      @@ -52,7 +52,7 @@
               
      diff --git a/dependency-check-cli/issue-tracking.html b/dependency-check-cli/issue-tracking.html
      index e3f5076a2..5744c112e 100644
      --- a/dependency-check-cli/issue-tracking.html
      +++ b/dependency-check-cli/issue-tracking.html
      @@ -1,13 +1,13 @@
       
       
       
         
           
           
      -    
      +    
           
           dependency-check-cli – Issue Management
           
      @@ -52,7 +52,7 @@
               
      diff --git a/dependency-check-cli/license.html b/dependency-check-cli/license.html
      index ee36f8926..0a539e996 100644
      --- a/dependency-check-cli/license.html
      +++ b/dependency-check-cli/license.html
      @@ -1,13 +1,13 @@
       
       
       
         
           
           
      -    
      +    
           
           dependency-check-cli – Project Licenses
           
      @@ -52,7 +52,7 @@
               
      diff --git a/dependency-check-cli/mail-lists.html b/dependency-check-cli/mail-lists.html
      index 68da4564e..44d190e02 100644
      --- a/dependency-check-cli/mail-lists.html
      +++ b/dependency-check-cli/mail-lists.html
      @@ -1,13 +1,13 @@
       
       
       
         
           
           
      -    
      +    
           
           dependency-check-cli – Project Mailing Lists
           
      @@ -52,7 +52,7 @@
               
      diff --git a/dependency-check-cli/plugin-updates-report.html b/dependency-check-cli/plugin-updates-report.html
      index 871aed4a8..b852bab4d 100644
      --- a/dependency-check-cli/plugin-updates-report.html
      +++ b/dependency-check-cli/plugin-updates-report.html
      @@ -1,13 +1,13 @@
       
       
       
         
           
           
      -    
      +    
           
           dependency-check-cli – Plugin Updates Report
           
      @@ -52,7 +52,7 @@
               
      @@ -237,7 +237,7 @@
       
      - + @@ -253,7 +253,7 @@ - + @@ -375,7 +375,7 @@ - + @@ -385,7 +385,7 @@ - + @@ -422,14 +422,14 @@ - + - + + - @@ -641,7 +641,7 @@ -
      dependency-check-core
      Current Version1.4.0
      1.4.2
      Scope compile
      dependency-check-utils
      Current Version1.4.0
      1.4.2
      Scope compile
      # of plugins using the latest version available18
      19
      # of plugins where the next version available is smaller than an incremental version update
      # of plugins where the next version available is a major version update1
      0
      # of plugins where a dependencies section containes a dependency with an updated version org.apache.maven.plugins maven-jar-plugin3.0.03.0.2 org.apache.maven.plugins maven-javadoc-plugin2.10.32.10.4
      org.apache.maven.plugins maven-source-plugin2.43.0.1 3.0.0
      maven-jar-plugin
      Current Version3.0.0
      +3.0.2

      Plugin org.apache.maven.plugins:maven-javadoc-plugin

      @@ -656,7 +656,7 @@ -
      maven-javadoc-plugin
      Current Version2.10.3
      +2.10.4

      Plugin org.apache.maven.plugins:maven-release-plugin

      @@ -707,7 +707,7 @@
      - + @@ -716,10 +716,7 @@ - - - -
      Status There is at least one newer major version available. Major updates are rarely passive.
       No newer versions available.
      Group Id org.apache.maven.plugins
      maven-source-plugin
      Current Version2.4
      Newer versions3.0.0 Next Major
      +3.0.1

      Plugin org.apache.maven.plugins:maven-surefire-plugin

      diff --git a/dependency-check-cli/pmd.html b/dependency-check-cli/pmd.html index 966973c7a..90153773a 100644 --- a/dependency-check-cli/pmd.html +++ b/dependency-check-cli/pmd.html @@ -1,13 +1,13 @@ - + dependency-check-cli – PMD Results @@ -52,7 +52,7 @@ @@ -243,7 +243,7 @@ -
      Line
      Useless parentheses.169
      +235

      org/owasp/dependencycheck/CliParser.java

      diff --git a/dependency-check-cli/project-info.html b/dependency-check-cli/project-info.html index 54ed9c99d..a98130d78 100644 --- a/dependency-check-cli/project-info.html +++ b/dependency-check-cli/project-info.html @@ -1,13 +1,13 @@ - + dependency-check-cli – Project Information @@ -52,7 +52,7 @@ diff --git a/dependency-check-cli/project-reports.html b/dependency-check-cli/project-reports.html index 46fb80e5d..af61c73a6 100644 --- a/dependency-check-cli/project-reports.html +++ b/dependency-check-cli/project-reports.html @@ -1,13 +1,13 @@ - + dependency-check-cli – Generated Reports @@ -52,7 +52,7 @@ diff --git a/dependency-check-cli/project-summary.html b/dependency-check-cli/project-summary.html index f3beb1f65..550d35be5 100644 --- a/dependency-check-cli/project-summary.html +++ b/dependency-check-cli/project-summary.html @@ -1,13 +1,13 @@ - + dependency-check-cli – Project Summary @@ -52,7 +52,7 @@ @@ -238,7 +238,7 @@ - + diff --git a/dependency-check-cli/source-repository.html b/dependency-check-cli/source-repository.html index 4431274fc..7321eb37e 100644 --- a/dependency-check-cli/source-repository.html +++ b/dependency-check-cli/source-repository.html @@ -1,13 +1,13 @@ - + dependency-check-cli – Source Code Management @@ -52,7 +52,7 @@ diff --git a/dependency-check-cli/surefire-report.html b/dependency-check-cli/surefire-report.html index faee48224..5fbe2ccbe 100644 --- a/dependency-check-cli/surefire-report.html +++ b/dependency-check-cli/surefire-report.html @@ -1,13 +1,13 @@ - + dependency-check-cli – Surefire Report @@ -52,7 +52,7 @@ @@ -266,7 +266,7 @@ function toggleDisplay(elementId) { -
      dependency-check-cli
      Version1.4.0
      1.4.2
      Type jar
      0 0 100%0.384

      +0.497

      Note: failures are anticipated and checked for with assertions while errors are unanticipated.


      Package List

      @@ -287,7 +287,7 @@ function toggleDisplay(elementId) { 0 0 100% -0.384
      +0.497

      Note: package statistics are not computed recursively, they only sum up all of its testsuites numbers.

      org.owasp.dependencycheck

      @@ -309,7 +309,7 @@ function toggleDisplay(elementId) { 0 0 100% -0.383 +0.497 CliParserTest @@ -318,7 +318,7 @@ function toggleDisplay(elementId) { 0 0 100% -0.001

      +0

      Test Cases

      [Summary] [Package List] [Test Cases]

      @@ -328,7 +328,7 @@ function toggleDisplay(elementId) { testEnsureCanonicalPath2 -0.32 +0.428 testEnsureCanonicalPath diff --git a/dependency-check-cli/taglist.html b/dependency-check-cli/taglist.html index ae001dd8b..877490858 100644 --- a/dependency-check-cli/taglist.html +++ b/dependency-check-cli/taglist.html @@ -1,13 +1,13 @@ - + dependency-check-cli – Tag List report @@ -52,7 +52,7 @@ diff --git a/dependency-check-cli/team-list.html b/dependency-check-cli/team-list.html index be910782e..0cfebe53c 100644 --- a/dependency-check-cli/team-list.html +++ b/dependency-check-cli/team-list.html @@ -1,13 +1,13 @@ - + dependency-check-cli – Project Team @@ -52,7 +52,7 @@ diff --git a/dependency-check-cli/xref-test/index.html b/dependency-check-cli/xref-test/index.html index 314aaf90b..985be0807 100644 --- a/dependency-check-cli/xref-test/index.html +++ b/dependency-check-cli/xref-test/index.html @@ -4,7 +4,7 @@ - Dependency-Check Command Line 1.4.0 Reference + Dependency-Check Command Line 1.4.2 Reference diff --git a/dependency-check-cli/xref-test/org/owasp/dependencycheck/package-frame.html b/dependency-check-cli/xref-test/org/owasp/dependencycheck/package-frame.html index 94b087be3..0f6e05577 100644 --- a/dependency-check-cli/xref-test/org/owasp/dependencycheck/package-frame.html +++ b/dependency-check-cli/xref-test/org/owasp/dependencycheck/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Command Line 1.4.0 Reference Package org.owasp.dependencycheck + Dependency-Check Command Line 1.4.2 Reference Package org.owasp.dependencycheck diff --git a/dependency-check-cli/xref-test/org/owasp/dependencycheck/package-summary.html b/dependency-check-cli/xref-test/org/owasp/dependencycheck/package-summary.html index 9b1fe3dc1..4071821a5 100644 --- a/dependency-check-cli/xref-test/org/owasp/dependencycheck/package-summary.html +++ b/dependency-check-cli/xref-test/org/owasp/dependencycheck/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Command Line 1.4.0 Reference Package org.owasp.dependencycheck + Dependency-Check Command Line 1.4.2 Reference Package org.owasp.dependencycheck diff --git a/dependency-check-cli/xref-test/overview-frame.html b/dependency-check-cli/xref-test/overview-frame.html index 6b5043647..587d5b4bc 100644 --- a/dependency-check-cli/xref-test/overview-frame.html +++ b/dependency-check-cli/xref-test/overview-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Command Line 1.4.0 Reference + Dependency-Check Command Line 1.4.2 Reference diff --git a/dependency-check-cli/xref-test/overview-summary.html b/dependency-check-cli/xref-test/overview-summary.html index c3857e7bb..49ca818ac 100644 --- a/dependency-check-cli/xref-test/overview-summary.html +++ b/dependency-check-cli/xref-test/overview-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Command Line 1.4.0 Reference + Dependency-Check Command Line 1.4.2 Reference @@ -24,7 +24,7 @@
      -

      Dependency-Check Command Line 1.4.0 Reference

      +

      Dependency-Check Command Line 1.4.2 Reference

      diff --git a/dependency-check-cli/xref/index.html b/dependency-check-cli/xref/index.html index 314aaf90b..985be0807 100644 --- a/dependency-check-cli/xref/index.html +++ b/dependency-check-cli/xref/index.html @@ -4,7 +4,7 @@ - Dependency-Check Command Line 1.4.0 Reference + Dependency-Check Command Line 1.4.2 Reference diff --git a/dependency-check-cli/xref/org/owasp/dependencycheck/App.html b/dependency-check-cli/xref/org/owasp/dependencycheck/App.html index 06ae04ae2..a20d1cd0e 100644 --- a/dependency-check-cli/xref/org/owasp/dependencycheck/App.html +++ b/dependency-check-cli/xref/org/owasp/dependencycheck/App.html @@ -45,411 +45,485 @@ 37import org.slf4j.Logger; 38import org.slf4j.LoggerFactory; 39import ch.qos.logback.core.FileAppender; -40import org.slf4j.impl.StaticLoggerBinder; -41 -42/** -43 * The command line interface for the DependencyCheck application. -44 * -45 * @author Jeremy Long -46 */ -47publicclassApp { -48 -49/** -50 * The logger. -51 */ -52privatestaticfinal Logger LOGGER = LoggerFactory.getLogger(App.class); -53 -54/** -55 * The main method for the application. -56 * -57 * @param args the command line arguments -58 */ -59publicstaticvoid main(String[] args) { -60try { -61 Settings.initialize(); -62finalApp app = newApp(); -63 app.run(args); -64 } finally { -65 Settings.cleanup(true); -66 } -67 } -68 -69/** -70 * Main CLI entry-point into the application. -71 * -72 * @param args the command line arguments -73 */ -74publicvoid run(String[] args) { -75finalCliParser cli = newCliParser(); -76 -77try { -78 cli.parse(args); -79 } catch (FileNotFoundException ex) { -80 System.err.println(ex.getMessage()); -81 cli.printHelp(); -82return; -83 } catch (ParseException ex) { -84 System.err.println(ex.getMessage()); -85 cli.printHelp(); -86return; -87 } -88 -89if (cli.getVerboseLog() != null) { -90 prepareLogger(cli.getVerboseLog()); -91 } -92 -93if (cli.isPurge()) { -94if (cli.getConnectionString() != null) { -95 LOGGER.error("Unable to purge the database when using a non-default connection string"); -96 } else { -97 populateSettings(cli); -98 File db; -99try { -100 db = new File(Settings.getDataDirectory(), "dc.h2.db"); -101if (db.exists()) { -102if (db.delete()) { -103 LOGGER.info("Database file purged; local copy of the NVD has been removed"); -104 } else { -105 LOGGER.error("Unable to delete '{}'; please delete the file manually", db.getAbsolutePath()); -106 } -107 } else { -108 LOGGER.error("Unable to purge database; the database file does not exists: {}", db.getAbsolutePath()); -109 } -110 } catch (IOException ex) { -111 LOGGER.error("Unable to delete the database"); -112 } -113 } -114 } elseif (cli.isGetVersion()) { -115 cli.printVersionInfo(); -116 } elseif (cli.isUpdateOnly()) { -117 populateSettings(cli); -118 runUpdateOnly(); -119 } elseif (cli.isRunScan()) { -120 populateSettings(cli); -121try { -122 runScan(cli.getReportDirectory(), cli.getReportFormat(), cli.getProjectName(), cli.getScanFiles(), -123 cli.getExcludeList(), cli.getSymLinkDepth()); -124 } catch (InvalidScanPathException ex) { -125 LOGGER.error("An invalid scan path was detected; unable to scan '//*' paths"); -126 } -127 } else { -128 cli.printHelp(); -129 } -130 } -131 -132/** -133 * Scans the specified directories and writes the dependency reports to the reportDirectory. -134 * -135 * @param reportDirectory the path to the directory where the reports will be written -136 * @param outputFormat the output format of the report -137 * @param applicationName the application name for the report -138 * @param files the files/directories to scan -139 * @param excludes the patterns for files/directories to exclude -140 * @param symLinkDepth the depth that symbolic links will be followed -141 * -142 * @throws InvalidScanPathException thrown if the path to scan starts with "//" -143 */ -144privatevoid runScan(String reportDirectory, String outputFormat, String applicationName, String[] files, -145 String[] excludes, int symLinkDepth) throws InvalidScanPathException { -146 Engine engine = null; -147try { -148 engine = new Engine(); -149final List<String> antStylePaths = new ArrayList<String>(); -150for (String file : files) { -151final String antPath = ensureCanonicalPath(file); -152 antStylePaths.add(antPath); -153 } -154 -155final Set<File> paths = new HashSet<File>(); -156for (String file : antStylePaths) { -157 LOGGER.debug("Scanning {}", file); -158final DirectoryScanner scanner = new DirectoryScanner(); -159 String include = file.replace('\\', '/'); -160 File baseDir; -161 -162if (include.startsWith("//")) { -163thrownewInvalidScanPathException("Unable to scan paths specified by //"); -164 } else { -165finalint pos = getLastFileSeparator(include); -166final String tmpBase = include.substring(0, pos); -167final String tmpInclude = include.substring(pos + 1); -168if (tmpInclude.indexOf('*') >= 0 || tmpInclude.indexOf('?') >= 0 -169 || (new File(include)).isFile()) { -170 baseDir = new File(tmpBase); -171 include = tmpInclude; -172 } else { -173 baseDir = new File(tmpBase, tmpInclude); -174 include = "**/*"; -175 } -176 } -177//LOGGER.debug("baseDir: {}", baseDir); -178//LOGGER.debug("include: {}", include); -179 scanner.setBasedir(baseDir); -180final String[] includes = {include}; -181 scanner.setIncludes(includes); -182 scanner.setMaxLevelsOfSymlinks(symLinkDepth); -183if (symLinkDepth <= 0) { -184 scanner.setFollowSymlinks(false); -185 } -186if (excludes != null && excludes.length > 0) { -187 scanner.addExcludes(excludes); -188 } -189 scanner.scan(); -190if (scanner.getIncludedFilesCount() > 0) { -191for (String s : scanner.getIncludedFiles()) { -192final File f = new File(baseDir, s); -193 LOGGER.debug("Found file {}", f.toString()); -194 paths.add(f); -195 } -196 } -197 } -198 engine.scan(paths); -199 -200 engine.analyzeDependencies(); -201final List<Dependency> dependencies = engine.getDependencies(); -202 DatabaseProperties prop = null; -203 CveDB cve = null; -204try { -205 cve = new CveDB(); -206 cve.open(); -207 prop = cve.getDatabaseProperties(); -208 } catch (DatabaseException ex) { -209 LOGGER.debug("Unable to retrieve DB Properties", ex); -210 } finally { -211if (cve != null) { -212 cve.close(); -213 } -214 } -215final ReportGenerator report = new ReportGenerator(applicationName, dependencies, engine.getAnalyzers(), prop); -216try { -217 report.generateReports(reportDirectory, outputFormat); -218 } catch (IOException ex) { -219 LOGGER.error("There was an IO error while attempting to generate the report."); -220 LOGGER.debug("", ex); -221 } catch (Throwable ex) { -222 LOGGER.error("There was an error while attempting to generate the report."); -223 LOGGER.debug("", ex); -224 } -225 } catch (DatabaseException ex) { -226 LOGGER.error("Unable to connect to the dependency-check database; analysis has stopped"); -227 LOGGER.debug("", ex); -228 } finally { -229if (engine != null) { -230 engine.cleanup(); -231 } -232 } -233 } -234 -235/** -236 * Only executes the update phase of dependency-check. -237 */ -238privatevoid runUpdateOnly() { -239 Engine engine = null; -240try { -241 engine = new Engine(); -242 engine.doUpdates(); -243 } catch (DatabaseException ex) { -244 LOGGER.error("Unable to connect to the dependency-check database; analysis has stopped"); -245 LOGGER.debug("", ex); -246 } finally { -247if (engine != null) { -248 engine.cleanup(); -249 } -250 } -251 } -252 -253/** -254 * Updates the global Settings. -255 * -256 * @param cli a reference to the CLI Parser that contains the command line arguments used to set the corresponding settings in -257 * the core engine. -258 */ -259privatevoid populateSettings(CliParser cli) { -260 -261finalboolean autoUpdate = cli.isAutoUpdate(); -262final String connectionTimeout = cli.getConnectionTimeout(); -263final String proxyServer = cli.getProxyServer(); -264final String proxyPort = cli.getProxyPort(); -265final String proxyUser = cli.getProxyUsername(); -266final String proxyPass = cli.getProxyPassword(); -267final String dataDirectory = cli.getDataDirectory(); -268final File propertiesFile = cli.getPropertiesFile(); -269final String suppressionFile = cli.getSuppressionFile(); -270final String nexusUrl = cli.getNexusUrl(); -271final String databaseDriverName = cli.getDatabaseDriverName(); -272final String databaseDriverPath = cli.getDatabaseDriverPath(); -273final String connectionString = cli.getConnectionString(); -274final String databaseUser = cli.getDatabaseUser(); -275final String databasePassword = cli.getDatabasePassword(); -276final String additionalZipExtensions = cli.getAdditionalZipExtensions(); -277final String pathToMono = cli.getPathToMono(); -278final String cveMod12 = cli.getModifiedCve12Url(); -279final String cveMod20 = cli.getModifiedCve20Url(); -280final String cveBase12 = cli.getBaseCve12Url(); -281final String cveBase20 = cli.getBaseCve20Url(); -282final Integer cveValidForHours = cli.getCveValidForHours(); -283finalboolean experimentalEnabled = cli.isExperimentalEnabled(); -284 -285if (propertiesFile != null) { +40import org.owasp.dependencycheck.data.update.exception.UpdateException; +41import org.owasp.dependencycheck.exception.ExceptionCollection; +42import org.owasp.dependencycheck.exception.ReportException; +43import org.owasp.dependencycheck.utils.InvalidSettingException; +44import org.slf4j.impl.StaticLoggerBinder; +45 +46/** +47 * The command line interface for the DependencyCheck application. +48 * +49 * @author Jeremy Long +50 */ +51publicclassApp { +52 +53/** +54 * The logger. +55 */ +56privatestaticfinal Logger LOGGER = LoggerFactory.getLogger(App.class); +57 +58/** +59 * The main method for the application. +60 * +61 * @param args the command line arguments +62 */ +63publicstaticvoid main(String[] args) { +64int exitCode = 0; +65try { +66 Settings.initialize(); +67finalApp app = newApp(); +68 exitCode = app.run(args); +69 LOGGER.debug("Exit code: " + exitCode); +70 } finally { +71 Settings.cleanup(true); +72 } +73 System.exit(exitCode); +74 } +75 +76/** +77 * Main CLI entry-point into the application. +78 * +79 * @param args the command line arguments +80 * @return the exit code to return +81 */ +82publicint run(String[] args) { +83int exitCode = 0; +84finalCliParser cli = newCliParser(); +85 +86try { +87 cli.parse(args); +88 } catch (FileNotFoundException ex) { +89 System.err.println(ex.getMessage()); +90 cli.printHelp(); +91return -1; +92 } catch (ParseException ex) { +93 System.err.println(ex.getMessage()); +94 cli.printHelp(); +95return -2; +96 } +97 +98if (cli.getVerboseLog() != null) { +99 prepareLogger(cli.getVerboseLog()); +100 } +101 +102if (cli.isPurge()) { +103if (cli.getConnectionString() != null) { +104 LOGGER.error("Unable to purge the database when using a non-default connection string"); +105 exitCode = -3; +106 } else { +107try { +108 populateSettings(cli); +109 } catch (InvalidSettingException ex) { +110 LOGGER.error(ex.getMessage()); +111 LOGGER.debug("Error loading properties file", ex); +112 exitCode = -4; +113 } +114 File db; +115try { +116 db = new File(Settings.getDataDirectory(), "dc.h2.db"); +117if (db.exists()) { +118if (db.delete()) { +119 LOGGER.info("Database file purged; local copy of the NVD has been removed"); +120 } else { +121 LOGGER.error("Unable to delete '{}'; please delete the file manually", db.getAbsolutePath()); +122 exitCode = -5; +123 } +124 } else { +125 LOGGER.error("Unable to purge database; the database file does not exists: {}", db.getAbsolutePath()); +126 exitCode = -6; +127 } +128 } catch (IOException ex) { +129 LOGGER.error("Unable to delete the database"); +130 exitCode = -7; +131 } +132 } +133 } elseif (cli.isGetVersion()) { +134 cli.printVersionInfo(); +135 } elseif (cli.isUpdateOnly()) { +136try { +137 populateSettings(cli); +138 } catch (InvalidSettingException ex) { +139 LOGGER.error(ex.getMessage()); +140 LOGGER.debug("Error loading properties file", ex); +141 exitCode = -4; +142 } +143try { +144 runUpdateOnly(); +145 } catch (UpdateException ex) { +146 LOGGER.error(ex.getMessage()); +147 exitCode = -8; +148 } catch (DatabaseException ex) { +149 LOGGER.error(ex.getMessage()); +150 exitCode = -9; +151 } +152 } elseif (cli.isRunScan()) { +153try { +154 populateSettings(cli); +155 } catch (InvalidSettingException ex) { +156 LOGGER.error(ex.getMessage()); +157 LOGGER.debug("Error loading properties file", ex); +158 exitCode = -4; +159 } +160try { +161 runScan(cli.getReportDirectory(), cli.getReportFormat(), cli.getProjectName(), cli.getScanFiles(), +162 cli.getExcludeList(), cli.getSymLinkDepth()); +163 } catch (InvalidScanPathException ex) { +164 LOGGER.error("An invalid scan path was detected; unable to scan '//*' paths"); +165 exitCode = -10; +166 } catch (DatabaseException ex) { +167 LOGGER.error(ex.getMessage()); +168 exitCode = -11; +169 } catch (ReportException ex) { +170 LOGGER.error(ex.getMessage()); +171 exitCode = -12; +172 } catch (ExceptionCollection ex) { +173if (ex.isFatal()) { +174 exitCode = -13; +175 LOGGER.error("One or more fatal errors occured"); +176 } else { +177 exitCode = -14; +178 } +179for (Throwable e : ex.getExceptions()) { +180 LOGGER.error(e.getMessage()); +181 } +182 } +183 } else { +184 cli.printHelp(); +185 } +186return exitCode; +187 } +188 +189/** +190 * Scans the specified directories and writes the dependency reports to the +191 * reportDirectory. +192 * +193 * @param reportDirectory the path to the directory where the reports will +194 * be written +195 * @param outputFormat the output format of the report +196 * @param applicationName the application name for the report +197 * @param files the files/directories to scan +198 * @param excludes the patterns for files/directories to exclude +199 * @param symLinkDepth the depth that symbolic links will be followed +200 * +201 * @throws InvalidScanPathException thrown if the path to scan starts with +202 * "//" +203 * @throws ReportException thrown when the report cannot be generated +204 * @throws DatabaseException thrown when there is an error connecting to the +205 * database +206 * @throws ExceptionCollection thrown when an exception occurs during +207 * analysis; there may be multiple exceptions contained within the +208 * collection. +209 */ +210privatevoid runScan(String reportDirectory, String outputFormat, String applicationName, String[] files, +211 String[] excludes, int symLinkDepth) throws InvalidScanPathException, DatabaseException, ExceptionCollection, ReportException { +212 Engine engine = null; +213try { +214 engine = new Engine(); +215final List<String> antStylePaths = new ArrayList<String>(); +216for (String file : files) { +217final String antPath = ensureCanonicalPath(file); +218 antStylePaths.add(antPath); +219 } +220 +221final Set<File> paths = new HashSet<File>(); +222for (String file : antStylePaths) { +223 LOGGER.debug("Scanning {}", file); +224final DirectoryScanner scanner = new DirectoryScanner(); +225 String include = file.replace('\\', '/'); +226 File baseDir; +227 +228if (include.startsWith("//")) { +229thrownewInvalidScanPathException("Unable to scan paths specified by //"); +230 } else { +231finalint pos = getLastFileSeparator(include); +232final String tmpBase = include.substring(0, pos); +233final String tmpInclude = include.substring(pos + 1); +234if (tmpInclude.indexOf('*') >= 0 || tmpInclude.indexOf('?') >= 0 +235 || (new File(include)).isFile()) { +236 baseDir = new File(tmpBase); +237 include = tmpInclude; +238 } else { +239 baseDir = new File(tmpBase, tmpInclude); +240 include = "**/*"; +241 } +242 } +243 scanner.setBasedir(baseDir); +244final String[] includes = {include}; +245 scanner.setIncludes(includes); +246 scanner.setMaxLevelsOfSymlinks(symLinkDepth); +247if (symLinkDepth <= 0) { +248 scanner.setFollowSymlinks(false); +249 } +250if (excludes != null && excludes.length > 0) { +251 scanner.addExcludes(excludes); +252 } +253 scanner.scan(); +254if (scanner.getIncludedFilesCount() > 0) { +255for (String s : scanner.getIncludedFiles()) { +256final File f = new File(baseDir, s); +257 LOGGER.debug("Found file {}", f.toString()); +258 paths.add(f); +259 } +260 } +261 } +262 engine.scan(paths); +263 +264 ExceptionCollection exCol = null; +265try { +266 engine.analyzeDependencies(); +267 } catch (ExceptionCollection ex) { +268if (ex.isFatal()) { +269throw ex; +270 } +271 exCol = ex; +272 } +273final List<Dependency> dependencies = engine.getDependencies(); +274 DatabaseProperties prop = null; +275 CveDB cve = null; +276try { +277 cve = new CveDB(); +278 cve.open(); +279 prop = cve.getDatabaseProperties(); +280 } finally { +281if (cve != null) { +282 cve.close(); +283 } +284 } +285final ReportGenerator report = new ReportGenerator(applicationName, dependencies, engine.getAnalyzers(), prop); 286try { -287 Settings.mergeProperties(propertiesFile); -288 } catch (FileNotFoundException ex) { -289 LOGGER.error("Unable to load properties file '{}'", propertiesFile.getPath()); -290 LOGGER.debug("", ex); -291 } catch (IOException ex) { -292 LOGGER.error("Unable to find properties file '{}'", propertiesFile.getPath()); -293 LOGGER.debug("", ex); -294 } -295 } -296// We have to wait until we've merged the properties before attempting to set whether we use -297// the proxy for Nexus since it could be disabled in the properties, but not explicitly stated -298// on the command line -299finalboolean nexusUsesProxy = cli.isNexusUsesProxy(); -300if (dataDirectory != null) { -301 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory); -302 } elseif (System.getProperty("basedir") != null) { -303final File dataDir = new File(System.getProperty("basedir"), "data"); -304 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath()); -305 } else { -306final File jarPath = new File(App.class.getProtectionDomain().getCodeSource().getLocation().getPath()); -307final File base = jarPath.getParentFile(); -308final String sub = Settings.getString(Settings.KEYS.DATA_DIRECTORY); -309final File dataDir = new File(base, sub); -310 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath()); -311 } -312 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate); -313 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_SERVER, proxyServer); -314 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PORT, proxyPort); -315 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_USERNAME, proxyUser); -316 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PASSWORD, proxyPass); -317 Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout); -318 Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile); -319 Settings.setIntIfNotNull(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, cveValidForHours); -320 -321//File Type Analyzer Settings -322 Settings.setBoolean(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, experimentalEnabled); -323 Settings.setBoolean(Settings.KEYS.ANALYZER_JAR_ENABLED, !cli.isJarDisabled()); -324 Settings.setBoolean(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, !cli.isArchiveDisabled()); -325 Settings.setBoolean(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, !cli.isPythonDistributionDisabled()); -326 Settings.setBoolean(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, !cli.isPythonPackageDisabled()); -327 Settings.setBoolean(Settings.KEYS.ANALYZER_AUTOCONF_ENABLED, !cli.isAutoconfDisabled()); -328 Settings.setBoolean(Settings.KEYS.ANALYZER_CMAKE_ENABLED, !cli.isCmakeDisabled()); -329 Settings.setBoolean(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, !cli.isNuspecDisabled()); -330 Settings.setBoolean(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, !cli.isAssemblyDisabled()); -331 Settings.setBoolean(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_ENABLED, !cli.isBundleAuditDisabled()); -332 Settings.setBoolean(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, !cli.isOpenSSLDisabled()); -333 Settings.setBoolean(Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED, !cli.isComposerDisabled()); -334 Settings.setBoolean(Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED, !cli.isNodeJsDisabled()); -335 Settings.setBoolean(Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED, !cli.isRubyGemspecDisabled()); -336 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, !cli.isCentralDisabled()); -337 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, !cli.isNexusDisabled()); -338 -339 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH, cli.getPathToBundleAudit()); -340 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl); -341 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy); -342 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName); -343 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath); -344 Settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString); -345 Settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser); -346 Settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword); -347 Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, additionalZipExtensions); -348 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono); -349if (cveBase12 != null && !cveBase12.isEmpty()) { -350 Settings.setString(Settings.KEYS.CVE_SCHEMA_1_2, cveBase12); -351 Settings.setString(Settings.KEYS.CVE_SCHEMA_2_0, cveBase20); -352 Settings.setString(Settings.KEYS.CVE_MODIFIED_12_URL, cveMod12); -353 Settings.setString(Settings.KEYS.CVE_MODIFIED_20_URL, cveMod20); -354 } -355 } -356 -357/** -358 * Creates a file appender and adds it to logback. -359 * -360 * @param verboseLog the path to the verbose log file -361 */ -362privatevoid prepareLogger(String verboseLog) { -363final StaticLoggerBinder loggerBinder = StaticLoggerBinder.getSingleton(); -364final LoggerContext context = (LoggerContext) loggerBinder.getLoggerFactory(); -365 -366final PatternLayoutEncoder encoder = new PatternLayoutEncoder(); -367 encoder.setPattern("%d %C:%L%n%-5level - %msg%n"); -368 encoder.setContext(context); -369 encoder.start(); -370final FileAppender fa = new FileAppender(); -371 fa.setAppend(true); -372 fa.setEncoder(encoder); -373 fa.setContext(context); -374 fa.setFile(verboseLog); -375final File f = new File(verboseLog); -376 String name = f.getName(); -377finalint i = name.lastIndexOf('.'); -378if (i > 1) { -379 name = name.substring(0, i); -380 } -381 fa.setName(name); -382 fa.start(); -383final ch.qos.logback.classic.Logger rootLogger = context.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME); -384 rootLogger.addAppender(fa); -385 } -386 -387/** -388 * Takes a path and resolves it to be a canonical &amp; absolute path. The caveats are that this method will take an Ant style -389 * file selector path (../someDir/**\/*.jar) and convert it to an absolute/canonical path (at least to the left of the first * -390 * or ?). -391 * -392 * @param path the path to canonicalize -393 * @return the canonical path -394 */ -395protected String ensureCanonicalPath(String path) { -396 String basePath = null; -397 String wildCards = null; -398final String file = path.replace('\\', '/'); -399if (file.contains("*") || file.contains("?")) { -400 -401int pos = getLastFileSeparator(file); -402if (pos < 0) { -403return file; -404 } -405 pos += 1; -406 basePath = file.substring(0, pos); -407 wildCards = file.substring(pos); -408 } else { -409 basePath = file; -410 } +287 report.generateReports(reportDirectory, outputFormat); +288 } catch (ReportException ex) { +289if (exCol != null) { +290 exCol.addException(ex); +291throw exCol; +292 } else { +293throw ex; +294 } +295 } +296if (exCol != null && exCol.getExceptions().size()>0) { +297throw exCol; +298 } +299 } finally { +300if (engine != null) { +301 engine.cleanup(); +302 } +303 } +304 +305 } +306 +307/** +308 * Only executes the update phase of dependency-check. +309 * +310 * @throws UpdateException thrown if there is an error updating +311 * @throws DatabaseException thrown if a fatal error occurred and a +312 * connection to the database could not be established +313 */ +314privatevoid runUpdateOnly() throws UpdateException, DatabaseException { +315 Engine engine = null; +316try { +317 engine = new Engine(); +318 engine.doUpdates(); +319 } finally { +320if (engine != null) { +321 engine.cleanup(); +322 } +323 } +324 } +325 +326/** +327 * Updates the global Settings. +328 * +329 * @param cli a reference to the CLI Parser that contains the command line +330 * arguments used to set the corresponding settings in the core engine. +331 * +332 * @throws InvalidSettingException thrown when a user defined properties +333 * file is unable to be loaded. +334 */ +335privatevoid populateSettings(CliParser cli) throws InvalidSettingException { +336finalboolean autoUpdate = cli.isAutoUpdate(); +337final String connectionTimeout = cli.getConnectionTimeout(); +338final String proxyServer = cli.getProxyServer(); +339final String proxyPort = cli.getProxyPort(); +340final String proxyUser = cli.getProxyUsername(); +341final String proxyPass = cli.getProxyPassword(); +342final String dataDirectory = cli.getDataDirectory(); +343final File propertiesFile = cli.getPropertiesFile(); +344final String suppressionFile = cli.getSuppressionFile(); +345final String nexusUrl = cli.getNexusUrl(); +346final String databaseDriverName = cli.getDatabaseDriverName(); +347final String databaseDriverPath = cli.getDatabaseDriverPath(); +348final String connectionString = cli.getConnectionString(); +349final String databaseUser = cli.getDatabaseUser(); +350final String databasePassword = cli.getDatabasePassword(); +351final String additionalZipExtensions = cli.getAdditionalZipExtensions(); +352final String pathToMono = cli.getPathToMono(); +353final String cveMod12 = cli.getModifiedCve12Url(); +354final String cveMod20 = cli.getModifiedCve20Url(); +355final String cveBase12 = cli.getBaseCve12Url(); +356final String cveBase20 = cli.getBaseCve20Url(); +357final Integer cveValidForHours = cli.getCveValidForHours(); +358finalboolean experimentalEnabled = cli.isExperimentalEnabled(); +359 +360if (propertiesFile != null) { +361try { +362 Settings.mergeProperties(propertiesFile); +363 } catch (FileNotFoundException ex) { +364thrownew InvalidSettingException("Unable to find properties file '" + propertiesFile.getPath() + "'", ex); +365 } catch (IOException ex) { +366thrownew InvalidSettingException("Error reading properties file '" + propertiesFile.getPath() + "'", ex); +367 } +368 } +369// We have to wait until we've merged the properties before attempting to set whether we use +370// the proxy for Nexus since it could be disabled in the properties, but not explicitly stated +371// on the command line +372finalboolean nexusUsesProxy = cli.isNexusUsesProxy(); +373if (dataDirectory != null) { +374 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory); +375 } elseif (System.getProperty("basedir") != null) { +376final File dataDir = new File(System.getProperty("basedir"), "data"); +377 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath()); +378 } else { +379final File jarPath = new File(App.class.getProtectionDomain().getCodeSource().getLocation().getPath()); +380final File base = jarPath.getParentFile(); +381final String sub = Settings.getString(Settings.KEYS.DATA_DIRECTORY); +382final File dataDir = new File(base, sub); +383 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath()); +384 } +385 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate); +386 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_SERVER, proxyServer); +387 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PORT, proxyPort); +388 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_USERNAME, proxyUser); +389 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PASSWORD, proxyPass); +390 Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout); +391 Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile); +392 Settings.setIntIfNotNull(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, cveValidForHours); +393 +394//File Type Analyzer Settings +395 Settings.setBoolean(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, experimentalEnabled); +396 Settings.setBoolean(Settings.KEYS.ANALYZER_JAR_ENABLED, !cli.isJarDisabled()); +397 Settings.setBoolean(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, !cli.isArchiveDisabled()); +398 Settings.setBoolean(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, !cli.isPythonDistributionDisabled()); +399 Settings.setBoolean(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, !cli.isPythonPackageDisabled()); +400 Settings.setBoolean(Settings.KEYS.ANALYZER_AUTOCONF_ENABLED, !cli.isAutoconfDisabled()); +401 Settings.setBoolean(Settings.KEYS.ANALYZER_CMAKE_ENABLED, !cli.isCmakeDisabled()); +402 Settings.setBoolean(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, !cli.isNuspecDisabled()); +403 Settings.setBoolean(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, !cli.isAssemblyDisabled()); +404 Settings.setBoolean(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_ENABLED, !cli.isBundleAuditDisabled()); +405 Settings.setBoolean(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, !cli.isOpenSSLDisabled()); +406 Settings.setBoolean(Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED, !cli.isComposerDisabled()); +407 Settings.setBoolean(Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED, !cli.isNodeJsDisabled()); +408 Settings.setBoolean(Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED, !cli.isRubyGemspecDisabled()); +409 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, !cli.isCentralDisabled()); +410 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, !cli.isNexusDisabled()); 411 -412 File f = new File(basePath); -413try { -414 f = f.getCanonicalFile(); -415if (wildCards != null) { -416 f = new File(f, wildCards); -417 } -418 } catch (IOException ex) { -419 LOGGER.warn("Invalid path '{}' was provided.", path); -420 LOGGER.debug("Invalid path provided", ex); -421 } -422return f.getAbsolutePath().replace('\\', '/'); -423 } -424 -425/** -426 * Returns the position of the last file separator. -427 * -428 * @param file a file path -429 * @return the position of the last file separator -430 */ -431privateint getLastFileSeparator(String file) { -432if (file.contains("*") || file.contains("?")) { -433int p1 = file.indexOf('*'); -434int p2 = file.indexOf('?'); -435 p1 = p1 > 0 ? p1 : file.length(); -436 p2 = p2 > 0 ? p2 : file.length(); -437int pos = p1 < p2 ? p1 : p2; -438 pos = file.lastIndexOf('/', pos); -439return pos; -440 } else { -441return file.lastIndexOf('/'); -442 } -443 } -444 } +412 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH, cli.getPathToBundleAudit()); +413 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl); +414 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy); +415 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName); +416 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath); +417 Settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString); +418 Settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser); +419 Settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword); +420 Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, additionalZipExtensions); +421 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono); +422if (cveBase12 != null && !cveBase12.isEmpty()) { +423 Settings.setString(Settings.KEYS.CVE_SCHEMA_1_2, cveBase12); +424 Settings.setString(Settings.KEYS.CVE_SCHEMA_2_0, cveBase20); +425 Settings.setString(Settings.KEYS.CVE_MODIFIED_12_URL, cveMod12); +426 Settings.setString(Settings.KEYS.CVE_MODIFIED_20_URL, cveMod20); +427 } +428 } +429 +430/** +431 * Creates a file appender and adds it to logback. +432 * +433 * @param verboseLog the path to the verbose log file +434 */ +435privatevoid prepareLogger(String verboseLog) { +436final StaticLoggerBinder loggerBinder = StaticLoggerBinder.getSingleton(); +437final LoggerContext context = (LoggerContext) loggerBinder.getLoggerFactory(); +438 +439final PatternLayoutEncoder encoder = new PatternLayoutEncoder(); +440 encoder.setPattern("%d %C:%L%n%-5level - %msg%n"); +441 encoder.setContext(context); +442 encoder.start(); +443final FileAppender fa = new FileAppender(); +444 fa.setAppend(true); +445 fa.setEncoder(encoder); +446 fa.setContext(context); +447 fa.setFile(verboseLog); +448final File f = new File(verboseLog); +449 String name = f.getName(); +450finalint i = name.lastIndexOf('.'); +451if (i > 1) { +452 name = name.substring(0, i); +453 } +454 fa.setName(name); +455 fa.start(); +456final ch.qos.logback.classic.Logger rootLogger = context.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME); +457 rootLogger.addAppender(fa); +458 } +459 +460/** +461 * Takes a path and resolves it to be a canonical &amp; absolute path. The +462 * caveats are that this method will take an Ant style file selector path +463 * (../someDir/**\/*.jar) and convert it to an absolute/canonical path (at +464 * least to the left of the first * or ?). +465 * +466 * @param path the path to canonicalize +467 * @return the canonical path +468 */ +469protected String ensureCanonicalPath(String path) { +470 String basePath; +471 String wildCards = null; +472final String file = path.replace('\\', '/'); +473if (file.contains("*") || file.contains("?")) { +474 +475int pos = getLastFileSeparator(file); +476if (pos < 0) { +477return file; +478 } +479 pos += 1; +480 basePath = file.substring(0, pos); +481 wildCards = file.substring(pos); +482 } else { +483 basePath = file; +484 } +485 +486 File f = new File(basePath); +487try { +488 f = f.getCanonicalFile(); +489if (wildCards != null) { +490 f = new File(f, wildCards); +491 } +492 } catch (IOException ex) { +493 LOGGER.warn("Invalid path '{}' was provided.", path); +494 LOGGER.debug("Invalid path provided", ex); +495 } +496return f.getAbsolutePath().replace('\\', '/'); +497 } +498 +499/** +500 * Returns the position of the last file separator. +501 * +502 * @param file a file path +503 * @return the position of the last file separator +504 */ +505privateint getLastFileSeparator(String file) { +506if (file.contains("*") || file.contains("?")) { +507int p1 = file.indexOf('*'); +508int p2 = file.indexOf('?'); +509 p1 = p1 > 0 ? p1 : file.length(); +510 p2 = p2 > 0 ? p2 : file.length(); +511int pos = p1 < p2 ? p1 : p2; +512 pos = file.lastIndexOf('/', pos); +513return pos; +514 } else { +515return file.lastIndexOf('/'); +516 } +517 } +518 }
      diff --git a/dependency-check-cli/xref/org/owasp/dependencycheck/package-frame.html b/dependency-check-cli/xref/org/owasp/dependencycheck/package-frame.html index 8d0a7cf67..359edacfb 100644 --- a/dependency-check-cli/xref/org/owasp/dependencycheck/package-frame.html +++ b/dependency-check-cli/xref/org/owasp/dependencycheck/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Command Line 1.4.0 Reference Package org.owasp.dependencycheck + Dependency-Check Command Line 1.4.2 Reference Package org.owasp.dependencycheck diff --git a/dependency-check-cli/xref/org/owasp/dependencycheck/package-summary.html b/dependency-check-cli/xref/org/owasp/dependencycheck/package-summary.html index 2ee075147..74598f9ec 100644 --- a/dependency-check-cli/xref/org/owasp/dependencycheck/package-summary.html +++ b/dependency-check-cli/xref/org/owasp/dependencycheck/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Command Line 1.4.0 Reference Package org.owasp.dependencycheck + Dependency-Check Command Line 1.4.2 Reference Package org.owasp.dependencycheck diff --git a/dependency-check-cli/xref/overview-frame.html b/dependency-check-cli/xref/overview-frame.html index 6b5043647..587d5b4bc 100644 --- a/dependency-check-cli/xref/overview-frame.html +++ b/dependency-check-cli/xref/overview-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Command Line 1.4.0 Reference + Dependency-Check Command Line 1.4.2 Reference diff --git a/dependency-check-cli/xref/overview-summary.html b/dependency-check-cli/xref/overview-summary.html index c3857e7bb..49ca818ac 100644 --- a/dependency-check-cli/xref/overview-summary.html +++ b/dependency-check-cli/xref/overview-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Command Line 1.4.0 Reference + Dependency-Check Command Line 1.4.2 Reference @@ -24,7 +24,7 @@ -

      Dependency-Check Command Line 1.4.0 Reference

      +

      Dependency-Check Command Line 1.4.2 Reference

      diff --git a/dependency-check-core/apidocs/allclasses-frame.html b/dependency-check-core/apidocs/allclasses-frame.html index 05755dd79..96aae0fc8 100644 --- a/dependency-check-core/apidocs/allclasses-frame.html +++ b/dependency-check-core/apidocs/allclasses-frame.html @@ -2,10 +2,10 @@ - + -All Classes (Dependency-Check Core 1.4.0 API) - +All Classes (Dependency-Check Core 1.4.2 API) + @@ -66,6 +66,7 @@
    6. EscapeTool
    7. Evidence
    8. EvidenceCollection
    9. +
    10. ExceptionCollection
    11. Experimental
    12. ExtractionUtil
    13. FalsePositiveAnalyzer
    14. @@ -76,9 +77,16 @@
    15. FileTypeAnalyzer
    16. Filter
    17. HintAnalyzer
    18. +
    19. HintErrorHandler
    20. +
    21. HintHandler
    22. +
    23. HintParseException
    24. +
    25. HintParser
    26. +
    27. HintRule
    28. +
    29. Hints
    30. Identifier
    31. IndexEntry
    32. IndexException
    33. +
    34. InitializationException
    35. InvalidDataException
    36. JarAnalyzer
    37. JarAnalyzer.ClassNameInformation
    38. @@ -108,10 +116,11 @@
    39. PomParser
    40. PomUtils
    41. ProcessTask
    42. -
    43. PropertyType
    44. +
    45. PropertyType
    46. PythonDistributionAnalyzer
    47. PythonPackageAnalyzer
    48. Reference
    49. +
    50. ReportException
    51. ReportGenerator
    52. ReportGenerator.Format
    53. RubyBundleAuditAnalyzer
    54. @@ -119,11 +128,11 @@
    55. RubyGemspecAnalyzer
    56. ScanAgentException
    57. SearchFieldAnalyzer
    58. -
    59. SuppressionErrorHandler
    60. -
    61. SuppressionHandler
    62. -
    63. SuppressionParseException
    64. -
    65. SuppressionParser
    66. -
    67. SuppressionRule
    68. +
    69. SuppressionErrorHandler
    70. +
    71. SuppressionHandler
    72. +
    73. SuppressionParseException
    74. +
    75. SuppressionParser
    76. +
    77. SuppressionRule
    78. TokenPairConcatenatingFilter
    79. UpdateableNvdCve
    80. UpdateException
    81. @@ -131,6 +140,7 @@
    82. UrlStringUtils
    83. UrlTokenizingFilter
    84. VelocityLoggerRedirect
    85. +
    86. VendorDuplicatingHintRule
    87. Vulnerability
    88. VulnerabilityComparator
    89. VulnerabilitySuppressionAnalyzer
    90. diff --git a/dependency-check-core/apidocs/allclasses-noframe.html b/dependency-check-core/apidocs/allclasses-noframe.html index b19fee50c..05bcb92e1 100644 --- a/dependency-check-core/apidocs/allclasses-noframe.html +++ b/dependency-check-core/apidocs/allclasses-noframe.html @@ -2,10 +2,10 @@ - + -All Classes (Dependency-Check Core 1.4.0 API) - +All Classes (Dependency-Check Core 1.4.2 API) + @@ -66,6 +66,7 @@
    91. EscapeTool
    92. Evidence
    93. EvidenceCollection
    94. +
    95. ExceptionCollection
    96. Experimental
    97. ExtractionUtil
    98. FalsePositiveAnalyzer
    99. @@ -76,9 +77,16 @@
    100. FileTypeAnalyzer
    101. Filter
    102. HintAnalyzer
    103. +
    104. HintErrorHandler
    105. +
    106. HintHandler
    107. +
    108. HintParseException
    109. +
    110. HintParser
    111. +
    112. HintRule
    113. +
    114. Hints
    115. Identifier
    116. IndexEntry
    117. IndexException
    118. +
    119. InitializationException
    120. InvalidDataException
    121. JarAnalyzer
    122. JarAnalyzer.ClassNameInformation
    123. @@ -108,10 +116,11 @@
    124. PomParser
    125. PomUtils
    126. ProcessTask
    127. -
    128. PropertyType
    129. +
    130. PropertyType
    131. PythonDistributionAnalyzer
    132. PythonPackageAnalyzer
    133. Reference
    134. +
    135. ReportException
    136. ReportGenerator
    137. ReportGenerator.Format
    138. RubyBundleAuditAnalyzer
    139. @@ -119,11 +128,11 @@
    140. RubyGemspecAnalyzer
    141. ScanAgentException
    142. SearchFieldAnalyzer
    143. -
    144. SuppressionErrorHandler
    145. -
    146. SuppressionHandler
    147. -
    148. SuppressionParseException
    149. -
    150. SuppressionParser
    151. -
    152. SuppressionRule
    153. +
    154. SuppressionErrorHandler
    155. +
    156. SuppressionHandler
    157. +
    158. SuppressionParseException
    159. +
    160. SuppressionParser
    161. +
    162. SuppressionRule
    163. TokenPairConcatenatingFilter
    164. UpdateableNvdCve
    165. UpdateException
    166. @@ -131,6 +140,7 @@
    167. UrlStringUtils
    168. UrlTokenizingFilter
    169. VelocityLoggerRedirect
    170. +
    171. VendorDuplicatingHintRule
    172. Vulnerability
    173. VulnerabilityComparator
    174. VulnerabilitySuppressionAnalyzer
    175. diff --git a/dependency-check-core/apidocs/constant-values.html b/dependency-check-core/apidocs/constant-values.html index 769130ba9..3e89fa51d 100644 --- a/dependency-check-core/apidocs/constant-values.html +++ b/dependency-check-core/apidocs/constant-values.html @@ -2,10 +2,10 @@ - + -Constant Field Values (Dependency-Check Core 1.4.0 API) - +Constant Field Values (Dependency-Check Core 1.4.2 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/agent/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/agent/package-summary.html index e7f15ede6..f420cff1f 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/agent/package-summary.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/agent/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.agent (Dependency-Check Core 1.4.0 API) - +org.owasp.dependencycheck.agent (Dependency-Check Core 1.4.2 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,13 +13,13 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/exception/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/exception/package-summary.html index e172a63bf..a7fd53a4a 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/exception/package-summary.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/exception/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.analyzer.exception (Dependency-Check Core 1.4.0 API) - +org.owasp.dependencycheck.analyzer.exception (Dependency-Check Core 1.4.2 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/package-summary.html index e0ab00959..579152a90 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/package-summary.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.analyzer (Dependency-Check Core 1.4.0 API) - +org.owasp.dependencycheck.analyzer (Dependency-Check Core 1.4.2 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/central/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/central/package-summary.html index d1e4b5caa..7f5e888e6 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/central/package-summary.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/central/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.data.central (Dependency-Check Core 1.4.0 API) - +org.owasp.dependencycheck.data.central (Dependency-Check Core 1.4.2 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/composer/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/composer/package-summary.html index e754ceed8..034f92e81 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/composer/package-summary.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/composer/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.data.composer (Dependency-Check Core 1.4.0 API) - +org.owasp.dependencycheck.data.composer (Dependency-Check Core 1.4.2 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/package-summary.html index 40ffd1f1c..1c0021853 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/package-summary.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.data.cpe (Dependency-Check Core 1.4.0 API) - +org.owasp.dependencycheck.data.cpe (Dependency-Check Core 1.4.2 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cwe/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cwe/package-summary.html index e0e083652..5656722b9 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cwe/package-summary.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cwe/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.data.cwe (Dependency-Check Core 1.4.0 API) - +org.owasp.dependencycheck.data.cwe (Dependency-Check Core 1.4.2 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,14 +13,14 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/package-summary.html index 14cac647f..9ade01397 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/package-summary.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.data.lucene (Dependency-Check Core 1.4.0 API) - +org.owasp.dependencycheck.data.lucene (Dependency-Check Core 1.4.2 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nexus/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nexus/package-summary.html index 1854d8a78..04f0bf987 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nexus/package-summary.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nexus/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.data.nexus (Dependency-Check Core 1.4.0 API) - +org.owasp.dependencycheck.data.nexus (Dependency-Check Core 1.4.2 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/package-summary.html index 0ad06a42a..ab2403406 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/package-summary.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.data.nuget (Dependency-Check Core 1.4.0 API) - +org.owasp.dependencycheck.data.nuget (Dependency-Check Core 1.4.2 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/package-summary.html index 245317dfa..58dcfdab8 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/package-summary.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.data.nvdcve (Dependency-Check Core 1.4.0 API) - +org.owasp.dependencycheck.data.nvdcve (Dependency-Check Core 1.4.2 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/cpe/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/cpe/package-summary.html index 2d76f5c19..1e84874a7 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/cpe/package-summary.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/cpe/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.data.update.cpe (Dependency-Check Core 1.4.0 API) - +org.owasp.dependencycheck.data.update.cpe (Dependency-Check Core 1.4.2 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/exception/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/exception/package-summary.html index 1ae11af6d..ca602850d 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/exception/package-summary.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/exception/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.data.update.exception (Dependency-Check Core 1.4.0 API) - +org.owasp.dependencycheck.data.update.exception (Dependency-Check Core 1.4.2 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/package-summary.html index a3d290d99..5b5df8ac5 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/package-summary.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.data.update.nvd (Dependency-Check Core 1.4.0 API) - +org.owasp.dependencycheck.data.update.nvd (Dependency-Check Core 1.4.2 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/package-summary.html index 3934485fe..4b792a5a8 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/package-summary.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.data.update (Dependency-Check Core 1.4.0 API) - +org.owasp.dependencycheck.data.update (Dependency-Check Core 1.4.2 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/dependency/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/dependency/package-summary.html index 1c0ed11f0..58d53a845 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/dependency/package-summary.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/dependency/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.dependency (Dependency-Check Core 1.4.0 API) - +org.owasp.dependencycheck.dependency (Dependency-Check Core 1.4.2 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ + + + + + +
      + + + + + + + +
      + + + +
      +
      org.owasp.dependencycheck.exception
      +

      Class ExceptionCollection

      +
      +
      + +
      +
        +
      • +
        +
        All Implemented Interfaces:
        +
        Serializable
        +
        +
        +
        +
        public class ExceptionCollection
        +extends Exception
        +
        A collection of several exceptions.
        +
        +
        Author:
        +
        Jeremy Lomg
        +
        See Also:
        +
        Serialized Form
        +
        +
      • +
      +
      +
      +
        +
      • + +
          +
        • + + +

          Constructor Summary

          +
      + + + + + + + + + + + + + + + + + + + + + + + + + +
      Constructors 
      Constructor and Description
      ExceptionCollection() +
      Instantiates a new exception collection.
      +
      ExceptionCollection(List<Throwable> exceptions) +
      Instantiates a new exception collection.
      +
      ExceptionCollection(List<Throwable> exceptions, + boolean fatal) +
      Instantiates a new exception collection.
      +
      ExceptionCollection(String msg, + List<Throwable> exceptions) +
      Instantiates a new exception collection.
      +
      ExceptionCollection(String msg, + List<Throwable> exceptions, + boolean fatal) +
      Instantiates a new exception collection.
      +
      ExceptionCollection(String msg, + Throwable exception) +
      Instantiates a new exception collection.
      +
      ExceptionCollection(Throwable exceptions, + boolean fatal) +
      Instantiates a new exception collection.
      +
      + + + + + + + +
      + +
      + + + +
      + + + + + + + +
      + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/exception/InitializationException.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/exception/InitializationException.html new file mode 100644 index 000000000..230ccdead --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/exception/InitializationException.html @@ -0,0 +1,330 @@ + + + + + + +InitializationException (Dependency-Check Core 1.4.2 API) + + + + + + + + +
      + + + + + + + +
      + + + +
      +
      org.owasp.dependencycheck.exception
      +

      Class InitializationException

      +
      +
      + +
      +
        +
      • +
        +
        All Implemented Interfaces:
        +
        Serializable
        +
        +
        +
        +
        public class InitializationException
        +extends Exception
        +
        An exception used when initializing analyzers.
        +
        +
        Author:
        +
        Jeremy Long
        +
        See Also:
        +
        Serialized Form
        +
        +
      • +
      +
      +
      + +
      +
      +
        +
      • + +
          +
        • + + +

          Constructor Detail

          + + + +
            +
          • +

            InitializationException

            +
            public InitializationException()
            +
            Creates a new InitializationException.
            +
          • +
          + + + +
            +
          • +

            InitializationException

            +
            public InitializationException(String msg)
            +
            Creates a new InitializationException.
            +
            +
            Parameters:
            +
            msg - a message for the exception.
            +
            +
          • +
          + + + +
            +
          • +

            InitializationException

            +
            public InitializationException(Throwable ex)
            +
            Creates a new InitializationException.
            +
            +
            Parameters:
            +
            ex - the cause of the exception.
            +
            +
          • +
          + + + +
            +
          • +

            InitializationException

            +
            public InitializationException(String msg,
            +                               Throwable ex)
            +
            Creates a new InitializationException.
            +
            +
            Parameters:
            +
            msg - a message for the exception.
            +
            ex - the cause of the exception.
            +
            +
          • +
          +
        • +
        +
      • +
      +
      +
      + + +
      + + + + + + + +
      + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/exception/NoDataException.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/exception/NoDataException.html index 705649056..490c3a85b 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/exception/NoDataException.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/exception/NoDataException.html @@ -2,10 +2,10 @@ - + -NoDataException (Dependency-Check Core 1.4.0 API) - +NoDataException (Dependency-Check Core 1.4.2 API) + @@ -13,7 +13,7 @@ + + + + + +
      + + + + + + + +
      + + + +
      +
      org.owasp.dependencycheck.exception
      +

      Class ReportException

      +
      +
      + +
      +
        +
      • +
        +
        All Implemented Interfaces:
        +
        Serializable
        +
        +
        +
        +
        public class ReportException
        +extends Exception
        +
        An exception used when generating reports.
        +
        +
        Author:
        +
        Jeremy Long
        +
        See Also:
        +
        Serialized Form
        +
        +
      • +
      +
      +
      + +
      +
      +
        +
      • + +
          +
        • + + +

          Constructor Detail

          + + + +
            +
          • +

            ReportException

            +
            public ReportException()
            +
            Creates a new ReportException.
            +
          • +
          + + + +
            +
          • +

            ReportException

            +
            public ReportException(String msg)
            +
            Creates a new ReportException.
            +
            +
            Parameters:
            +
            msg - a message for the exception.
            +
            +
          • +
          + + + +
            +
          • +

            ReportException

            +
            public ReportException(Throwable ex)
            +
            Creates a new ReportException.
            +
            +
            Parameters:
            +
            ex - the cause of the exception.
            +
            +
          • +
          + + + +
            +
          • +

            ReportException

            +
            public ReportException(String msg,
            +                       Throwable ex)
            +
            Creates a new ReportException.
            +
            +
            Parameters:
            +
            msg - a message for the exception.
            +
            ex - the cause of the exception.
            +
            +
          • +
          +
        • +
        +
      • +
      +
      +
      + + +
      + + + + + + + +
      + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/exception/ScanAgentException.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/exception/ScanAgentException.html index b318666a9..139a4268a 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/exception/ScanAgentException.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/exception/ScanAgentException.html @@ -2,10 +2,10 @@ - + -ScanAgentException (Dependency-Check Core 1.4.0 API) - +ScanAgentException (Dependency-Check Core 1.4.2 API) + @@ -13,7 +13,7 @@ + + + + + +
      + + + + + + + +
      + + +
      +

      Uses of Class
      org.owasp.dependencycheck.exception.ExceptionCollection

      +
      +
      + +
      + +
      + + + + + + + +
      + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/exception/class-use/InitializationException.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/exception/class-use/InitializationException.html new file mode 100644 index 000000000..de5470192 --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/exception/class-use/InitializationException.html @@ -0,0 +1,325 @@ + + + + + + +Uses of Class org.owasp.dependencycheck.exception.InitializationException (Dependency-Check Core 1.4.2 API) + + + + + + + + +
      + + + + + + + +
      + + +
      +

      Uses of Class
      org.owasp.dependencycheck.exception.InitializationException

      +
      +
      + +
      + +
      + + + + + + + +
      + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/exception/class-use/NoDataException.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/exception/class-use/NoDataException.html index ab6368282..595c0e968 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/exception/class-use/NoDataException.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/exception/class-use/NoDataException.html @@ -2,10 +2,10 @@ - + -Uses of Class org.owasp.dependencycheck.exception.NoDataException (Dependency-Check Core 1.4.0 API) - +Uses of Class org.owasp.dependencycheck.exception.NoDataException (Dependency-Check Core 1.4.2 API) + @@ -13,7 +13,7 @@ + + + + + +
      + + + + + + + +
      + + +
      +

      Uses of Class
      org.owasp.dependencycheck.exception.ReportException

      +
      +
      + +
      + +
      + + + + + + + +
      + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/exception/class-use/ScanAgentException.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/exception/class-use/ScanAgentException.html index 0824f563b..99029877a 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/exception/class-use/ScanAgentException.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/exception/class-use/ScanAgentException.html @@ -2,10 +2,10 @@ - + -Uses of Class org.owasp.dependencycheck.exception.ScanAgentException (Dependency-Check Core 1.4.0 API) - +Uses of Class org.owasp.dependencycheck.exception.ScanAgentException (Dependency-Check Core 1.4.2 API) + @@ -13,7 +13,7 @@ @@ -14,7 +14,10 @@

      Exceptions

      diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/exception/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/exception/package-summary.html index fdf138c82..2bc5c65c5 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/exception/package-summary.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/exception/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.exception (Dependency-Check Core 1.4.0 API) - +org.owasp.dependencycheck.exception (Dependency-Check Core 1.4.2 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/package-summary.html index 19f8da6c5..20cec8787 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/package-summary.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck (Dependency-Check Core 1.4.0 API) - +org.owasp.dependencycheck (Dependency-Check Core 1.4.2 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/reporting/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/reporting/package-summary.html index 0a209d862..a3937106f 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/reporting/package-summary.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/reporting/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.reporting (Dependency-Check Core 1.4.0 API) - +org.owasp.dependencycheck.reporting (Dependency-Check Core 1.4.2 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/utils/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/utils/package-summary.html index 0e688a987..ffa5f861d 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/utils/package-summary.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/utils/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.utils (Dependency-Check Core 1.4.0 API) - +org.owasp.dependencycheck.utils (Dependency-Check Core 1.4.2 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ + + + + + +
      + + + + + + + +
      + + + +
      +
      org.owasp.dependencycheck.xml.hints
      +

      Class HintErrorHandler

      +
      +
      + +
      +
        +
      • +
        +
        All Implemented Interfaces:
        +
        ErrorHandler
        +
        +
        +
        +
        public class HintErrorHandler
        +extends Object
        +implements ErrorHandler
        +
        An XML parsing error handler.
        +
        +
        Author:
        +
        Jeremy Long
        +
        +
      • +
      +
      +
      + +
      +
      + +
      +
      + + +
      + + + + + + + +
      + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/HintHandler.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/HintHandler.html new file mode 100644 index 000000000..57e79bd11 --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/HintHandler.html @@ -0,0 +1,391 @@ + + + + + + +HintHandler (Dependency-Check Core 1.4.2 API) + + + + + + + + +
      + + + + + + + +
      + + + +
      +
      org.owasp.dependencycheck.xml.hints
      +

      Class HintHandler

      +
      +
      + +
      + +
      +
      + +
      +
      +
        +
      • + +
          +
        • + + +

          Constructor Detail

          + + + +
            +
          • +

            HintHandler

            +
            public HintHandler()
            +
          • +
          +
        • +
        + +
          +
        • + + +

          Method Detail

          + + + +
            +
          • +

            getHintRules

            +
            public List<HintRule> getHintRules()
            +
            Returns the list of hint rules.
            +
            +
            Returns:
            +
            the value of hintRules
            +
            +
          • +
          + + + +
            +
          • +

            getVendorDuplicatingHintRules

            +
            public List<VendorDuplicatingHintRule> getVendorDuplicatingHintRules()
            +
            Returns the list of vendor duplicating hint rules.
            +
            +
            Returns:
            +
            the list of vendor duplicating hint rules
            +
            +
          • +
          + + + +
            +
          • +

            startElement

            +
            public void startElement(String uri,
            +                         String localName,
            +                         String qName,
            +                         Attributes attr)
            +                  throws SAXException
            +
            Handles the start element event.
            +
            +
            Specified by:
            +
            startElement in interface ContentHandler
            +
            Overrides:
            +
            startElement in class DefaultHandler
            +
            Parameters:
            +
            uri - the uri of the element being processed
            +
            localName - the local name of the element being processed
            +
            qName - the qName of the element being processed
            +
            attr - the attributes of the element being processed
            +
            Throws:
            +
            SAXException - thrown if there is an exception processing
            +
            +
          • +
          + + + + +
        • +
        +
      • +
      +
      +
      + + +
      + + + + + + + +
      + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/HintParseException.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/HintParseException.html new file mode 100644 index 000000000..95e954b7f --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/HintParseException.html @@ -0,0 +1,335 @@ + + + + + + +HintParseException (Dependency-Check Core 1.4.2 API) + + + + + + + + +
      + + + + + + + +
      + + + +
      +
      org.owasp.dependencycheck.xml.hints
      +

      Class HintParseException

      +
      +
      + +
      +
        +
      • +
        +
        All Implemented Interfaces:
        +
        Serializable
        +
        +
        +
        +
        public class HintParseException
        +extends IOException
        +
        An exception used when parsing a suppression rule file fails.
        +
        +
        Author:
        +
        Jeremy Long
        +
        See Also:
        +
        Serialized Form
        +
        +
      • +
      +
      +
      + +
      +
      +
        +
      • + +
          +
        • + + +

          Constructor Detail

          + + + +
            +
          • +

            HintParseException

            +
            public HintParseException()
            +
            Creates a new SuppressionParseException.
            +
          • +
          + + + +
            +
          • +

            HintParseException

            +
            public HintParseException(String msg)
            +
            Creates a new SuppressionParseException.
            +
            +
            Parameters:
            +
            msg - a message for the exception.
            +
            +
          • +
          + + + +
            +
          • +

            HintParseException

            +
            public HintParseException(Throwable ex)
            +
            Creates a new SuppressionParseException.
            +
            +
            Parameters:
            +
            ex - the cause of the parse exception
            +
            +
          • +
          + + + +
            +
          • +

            HintParseException

            +
            public HintParseException(String msg,
            +                          Throwable ex)
            +
            Creates a new SuppressionParseException.
            +
            +
            Parameters:
            +
            msg - a message for the exception.
            +
            ex - the cause of the parse exception
            +
            +
          • +
          +
        • +
        +
      • +
      +
      +
      + + +
      + + + + + + + +
      + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/HintParser.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/HintParser.html new file mode 100644 index 000000000..4d09430c4 --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/HintParser.html @@ -0,0 +1,405 @@ + + + + + + +HintParser (Dependency-Check Core 1.4.2 API) + + + + + + + + +
      + + + + + + + +
      + + + +
      +
      org.owasp.dependencycheck.xml.hints
      +

      Class HintParser

      +
      +
      + +
      +
        +
      • +
        +
        +
        public class HintParser
        +extends Object
        +
        A simple validating parser for XML Hint Rules.
        +
        +
        Author:
        +
        Jeremy Long
        +
        +
      • +
      +
      +
      + +
      +
      +
        +
      • + +
          +
        • + + +

          Field Detail

          + + + +
            +
          • +

            JAXP_SCHEMA_LANGUAGE

            +
            public static final String JAXP_SCHEMA_LANGUAGE
            +
            JAXP Schema Language. Source: + http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html
            +
            +
            See Also:
            +
            Constant Field Values
            +
            +
          • +
          + + + +
            +
          • +

            W3C_XML_SCHEMA

            +
            public static final String W3C_XML_SCHEMA
            +
            W3C XML Schema. Source: + http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html
            +
            +
            See Also:
            +
            Constant Field Values
            +
            +
          • +
          + + + +
            +
          • +

            JAXP_SCHEMA_SOURCE

            +
            public static final String JAXP_SCHEMA_SOURCE
            +
            JAXP Schema Source. Source: + http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html
            +
            +
            See Also:
            +
            Constant Field Values
            +
            +
          • +
          +
        • +
        + +
          +
        • + + +

          Constructor Detail

          + + + +
            +
          • +

            HintParser

            +
            public HintParser()
            +
          • +
          +
        • +
        + +
          +
        • + + +

          Method Detail

          + + + +
            +
          • +

            parseHints

            +
            public Hints parseHints(File file)
            +                 throws HintParseException
            +
            Parses the given XML file and returns a list of the hints contained.
            +
            +
            Parameters:
            +
            file - an XML file containing hints
            +
            Returns:
            +
            a list of hint rules
            +
            Throws:
            +
            HintParseException - thrown if the XML file cannot be parsed
            +
            +
          • +
          + + + +
            +
          • +

            parseHints

            +
            public Hints parseHints(InputStream inputStream)
            +                 throws HintParseException,
            +                        SAXException
            +
            Parses the given XML stream and returns a list of the hint rules + contained.
            +
            +
            Parameters:
            +
            inputStream - an InputStream containing hint rules
            +
            Returns:
            +
            a list of hint rules
            +
            Throws:
            +
            HintParseException - thrown if the XML cannot be parsed
            +
            SAXException - thrown if the XML cannot be parsed
            +
            +
          • +
          +
        • +
        +
      • +
      +
      +
      + + +
      + + + + + + + +
      + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/HintRule.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/HintRule.html new file mode 100644 index 000000000..664dde2f5 --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/HintRule.html @@ -0,0 +1,503 @@ + + + + + + +HintRule (Dependency-Check Core 1.4.2 API) + + + + + + + + +
      + + + + + + + +
      + + + +
      +
      org.owasp.dependencycheck.xml.hints
      +

      Class HintRule

      +
      +
      + +
      +
        +
      • +
        +
        +
        public class HintRule
        +extends Object
        +
        A collection of product and vendor evidence to match; if any evidence is + matched the addVendor and addProduct evidence should be added to the + dependency.
        +
        +
        Author:
        +
        Jeremy Long
        +
        +
      • +
      +
      +
      + +
      +
      +
        +
      • + +
          +
        • + + +

          Constructor Detail

          + + + +
            +
          • +

            HintRule

            +
            public HintRule()
            +
          • +
          +
        • +
        + +
          +
        • + + +

          Method Detail

          + + + +
            +
          • +

            addFilename

            +
            public void addFilename(PropertyType filename)
            +
            Adds the filename evidence to the collection.
            +
            +
            Parameters:
            +
            filename - the filename to add
            +
            +
          • +
          + + + +
            +
          • +

            getFilenames

            +
            public List<PropertyType> getFilenames()
            +
            Returns the list of filename evidence to match against.
            +
            +
            Returns:
            +
            the list of filename evidence to match against
            +
            +
          • +
          + + + +
            +
          • +

            addGivenProduct

            +
            public void addGivenProduct(String source,
            +                            String name,
            +                            String value,
            +                            Confidence confidence)
            +
            Adds a given product to the list of evidence to matched.
            +
            +
            Parameters:
            +
            source - the source of the evidence
            +
            name - the name of the evidence
            +
            value - the value of the evidence
            +
            confidence - the confidence of the evidence
            +
            +
          • +
          + + + +
            +
          • +

            getGivenProduct

            +
            public List<Evidence> getGivenProduct()
            +
            Get the value of givenProduct.
            +
            +
            Returns:
            +
            the value of givenProduct
            +
            +
          • +
          + + + +
            +
          • +

            addGivenVendor

            +
            public void addGivenVendor(String source,
            +                           String name,
            +                           String value,
            +                           Confidence confidence)
            +
            Adds a given vendors to the list of evidence to matched.
            +
            +
            Parameters:
            +
            source - the source of the evidence
            +
            name - the name of the evidence
            +
            value - the value of the evidence
            +
            confidence - the confidence of the evidence
            +
            +
          • +
          + + + +
            +
          • +

            getGivenVendor

            +
            public List<Evidence> getGivenVendor()
            +
            Get the value of givenVendor.
            +
            +
            Returns:
            +
            the value of givenVendor
            +
            +
          • +
          + + + +
            +
          • +

            addAddProduct

            +
            public void addAddProduct(String source,
            +                          String name,
            +                          String value,
            +                          Confidence confidence)
            +
            Adds a given product to the list of evidence to add when matched.
            +
            +
            Parameters:
            +
            source - the source of the evidence
            +
            name - the name of the evidence
            +
            value - the value of the evidence
            +
            confidence - the confidence of the evidence
            +
            +
          • +
          + + + +
            +
          • +

            getAddProduct

            +
            public List<Evidence> getAddProduct()
            +
            Get the value of addProduct.
            +
            +
            Returns:
            +
            the value of addProduct
            +
            +
          • +
          + + + +
            +
          • +

            addAddVendor

            +
            public void addAddVendor(String source,
            +                         String name,
            +                         String value,
            +                         Confidence confidence)
            +
            Adds a given vendor to the list of evidence to add when matched.
            +
            +
            Parameters:
            +
            source - the source of the evidence
            +
            name - the name of the evidence
            +
            value - the value of the evidence
            +
            confidence - the confidence of the evidence
            +
            +
          • +
          + + + +
            +
          • +

            getAddVendor

            +
            public List<Evidence> getAddVendor()
            +
            Get the value of addVendor.
            +
            +
            Returns:
            +
            the value of addVendor
            +
            +
          • +
          +
        • +
        +
      • +
      +
      +
      + + +
      + + + + + + + +
      + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/Hints.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/Hints.html new file mode 100644 index 000000000..c2754c2f9 --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/Hints.html @@ -0,0 +1,345 @@ + + + + + + +Hints (Dependency-Check Core 1.4.2 API) + + + + + + + + +
      + + + + + + + +
      + + + +
      +
      org.owasp.dependencycheck.xml.hints
      +

      Class Hints

      +
      +
      + +
      +
        +
      • +
        +
        +
        public class Hints
        +extends Object
        +
        A collection of hint rules.
        +
        +
        Author:
        +
        Jeremy Long
        +
        +
      • +
      +
      +
      + +
      +
      +
        +
      • + +
          +
        • + + +

          Constructor Detail

          + + + +
            +
          • +

            Hints

            +
            public Hints()
            +
          • +
          +
        • +
        + +
          +
        • + + +

          Method Detail

          + + + +
            +
          • +

            getHintRules

            +
            public List<HintRule> getHintRules()
            +
            Get the value of hintRules.
            +
            +
            Returns:
            +
            the value of hintRules
            +
            +
          • +
          + + + +
            +
          • +

            setHintRules

            +
            public void setHintRules(List<HintRule> hintRules)
            +
            Set the value of hintRules.
            +
            +
            Parameters:
            +
            hintRules - new value of hintRules
            +
            +
          • +
          + + + +
            +
          • +

            getVendorDuplicatingHintRules

            +
            public List<VendorDuplicatingHintRule> getVendorDuplicatingHintRules()
            +
            Get the value of vendorDuplicatingHintRules.
            +
            +
            Returns:
            +
            the value of vendorDuplicatingHintRules
            +
            +
          • +
          + + + +
            +
          • +

            setVendorDuplicatingHintRules

            +
            public void setVendorDuplicatingHintRules(List<VendorDuplicatingHintRule> vendorDuplicatingHintRules)
            +
            Set the value of vendorDuplicatingHintRules.
            +
            +
            Parameters:
            +
            vendorDuplicatingHintRules - new value of vendorDuplicatingHintRules
            +
            +
          • +
          +
        • +
        +
      • +
      +
      +
      + + +
      + + + + + + + +
      + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/VendorDuplicatingHintRule.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/VendorDuplicatingHintRule.html new file mode 100644 index 000000000..e1d5029fb --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/VendorDuplicatingHintRule.html @@ -0,0 +1,357 @@ + + + + + + +VendorDuplicatingHintRule (Dependency-Check Core 1.4.2 API) + + + + + + + + +
      + + + + + + + +
      + + + +
      +
      org.owasp.dependencycheck.xml.hints
      +

      Class VendorDuplicatingHintRule

      +
      +
      + +
      +
        +
      • +
        +
        +
        public class VendorDuplicatingHintRule
        +extends Object
        +
        Used to duplicate vendor evidence within a collection. The intent is if any evidence + is found in a collection that matches the value given the evidence will be + duplicated and the value replaced with the value indicated.
        +
        +
        Author:
        +
        Jeremy Long
        +
        +
      • +
      +
      +
      + +
      +
      +
        +
      • + +
          +
        • + + +

          Constructor Detail

          + + + +
            +
          • +

            VendorDuplicatingHintRule

            +
            public VendorDuplicatingHintRule(String value,
            +                                 String duplicate)
            +
            Constructs a new duplicating rule.
            +
            +
            Parameters:
            +
            value - the value to duplicate the evidence if found
            +
            duplicate - the value to replace within the duplicated evidence
            +
            +
          • +
          +
        • +
        + +
          +
        • + + +

          Method Detail

          + + + +
            +
          • +

            getValue

            +
            public String getValue()
            +
            Get the value of value.
            +
            +
            Returns:
            +
            the value of value
            +
            +
          • +
          + + + +
            +
          • +

            setValue

            +
            public void setValue(String value)
            +
            Set the value of value.
            +
            +
            Parameters:
            +
            value - new value of value
            +
            +
          • +
          + + + +
            +
          • +

            getDuplicate

            +
            public String getDuplicate()
            +
            Get the value of duplicate.
            +
            +
            Returns:
            +
            the value of duplicate
            +
            +
          • +
          + + + +
            +
          • +

            setDuplicate

            +
            public void setDuplicate(String duplicate)
            +
            Set the value of duplicate.
            +
            +
            Parameters:
            +
            duplicate - new value of duplicate
            +
            +
          • +
          +
        • +
        +
      • +
      +
      +
      + + +
      + + + + + + + +
      + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/class-use/HintErrorHandler.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/class-use/HintErrorHandler.html new file mode 100644 index 000000000..dbc34552f --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/class-use/HintErrorHandler.html @@ -0,0 +1,126 @@ + + + + + + +Uses of Class org.owasp.dependencycheck.xml.hints.HintErrorHandler (Dependency-Check Core 1.4.2 API) + + + + + + + + +
      + + + + + + + +
      + + +
      +

      Uses of Class
      org.owasp.dependencycheck.xml.hints.HintErrorHandler

      +
      +
      No usage of org.owasp.dependencycheck.xml.hints.HintErrorHandler
      + +
      + + + + + + + +
      + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/class-use/HintHandler.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/class-use/HintHandler.html new file mode 100644 index 000000000..7c6294ac5 --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/class-use/HintHandler.html @@ -0,0 +1,126 @@ + + + + + + +Uses of Class org.owasp.dependencycheck.xml.hints.HintHandler (Dependency-Check Core 1.4.2 API) + + + + + + + + +
      + + + + + + + +
      + + +
      +

      Uses of Class
      org.owasp.dependencycheck.xml.hints.HintHandler

      +
      +
      No usage of org.owasp.dependencycheck.xml.hints.HintHandler
      + +
      + + + + + + + +
      + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/class-use/HintParseException.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/class-use/HintParseException.html new file mode 100644 index 000000000..b129367c5 --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/class-use/HintParseException.html @@ -0,0 +1,177 @@ + + + + + + +Uses of Class org.owasp.dependencycheck.xml.hints.HintParseException (Dependency-Check Core 1.4.2 API) + + + + + + + + +
      + + + + + + + +
      + + +
      +

      Uses of Class
      org.owasp.dependencycheck.xml.hints.HintParseException

      +
      +
      + +
      + +
      + + + + + + + +
      + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/class-use/HintParser.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/class-use/HintParser.html new file mode 100644 index 000000000..90021d077 --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/class-use/HintParser.html @@ -0,0 +1,126 @@ + + + + + + +Uses of Class org.owasp.dependencycheck.xml.hints.HintParser (Dependency-Check Core 1.4.2 API) + + + + + + + + +
      + + + + + + + +
      + + +
      +

      Uses of Class
      org.owasp.dependencycheck.xml.hints.HintParser

      +
      +
      No usage of org.owasp.dependencycheck.xml.hints.HintParser
      + +
      + + + + + + + +
      + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/class-use/HintRule.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/class-use/HintRule.html new file mode 100644 index 000000000..789dd352a --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/class-use/HintRule.html @@ -0,0 +1,191 @@ + + + + + + +Uses of Class org.owasp.dependencycheck.xml.hints.HintRule (Dependency-Check Core 1.4.2 API) + + + + + + + + +
      + + + + + + + +
      + + +
      +

      Uses of Class
      org.owasp.dependencycheck.xml.hints.HintRule

      +
      +
      + +
      + +
      + + + + + + + +
      + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/class-use/Hints.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/class-use/Hints.html new file mode 100644 index 000000000..3d6115f73 --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/class-use/Hints.html @@ -0,0 +1,177 @@ + + + + + + +Uses of Class org.owasp.dependencycheck.xml.hints.Hints (Dependency-Check Core 1.4.2 API) + + + + + + + + +
      + + + + + + + +
      + + +
      +

      Uses of Class
      org.owasp.dependencycheck.xml.hints.Hints

      +
      +
      + +
      + +
      + + + + + + + +
      + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/class-use/VendorDuplicatingHintRule.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/class-use/VendorDuplicatingHintRule.html new file mode 100644 index 000000000..e9151d231 --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/class-use/VendorDuplicatingHintRule.html @@ -0,0 +1,191 @@ + + + + + + +Uses of Class org.owasp.dependencycheck.xml.hints.VendorDuplicatingHintRule (Dependency-Check Core 1.4.2 API) + + + + + + + + +
      + + + + + + + +
      + + +
      +

      Uses of Class
      org.owasp.dependencycheck.xml.hints.VendorDuplicatingHintRule

      +
      +
      + +
      + +
      + + + + + + + +
      + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/package-frame.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/package-frame.html new file mode 100644 index 000000000..046d5d4fe --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/package-frame.html @@ -0,0 +1,30 @@ + + + + + + +org.owasp.dependencycheck.xml.hints (Dependency-Check Core 1.4.2 API) + + + + + +

      org.owasp.dependencycheck.xml.hints

      +
      +

      Classes

      + +

      Exceptions

      + +
      + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/package-summary.html new file mode 100644 index 000000000..c5d972a04 --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/package-summary.html @@ -0,0 +1,204 @@ + + + + + + +org.owasp.dependencycheck.xml.hints (Dependency-Check Core 1.4.2 API) + + + + + + + + +
      + + + + + + + +
      + + +
      +

      Package org.owasp.dependencycheck.xml.hints

      +
      +
      Contains classes used to parse the hints file to add evidence to dependencies.
      +
      +

      See: Description

      +
      +
      + + + + +

      Package org.owasp.dependencycheck.xml.hints Description

      +
      Contains classes used to parse the hints file to add evidence to dependencies.
      +
      + +
      + + + + + + + +
      + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/package-tree.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/package-tree.html new file mode 100644 index 000000000..c6772e661 --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/package-tree.html @@ -0,0 +1,161 @@ + + + + + + +org.owasp.dependencycheck.xml.hints Class Hierarchy (Dependency-Check Core 1.4.2 API) + + + + + + + + +
      + + + + + + + +
      + + +
      +

      Hierarchy For Package org.owasp.dependencycheck.xml.hints

      +Package Hierarchies: + +
      +
      +

      Class Hierarchy

      + +
      + +
      + + + + + + + +
      + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/package-use.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/package-use.html new file mode 100644 index 000000000..56b8e3eac --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/hints/package-use.html @@ -0,0 +1,180 @@ + + + + + + +Uses of Package org.owasp.dependencycheck.xml.hints (Dependency-Check Core 1.4.2 API) + + + + + + + + +
      + + + + + + + +
      + + +
      +

      Uses of Package
      org.owasp.dependencycheck.xml.hints

      +
      +
      + +
      + +
      + + + + + + + +
      + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/License.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/License.html index 9d14b1db2..981e3c50c 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/License.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/License.html @@ -2,10 +2,10 @@ - + -License (Dependency-Check Core 1.4.0 API) - +License (Dependency-Check Core 1.4.2 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/package-summary.html index 94f6bd963..147a7ec1e 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/package-summary.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.xml.pom (Dependency-Check Core 1.4.0 API) - +org.owasp.dependencycheck.xml.pom (Dependency-Check Core 1.4.2 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ + + + + + +
      + + + + + + + +
      + + + +
      +
      org.owasp.dependencycheck.xml.suppression
      +

      Class PropertyType

      +
      +
      + +
      +
        +
      • +
        +
        +
        public class PropertyType
        +extends Object
        +
        A simple PropertyType used to represent a string value that could be used as a regular expression or could be case + insensitive. The equals method has been over-ridden so that the object will correctly compare to strings.
        +
        +
        Author:
        +
        Jeremy Long
        +
        +
      • +
      +
      +
      +
        +
      • + +
          +
        • + + +

          Constructor Summary

          + + + + + + + + +
          Constructors 
          Constructor and Description
          PropertyType() 
          +
        • +
        + + +
      • +
      +
      +
      +
        +
      • + +
          +
        • + + +

          Constructor Detail

          + + + +
            +
          • +

            PropertyType

            +
            public PropertyType()
            +
          • +
          +
        • +
        + +
          +
        • + + +

          Method Detail

          + + + +
            +
          • +

            getValue

            +
            public String getValue()
            +
            Gets the value of the value property.
            +
            +
            Returns:
            +
            the value of the value property
            +
            +
          • +
          + + + +
            +
          • +

            setValue

            +
            public void setValue(String value)
            +
            Sets the value of the value property.
            +
            +
            Parameters:
            +
            value - the value of the value property
            +
            +
          • +
          + + + +
            +
          • +

            isRegex

            +
            public boolean isRegex()
            +
            Returns whether or not the value is a regex.
            +
            +
            Returns:
            +
            true if the value is a regex, otherwise false
            +
            +
          • +
          + + + +
            +
          • +

            setRegex

            +
            public void setRegex(boolean value)
            +
            Sets whether the value property is a regex.
            +
            +
            Parameters:
            +
            value - true if the value is a regex, otherwise false
            +
            +
          • +
          + + + +
            +
          • +

            isCaseSensitive

            +
            public boolean isCaseSensitive()
            +
            Gets the value of the caseSensitive property.
            +
            +
            Returns:
            +
            true if the value is case sensitive
            +
            +
          • +
          + + + +
            +
          • +

            setCaseSensitive

            +
            public void setCaseSensitive(boolean value)
            +
            Sets the value of the caseSensitive property.
            +
            +
            Parameters:
            +
            value - whether the value is case sensitive
            +
            +
          • +
          + + + +
            +
          • +

            matches

            +
            public boolean matches(String text)
            +
            Uses the object's properties to determine if the supplied string matches the value of this property.
            +
            +
            Parameters:
            +
            text - the String to validate
            +
            Returns:
            +
            whether the text supplied is matched by the value of the property
            +
            +
          • +
          + + + +
            +
          • +

            hashCode

            +
            public int hashCode()
            +
            Default implementation of hashCode.
            +
            +
            Overrides:
            +
            hashCode in class Object
            +
            Returns:
            +
            the hash code
            +
            +
          • +
          + + + +
            +
          • +

            equals

            +
            public boolean equals(Object obj)
            +
            Default implementation of equals.
            +
            +
            Overrides:
            +
            equals in class Object
            +
            Parameters:
            +
            obj - the object to compare
            +
            Returns:
            +
            whether the objects are equivalent
            +
            +
          • +
          + + + +
            +
          • +

            toString

            +
            public String toString()
            +
            Default implementation of toString().
            +
            +
            Overrides:
            +
            toString in class Object
            +
            Returns:
            +
            the string representation of the object
            +
            +
          • +
          +
        • +
        +
      • +
      +
      +
      + + +
      + + + + + + + +
      + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/SuppressionErrorHandler.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/SuppressionErrorHandler.html new file mode 100644 index 000000000..bf24ba0a5 --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/SuppressionErrorHandler.html @@ -0,0 +1,345 @@ + + + + + + +SuppressionErrorHandler (Dependency-Check Core 1.4.2 API) + + + + + + + + +
      + + + + + + + +
      + + + +
      +
      org.owasp.dependencycheck.xml.suppression
      +

      Class SuppressionErrorHandler

      +
      +
      + +
      +
        +
      • +
        +
        All Implemented Interfaces:
        +
        ErrorHandler
        +
        +
        +
        +
        public class SuppressionErrorHandler
        +extends Object
        +implements ErrorHandler
        +
        An XML parsing error handler.
        +
        +
        Author:
        +
        Jeremy Long
        +
        +
      • +
      +
      +
      + +
      +
      + +
      +
      + + +
      + + + + + + + +
      + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/SuppressionHandler.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/SuppressionHandler.html new file mode 100644 index 000000000..bd136bf32 --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/SuppressionHandler.html @@ -0,0 +1,586 @@ + + + + + + +SuppressionHandler (Dependency-Check Core 1.4.2 API) + + + + + + + + +
      + + + + + + + +
      + + + +
      +
      org.owasp.dependencycheck.xml.suppression
      +

      Class SuppressionHandler

      +
      +
      + +
      + +
      +
      + +
      +
      +
        +
      • + + + +
          +
        • + + +

          Constructor Detail

          + + + +
            +
          • +

            SuppressionHandler

            +
            public SuppressionHandler()
            +
          • +
          +
        • +
        + +
          +
        • + + +

          Method Detail

          + + + +
            +
          • +

            getSuppressionRules

            +
            public List<SuppressionRule> getSuppressionRules()
            +
            Get the value of suppressionRules.
            +
            +
            Returns:
            +
            the value of suppressionRules
            +
            +
          • +
          + + + +
            +
          • +

            startElement

            +
            public void startElement(String uri,
            +                         String localName,
            +                         String qName,
            +                         Attributes attributes)
            +                  throws SAXException
            +
            Handles the start element event.
            +
            +
            Specified by:
            +
            startElement in interface ContentHandler
            +
            Overrides:
            +
            startElement in class DefaultHandler
            +
            Parameters:
            +
            uri - the uri of the element being processed
            +
            localName - the local name of the element being processed
            +
            qName - the qName of the element being processed
            +
            attributes - the attributes of the element being processed
            +
            Throws:
            +
            SAXException - thrown if there is an exception processing
            +
            +
          • +
          + + + + + + + +
            +
          • +

            characters

            +
            public void characters(char[] ch,
            +                       int start,
            +                       int length)
            +                throws SAXException
            +
            Collects the body text of the node being processed.
            +
            +
            Specified by:
            +
            characters in interface ContentHandler
            +
            Overrides:
            +
            characters in class DefaultHandler
            +
            Parameters:
            +
            ch - the char array of text
            +
            start - the start position to copy text from in the char array
            +
            length - the number of characters to copy from the char array
            +
            Throws:
            +
            SAXException - thrown if there is a parsing exception
            +
            +
          • +
          +
        • +
        +
      • +
      +
      +
      + + +
      + + + + + + + +
      + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/SuppressionParseException.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/SuppressionParseException.html new file mode 100644 index 000000000..076ab2548 --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/SuppressionParseException.html @@ -0,0 +1,335 @@ + + + + + + +SuppressionParseException (Dependency-Check Core 1.4.2 API) + + + + + + + + +
      + + + + + + + +
      + + + +
      +
      org.owasp.dependencycheck.xml.suppression
      +

      Class SuppressionParseException

      +
      +
      + +
      +
        +
      • +
        +
        All Implemented Interfaces:
        +
        Serializable
        +
        +
        +
        +
        public class SuppressionParseException
        +extends IOException
        +
        An exception used when parsing a suppression rule file fails.
        +
        +
        Author:
        +
        Jeremy Long
        +
        See Also:
        +
        Serialized Form
        +
        +
      • +
      +
      +
      + +
      +
      +
        +
      • + +
          +
        • + + +

          Constructor Detail

          + + + +
            +
          • +

            SuppressionParseException

            +
            public SuppressionParseException()
            +
            Creates a new SuppressionParseException.
            +
          • +
          + + + +
            +
          • +

            SuppressionParseException

            +
            public SuppressionParseException(String msg)
            +
            Creates a new SuppressionParseException.
            +
            +
            Parameters:
            +
            msg - a message for the exception.
            +
            +
          • +
          + + + +
            +
          • +

            SuppressionParseException

            +
            public SuppressionParseException(Throwable ex)
            +
            Creates a new SuppressionParseException.
            +
            +
            Parameters:
            +
            ex - the cause of the parse exception
            +
            +
          • +
          + + + +
            +
          • +

            SuppressionParseException

            +
            public SuppressionParseException(String msg,
            +                                 Throwable ex)
            +
            Creates a new SuppressionParseException.
            +
            +
            Parameters:
            +
            msg - a message for the exception.
            +
            ex - the cause of the parse exception
            +
            +
          • +
          +
        • +
        +
      • +
      +
      +
      + + +
      + + + + + + + +
      + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/SuppressionParser.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/SuppressionParser.html new file mode 100644 index 000000000..243510419 --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/SuppressionParser.html @@ -0,0 +1,407 @@ + + + + + + +SuppressionParser (Dependency-Check Core 1.4.2 API) + + + + + + + + +
      + + + + + + + +
      + + + +
      +
      org.owasp.dependencycheck.xml.suppression
      +

      Class SuppressionParser

      +
      +
      + +
      +
        +
      • +
        +
        +
        public class SuppressionParser
        +extends Object
        +
        A simple validating parser for XML Suppression Rules.
        +
        +
        Author:
        +
        Jeremy Long
        +
        +
      • +
      +
      +
      + +
      +
      +
        +
      • + +
          +
        • + + +

          Field Detail

          + + + +
            +
          • +

            JAXP_SCHEMA_LANGUAGE

            +
            public static final String JAXP_SCHEMA_LANGUAGE
            +
            JAXP Schema Language. Source: + http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html
            +
            +
            See Also:
            +
            Constant Field Values
            +
            +
          • +
          + + + +
            +
          • +

            W3C_XML_SCHEMA

            +
            public static final String W3C_XML_SCHEMA
            +
            W3C XML Schema. Source: + http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html
            +
            +
            See Also:
            +
            Constant Field Values
            +
            +
          • +
          + + + +
            +
          • +

            JAXP_SCHEMA_SOURCE

            +
            public static final String JAXP_SCHEMA_SOURCE
            +
            JAXP Schema Source. Source: + http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html
            +
            +
            See Also:
            +
            Constant Field Values
            +
            +
          • +
          +
        • +
        + +
          +
        • + + +

          Constructor Detail

          + + + +
            +
          • +

            SuppressionParser

            +
            public SuppressionParser()
            +
          • +
          +
        • +
        + + +
      • +
      +
      +
      + + +
      + + + + + + + +
      + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/SuppressionRule.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/SuppressionRule.html new file mode 100644 index 000000000..4e047db36 --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/SuppressionRule.html @@ -0,0 +1,807 @@ + + + + + + +SuppressionRule (Dependency-Check Core 1.4.2 API) + + + + + + + + +
      + + + + + + + +
      + + + +
      +
      org.owasp.dependencycheck.xml.suppression
      +

      Class SuppressionRule

      +
      +
      + +
      +
        +
      • +
        +
        +
        public class SuppressionRule
        +extends Object
        +
        +
        Author:
        +
        Jeremy Long
        +
        +
      • +
      +
      +
      + +
      +
      +
        +
      • + +
          +
        • + + +

          Constructor Detail

          + + + +
            +
          • +

            SuppressionRule

            +
            public SuppressionRule()
            +
          • +
          +
        • +
        + +
          +
        • + + +

          Method Detail

          + + + +
            +
          • +

            getFilePath

            +
            public PropertyType getFilePath()
            +
            Get the value of filePath.
            +
            +
            Returns:
            +
            the value of filePath
            +
            +
          • +
          + + + +
            +
          • +

            setFilePath

            +
            public void setFilePath(PropertyType filePath)
            +
            Set the value of filePath.
            +
            +
            Parameters:
            +
            filePath - new value of filePath
            +
            +
          • +
          + + + +
            +
          • +

            getSha1

            +
            public String getSha1()
            +
            Get the value of sha1.
            +
            +
            Returns:
            +
            the value of sha1
            +
            +
          • +
          + + + +
            +
          • +

            setSha1

            +
            public void setSha1(String sha1)
            +
            Set the value of sha1.
            +
            +
            Parameters:
            +
            sha1 - new value of sha1
            +
            +
          • +
          + + + +
            +
          • +

            getCpe

            +
            public List<PropertyType> getCpe()
            +
            Get the value of cpe.
            +
            +
            Returns:
            +
            the value of cpe
            +
            +
          • +
          + + + +
            +
          • +

            setCpe

            +
            public void setCpe(List<PropertyType> cpe)
            +
            Set the value of cpe.
            +
            +
            Parameters:
            +
            cpe - new value of cpe
            +
            +
          • +
          + + + +
            +
          • +

            addCpe

            +
            public void addCpe(PropertyType cpe)
            +
            Adds the cpe to the cpe list.
            +
            +
            Parameters:
            +
            cpe - the cpe to add
            +
            +
          • +
          + + + +
            +
          • +

            hasCpe

            +
            public boolean hasCpe()
            +
            Returns whether or not this suppression rule as CPE entries.
            +
            +
            Returns:
            +
            whether or not this suppression rule as CPE entries
            +
            +
          • +
          + + + +
            +
          • +

            getCvssBelow

            +
            public List<Float> getCvssBelow()
            +
            Get the value of cvssBelow.
            +
            +
            Returns:
            +
            the value of cvssBelow
            +
            +
          • +
          + + + +
            +
          • +

            setCvssBelow

            +
            public void setCvssBelow(List<Float> cvssBelow)
            +
            Set the value of cvssBelow.
            +
            +
            Parameters:
            +
            cvssBelow - new value of cvssBelow
            +
            +
          • +
          + + + +
            +
          • +

            addCvssBelow

            +
            public void addCvssBelow(Float cvss)
            +
            Adds the cvss to the cvssBelow list.
            +
            +
            Parameters:
            +
            cvss - the cvss to add
            +
            +
          • +
          + + + +
            +
          • +

            hasCvssBelow

            +
            public boolean hasCvssBelow()
            +
            Returns whether or not this suppression rule has cvss suppressions.
            +
            +
            Returns:
            +
            whether or not this suppression rule has cvss suppressions
            +
            +
          • +
          + + + +
            +
          • +

            getCwe

            +
            public List<String> getCwe()
            +
            Get the value of cwe.
            +
            +
            Returns:
            +
            the value of cwe
            +
            +
          • +
          + + + +
            +
          • +

            setCwe

            +
            public void setCwe(List<String> cwe)
            +
            Set the value of cwe.
            +
            +
            Parameters:
            +
            cwe - new value of cwe
            +
            +
          • +
          + + + +
            +
          • +

            addCwe

            +
            public void addCwe(String cwe)
            +
            Adds the cwe to the cwe list.
            +
            +
            Parameters:
            +
            cwe - the cwe to add
            +
            +
          • +
          + + + +
            +
          • +

            hasCwe

            +
            public boolean hasCwe()
            +
            Returns whether this suppression rule has CWE entries.
            +
            +
            Returns:
            +
            whether this suppression rule has CWE entries
            +
            +
          • +
          + + + +
            +
          • +

            getCve

            +
            public List<String> getCve()
            +
            Get the value of cve.
            +
            +
            Returns:
            +
            the value of cve
            +
            +
          • +
          + + + +
            +
          • +

            setCve

            +
            public void setCve(List<String> cve)
            +
            Set the value of cve.
            +
            +
            Parameters:
            +
            cve - new value of cve
            +
            +
          • +
          + + + +
            +
          • +

            addCve

            +
            public void addCve(String cve)
            +
            Adds the cve to the cve list.
            +
            +
            Parameters:
            +
            cve - the cve to add
            +
            +
          • +
          + + + +
            +
          • +

            hasCve

            +
            public boolean hasCve()
            +
            Returns whether this suppression rule has CVE entries.
            +
            +
            Returns:
            +
            whether this suppression rule has CVE entries
            +
            +
          • +
          + + + +
            +
          • +

            getGav

            +
            public PropertyType getGav()
            +
            Get the value of Maven GAV.
            +
            +
            Returns:
            +
            the value of gav
            +
            +
          • +
          + + + +
            +
          • +

            setGav

            +
            public void setGav(PropertyType gav)
            +
            Set the value of Maven GAV.
            +
            +
            Parameters:
            +
            gav - new value of Maven gav
            +
            +
          • +
          + + + +
            +
          • +

            hasGav

            +
            public boolean hasGav()
            +
            Returns whether or not this suppression rule as GAV entries.
            +
            +
            Returns:
            +
            whether or not this suppression rule as GAV entries
            +
            +
          • +
          + + + +
            +
          • +

            isBase

            +
            public boolean isBase()
            +
            Get the value of base.
            +
            +
            Returns:
            +
            the value of base
            +
            +
          • +
          + + + +
            +
          • +

            setBase

            +
            public void setBase(boolean base)
            +
            Set the value of base.
            +
            +
            Parameters:
            +
            base - new value of base
            +
            +
          • +
          + + + +
            +
          • +

            process

            +
            public void process(Dependency dependency)
            +
            Processes a given dependency to determine if any CPE, CVE, CWE, or CVSS scores should be suppressed. If any should be, they + are removed from the dependency.
            +
            +
            Parameters:
            +
            dependency - a project dependency to analyze
            +
            +
          • +
          + + + +
            +
          • +

            toString

            +
            public String toString()
            +
            Standard toString implementation.
            +
            +
            Overrides:
            +
            toString in class Object
            +
            Returns:
            +
            a string representation of this object
            +
            +
          • +
          +
        • +
        +
      • +
      +
      +
      + + +
      + + + + + + + +
      + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/class-use/PropertyType.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/class-use/PropertyType.html new file mode 100644 index 000000000..7497559d3 --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/class-use/PropertyType.html @@ -0,0 +1,274 @@ + + + + + + +Uses of Class org.owasp.dependencycheck.xml.suppression.PropertyType (Dependency-Check Core 1.4.2 API) + + + + + + + + +
      + + + + + + + +
      + + +
      +

      Uses of Class
      org.owasp.dependencycheck.xml.suppression.PropertyType

      +
      +
      + +
      + +
      + + + + + + + +
      + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/class-use/SuppressionErrorHandler.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/class-use/SuppressionErrorHandler.html new file mode 100644 index 000000000..b597b67a8 --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/class-use/SuppressionErrorHandler.html @@ -0,0 +1,126 @@ + + + + + + +Uses of Class org.owasp.dependencycheck.xml.suppression.SuppressionErrorHandler (Dependency-Check Core 1.4.2 API) + + + + + + + + +
      + + + + + + + +
      + + +
      +

      Uses of Class
      org.owasp.dependencycheck.xml.suppression.SuppressionErrorHandler

      +
      +
      No usage of org.owasp.dependencycheck.xml.suppression.SuppressionErrorHandler
      + +
      + + + + + + + +
      + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/class-use/SuppressionHandler.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/class-use/SuppressionHandler.html new file mode 100644 index 000000000..cc7633f9e --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/class-use/SuppressionHandler.html @@ -0,0 +1,126 @@ + + + + + + +Uses of Class org.owasp.dependencycheck.xml.suppression.SuppressionHandler (Dependency-Check Core 1.4.2 API) + + + + + + + + +
      + + + + + + + +
      + + +
      +

      Uses of Class
      org.owasp.dependencycheck.xml.suppression.SuppressionHandler

      +
      +
      No usage of org.owasp.dependencycheck.xml.suppression.SuppressionHandler
      + +
      + + + + + + + +
      + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/class-use/SuppressionParseException.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/class-use/SuppressionParseException.html new file mode 100644 index 000000000..160286e17 --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/class-use/SuppressionParseException.html @@ -0,0 +1,178 @@ + + + + + + +Uses of Class org.owasp.dependencycheck.xml.suppression.SuppressionParseException (Dependency-Check Core 1.4.2 API) + + + + + + + + +
      + + + + + + + +
      + + +
      +

      Uses of Class
      org.owasp.dependencycheck.xml.suppression.SuppressionParseException

      +
      +
      + +
      + +
      + + + + + + + +
      + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/class-use/SuppressionParser.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/class-use/SuppressionParser.html new file mode 100644 index 000000000..687449165 --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/class-use/SuppressionParser.html @@ -0,0 +1,126 @@ + + + + + + +Uses of Class org.owasp.dependencycheck.xml.suppression.SuppressionParser (Dependency-Check Core 1.4.2 API) + + + + + + + + +
      + + + + + + + +
      + + +
      +

      Uses of Class
      org.owasp.dependencycheck.xml.suppression.SuppressionParser

      +
      +
      No usage of org.owasp.dependencycheck.xml.suppression.SuppressionParser
      + +
      + + + + + + + +
      + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/class-use/SuppressionRule.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/class-use/SuppressionRule.html new file mode 100644 index 000000000..9da1b0878 --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/class-use/SuppressionRule.html @@ -0,0 +1,225 @@ + + + + + + +Uses of Class org.owasp.dependencycheck.xml.suppression.SuppressionRule (Dependency-Check Core 1.4.2 API) + + + + + + + + +
      + + + + + + + +
      + + +
      +

      Uses of Class
      org.owasp.dependencycheck.xml.suppression.SuppressionRule

      +
      +
      + +
      + +
      + + + + + + + +
      + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/package-frame.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/package-frame.html new file mode 100644 index 000000000..df23e8119 --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/package-frame.html @@ -0,0 +1,29 @@ + + + + + + +org.owasp.dependencycheck.xml.suppression (Dependency-Check Core 1.4.2 API) + + + + + +

      org.owasp.dependencycheck.xml.suppression

      +
      +

      Classes

      + +

      Exceptions

      + +
      + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/package-summary.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/package-summary.html new file mode 100644 index 000000000..28dd40131 --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/package-summary.html @@ -0,0 +1,195 @@ + + + + + + +org.owasp.dependencycheck.xml.suppression (Dependency-Check Core 1.4.2 API) + + + + + + + + +
      + + + + + + + +
      + + +
      +

      Package org.owasp.dependencycheck.xml.suppression

      +
      +
      Contains classes used to suppress findings.
      +
      +

      See: Description

      +
      +
      + + + + +

      Package org.owasp.dependencycheck.xml.suppression Description

      +
      Contains classes used to suppress findings.
      +
      + +
      + + + + + + + +
      + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/package-tree.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/package-tree.html new file mode 100644 index 000000000..eb21a3e66 --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/package-tree.html @@ -0,0 +1,160 @@ + + + + + + +org.owasp.dependencycheck.xml.suppression Class Hierarchy (Dependency-Check Core 1.4.2 API) + + + + + + + + +
      + + + + + + + +
      + + +
      +

      Hierarchy For Package org.owasp.dependencycheck.xml.suppression

      +Package Hierarchies: + +
      +
      +

      Class Hierarchy

      + +
      + +
      + + + + + + + +
      + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/package-use.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/package-use.html new file mode 100644 index 000000000..c942beb07 --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/suppression/package-use.html @@ -0,0 +1,217 @@ + + + + + + +Uses of Package org.owasp.dependencycheck.xml.suppression (Dependency-Check Core 1.4.2 API) + + + + + + + + +
      + + + + + + + +
      + + +
      +

      Uses of Package
      org.owasp.dependencycheck.xml.suppression

      +
      +
      + +
      + +
      + + + + + + + +
      + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-core/apidocs/overview-frame.html b/dependency-check-core/apidocs/overview-frame.html index 6773821fb..0e07f9625 100644 --- a/dependency-check-core/apidocs/overview-frame.html +++ b/dependency-check-core/apidocs/overview-frame.html @@ -2,10 +2,10 @@ - + -Overview List (Dependency-Check Core 1.4.0 API) - +Overview List (Dependency-Check Core 1.4.2 API) + @@ -33,9 +33,10 @@
    176. org.owasp.dependencycheck.dependency
    177. org.owasp.dependencycheck.exception
    178. org.owasp.dependencycheck.reporting
    179. -
    180. org.owasp.dependencycheck.suppression
    181. org.owasp.dependencycheck.utils
    182. +
    183. org.owasp.dependencycheck.xml.hints
    184. org.owasp.dependencycheck.xml.pom
    185. +
    186. org.owasp.dependencycheck.xml.suppression
    187.  

      diff --git a/dependency-check-core/apidocs/overview-summary.html b/dependency-check-core/apidocs/overview-summary.html index 5a7547168..04a0f45b4 100644 --- a/dependency-check-core/apidocs/overview-summary.html +++ b/dependency-check-core/apidocs/overview-summary.html @@ -2,10 +2,10 @@ - + -Overview (Dependency-Check Core 1.4.0 API) - +Overview (Dependency-Check Core 1.4.2 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ - + diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.analyzer.exception.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.analyzer.exception.html index 110ccb0a2..e05aa2233 100644 --- a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.analyzer.exception.html +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.analyzer.exception.html @@ -39,6 +39,6 @@ var classTable = new SortableTable(document.getElementById("classResults"), ["String", "Percentage", "Percentage", "FormattedNumber"]); classTable.sort(0); - + diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.analyzer.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.analyzer.html index 2865e11e1..51b613639 100644 --- a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.analyzer.html +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.analyzer.html @@ -16,7 +16,7 @@ - +
      Package # Classes Line Coverage Branch Coverage Complexity
      org.owasp.dependencycheck.analyzer37
      60%
      1650/2711
      44%
      656/1472
      4.393
      org.owasp.dependencycheck.analyzer37
      58%
      1676/2856
      43%
      664/1534
      4.669
      org.owasp.dependencycheck.analyzer.exception2
      25%
      4/16
      N/A
      1
      @@ -33,7 +33,7 @@ packageTable.sort(0); AbstractFileTypeAnalyzer
      84%
      33/39
      80%
      8/10
      1.429 - AbstractSuppressionAnalyzer
      75%
      48/64
      71%
      10/14
      4 + AbstractSuppressionAnalyzer
      80%
      50/62
      71%
      10/14
      4.333 AnalysisPhase
      100%
      11/11
      N/A
      0 @@ -41,21 +41,21 @@ packageTable.sort(0); AnalyzerService
      89%
      17/19
      100%
      6/6
      3 - ArchiveAnalyzer
      36%
      73/200
      25%
      23/90
      5.188 + ArchiveAnalyzer
      34%
      78/225
      14%
      20/136
      6.412 - AssemblyAnalyzer
      65%
      75/115
      55%
      21/38
      6 + AssemblyAnalyzer
      62%
      77/123
      55%
      21/38
      6.5 AutoconfAnalyzer
      90%
      64/71
      76%
      26/34
      3.222 CMakeAnalyzer
      91%
      65/71
      80%
      8/10
      2.143 - CPEAnalyzer
      83%
      194/232
      76%
      103/134
      4.607 - CPEAnalyzer$IdentifierConfidence
      100%
      4/4
      N/A
      4.607 - CPEAnalyzer$IdentifierMatch
      38%
      15/39
      16%
      4/24
      4.607 + CPEAnalyzer
      81%
      194/238
      76%
      103/134
      4.75 + CPEAnalyzer$IdentifierConfidence
      100%
      4/4
      N/A
      4.75 + CPEAnalyzer$IdentifierMatch
      38%
      15/39
      16%
      4/24
      4.75 - CentralAnalyzer
      26%
      18/69
      10%
      3/30
      3.625 + CentralAnalyzer
      24%
      18/73
      10%
      3/30
      3.875 - ComposerLockAnalyzer
      83%
      31/37
      75%
      3/4
      1.833 + ComposerLockAnalyzer
      78%
      32/41
      75%
      3/4
      2.167 CpeSuppressionAnalyzer
      90%
      9/10
      66%
      4/6
      2.333 @@ -69,26 +69,26 @@ packageTable.sort(0); FileTypeAnalyzer
      N/A
      N/A
      1 - HintAnalyzer
      74%
      37/50
      56%
      17/30
      6 + HintAnalyzer
      45%
      49/107
      60%
      28/46
      8.8 - JarAnalyzer
      66%
      349/522
      56%
      195/346
      7.355 - JarAnalyzer$ClassNameInformation
      80%
      17/21
      80%
      8/10
      7.355 + JarAnalyzer
      66%
      350/528
      56%
      195/346
      7.419 + JarAnalyzer$ClassNameInformation
      80%
      17/21
      80%
      8/10
      7.419 - NexusAnalyzer
      20%
      14/70
      4%
      1/24
      3.375 + NexusAnalyzer
      20%
      14/70
      4%
      1/24
      3.625 NodePackageAnalyzer
      86%
      46/53
      64%
      9/14
      2.429 NuspecAnalyzer
      25%
      9/36
      0%
      0/6
      2.667 - NvdCveAnalyzer
      68%
      24/35
      50%
      6/12
      2.125 + NvdCveAnalyzer
      53%
      26/49
      50%
      6/12
      3.125 OpenSSLAnalyzer
      91%
      32/35
      71%
      10/14
      2.25 - PythonDistributionAnalyzer
      85%
      89/104
      65%
      30/46
      3.308 + PythonDistributionAnalyzer
      81%
      90/110
      65%
      30/46
      3.462 PythonPackageAnalyzer
      91%
      66/72
      77%
      14/18
      2 - RubyBundleAuditAnalyzer
      16%
      32/200
      2%
      2/74
      5.154 + RubyBundleAuditAnalyzer
      14%
      32/217
      2%
      2/74
      5.846 RubyBundlerAnalyzer
      66%
      20/30
      43%
      13/30
      4.5 RubyBundlerAnalyzer$1
      100%
      2/2
      N/A
      4.5 @@ -105,6 +105,6 @@ var classTable = new SortableTable(document.getElementById("classResults"), ["String", "Percentage", "Percentage", "FormattedNumber"]); classTable.sort(0); - + diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.central.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.central.html index 117831c2b..ea7945662 100644 --- a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.central.html +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.central.html @@ -37,6 +37,6 @@ var classTable = new SortableTable(document.getElementById("classResults"), ["String", "Percentage", "Percentage", "FormattedNumber"]); classTable.sort(0); - + diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.composer.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.composer.html index 115ee547f..209f120a1 100644 --- a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.composer.html +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.composer.html @@ -41,6 +41,6 @@ var classTable = new SortableTable(document.getElementById("classResults"), ["String", "Percentage", "Percentage", "FormattedNumber"]); classTable.sort(0); - + diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.cpe.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.cpe.html index 4edeba148..a64125802 100644 --- a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.cpe.html +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.cpe.html @@ -16,7 +16,7 @@ - +
      Package # Classes Line Coverage Branch Coverage Complexity
      org.owasp.dependencycheck.data.cpe4
      70%
      102/145
      41%
      23/56
      2.5
      org.owasp.dependencycheck.data.cpe4
      69%
      100/143
      41%
      23/56
      2.552
      - + diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.cwe.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.cwe.html index 587dc687a..b53d8c582 100644 --- a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.cwe.html +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.cwe.html @@ -39,6 +39,6 @@ var classTable = new SortableTable(document.getElementById("classResults"), ["String", "Percentage", "Percentage", "FormattedNumber"]); classTable.sort(0); - + diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.lucene.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.lucene.html index bde8a78fe..0d09ba940 100644 --- a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.lucene.html +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.lucene.html @@ -51,6 +51,6 @@ var classTable = new SortableTable(document.getElementById("classResults"), ["String", "Percentage", "Percentage", "FormattedNumber"]); classTable.sort(0); - + diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.nexus.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.nexus.html index 2145cb668..62211709e 100644 --- a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.nexus.html +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.nexus.html @@ -39,6 +39,6 @@ var classTable = new SortableTable(document.getElementById("classResults"), ["String", "Percentage", "Percentage", "FormattedNumber"]); classTable.sort(0); - + diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.nuget.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.nuget.html index f613aec14..34b89a7be 100644 --- a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.nuget.html +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.nuget.html @@ -43,6 +43,6 @@ var classTable = new SortableTable(document.getElementById("classResults"), ["String", "Percentage", "Percentage", "FormattedNumber"]); classTable.sort(0); - + diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.nvdcve.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.nvdcve.html index 244356600..cd5f8327e 100644 --- a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.nvdcve.html +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.nvdcve.html @@ -52,6 +52,6 @@ var classTable = new SortableTable(document.getElementById("classResults"), ["String", "Percentage", "Percentage", "FormattedNumber"]); classTable.sort(0); - + diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.update.cpe.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.update.cpe.html index 2b6834b47..d4fe6b6b4 100644 --- a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.update.cpe.html +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.update.cpe.html @@ -16,7 +16,7 @@ - +
      Package # Classes Line Coverage Branch Coverage Complexity
      org.owasp.dependencycheck.data.update.cpe3
      0%
      0/65
      0%
      0/18
      1.5
      org.owasp.dependencycheck.data.update.cpe3
      0%
      0/66
      0%
      0/18
      1.5
      - + diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.update.exception.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.update.exception.html index 21ddc6106..3c5bb3b8c 100644 --- a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.update.exception.html +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.update.exception.html @@ -39,6 +39,6 @@ var classTable = new SortableTable(document.getElementById("classResults"), ["String", "Percentage", "Percentage", "FormattedNumber"]); classTable.sort(0); - + diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.update.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.update.html index 32a856cb0..285d2a859 100644 --- a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.update.html +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.update.html @@ -16,10 +16,10 @@ - - + + - +
      Package # Classes Line Coverage Branch Coverage Complexity
      org.owasp.dependencycheck.data.update6
      14%
      52/348
      11%
      14/122
      5.6
      org.owasp.dependencycheck.data.update.cpe3
      0%
      0/65
      0%
      0/18
      1.5
      org.owasp.dependencycheck.data.update6
      14%
      52/347
      11%
      14/122
      5.68
      org.owasp.dependencycheck.data.update.cpe3
      0%
      0/66
      0%
      0/18
      1.5
      org.owasp.dependencycheck.data.update.exception2
      0%
      0/12
      N/A
      1
      org.owasp.dependencycheck.data.update.nvd8
      69%
      288/413
      69%
      134/194
      2.865
      org.owasp.dependencycheck.data.update.nvd8
      69%
      290/415
      69%
      134/194
      2.865
      - + diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.update.nvd.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.update.nvd.html index 50f2c262d..b878ba377 100644 --- a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.update.nvd.html +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.update.nvd.html @@ -16,7 +16,7 @@ - +
      Package # Classes Line Coverage Branch Coverage Complexity
      org.owasp.dependencycheck.data.update.nvd8
      69%
      288/413
      69%
      134/194
      2.865
      org.owasp.dependencycheck.data.update.nvd8
      69%
      290/415
      69%
      134/194
      2.865
      - + diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.dependency.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.dependency.html index 03f1974b5..58bad1df8 100644 --- a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.dependency.html +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.dependency.html @@ -16,7 +16,7 @@ - +
      Package # Classes Line Coverage Branch Coverage Complexity
      org.owasp.dependencycheck.dependency14
      64%
      412/637
      55%
      162/294
      1.989
      org.owasp.dependencycheck.dependency14
      64%
      412/639
      55%
      162/294
      1.989
      - + diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.exception.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.exception.html index dd0a5f410..6c7bcbdfe 100644 --- a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.exception.html +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.exception.html @@ -16,7 +16,7 @@ - +
      Package # Classes Line Coverage Branch Coverage Complexity
      org.owasp.dependencycheck.exception2
      0%
      0/16
      N/A
      1
      org.owasp.dependencycheck.exception5
      7%
      6/85
      0%
      0/4
      1.065
      - + diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.html index 51b4bcd0f..4823ffb2b 100644 --- a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.html +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.html @@ -16,28 +16,29 @@ - - - + + + - + - - + + - - - - - + + + + + +
      Package # Classes Line Coverage Branch Coverage Complexity
      org.owasp.dependencycheck1
      58%
      108/186
      60%
      39/64
      3.174
      org.owasp.dependencycheck.agent1
      0%
      0/226
      0%
      0/36
      1.319
      org.owasp.dependencycheck.analyzer37
      60%
      1650/2711
      44%
      656/1472
      4.393
      org.owasp.dependencycheck1
      55%
      116/208
      62%
      41/66
      3.478
      org.owasp.dependencycheck.agent1
      0%
      0/231
      0%
      0/38
      1.375
      org.owasp.dependencycheck.analyzer37
      58%
      1676/2856
      43%
      664/1534
      4.669
      org.owasp.dependencycheck.analyzer.exception2
      25%
      4/16
      N/A
      1
      org.owasp.dependencycheck.data.central1
      83%
      51/61
      83%
      20/24
      10
      org.owasp.dependencycheck.data.composer3
      79%
      53/67
      45%
      19/42
      3.417
      org.owasp.dependencycheck.data.cpe4
      70%
      102/145
      41%
      23/56
      2.5
      org.owasp.dependencycheck.data.cpe4
      69%
      100/143
      41%
      23/56
      2.552
      org.owasp.dependencycheck.data.cwe2
      39%
      13/33
      25%
      2/8
      2.8
      org.owasp.dependencycheck.data.lucene8
      78%
      97/124
      53%
      35/66
      3.32
      org.owasp.dependencycheck.data.nexus2
      20%
      22/105
      10%
      3/30
      2.444
      org.owasp.dependencycheck.data.nuget4
      66%
      44/66
      15%
      6/40
      2.238
      org.owasp.dependencycheck.data.nvdcve9
      41%
      313/749
      43%
      93/216
      4.177
      org.owasp.dependencycheck.data.update6
      14%
      52/348
      11%
      14/122
      5.6
      org.owasp.dependencycheck.data.update.cpe3
      0%
      0/65
      0%
      0/18
      1.5
      org.owasp.dependencycheck.data.update6
      14%
      52/347
      11%
      14/122
      5.68
      org.owasp.dependencycheck.data.update.cpe3
      0%
      0/66
      0%
      0/18
      1.5
      org.owasp.dependencycheck.data.update.exception2
      0%
      0/12
      N/A
      1
      org.owasp.dependencycheck.data.update.nvd8
      69%
      288/413
      69%
      134/194
      2.865
      org.owasp.dependencycheck.dependency14
      64%
      412/637
      55%
      162/294
      1.989
      org.owasp.dependencycheck.exception2
      0%
      0/16
      N/A
      1
      org.owasp.dependencycheck.reporting4
      0%
      0/158
      0%
      0/88
      5.067
      org.owasp.dependencycheck.suppression6
      74%
      255/343
      64%
      118/182
      3.286
      org.owasp.dependencycheck.data.update.nvd8
      69%
      290/415
      69%
      134/194
      2.865
      org.owasp.dependencycheck.dependency14
      64%
      412/639
      55%
      162/294
      1.989
      org.owasp.dependencycheck.exception5
      7%
      6/85
      0%
      0/4
      1.065
      org.owasp.dependencycheck.reporting4
      0%
      0/164
      0%
      0/90
      5.6
      org.owasp.dependencycheck.utils11
      63%
      231/364
      60%
      113/186
      3.759
      org.owasp.dependencycheck.xml.hints7
      70%
      113/161
      62%
      25/40
      2.152
      org.owasp.dependencycheck.xml.pom7
      61%
      133/217
      54%
      38/70
      2.286
      org.owasp.dependencycheck.xml.suppression6
      74%
      254/342
      64%
      118/182
      3.286
      - + diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.reporting.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.reporting.html index 7e16d0ad5..e0252741a 100644 --- a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.reporting.html +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.reporting.html @@ -16,7 +16,7 @@ - +
      Package # Classes Line Coverage Branch Coverage Complexity
      org.owasp.dependencycheck.reporting4
      0%
      0/158
      0%
      0/88
      5.067
      org.owasp.dependencycheck.reporting4
      0%
      0/164
      0%
      0/90
      5.6
      - + diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.utils.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.utils.html index 52101da76..33ded339f 100644 --- a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.utils.html +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.utils.html @@ -55,6 +55,6 @@ var classTable = new SortableTable(document.getElementById("classResults"), ["String", "Percentage", "Percentage", "FormattedNumber"]); classTable.sort(0); - + diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.xml.hints.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.xml.hints.html new file mode 100644 index 000000000..a64947858 --- /dev/null +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.xml.hints.html @@ -0,0 +1,54 @@ + + + + +Coverage Report + + + + + + + +
      Coverage Report - org.owasp.dependencycheck.xml.hints
      +
       
      + + + + + +
      Package # Classes Line Coverage Branch Coverage Complexity
      org.owasp.dependencycheck.xml.hints7
      70%
      113/161
      62%
      25/40
      2.152
      + +
       
      + + + + + + + + + + + + + + + + + + +
      Classes in this Package Line Coverage Branch Coverage Complexity
      HintErrorHandler
      11%
      2/17
      0%
      0/8
      2.5
      HintHandler
      100%
      51/51
      85%
      24/28
      4.5
      HintParseException
      0%
      0/8
      N/A
      1
      HintParser
      55%
      26/47
      25%
      1/4
      10
      HintRule
      100%
      21/21
      N/A
      1
      Hints
      100%
      7/7
      N/A
      1
      VendorDuplicatingHintRule
      60%
      6/10
      N/A
      1
      + + + + diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.xml.pom.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.xml.pom.html index 82f1de399..dace7da1d 100644 --- a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.xml.pom.html +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.xml.pom.html @@ -48,6 +48,6 @@ var classTable = new SortableTable(document.getElementById("classResults"), ["String", "Percentage", "Percentage", "FormattedNumber"]); classTable.sort(0); - + diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.xml.suppression.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.xml.suppression.html new file mode 100644 index 000000000..cb410ec49 --- /dev/null +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.xml.suppression.html @@ -0,0 +1,52 @@ + + + + +Coverage Report + + + + + + + +
      Coverage Report - org.owasp.dependencycheck.xml.suppression
      +
       
      + + + + + +
      Package # Classes Line Coverage Branch Coverage Complexity
      org.owasp.dependencycheck.xml.suppression6
      74%
      254/342
      64%
      118/182
      3.286
      + +
       
      + + + + + + + + + + + + + + + + +
      Classes in this Package Line Coverage Branch Coverage Complexity
      PropertyType
      70%
      28/40
      46%
      13/28
      3.1
      SuppressionErrorHandler
      81%
      13/16
      50%
      4/8
      2.5
      SuppressionHandler
      95%
      44/46
      78%
      22/28
      3.8
      SuppressionParseException
      50%
      4/8
      N/A
      1
      SuppressionParser
      63%
      51/80
      50%
      3/6
      11.333
      SuppressionRule
      75%
      114/152
      67%
      76/112
      2.867
      + + + + diff --git a/dependency-check-core/cobertura/frame-summary.html b/dependency-check-core/cobertura/frame-summary.html index deda9ca60..3501fd6de 100644 --- a/dependency-check-core/cobertura/frame-summary.html +++ b/dependency-check-core/cobertura/frame-summary.html @@ -16,29 +16,30 @@ - - - - + + + + - + - - + + - - - - - + + + + + +
      Package # Classes Line Coverage Branch Coverage Complexity
      All Packages137
      54%
      3828/7062
      45%
      1475/3208
      3.151
      org.owasp.dependencycheck1
      58%
      108/186
      60%
      39/64
      3.174
      org.owasp.dependencycheck.agent1
      0%
      0/226
      0%
      0/36
      1.319
      org.owasp.dependencycheck.analyzer37
      60%
      1650/2711
      44%
      656/1472
      4.393
      All Packages147
      53%
      3980/7471
      45%
      1510/3320
      3.171
      org.owasp.dependencycheck1
      55%
      116/208
      62%
      41/66
      3.478
      org.owasp.dependencycheck.agent1
      0%
      0/231
      0%
      0/38
      1.375
      org.owasp.dependencycheck.analyzer37
      58%
      1676/2856
      43%
      664/1534
      4.669
      org.owasp.dependencycheck.analyzer.exception2
      25%
      4/16
      N/A
      1
      org.owasp.dependencycheck.data.central1
      83%
      51/61
      83%
      20/24
      10
      org.owasp.dependencycheck.data.composer3
      79%
      53/67
      45%
      19/42
      3.417
      org.owasp.dependencycheck.data.cpe4
      70%
      102/145
      41%
      23/56
      2.5
      org.owasp.dependencycheck.data.cpe4
      69%
      100/143
      41%
      23/56
      2.552
      org.owasp.dependencycheck.data.cwe2
      39%
      13/33
      25%
      2/8
      2.8
      org.owasp.dependencycheck.data.lucene8
      78%
      97/124
      53%
      35/66
      3.32
      org.owasp.dependencycheck.data.nexus2
      20%
      22/105
      10%
      3/30
      2.444
      org.owasp.dependencycheck.data.nuget4
      66%
      44/66
      15%
      6/40
      2.238
      org.owasp.dependencycheck.data.nvdcve9
      41%
      313/749
      43%
      93/216
      4.177
      org.owasp.dependencycheck.data.update6
      14%
      52/348
      11%
      14/122
      5.6
      org.owasp.dependencycheck.data.update.cpe3
      0%
      0/65
      0%
      0/18
      1.5
      org.owasp.dependencycheck.data.update6
      14%
      52/347
      11%
      14/122
      5.68
      org.owasp.dependencycheck.data.update.cpe3
      0%
      0/66
      0%
      0/18
      1.5
      org.owasp.dependencycheck.data.update.exception2
      0%
      0/12
      N/A
      1
      org.owasp.dependencycheck.data.update.nvd8
      69%
      288/413
      69%
      134/194
      2.865
      org.owasp.dependencycheck.dependency14
      64%
      412/637
      55%
      162/294
      1.989
      org.owasp.dependencycheck.exception2
      0%
      0/16
      N/A
      1
      org.owasp.dependencycheck.reporting4
      0%
      0/158
      0%
      0/88
      5.067
      org.owasp.dependencycheck.suppression6
      74%
      255/343
      64%
      118/182
      3.286
      org.owasp.dependencycheck.data.update.nvd8
      69%
      290/415
      69%
      134/194
      2.865
      org.owasp.dependencycheck.dependency14
      64%
      412/639
      55%
      162/294
      1.989
      org.owasp.dependencycheck.exception5
      7%
      6/85
      0%
      0/4
      1.065
      org.owasp.dependencycheck.reporting4
      0%
      0/164
      0%
      0/90
      5.6
      org.owasp.dependencycheck.utils11
      63%
      231/364
      60%
      113/186
      3.759
      org.owasp.dependencycheck.xml.hints7
      70%
      113/161
      62%
      25/40
      2.152
      org.owasp.dependencycheck.xml.pom7
      61%
      133/217
      54%
      38/70
      2.286
      org.owasp.dependencycheck.xml.suppression6
      74%
      254/342
      64%
      118/182
      3.286
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.Engine.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.Engine.html index c49aa0f85..6d5a15d42 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.Engine.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.Engine.html @@ -12,7 +12,7 @@
       
      - +
      Classes in this File Line Coverage Branch Coverage Complexity
      Engine
      58%
      108/186
      60%
      39/64
      3.174
      Engine
      55%
      116/208
      62%
      41/66
      3.478
       
      @@ -82,765 +82,861 @@  32  
       import org.owasp.dependencycheck.exception.NoDataException;
       33   -
       import org.owasp.dependencycheck.utils.InvalidSettingException;
      +
       import org.owasp.dependencycheck.exception.ExceptionCollection;
       34   -
       import org.owasp.dependencycheck.utils.Settings;
      +
       import org.owasp.dependencycheck.exception.InitializationException;
       35   -
       import org.slf4j.Logger;
      +
       import org.owasp.dependencycheck.utils.InvalidSettingException;
       36   -
       import org.slf4j.LoggerFactory;
      +
       import org.owasp.dependencycheck.utils.Settings;
       37   -
       
      +
       import org.slf4j.Logger;
       38   -
       import java.io.File;
      +
       import org.slf4j.LoggerFactory;
       39   -
       import java.io.FileFilter;
      +
       
       40   -
       import java.util.ArrayList;
      +
       import java.io.File;
       41   -
       import java.util.Collection;
      +
       import java.io.FileFilter;
       42   -
       import java.util.EnumMap;
      +
       import java.util.ArrayList;
       43   -
       import java.util.HashSet;
      +
       import java.util.Collection;
       44   -
       import java.util.Iterator;
      +
       import java.util.EnumMap;
       45   -
       import java.util.List;
      +
       import java.util.HashSet;
       46   -
       import java.util.Map;
      +
       import java.util.Iterator;
       47   -
       import java.util.Set;
      +
       import java.util.List;
       48   -
       
      +
       import java.util.Map;
       49   -
       /**
      +
       import java.util.Set;
       50   -
        * Scans files, directories, etc. for Dependencies. Analyzers are loaded and used to process the files found by the scan, if a
      -  51   -
        * file is encountered and an Analyzer is associated with the file type then the file is turned into a dependency.
      -  52   -
        *
      -  53   -
        * @author Jeremy Long
      -  54   -
        */
      -  55   -
       public class Engine implements FileFilter {
      -  56  
       
      +  51   +
       /**
      +  52   +
        * Scans files, directories, etc. for Dependencies. Analyzers are loaded and
      +  53   +
        * used to process the files found by the scan, if a file is encountered and an
      +  54   +
        * Analyzer is associated with the file type then the file is turned into a
      +  55   +
        * dependency.
      +  56   +
        *
       57   -
           /**
      +
        * @author Jeremy Long
       58   -
            * The list of dependencies.
      +
        */
       59   -
            */
      -  60  8
           private List<Dependency> dependencies = new ArrayList<Dependency>();
      +
       public class Engine implements FileFilter {
      +  60   +
       
       61  
           /**
       62   -
            * A Map of analyzers grouped by Analysis phase.
      +
            * The list of dependencies.
       63  
            */
      -  64  8
           private Map<AnalysisPhase, List<Analyzer>> analyzers = new EnumMap<AnalysisPhase, List<Analyzer>>(AnalysisPhase.class);
      +  64  4
           private List<Dependency> dependencies = new ArrayList<Dependency>();
       65   -
       
      +
           /**
       66   -
           /**
      -  67  
            * A Map of analyzers grouped by Analysis phase.
      -  68   +  67  
            */
      -  69  8
           private Set<FileTypeAnalyzer> fileTypeAnalyzers = new HashSet<FileTypeAnalyzer>();
      -  70   +  68  4
           private final Map<AnalysisPhase, List<Analyzer>> analyzers = new EnumMap<AnalysisPhase, List<Analyzer>>(AnalysisPhase.class);
      +  69  
       
      -  71   +  70  
           /**
      +  71   +
            * A Map of analyzers grouped by Analysis phase.
       72   -
            * The ClassLoader to use when dynamically loading Analyzer and Update services.
      -  73  
            */
      -  74  8
           private ClassLoader serviceClassLoader = Thread.currentThread().getContextClassLoader();
      +  73  4
           private final Set<FileTypeAnalyzer> fileTypeAnalyzers = new HashSet<FileTypeAnalyzer>();
      +  74   +
       
       75  
           /**
       76   -
            * The Logger for use throughout the class.
      +
            * The ClassLoader to use when dynamically loading Analyzer and Update
       77   +
            * services.
      +  78  
            */
      -  78  2
           private static final Logger LOGGER = LoggerFactory.getLogger(Engine.class);
      -  79   -
       
      +  79  4
           private ClassLoader serviceClassLoader = Thread.currentThread().getContextClassLoader();
       80  
           /**
       81   -
            * Creates a new Engine.
      +
            * The Logger for use throughout the class.
       82   -
            *
      -  83   -
            * @throws DatabaseException thrown if there is an error connecting to the database
      +
            */
      +  83  1
           private static final Logger LOGGER = LoggerFactory.getLogger(Engine.class);
       84   -
            */
      -  85  8
           public Engine() throws DatabaseException {
      -  86  8
               initializeEngine();
      -  87  8
           }
      -  88  
       
      -  89   +  85  
           /**
      -  90   +  86  
            * Creates a new Engine.
      -  91   +  87  
            *
      -  92   -
            * @param serviceClassLoader a reference the class loader being used
      -  93   -
            * @throws DatabaseException thrown if there is an error connecting to the database
      +  88   +
            * @throws DatabaseException thrown if there is an error connecting to the
      +  89   +
            * database
      +  90   +
            */
      +  91  4
           public Engine() throws DatabaseException {
      +  92  4
               initializeEngine();
      +  93  4
           }
       94   -
            */
      -  95  0
           public Engine(ClassLoader serviceClassLoader) throws DatabaseException {
      -  96  0
               this.serviceClassLoader = serviceClassLoader;
      -  97  0
               initializeEngine();
      -  98  0
           }
      -  99  
       
      -  100   +  95  
           /**
      -  101   -
            * Creates a new Engine using the specified classloader to dynamically load Analyzer and Update services.
      -  102   +  96   +
            * Creates a new Engine.
      +  97  
            *
      -  103   -
            * @throws DatabaseException thrown if there is an error connecting to the database
      -  104   +  98   +
            * @param serviceClassLoader a reference the class loader being used
      +  99   +
            * @throws DatabaseException thrown if there is an error connecting to the
      +  100   +
            * database
      +  101  
            */
      -  105   -
           protected final void initializeEngine() throws DatabaseException {
      -  106  8
               ConnectionFactory.initialize();
      -  107  8
               loadAnalyzers();
      -  108  8
           }
      +  102  0
           public Engine(ClassLoader serviceClassLoader) throws DatabaseException {
      +  103  0
               this.serviceClassLoader = serviceClassLoader;
      +  104  0
               initializeEngine();
      +  105  0
           }
      +  106   +
       
      +  107   +
           /**
      +  108   +
            * Creates a new Engine using the specified classloader to dynamically load
       109   -
       
      +
            * Analyzer and Update services.
       110   -
           /**
      +
            *
       111   -
            * Properly cleans up resources allocated during analysis.
      +
            * @throws DatabaseException thrown if there is an error connecting to the
       112   -
            */
      +
            * database
       113   -
           public void cleanup() {
      -  114  0
               ConnectionFactory.cleanup();
      -  115  0
           }
      -  116   -
       
      -  117   -
           /**
      -  118   -
            * Loads the analyzers specified in the configuration file (or system properties).
      -  119  
            */
      -  120   -
           private void loadAnalyzers() {
      -  121  8
               if (!analyzers.isEmpty()) {
      -  122  0
                   return;
      -  123   -
               }
      -  124  88
               for (AnalysisPhase phase : AnalysisPhase.values()) {
      -  125  80
                   analyzers.put(phase, new ArrayList<Analyzer>());
      -  126   -
               }
      -  127   +  114   +
           protected final void initializeEngine() throws DatabaseException {
      +  115  4
               ConnectionFactory.initialize();
      +  116  4
               loadAnalyzers();
      +  117  4
           }
      +  118  
       
      -  128  8
               final AnalyzerService service = new AnalyzerService(serviceClassLoader);
      -  129  8
               final List<Analyzer> iterator = service.getAnalyzers();
      -  130  8
               for (Analyzer a : iterator) {
      -  131  192
                   analyzers.get(a.getAnalysisPhase()).add(a);
      -  132  192
                   if (a instanceof FileTypeAnalyzer) {
      -  133  128
                       this.fileTypeAnalyzers.add((FileTypeAnalyzer) a);
      -  134   -
                   }
      -  135  192
               }
      -  136  8
           }
      +  119   +
           /**
      +  120   +
            * Properly cleans up resources allocated during analysis.
      +  121   +
            */
      +  122   +
           public void cleanup() {
      +  123  0
               ConnectionFactory.cleanup();
      +  124  0
           }
      +  125   +
       
      +  126   +
           /**
      +  127   +
            * Loads the analyzers specified in the configuration file (or system
      +  128   +
            * properties).
      +  129   +
            */
      +  130   +
           private void loadAnalyzers() {
      +  131  4
               if (!analyzers.isEmpty()) {
      +  132  0
                   return;
      +  133   +
               }
      +  134  44
               for (AnalysisPhase phase : AnalysisPhase.values()) {
      +  135  40
                   analyzers.put(phase, new ArrayList<Analyzer>());
      +  136   +
               }
       137  
       
      -  138   -
           /**
      -  139   -
            * Get the List of the analyzers for a specific phase of analysis.
      -  140   -
            *
      -  141   -
            * @param phase the phase to get the configured analyzers.
      -  142   -
            * @return the analyzers loaded
      -  143   -
            */
      +  138  4
               final AnalyzerService service = new AnalyzerService(serviceClassLoader);
      +  139  4
               final List<Analyzer> iterator = service.getAnalyzers();
      +  140  4
               for (Analyzer a : iterator) {
      +  141  96
                   analyzers.get(a.getAnalysisPhase()).add(a);
      +  142  96
                   if (a instanceof FileTypeAnalyzer) {
      +  143  64
                       this.fileTypeAnalyzers.add((FileTypeAnalyzer) a);
       144   -
           public List<Analyzer> getAnalyzers(AnalysisPhase phase) {
      -  145  0
               return analyzers.get(phase);
      -  146   -
           }
      +
                   }
      +  145  96
               }
      +  146  4
           }
       147  
       
       148  
           /**
       149   -
            * Get the dependencies identified.
      +
            * Get the List of the analyzers for a specific phase of analysis.
       150  
            *
       151   -
            * @return the dependencies identified
      +
            * @param phase the phase to get the configured analyzers.
       152   -
            */
      +
            * @return the analyzers loaded
       153   -
           public List<Dependency> getDependencies() {
      -  154  98
               return dependencies;
      -  155   -
           }
      -  156   -
       
      -  157   -
           /**
      -  158   -
            * Sets the dependencies.
      -  159   -
            *
      -  160   -
            * @param dependencies the dependencies
      -  161  
            */
      -  162   -
           public void setDependencies(List<Dependency> dependencies) {
      -  163  0
               this.dependencies = dependencies;
      -  164  0
           }
      -  165   +  154   +
           public List<Analyzer> getAnalyzers(AnalysisPhase phase) {
      +  155  0
               return analyzers.get(phase);
      +  156   +
           }
      +  157  
       
      -  166   +  158  
           /**
      +  159   +
            * Get the dependencies identified.
      +  160   +
            *
      +  161   +
            * @return the dependencies identified
      +  162   +
            */
      +  163   +
           public List<Dependency> getDependencies() {
      +  164  48
               return dependencies;
      +  165   +
           }
      +  166   +
       
       167   -
            * Scans an array of files or directories. If a directory is specified, it will be scanned recursively. Any dependencies
      +
           /**
       168   -
            * identified are added to the dependency collection.
      +
            * Sets the dependencies.
       169  
            *
       170   -
            * @param paths an array of paths to files or directories to be analyzed
      +
            * @param dependencies the dependencies
       171   -
            * @return the list of dependencies scanned
      +
            */
       172   -
            * @since v0.3.2.5
      -  173   -
            */
      -  174   -
           public List<Dependency> scan(String[] paths) {
      -  175  0
               final List<Dependency> deps = new ArrayList<Dependency>();
      -  176  0
               for (String path : paths) {
      -  177  0
                   final List<Dependency> d = scan(path);
      -  178  0
                   if (d != null) {
      -  179  0
                       deps.addAll(d);
      +
           public void setDependencies(List<Dependency> dependencies) {
      +  173  0
               this.dependencies = dependencies;
      +  174  0
           }
      +  175   +
       
      +  176   +
           /**
      +  177   +
            * Scans an array of files or directories. If a directory is specified, it
      +  178   +
            * will be scanned recursively. Any dependencies identified are added to the
      +  179   +
            * dependency collection.
       180   -
                   }
      -  181   -
               }
      -  182  0
               return deps;
      -  183   -
           }
      -  184   -
       
      -  185   -
           /**
      -  186   -
            * Scans a given file or directory. If a directory is specified, it will be scanned recursively. Any dependencies identified
      -  187   -
            * are added to the dependency collection.
      -  188  
            *
      -  189   -
            * @param path the path to a file or directory to be analyzed
      -  190   +  181   +
            * @param paths an array of paths to files or directories to be analyzed
      +  182  
            * @return the list of dependencies scanned
      -  191   +  183   +
            * @since v0.3.2.5
      +  184  
            */
      +  185   +
           public List<Dependency> scan(String[] paths) {
      +  186  0
               final List<Dependency> deps = new ArrayList<Dependency>();
      +  187  0
               for (String path : paths) {
      +  188  0
                   final List<Dependency> d = scan(path);
      +  189  0
                   if (d != null) {
      +  190  0
                       deps.addAll(d);
      +  191   +
                   }
       192   -
           public List<Dependency> scan(String path) {
      -  193  0
               final File file = new File(path);
      -  194  0
               return scan(file);
      -  195   +
               }
      +  193  0
               return deps;
      +  194  
           }
      -  196   +  195  
       
      -  197   +  196  
           /**
      +  197   +
            * Scans a given file or directory. If a directory is specified, it will be
       198   -
            * Scans an array of files or directories. If a directory is specified, it will be scanned recursively. Any dependencies
      +
            * scanned recursively. Any dependencies identified are added to the
       199   -
            * identified are added to the dependency collection.
      +
            * dependency collection.
       200  
            *
       201   -
            * @param files an array of paths to files or directories to be analyzed.
      +
            * @param path the path to a file or directory to be analyzed
       202   -
            * @return the list of dependencies
      +
            * @return the list of dependencies scanned
       203   -
            * @since v0.3.2.5
      +
            */
       204   -
            */
      -  205   -
           public List<Dependency> scan(File[] files) {
      -  206  0
               final List<Dependency> deps = new ArrayList<Dependency>();
      -  207  0
               for (File file : files) {
      -  208  0
                   final List<Dependency> d = scan(file);
      -  209  0
                   if (d != null) {
      -  210  0
                       deps.addAll(d);
      +
           public List<Dependency> scan(String path) {
      +  205  0
               final File file = new File(path);
      +  206  0
               return scan(file);
      +  207   +
           }
      +  208   +
       
      +  209   +
           /**
      +  210   +
            * Scans an array of files or directories. If a directory is specified, it
       211   -
                   }
      +
            * will be scanned recursively. Any dependencies identified are added to the
       212   -
               }
      -  213  0
               return deps;
      +
            * dependency collection.
      +  213   +
            *
       214   -
           }
      +
            * @param files an array of paths to files or directories to be analyzed.
       215   -
       
      +
            * @return the list of dependencies
       216   -
           /**
      -  217   -
            * Scans a collection of files or directories. If a directory is specified, it will be scanned recursively. Any dependencies
      -  218   -
            * identified are added to the dependency collection.
      -  219   -
            *
      -  220   -
            * @param files a set of paths to files or directories to be analyzed
      -  221   -
            * @return the list of dependencies scanned
      -  222  
            * @since v0.3.2.5
      -  223   +  217  
            */
      +  218   +
           public List<Dependency> scan(File[] files) {
      +  219  0
               final List<Dependency> deps = new ArrayList<Dependency>();
      +  220  0
               for (File file : files) {
      +  221  0
                   final List<Dependency> d = scan(file);
      +  222  0
                   if (d != null) {
      +  223  0
                       deps.addAll(d);
       224   -
           public List<Dependency> scan(Collection<File> files) {
      -  225  0
               final List<Dependency> deps = new ArrayList<Dependency>();
      -  226  0
               for (File file : files) {
      -  227  0
                   final List<Dependency> d = scan(file);
      -  228  0
                   if (d != null) {
      -  229  0
                       deps.addAll(d);
      +
                   }
      +  225   +
               }
      +  226  0
               return deps;
      +  227   +
           }
      +  228   +
       
      +  229   +
           /**
       230   -
                   }
      -  231  0
               }
      -  232  0
               return deps;
      +
            * Scans a collection of files or directories. If a directory is specified,
      +  231   +
            * it will be scanned recursively. Any dependencies identified are added to
      +  232   +
            * the dependency collection.
       233   -
           }
      +
            *
       234   -
       
      +
            * @param files a set of paths to files or directories to be analyzed
       235   -
           /**
      -  236   -
            * Scans a given file or directory. If a directory is specified, it will be scanned recursively. Any dependencies identified
      -  237   -
            * are added to the dependency collection.
      -  238   -
            *
      -  239   -
            * @param file the path to a file or directory to be analyzed
      -  240  
            * @return the list of dependencies scanned
      -  241   -
            * @since v0.3.2.4
      -  242   +  236   +
            * @since v0.3.2.5
      +  237  
            */
      -  243   -
           public List<Dependency> scan(File file) {
      -  244  10
               if (file.exists()) {
      -  245  10
                   if (file.isDirectory()) {
      -  246  6
                       return scanDirectory(file);
      +  238   +
           public List<Dependency> scan(Collection<File> files) {
      +  239  0
               final List<Dependency> deps = new ArrayList<Dependency>();
      +  240  0
               for (File file : files) {
      +  241  0
                   final List<Dependency> d = scan(file);
      +  242  0
                   if (d != null) {
      +  243  0
                       deps.addAll(d);
      +  244   +
                   }
      +  245  0
               }
      +  246  0
               return deps;
       247   -
                   } else {
      -  248  4
                       final Dependency d = scanFile(file);
      -  249  4
                       if (d != null) {
      -  250  4
                           final List<Dependency> deps = new ArrayList<Dependency>();
      -  251  4
                           deps.add(d);
      -  252  4
                           return deps;
      +
           }
      +  248   +
       
      +  249   +
           /**
      +  250   +
            * Scans a given file or directory. If a directory is specified, it will be
      +  251   +
            * scanned recursively. Any dependencies identified are added to the
      +  252   +
            * dependency collection.
       253   -
                       }
      +
            *
       254   -
                   }
      +
            * @param file the path to a file or directory to be analyzed
       255   -
               }
      -  256  0
               return null;
      +
            * @return the list of dependencies scanned
      +  256   +
            * @since v0.3.2.4
       257   -
           }
      +
            */
       258   -
       
      -  259   -
           /**
      -  260   -
            * Recursively scans files and directories. Any dependencies identified are added to the dependency collection.
      -  261   -
            *
      +
           public List<Dependency> scan(File file) {
      +  259  5
               if (file.exists()) {
      +  260  5
                   if (file.isDirectory()) {
      +  261  3
                       return scanDirectory(file);
       262   -
            * @param dir the directory to scan
      -  263   -
            * @return the list of Dependency objects scanned
      -  264   -
            */
      -  265   -
           protected List<Dependency> scanDirectory(File dir) {
      -  266  92
               final File[] files = dir.listFiles();
      -  267  92
               final List<Dependency> deps = new ArrayList<Dependency>();
      -  268  92
               if (files != null) {
      -  269  186
                   for (File f : files) {
      -  270  94
                       if (f.isDirectory()) {
      -  271  86
                           final List<Dependency> d = scanDirectory(f);
      -  272  86
                           if (d != null) {
      -  273  86
                               deps.addAll(d);
      -  274   -
                           }
      -  275  86
                       } else {
      -  276  8
                           final Dependency d = scanFile(f);
      -  277  8
                           deps.add(d);
      -  278   +
                   } else {
      +  263  2
                       final Dependency d = scanFile(file);
      +  264  2
                       if (d != null) {
      +  265  2
                           final List<Dependency> deps = new ArrayList<Dependency>();
      +  266  2
                           deps.add(d);
      +  267  2
                           return deps;
      +  268  
                       }
      -  279   +  269  
                   }
      -  280   +  270  
               }
      -  281  92
               return deps;
      -  282   +  271  0
               return null;
      +  272  
           }
      -  283   +  273  
       
      -  284   +  274  
           /**
      -  285   -
            * Scans a specified file. If a dependency is identified it is added to the dependency collection.
      -  286   +  275   +
            * Recursively scans files and directories. Any dependencies identified are
      +  276   +
            * added to the dependency collection.
      +  277  
            *
      -  287   -
            * @param file The file to scan
      -  288   -
            * @return the scanned dependency
      -  289   +  278   +
            * @param dir the directory to scan
      +  279   +
            * @return the list of Dependency objects scanned
      +  280  
            */
      +  281   +
           protected List<Dependency> scanDirectory(File dir) {
      +  282  10
               final File[] files = dir.listFiles();
      +  283  10
               final List<Dependency> deps = new ArrayList<Dependency>();
      +  284  10
               if (files != null) {
      +  285  21
                   for (File f : files) {
      +  286  11
                       if (f.isDirectory()) {
      +  287  7
                           final List<Dependency> d = scanDirectory(f);
      +  288  7
                           if (d != null) {
      +  289  7
                               deps.addAll(d);
       290   -
           protected Dependency scanFile(File file) {
      -  291  12
               Dependency dependency = null;
      -  292  12
               if (file.isFile()) {
      -  293  12
                   if (accept(file)) {
      -  294  8
                       dependency = new Dependency(file);
      -  295  8
                       dependencies.add(dependency);
      -  296   +
                           }
      +  291  7
                       } else {
      +  292  4
                           final Dependency d = scanFile(f);
      +  293  4
                           deps.add(d);
      +  294   +
                       }
      +  295  
                   }
      -  297   -
               } else {
      -  298  0
                   LOGGER.debug("Path passed to scanFile(File) is not a file: {}. Skipping the file.", file);
      -  299   +  296  
               }
      -  300  12
               return dependency;
      -  301   +  297  10
               return deps;
      +  298  
           }
      -  302   +  299  
       
      -  303   +  300  
           /**
      +  301   +
            * Scans a specified file. If a dependency is identified it is added to the
      +  302   +
            * dependency collection.
      +  303   +
            *
       304   -
            * Runs the analyzers against all of the dependencies. Since the mutable dependencies list is exposed via
      +
            * @param file The file to scan
       305   -
            * {@link #getDependencies()}, this method iterates over a copy of the dependencies list. Thus, the potential for
      +
            * @return the scanned dependency
       306   -
            * {@link java.util.ConcurrentModificationException}s is avoided, and analyzers may safely add or remove entries from the
      -  307   -
            * dependencies list.
      -  308  
            */
      -  309   -
           public void analyzeDependencies() {
      -  310  4
               boolean autoUpdate = true;
      -  311   -
               try {
      -  312  4
                   autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE);
      -  313  0
               } catch (InvalidSettingException ex) {
      -  314  0
                   LOGGER.debug("Invalid setting for auto-update; using true.");
      -  315  4
               }
      -  316  4
               if (autoUpdate) {
      -  317  0
                   doUpdates();
      -  318   +  307   +
           protected Dependency scanFile(File file) {
      +  308  6
               Dependency dependency = null;
      +  309  6
               if (file.isFile()) {
      +  310  6
                   if (accept(file)) {
      +  311  4
                       dependency = new Dependency(file);
      +  312  4
                       dependencies.add(dependency);
      +  313   +
                   }
      +  314   +
               } else {
      +  315  0
                   LOGGER.debug("Path passed to scanFile(File) is not a file: {}. Skipping the file.", file);
      +  316  
               }
      +  317  6
               return dependency;
      +  318   +
           }
       319  
       
       320   -
               //need to ensure that data exists
      +
           /**
       321   -
               try {
      -  322  4
                   ensureDataExists();
      -  323  0
               } catch (NoDataException ex) {
      -  324  0
                   LOGGER.error("{}\n\nUnable to continue dependency-check analysis.", ex.getMessage());
      -  325  0
                   LOGGER.debug("", ex);
      -  326  0
                   return;
      -  327  0
               } catch (DatabaseException ex) {
      -  328  0
                   LOGGER.error("{}\n\nUnable to continue dependency-check analysis.", ex.getMessage());
      -  329  0
                   LOGGER.debug("", ex);
      -  330  0
                   return;
      +
            * Runs the analyzers against all of the dependencies. Since the mutable
      +  322   +
            * dependencies list is exposed via {@link #getDependencies()}, this method
      +  323   +
            * iterates over a copy of the dependencies list. Thus, the potential for
      +  324   +
            * {@link java.util.ConcurrentModificationException}s is avoided, and
      +  325   +
            * analyzers may safely add or remove entries from the dependencies list.
      +  326   +
            *
      +  327   +
            * Every effort is made to complete analysis on the dependencies. In some
      +  328   +
            * cases an exception will occur with part of the analysis being performed
      +  329   +
            * which may not affect the entire analysis. If an exception occurs it will
      +  330   +
            * be included in the thrown exception collection.
       331   -
       
      -  332  4
               }
      +
            *
      +  332   +
            * @throws ExceptionCollection a collections of any exceptions that occurred
       333   -
       
      -  334  4
               LOGGER.debug("\n----------------------------------------------------\nBEGIN ANALYSIS\n----------------------------------------------------");
      -  335  4
               LOGGER.info("Analysis Starting");
      -  336  4
               final long analysisStart = System.currentTimeMillis();
      -  337   -
       
      +
            * during analysis
      +  334   +
            */
      +  335   +
           public void analyzeDependencies() throws ExceptionCollection {
      +  336  2
               final List<Throwable> exceptions = new ArrayList<Throwable>();
      +  337  2
               boolean autoUpdate = true;
       338   -
               // analysis phases
      -  339  44
               for (AnalysisPhase phase : AnalysisPhase.values()) {
      -  340  40
                   final List<Analyzer> analyzerList = analyzers.get(phase);
      -  341   -
       
      -  342  40
                   for (Analyzer a : analyzerList) {
      -  343  96
                       a = initializeAnalyzer(a);
      -  344   -
       
      +
               try {
      +  339  2
                   autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE);
      +  340  0
               } catch (InvalidSettingException ex) {
      +  341  0
                   LOGGER.debug("Invalid setting for auto-update; using true.");
      +  342  0
                   exceptions.add(ex);
      +  343  2
               }
      +  344  2
               if (autoUpdate) {
       345   -
                       /* need to create a copy of the collection because some of the
      -  346   -
                        * analyzers may modify it. This prevents ConcurrentModificationExceptions.
      -  347   -
                        * This is okay for adds/deletes because it happens per analyzer.
      -  348   -
                        */
      -  349  96
                       LOGGER.debug("Begin Analyzer '{}'", a.getName());
      -  350  96
                       final Set<Dependency> dependencySet = new HashSet<Dependency>(dependencies);
      -  351  96
                       for (Dependency d : dependencySet) {
      -  352  192
                           boolean shouldAnalyze = true;
      -  353  192
                           if (a instanceof FileTypeAnalyzer) {
      -  354  128
                               final FileTypeAnalyzer fAnalyzer = (FileTypeAnalyzer) a;
      -  355  128
                               shouldAnalyze = fAnalyzer.accept(d.getActualFile());
      +
                   try {
      +  346  0
                       doUpdates();
      +  347  0
                   } catch (UpdateException ex) {
      +  348  0
                       exceptions.add(ex);
      +  349  0
                       LOGGER.warn("Unable to update Cached Web DataSource, using local "
      +  350   +
                               + "data instead. Results may not include recent vulnerabilities.");
      +  351  0
                       LOGGER.debug("Update Error", ex);
      +  352  0
                   }
      +  353   +
               }
      +  354   +
       
      +  355   +
               //need to ensure that data exists
       356   -
                           }
      -  357  192
                           if (shouldAnalyze) {
      -  358  76
                               LOGGER.debug("Begin Analysis of '{}'", d.getActualFilePath());
      -  359   -
                               try {
      -  360  76
                                   a.analyze(d, this);
      -  361  0
                               } catch (AnalysisException ex) {
      -  362  0
                                   LOGGER.warn("An error occurred while analyzing '{}'.", d.getActualFilePath());
      -  363  0
                                   LOGGER.debug("", ex);
      -  364  0
                               } catch (Throwable ex) {
      -  365   -
                                   //final AnalysisException ax = new AnalysisException(axMsg, ex);
      -  366  0
                                   LOGGER.warn("An unexpected error occurred during analysis of '{}'", d.getActualFilePath());
      -  367  0
                                   LOGGER.debug("", ex);
      -  368  76
                               }
      +
               try {
      +  357  2
                   ensureDataExists();
      +  358  0
               } catch (NoDataException ex) {
      +  359  0
                   LOGGER.error("{}\n\nUnable to continue dependency-check analysis.", ex.getMessage());
      +  360  0
                   LOGGER.debug("", ex);
      +  361  0
                   exceptions.add(ex);
      +  362  0
                   throw new ExceptionCollection("Unable to continue dependency-check analysis.", exceptions, true);
      +  363  0
               } catch (DatabaseException ex) {
      +  364  0
                   LOGGER.error("{}\n\nUnable to continue dependency-check analysis.", ex.getMessage());
      +  365  0
                   LOGGER.debug("", ex);
      +  366  0
                   exceptions.add(ex);
      +  367  0
                   throw new ExceptionCollection("Unable to connect to the dependency-check database", exceptions, true);
      +  368  2
               }
       369   -
                           }
      -  370  192
                       }
      -  371  96
                   }
      -  372   -
               }
      -  373  44
               for (AnalysisPhase phase : AnalysisPhase.values()) {
      -  374  40
                   final List<Analyzer> analyzerList = analyzers.get(phase);
      -  375  
       
      -  376  40
                   for (Analyzer a : analyzerList) {
      -  377  96
                       closeAnalyzer(a);
      -  378  96
                   }
      +  370  2
               LOGGER.debug("\n----------------------------------------------------\nBEGIN ANALYSIS\n----------------------------------------------------");
      +  371  2
               LOGGER.info("Analysis Starting");
      +  372  2
               final long analysisStart = System.currentTimeMillis();
      +  373   +
       
      +  374   +
               // analysis phases
      +  375  22
               for (AnalysisPhase phase : AnalysisPhase.values()) {
      +  376  20
                   final List<Analyzer> analyzerList = analyzers.get(phase);
      +  377   +
       
      +  378  20
                   for (Analyzer a : analyzerList) {
       379   -
               }
      -  380   -
       
      -  381  4
               LOGGER.debug("\n----------------------------------------------------\nEND ANALYSIS\n----------------------------------------------------");
      -  382  4
               LOGGER.info("Analysis Complete ({} ms)", System.currentTimeMillis() - analysisStart);
      -  383  4
           }
      -  384   -
       
      +
                       try {
      +  380  48
                           a = initializeAnalyzer(a);
      +  381  1
                       } catch (InitializationException ex) {
      +  382  1
                           exceptions.add(ex);
      +  383  1
                           continue;
      +  384  47
                       }
       385   -
           /**
      +
       
       386   -
            * Initializes the given analyzer.
      +
                       /* need to create a copy of the collection because some of the
       387   -
            *
      +
                        * analyzers may modify it. This prevents ConcurrentModificationExceptions.
       388   -
            * @param analyzer the analyzer to initialize
      +
                        * This is okay for adds/deletes because it happens per analyzer.
       389   -
            * @return the initialized analyzer
      -  390   -
            */
      -  391   -
           protected Analyzer initializeAnalyzer(Analyzer analyzer) {
      -  392   -
               try {
      -  393  96
                   LOGGER.debug("Initializing {}", analyzer.getName());
      -  394  96
                   analyzer.initialize();
      -  395  2
               } catch (Throwable ex) {
      -  396  2
                   LOGGER.error("Exception occurred initializing {}.", analyzer.getName());
      -  397  2
                   LOGGER.debug("", ex);
      -  398   -
                   try {
      -  399  2
                       analyzer.close();
      -  400  0
                   } catch (Throwable ex1) {
      -  401  0
                       LOGGER.trace("", ex1);
      -  402  2
                   }
      -  403  94
               }
      -  404  96
               return analyzer;
      -  405   -
           }
      -  406   -
       
      +
                        */
      +  390  47
                       LOGGER.debug("Begin Analyzer '{}'", a.getName());
      +  391  47
                       final Set<Dependency> dependencySet = new HashSet<Dependency>(dependencies);
      +  392  47
                       for (Dependency d : dependencySet) {
      +  393  94
                           boolean shouldAnalyze = true;
      +  394  94
                           if (a instanceof FileTypeAnalyzer) {
      +  395  62
                               final FileTypeAnalyzer fAnalyzer = (FileTypeAnalyzer) a;
      +  396  62
                               shouldAnalyze = fAnalyzer.accept(d.getActualFile());
      +  397   +
                           }
      +  398  94
                           if (shouldAnalyze) {
      +  399  38
                               LOGGER.debug("Begin Analysis of '{}'", d.getActualFilePath());
      +  400   +
                               try {
      +  401  38
                                   a.analyze(d, this);
      +  402  0
                               } catch (AnalysisException ex) {
      +  403  0
                                   LOGGER.warn("An error occurred while analyzing '{}'.", d.getActualFilePath());
      +  404  0
                                   LOGGER.debug("", ex);
      +  405  0
                                   exceptions.add(ex);
      +  406  0
                               } catch (Throwable ex) {
       407   -
           /**
      -  408   -
            * Closes the given analyzer.
      -  409   -
            *
      -  410   -
            * @param analyzer the analyzer to close
      -  411   -
            */
      +
                                   //final AnalysisException ax = new AnalysisException(axMsg, ex);
      +  408  0
                                   LOGGER.warn("An unexpected error occurred during analysis of '{}'", d.getActualFilePath());
      +  409  0
                                   LOGGER.debug("", ex);
      +  410  0
                                   exceptions.add(ex);
      +  411  38
                               }
       412   -
           protected void closeAnalyzer(Analyzer analyzer) {
      -  413  96
               LOGGER.debug("Closing Analyzer '{}'", analyzer.getName());
      -  414   -
               try {
      -  415  96
                   analyzer.close();
      -  416  0
               } catch (Throwable ex) {
      -  417  0
                   LOGGER.trace("", ex);
      -  418  96
               }
      -  419  96
           }
      -  420   +
                           }
      +  413  94
                       }
      +  414  47
                   }
      +  415   +
               }
      +  416  22
               for (AnalysisPhase phase : AnalysisPhase.values()) {
      +  417  20
                   final List<Analyzer> analyzerList = analyzers.get(phase);
      +  418  
       
      -  421   -
           /**
      +  419  20
                   for (Analyzer a : analyzerList) {
      +  420  48
                       closeAnalyzer(a);
      +  421  48
                   }
       422   -
            * Cycles through the cached web data sources and calls update on all of them.
      +
               }
       423   -
            */
      -  424   -
           public void doUpdates() {
      -  425  0
               LOGGER.info("Checking for updates");
      -  426  0
               final long updateStart = System.currentTimeMillis();
      -  427  0
               final UpdateService service = new UpdateService(serviceClassLoader);
      -  428  0
               final Iterator<CachedWebDataSource> iterator = service.getDataSources();
      -  429  0
               while (iterator.hasNext()) {
      -  430  0
                   final CachedWebDataSource source = iterator.next();
      +
       
      +  424  2
               LOGGER.debug("\n----------------------------------------------------\nEND ANALYSIS\n----------------------------------------------------");
      +  425  2
               LOGGER.info("Analysis Complete ({} ms)", System.currentTimeMillis() - analysisStart);
      +  426  2
               if (exceptions.size() > 0) {
      +  427  1
                   throw new ExceptionCollection("One or more exceptions occured during dependency-check analysis", exceptions);
      +  428   +
               }
      +  429  1
           }
      +  430   +
       
       431   -
                   try {
      -  432  0
                       source.update();
      -  433  0
                   } catch (UpdateException ex) {
      -  434  0
                       LOGGER.warn(
      +
           /**
      +  432   +
            * Initializes the given analyzer.
      +  433   +
            *
      +  434   +
            * @param analyzer the analyzer to initialize
       435   -
                               "Unable to update Cached Web DataSource, using local data instead. Results may not include recent vulnerabilities.");
      -  436  0
                       LOGGER.debug("Unable to update details for {}", source.getClass().getName(), ex);
      -  437  0
                   }
      -  438  0
               }
      -  439  0
               LOGGER.info("Check for updates complete ({} ms)", System.currentTimeMillis() - updateStart);
      -  440  0
           }
      -  441   -
       
      -  442   -
           /**
      -  443   -
            * Returns a full list of all of the analyzers. This is useful for reporting which analyzers where used.
      -  444   -
            *
      -  445   -
            * @return a list of Analyzers
      -  446   +
            * @return the initialized analyzer
      +  436   +
            * @throws InitializationException thrown when there is a problem
      +  437   +
            * initializing the analyzer
      +  438  
            */
      -  447   -
           public List<Analyzer> getAnalyzers() {
      -  448  0
               final List<Analyzer> ret = new ArrayList<Analyzer>();
      -  449  0
               for (AnalysisPhase phase : AnalysisPhase.values()) {
      -  450  0
                   final List<Analyzer> analyzerList = analyzers.get(phase);
      -  451  0
                   ret.addAll(analyzerList);
      -  452   -
               }
      -  453  0
               return ret;
      -  454   -
           }
      -  455   -
       
      -  456   -
           /**
      -  457   -
            * Checks all analyzers to see if an extension is supported.
      -  458   -
            *
      -  459   -
            * @param file a file extension
      -  460   -
            * @return true or false depending on whether or not the file extension is supported
      -  461   -
            */
      -  462   -
           @Override
      -  463   -
           public boolean accept(File file) {
      -  464  1710
               if (file == null) {
      -  465  0
                   return false;
      -  466   -
               }
      -  467  1710
               boolean scan = false;
      -  468  1710
               for (FileTypeAnalyzer a : this.fileTypeAnalyzers) {
      -  469   -
                   /* note, we can't break early on this loop as the analyzers need to know if
      -  470   -
                    they have files to work on prior to initialization */
      -  471  27360
                   scan |= a.accept(file);
      -  472  27360
               }
      -  473  1710
               return scan;
      -  474   -
           }
      -  475   -
       
      -  476   -
           /**
      -  477   -
            * Returns the set of file type analyzers.
      -  478   -
            *
      -  479   -
            * @return the set of file type analyzers
      -  480   -
            */
      -  481   -
           public Set<FileTypeAnalyzer> getFileTypeAnalyzers() {
      -  482  0
               return this.fileTypeAnalyzers;
      -  483   -
           }
      -  484   -
       
      -  485   -
           /**
      -  486   -
            * Checks the CPE Index to ensure documents exists. If none exist a NoDataException is thrown.
      -  487   -
            *
      -  488   -
            * @throws NoDataException thrown if no data exists in the CPE Index
      -  489   -
            * @throws DatabaseException thrown if there is an exception opening the database
      -  490   -
            */
      -  491   -
           private void ensureDataExists() throws NoDataException, DatabaseException {
      -  492  4
               final CveDB cve = new CveDB();
      -  493   +  439   +
           protected Analyzer initializeAnalyzer(Analyzer analyzer) throws InitializationException {
      +  440  
               try {
      -  494  4
                   cve.open();
      -  495  4
                   if (!cve.dataExists()) {
      -  496  0
                       throw new NoDataException("No documents exist");
      +  441  48
                   LOGGER.debug("Initializing {}", analyzer.getName());
      +  442  48
                   analyzer.initialize();
      +  443  1
               } catch (InitializationException ex) {
      +  444  1
                   LOGGER.error("Exception occurred initializing {}.", analyzer.getName());
      +  445  1
                   LOGGER.debug("", ex);
      +  446   +
                   try {
      +  447  1
                       analyzer.close();
      +  448  0
                   } catch (Throwable ex1) {
      +  449  0
                       LOGGER.trace("", ex1);
      +  450  1
                   }
      +  451  1
                   throw ex;
      +  452  0
               } catch (Throwable ex) {
      +  453  0
                   LOGGER.error("Unexpected exception occurred initializing {}.", analyzer.getName());
      +  454  0
                   LOGGER.debug("", ex);
      +  455   +
                   try {
      +  456  0
                       analyzer.close();
      +  457  0
                   } catch (Throwable ex1) {
      +  458  0
                       LOGGER.trace("", ex1);
      +  459  0
                   }
      +  460  0
                   throw new InitializationException("Unexpected Exception", ex);
      +  461  47
               }
      +  462  47
               return analyzer;
      +  463   +
           }
      +  464   +
       
      +  465   +
           /**
      +  466   +
            * Closes the given analyzer.
      +  467   +
            *
      +  468   +
            * @param analyzer the analyzer to close
      +  469   +
            */
      +  470   +
           protected void closeAnalyzer(Analyzer analyzer) {
      +  471  48
               LOGGER.debug("Closing Analyzer '{}'", analyzer.getName());
      +  472   +
               try {
      +  473  48
                   analyzer.close();
      +  474  0
               } catch (Throwable ex) {
      +  475  0
                   LOGGER.trace("", ex);
      +  476  48
               }
      +  477  48
           }
      +  478   +
       
      +  479   +
           /**
      +  480   +
            * Cycles through the cached web data sources and calls update on all of
      +  481   +
            * them.
      +  482   +
            *
      +  483   +
            * @throws UpdateException thrown if the operation fails
      +  484   +
            */
      +  485   +
           public void doUpdates() throws UpdateException {
      +  486  0
               LOGGER.info("Checking for updates");
      +  487  0
               final long updateStart = System.currentTimeMillis();
      +  488  0
               final UpdateService service = new UpdateService(serviceClassLoader);
      +  489  0
               final Iterator<CachedWebDataSource> iterator = service.getDataSources();
      +  490  0
               while (iterator.hasNext()) {
      +  491  0
                   final CachedWebDataSource source = iterator.next();
      +  492  0
                   source.update();
      +  493  0
               }
      +  494  0
               LOGGER.info("Check for updates complete ({} ms)", System.currentTimeMillis() - updateStart);
      +  495  0
           }
      +  496   +
       
       497   -
                   }
      -  498  0
               } catch (DatabaseException ex) {
      -  499  0
                   throw new NoDataException(ex.getMessage(), ex);
      +
           /**
      +  498   +
            * Returns a full list of all of the analyzers. This is useful for reporting
      +  499   +
            * which analyzers where used.
       500   +
            *
      +  501   +
            * @return a list of Analyzers
      +  502   +
            */
      +  503   +
           public List<Analyzer> getAnalyzers() {
      +  504  0
               final List<Analyzer> ret = new ArrayList<Analyzer>();
      +  505  0
               for (AnalysisPhase phase : AnalysisPhase.values()) {
      +  506  0
                   final List<Analyzer> analyzerList = analyzers.get(phase);
      +  507  0
                   ret.addAll(analyzerList);
      +  508   +
               }
      +  509  0
               return ret;
      +  510   +
           }
      +  511   +
       
      +  512   +
           /**
      +  513   +
            * Checks all analyzers to see if an extension is supported.
      +  514   +
            *
      +  515   +
            * @param file a file extension
      +  516   +
            * @return true or false depending on whether or not the file extension is
      +  517   +
            * supported
      +  518   +
            */
      +  519   +
           @Override
      +  520   +
           public boolean accept(File file) {
      +  521  6
               if (file == null) {
      +  522  0
                   return false;
      +  523   +
               }
      +  524  6
               boolean scan = false;
      +  525  6
               for (FileTypeAnalyzer a : this.fileTypeAnalyzers) {
      +  526   +
                   /* note, we can't break early on this loop as the analyzers need to know if
      +  527   +
                    they have files to work on prior to initialization */
      +  528  96
                   scan |= a.accept(file);
      +  529  96
               }
      +  530  6
               return scan;
      +  531   +
           }
      +  532   +
       
      +  533   +
           /**
      +  534   +
            * Returns the set of file type analyzers.
      +  535   +
            *
      +  536   +
            * @return the set of file type analyzers
      +  537   +
            */
      +  538   +
           public Set<FileTypeAnalyzer> getFileTypeAnalyzers() {
      +  539  0
               return this.fileTypeAnalyzers;
      +  540   +
           }
      +  541   +
       
      +  542   +
           /**
      +  543   +
            * Checks the CPE Index to ensure documents exists. If none exist a
      +  544   +
            * NoDataException is thrown.
      +  545   +
            *
      +  546   +
            * @throws NoDataException thrown if no data exists in the CPE Index
      +  547   +
            * @throws DatabaseException thrown if there is an exception opening the
      +  548   +
            * database
      +  549   +
            */
      +  550   +
           private void ensureDataExists() throws NoDataException, DatabaseException {
      +  551  2
               final CveDB cve = new CveDB();
      +  552   +
               try {
      +  553  2
                   cve.open();
      +  554  2
                   if (!cve.dataExists()) {
      +  555  0
                       throw new NoDataException("No documents exist");
      +  556   +
                   }
      +  557  0
               } catch (DatabaseException ex) {
      +  558  0
                   throw new NoDataException(ex.getMessage(), ex);
      +  559  
               } finally {
      -  501  4
                   cve.close();
      -  502  4
               }
      -  503  4
           }
      -  504   +  560  2
                   cve.close();
      +  561  2
               }
      +  562  2
           }
      +  563  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.agent.DependencyCheckScanAgent.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.agent.DependencyCheckScanAgent.html index 39ca02839..f5ef853cc 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.agent.DependencyCheckScanAgent.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.agent.DependencyCheckScanAgent.html @@ -12,7 +12,7 @@
       
      - +
      Classes in this File Line Coverage Branch Coverage Complexity
      DependencyCheckScanAgent
      0%
      0/226
      0%
      0/36
      1.319
      DependencyCheckScanAgent
      0%
      0/231
      0%
      0/38
      1.375
       
      @@ -76,1777 +76,1814 @@  29  
       import org.owasp.dependencycheck.dependency.Vulnerability;
       30   -
       import org.owasp.dependencycheck.exception.ScanAgentException;
      +
       import org.owasp.dependencycheck.exception.ExceptionCollection;
       31   -
       import org.owasp.dependencycheck.reporting.ReportGenerator;
      +
       import org.owasp.dependencycheck.exception.ScanAgentException;
       32   -
       import org.owasp.dependencycheck.utils.Settings;
      +
       import org.owasp.dependencycheck.reporting.ReportGenerator;
       33   -
       import org.slf4j.Logger;
      +
       import org.owasp.dependencycheck.utils.Settings;
       34   -
       import org.slf4j.LoggerFactory;
      +
       import org.slf4j.Logger;
       35   -
       
      +
       import org.slf4j.LoggerFactory;
       36   -
       /**
      +
       
       37   -
        * This class provides a way to easily conduct a scan solely based on existing evidence metadata rather than collecting evidence
      +
       /**
       38   -
        * from the files themselves. This class is based on the Ant task and Maven plugin with the exception that it takes a list of
      +
        * This class provides a way to easily conduct a scan solely based on existing
       39   -
        * dependencies that can be programmatically added from data in a spreadsheet, database or some other datasource and conduct a
      +
        * evidence metadata rather than collecting evidence from the files themselves.
       40   -
        * scan based on this pre-defined evidence.
      +
        * This class is based on the Ant task and Maven plugin with the exception that
       41   -
        *
      +
        * it takes a list of dependencies that can be programmatically added from data
       42   -
        * <h2>Example:</h2>
      +
        * in a spreadsheet, database or some other datasource and conduct a scan based
       43   -
        * <pre>
      +
        * on this pre-defined evidence.
       44   -
        * List&lt;Dependency&gt; dependencies = new ArrayList&lt;Dependency&gt;();
      +
        *
       45   -
        * Dependency dependency = new Dependency(new File(FileUtils.getBitBucket()));
      +
        * <h2>Example:</h2>
       46   -
        * dependency.getProductEvidence().addEvidence("my-datasource", "name", "Jetty", Confidence.HIGH);
      +
        * <pre>
       47   -
        * dependency.getVersionEvidence().addEvidence("my-datasource", "version", "5.1.10", Confidence.HIGH);
      +
        * List&lt;Dependency&gt; dependencies = new ArrayList&lt;Dependency&gt;();
       48   -
        * dependency.getVendorEvidence().addEvidence("my-datasource", "vendor", "mortbay", Confidence.HIGH);
      +
        * Dependency dependency = new Dependency(new File(FileUtils.getBitBucket()));
       49   -
        * dependencies.add(dependency);
      +
        * dependency.getProductEvidence().addEvidence("my-datasource", "name", "Jetty", Confidence.HIGH);
       50   -
        *
      +
        * dependency.getVersionEvidence().addEvidence("my-datasource", "version", "5.1.10", Confidence.HIGH);
       51   -
        * DependencyCheckScanAgent scan = new DependencyCheckScanAgent();
      +
        * dependency.getVendorEvidence().addEvidence("my-datasource", "vendor", "mortbay", Confidence.HIGH);
       52   -
        * scan.setDependencies(dependencies);
      +
        * dependencies.add(dependency);
       53   -
        * scan.setReportFormat(ReportGenerator.Format.ALL);
      -  54   -
        * scan.setReportOutputDirectory(System.getProperty("user.home"));
      -  55   -
        * scan.execute();
      -  56   -
        * </pre>
      -  57  
        *
      +  54   +
        * DependencyCheckScanAgent scan = new DependencyCheckScanAgent();
      +  55   +
        * scan.setDependencies(dependencies);
      +  56   +
        * scan.setReportFormat(ReportGenerator.Format.ALL);
      +  57   +
        * scan.setReportOutputDirectory(System.getProperty("user.home"));
       58   -
        * @author Steve Springett
      +
        * scan.execute();
       59   -
        */
      +
        * </pre>
       60   -
       @SuppressWarnings("unused")
      -  61  0
       public class DependencyCheckScanAgent {
      +
        *
      +  61   +
        * @author Steve Springett
       62   -
       
      +
        */
       63   -
           /**
      -  64   -
            * System specific new line character.
      +
       @SuppressWarnings("unused")
      +  64  0
       public class DependencyCheckScanAgent {
       65   -
            */
      -  66  0
           private static final String NEW_LINE = System.getProperty("line.separator", "\n").intern();
      +
       
      +  66   +
           /**
       67   -
           /**
      +
            * System specific new line character.
       68   -
            * Logger for use throughout the class.
      -  69  
            */
      -  70  0
           private static final Logger LOGGER = LoggerFactory.getLogger(DependencyCheckScanAgent.class);
      +  69  0
           private static final String NEW_LINE = System.getProperty("line.separator", "\n").intern();
      +  70   +
           /**
       71   -
           /**
      +
            * Logger for use throughout the class.
       72   -
            * The application name for the report.
      -  73  
            */
      -  74  0
           private String applicationName = "Dependency-Check";
      +  73  0
           private static final Logger LOGGER = LoggerFactory.getLogger(DependencyCheckScanAgent.class);
      +  74   +
           /**
       75   -
       
      +
            * The application name for the report.
       76   -
           /**
      -  77   -
            * Get the value of applicationName.
      +
            */
      +  77  0
           private String applicationName = "Dependency-Check";
       78   -
            *
      +
       
       79   -
            * @return the value of applicationName
      +
           /**
       80   -
            */
      +
            * Get the value of applicationName.
       81   -
           public String getApplicationName() {
      -  82  0
               return applicationName;
      +
            *
      +  82   +
            * @return the value of applicationName
       83   -
           }
      +
            */
       84   -
       
      -  85   -
           /**
      +
           public String getApplicationName() {
      +  85  0
               return applicationName;
       86   -
            * Set the value of applicationName.
      +
           }
       87   -
            *
      +
       
       88   -
            * @param applicationName new value of applicationName
      +
           /**
       89   -
            */
      +
            * Set the value of applicationName.
       90   -
           public void setApplicationName(String applicationName) {
      -  91  0
               this.applicationName = applicationName;
      -  92  0
           }
      +
            *
      +  91   +
            * @param applicationName new value of applicationName
      +  92   +
            */
       93   -
       
      -  94   -
           /**
      -  95   -
            * The pre-determined dependencies to scan
      +
           public void setApplicationName(String applicationName) {
      +  94  0
               this.applicationName = applicationName;
      +  95  0
           }
       96   -
            */
      +
       
       97   -
           private List<Dependency> dependencies;
      +
           /**
       98   -
       
      +
            * The pre-determined dependencies to scan
       99   -
           /**
      +
            */
       100   -
            * Returns a list of pre-determined dependencies.
      +
           private List<Dependency> dependencies;
       101   -
            *
      +
       
       102   -
            * @return returns a list of dependencies
      +
           /**
       103   -
            */
      +
            * Returns a list of pre-determined dependencies.
       104   -
           public List<Dependency> getDependencies() {
      -  105  0
               return dependencies;
      +
            *
      +  105   +
            * @return returns a list of dependencies
       106   -
           }
      +
            */
       107   -
       
      -  108   -
           /**
      +
           public List<Dependency> getDependencies() {
      +  108  0
               return dependencies;
       109   -
            * Sets the list of dependencies to scan.
      +
           }
       110   -
            *
      +
       
       111   -
            * @param dependencies new value of dependencies
      +
           /**
       112   -
            */
      +
            * Sets the list of dependencies to scan.
       113   -
           public void setDependencies(List<Dependency> dependencies) {
      -  114  0
               this.dependencies = dependencies;
      -  115  0
           }
      +
            *
      +  114   +
            * @param dependencies new value of dependencies
      +  115   +
            */
       116   -
       
      -  117   -
           /**
      -  118   -
            * The location of the data directory that contains
      +
           public void setDependencies(List<Dependency> dependencies) {
      +  117  0
               this.dependencies = dependencies;
      +  118  0
           }
       119   -
            */
      -  120  0
           private String dataDirectory = null;
      +
       
      +  120   +
           /**
       121   -
       
      +
            * The location of the data directory that contains
       122   -
           /**
      -  123   -
            * Get the value of dataDirectory.
      +
            */
      +  123  0
           private String dataDirectory = null;
       124   -
            *
      +
       
       125   -
            * @return the value of dataDirectory
      +
           /**
       126   -
            */
      +
            * Get the value of dataDirectory.
       127   -
           public String getDataDirectory() {
      -  128  0
               return dataDirectory;
      +
            *
      +  128   +
            * @return the value of dataDirectory
       129   -
           }
      +
            */
       130   -
       
      -  131   -
           /**
      +
           public String getDataDirectory() {
      +  131  0
               return dataDirectory;
       132   -
            * Set the value of dataDirectory.
      +
           }
       133   -
            *
      +
       
       134   -
            * @param dataDirectory new value of dataDirectory
      +
           /**
       135   -
            */
      +
            * Set the value of dataDirectory.
       136   -
           public void setDataDirectory(String dataDirectory) {
      -  137  0
               this.dataDirectory = dataDirectory;
      -  138  0
           }
      +
            *
      +  137   +
            * @param dataDirectory new value of dataDirectory
      +  138   +
            */
       139   -
       
      -  140   -
           /**
      -  141   -
            * Specifies the destination directory for the generated Dependency-Check report.
      +
           public void setDataDirectory(String dataDirectory) {
      +  140  0
               this.dataDirectory = dataDirectory;
      +  141  0
           }
       142   -
            */
      +
       
       143   -
           private String reportOutputDirectory;
      +
           /**
       144   -
       
      +
            * Specifies the destination directory for the generated Dependency-Check
       145   -
           /**
      +
            * report.
       146   -
            * Get the value of reportOutputDirectory.
      +
            */
       147   -
            *
      +
           private String reportOutputDirectory;
       148   -
            * @return the value of reportOutputDirectory
      +
       
       149   -
            */
      +
           /**
       150   -
           public String getReportOutputDirectory() {
      -  151  0
               return reportOutputDirectory;
      +
            * Get the value of reportOutputDirectory.
      +  151   +
            *
       152   -
           }
      +
            * @return the value of reportOutputDirectory
       153   -
       
      +
            */
       154   -
           /**
      -  155   -
            * Set the value of reportOutputDirectory.
      +
           public String getReportOutputDirectory() {
      +  155  0
               return reportOutputDirectory;
       156   -
            *
      -  157   -
            * @param reportOutputDirectory new value of reportOutputDirectory
      -  158   -
            */
      -  159   -
           public void setReportOutputDirectory(String reportOutputDirectory) {
      -  160  0
               this.reportOutputDirectory = reportOutputDirectory;
      -  161  0
           }
      -  162   -
       
      -  163   -
           /**
      -  164   -
            * Specifies if the build should be failed if a CVSS score above a specified level is identified. The default is 11 which
      -  165   -
            * means since the CVSS scores are 0-10, by default the build will never fail and the CVSS score is set to 11. The valid range
      -  166   -
            * for the fail build on CVSS is 0 to 11, where anything above 10 will not cause the build to fail.
      -  167   -
            */
      -  168  0
           private float failBuildOnCVSS = 11;
      -  169   -
       
      -  170   -
           /**
      -  171   -
            * Get the value of failBuildOnCVSS.
      -  172   -
            *
      -  173   -
            * @return the value of failBuildOnCVSS
      -  174   -
            */
      -  175   -
           public float getFailBuildOnCVSS() {
      -  176  0
               return failBuildOnCVSS;
      -  177  
           }
      -  178   +  157  
       
      -  179   +  158  
           /**
      -  180   -
            * Set the value of failBuildOnCVSS.
      -  181   +  159   +
            * Set the value of reportOutputDirectory.
      +  160  
            *
      -  182   -
            * @param failBuildOnCVSS new value of failBuildOnCVSS
      -  183   +  161   +
            * @param reportOutputDirectory new value of reportOutputDirectory
      +  162  
            */
      -  184   -
           public void setFailBuildOnCVSS(float failBuildOnCVSS) {
      -  185  0
               this.failBuildOnCVSS = failBuildOnCVSS;
      -  186  0
           }
      -  187   +  163   +
           public void setReportOutputDirectory(String reportOutputDirectory) {
      +  164  0
               this.reportOutputDirectory = reportOutputDirectory;
      +  165  0
           }
      +  166  
       
      -  188   +  167  
           /**
      -  189   -
            * Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not recommended that this be turned to false. Default
      -  190   -
            * is true.
      -  191   +  168   +
            * Specifies if the build should be failed if a CVSS score above a specified
      +  169   +
            * level is identified. The default is 11 which means since the CVSS scores
      +  170   +
            * are 0-10, by default the build will never fail and the CVSS score is set
      +  171   +
            * to 11. The valid range for the fail build on CVSS is 0 to 11, where
      +  172   +
            * anything above 10 will not cause the build to fail.
      +  173  
            */
      -  192  0
           private boolean autoUpdate = true;
      +  174  0
           private float failBuildOnCVSS = 11;
      +  175   +
       
      +  176   +
           /**
      +  177   +
            * Get the value of failBuildOnCVSS.
      +  178   +
            *
      +  179   +
            * @return the value of failBuildOnCVSS
      +  180   +
            */
      +  181   +
           public float getFailBuildOnCVSS() {
      +  182  0
               return failBuildOnCVSS;
      +  183   +
           }
      +  184   +
       
      +  185   +
           /**
      +  186   +
            * Set the value of failBuildOnCVSS.
      +  187   +
            *
      +  188   +
            * @param failBuildOnCVSS new value of failBuildOnCVSS
      +  189   +
            */
      +  190   +
           public void setFailBuildOnCVSS(float failBuildOnCVSS) {
      +  191  0
               this.failBuildOnCVSS = failBuildOnCVSS;
      +  192  0
           }
       193  
       
       194  
           /**
       195   -
            * Get the value of autoUpdate.
      +
            * Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not
       196   -
            *
      +
            * recommended that this be turned to false. Default is true.
       197   -
            * @return the value of autoUpdate
      -  198  
            */
      +  198  0
           private boolean autoUpdate = true;
       199   -
           public boolean isAutoUpdate() {
      -  200  0
               return autoUpdate;
      +
       
      +  200   +
           /**
       201   -
           }
      +
            * Get the value of autoUpdate.
       202   -
       
      +
            *
       203   -
           /**
      +
            * @return the value of autoUpdate
       204   -
            * Set the value of autoUpdate.
      +
            */
       205   -
            *
      -  206   -
            * @param autoUpdate new value of autoUpdate
      +
           public boolean isAutoUpdate() {
      +  206  0
               return autoUpdate;
       207   -
            */
      -  208   -
           public void setAutoUpdate(boolean autoUpdate) {
      -  209  0
               this.autoUpdate = autoUpdate;
      -  210  0
           }
      -  211   -
       
      -  212   -
           /**
      -  213   -
            * flag indicating whether or not to generate a report of findings.
      -  214   -
            */
      -  215  0
           private boolean generateReport = true;
      -  216   -
       
      -  217   -
           /**
      -  218   -
            * Get the value of generateReport.
      -  219   -
            *
      -  220   -
            * @return the value of generateReport
      -  221   -
            */
      -  222   -
           public boolean isGenerateReport() {
      -  223  0
               return generateReport;
      -  224  
           }
      -  225   +  208  
       
      -  226   +  209  
           /**
      -  227   -
            * Set the value of generateReport.
      -  228   +  210   +
            * Set the value of autoUpdate.
      +  211  
            *
      -  229   -
            * @param generateReport new value of generateReport
      -  230   +  212   +
            * @param autoUpdate new value of autoUpdate
      +  213  
            */
      -  231   -
           public void setGenerateReport(boolean generateReport) {
      -  232  0
               this.generateReport = generateReport;
      -  233  0
           }
      -  234   +  214   +
           public void setAutoUpdate(boolean autoUpdate) {
      +  215  0
               this.autoUpdate = autoUpdate;
      +  216  0
           }
      +  217  
       
      -  235   +  218  
           /**
      -  236   -
            * The report format to be generated (HTML, XML, VULN, ALL). This configuration option has no affect if using this within the
      -  237   -
            * Site plugin unless the externalReport is set to true. Default is HTML.
      -  238   +  219   +
            * flag indicating whether or not to generate a report of findings.
      +  220  
            */
      -  239  0
           private ReportGenerator.Format reportFormat = ReportGenerator.Format.HTML;
      +  221  0
           private boolean generateReport = true;
      +  222   +
       
      +  223   +
           /**
      +  224   +
            * Get the value of generateReport.
      +  225   +
            *
      +  226   +
            * @return the value of generateReport
      +  227   +
            */
      +  228   +
           public boolean isGenerateReport() {
      +  229  0
               return generateReport;
      +  230   +
           }
      +  231   +
       
      +  232   +
           /**
      +  233   +
            * Set the value of generateReport.
      +  234   +
            *
      +  235   +
            * @param generateReport new value of generateReport
      +  236   +
            */
      +  237   +
           public void setGenerateReport(boolean generateReport) {
      +  238  0
               this.generateReport = generateReport;
      +  239  0
           }
       240  
       
       241  
           /**
       242   -
            * Get the value of reportFormat.
      +
            * The report format to be generated (HTML, XML, VULN, ALL). This
       243   -
            *
      +
            * configuration option has no affect if using this within the Site plugin
       244   -
            * @return the value of reportFormat
      +
            * unless the externalReport is set to true. Default is HTML.
       245  
            */
      -  246   -
           public ReportGenerator.Format getReportFormat() {
      -  247  0
               return reportFormat;
      +  246  0
           private ReportGenerator.Format reportFormat = ReportGenerator.Format.HTML;
      +  247   +
       
       248   -
           }
      +
           /**
       249   -
       
      +
            * Get the value of reportFormat.
       250   -
           /**
      -  251   -
            * Set the value of reportFormat.
      -  252  
            *
      -  253   -
            * @param reportFormat new value of reportFormat
      -  254   +  251   +
            * @return the value of reportFormat
      +  252  
            */
      +  253   +
           public ReportGenerator.Format getReportFormat() {
      +  254  0
               return reportFormat;
       255   -
           public void setReportFormat(ReportGenerator.Format reportFormat) {
      -  256  0
               this.reportFormat = reportFormat;
      -  257  0
           }
      -  258   +
           }
      +  256  
       
      -  259   +  257  
           /**
      +  258   +
            * Set the value of reportFormat.
      +  259   +
            *
       260   -
            * The Proxy Server.
      +
            * @param reportFormat new value of reportFormat
       261  
            */
       262   -
           private String proxyServer;
      -  263   -
       
      -  264   -
           /**
      +
           public void setReportFormat(ReportGenerator.Format reportFormat) {
      +  263  0
               this.reportFormat = reportFormat;
      +  264  0
           }
       265   -
            * Get the value of proxyServer.
      +
       
       266   -
            *
      +
           /**
       267   -
            * @return the value of proxyServer
      +
            * The Proxy Server.
       268  
            */
       269   -
           public String getProxyServer() {
      -  270  0
               return proxyServer;
      +
           private String proxyServer;
      +  270   +
       
       271   -
           }
      +
           /**
       272   -
       
      -  273   -
           /**
      -  274   -
            * Set the value of proxyServer.
      -  275   -
            *
      -  276   -
            * @param proxyServer new value of proxyServer
      -  277   -
            */
      -  278   -
           public void setProxyServer(String proxyServer) {
      -  279  0
               this.proxyServer = proxyServer;
      -  280  0
           }
      -  281   -
       
      -  282   -
           /**
      -  283  
            * Get the value of proxyServer.
      -  284   +  273  
            *
      -  285   +  274  
            * @return the value of proxyServer
      -  286   -
            * @deprecated use {@link org.owasp.dependencycheck.agent.DependencyCheckScanAgent#getProxyServer()} instead
      -  287   +  275  
            */
      -  288   -
           @Deprecated
      -  289   -
           public String getProxyUrl() {
      -  290  0
               return proxyServer;
      -  291   +  276   +
           public String getProxyServer() {
      +  277  0
               return proxyServer;
      +  278  
           }
      -  292   +  279  
       
      -  293   +  280  
           /**
      -  294   +  281  
            * Set the value of proxyServer.
      +  282   +
            *
      +  283   +
            * @param proxyServer new value of proxyServer
      +  284   +
            */
      +  285   +
           public void setProxyServer(String proxyServer) {
      +  286  0
               this.proxyServer = proxyServer;
      +  287  0
           }
      +  288   +
       
      +  289   +
           /**
      +  290   +
            * Get the value of proxyServer.
      +  291   +
            *
      +  292   +
            * @return the value of proxyServer
      +  293   +
            * @deprecated use
      +  294   +
            * {@link org.owasp.dependencycheck.agent.DependencyCheckScanAgent#getProxyServer()}
       295   -
            *
      +
            * instead
       296   -
            * @param proxyUrl new value of proxyServer
      +
            */
       297   -
            * @deprecated use {@link org.owasp.dependencycheck.agent.DependencyCheckScanAgent#setProxyServer(java.lang.String)
      -  298   -
            * } instead
      -  299   -
            */
      -  300  
           @Deprecated
      -  301   -
           public void setProxyUrl(String proxyUrl) {
      -  302  0
               this.proxyServer = proxyUrl;
      -  303  0
           }
      -  304   -
       
      -  305   -
           /**
      -  306   -
            * The Proxy Port.
      -  307   -
            */
      -  308   -
           private String proxyPort;
      -  309   -
       
      -  310   -
           /**
      -  311   -
            * Get the value of proxyPort.
      -  312   -
            *
      -  313   -
            * @return the value of proxyPort
      -  314   -
            */
      -  315   -
           public String getProxyPort() {
      -  316  0
               return proxyPort;
      -  317   +  298   +
           public String getProxyUrl() {
      +  299  0
               return proxyServer;
      +  300  
           }
      +  301   +
       
      +  302   +
           /**
      +  303   +
            * Set the value of proxyServer.
      +  304   +
            *
      +  305   +
            * @param proxyUrl new value of proxyServer
      +  306   +
            * @deprecated use {@link org.owasp.dependencycheck.agent.DependencyCheckScanAgent#setProxyServer(java.lang.String)
      +  307   +
            * } instead
      +  308   +
            */
      +  309   +
           @Deprecated
      +  310   +
           public void setProxyUrl(String proxyUrl) {
      +  311  0
               this.proxyServer = proxyUrl;
      +  312  0
           }
      +  313   +
       
      +  314   +
           /**
      +  315   +
            * The Proxy Port.
      +  316   +
            */
      +  317   +
           private String proxyPort;
       318  
       
       319  
           /**
       320   -
            * Set the value of proxyPort.
      +
            * Get the value of proxyPort.
       321  
            *
       322   -
            * @param proxyPort new value of proxyPort
      +
            * @return the value of proxyPort
       323  
            */
       324   -
           public void setProxyPort(String proxyPort) {
      -  325  0
               this.proxyPort = proxyPort;
      -  326  0
           }
      +
           public String getProxyPort() {
      +  325  0
               return proxyPort;
      +  326   +
           }
       327  
       
       328  
           /**
       329   -
            * The Proxy username.
      +
            * Set the value of proxyPort.
       330   -
            */
      -  331   -
           private String proxyUsername;
      -  332   -
       
      -  333   -
           /**
      -  334   -
            * Get the value of proxyUsername.
      -  335  
            *
      -  336   -
            * @return the value of proxyUsername
      -  337   +  331   +
            * @param proxyPort new value of proxyPort
      +  332  
            */
      +  333   +
           public void setProxyPort(String proxyPort) {
      +  334  0
               this.proxyPort = proxyPort;
      +  335  0
           }
      +  336   +
       
      +  337   +
           /**
       338   -
           public String getProxyUsername() {
      -  339  0
               return proxyUsername;
      +
            * The Proxy username.
      +  339   +
            */
       340   -
           }
      +
           private String proxyUsername;
       341  
       
       342  
           /**
       343   -
            * Set the value of proxyUsername.
      +
            * Get the value of proxyUsername.
       344  
            *
       345   -
            * @param proxyUsername new value of proxyUsername
      +
            * @return the value of proxyUsername
       346  
            */
       347   -
           public void setProxyUsername(String proxyUsername) {
      -  348  0
               this.proxyUsername = proxyUsername;
      -  349  0
           }
      +
           public String getProxyUsername() {
      +  348  0
               return proxyUsername;
      +  349   +
           }
       350  
       
       351  
           /**
       352   -
            * The Proxy password.
      +
            * Set the value of proxyUsername.
       353   -
            */
      -  354   -
           private String proxyPassword;
      -  355   -
       
      -  356   -
           /**
      -  357   -
            * Get the value of proxyPassword.
      -  358  
            *
      -  359   -
            * @return the value of proxyPassword
      -  360   +  354   +
            * @param proxyUsername new value of proxyUsername
      +  355  
            */
      +  356   +
           public void setProxyUsername(String proxyUsername) {
      +  357  0
               this.proxyUsername = proxyUsername;
      +  358  0
           }
      +  359   +
       
      +  360   +
           /**
       361   -
           public String getProxyPassword() {
      -  362  0
               return proxyPassword;
      +
            * The Proxy password.
      +  362   +
            */
       363   -
           }
      +
           private String proxyPassword;
       364  
       
       365  
           /**
       366   -
            * Set the value of proxyPassword.
      +
            * Get the value of proxyPassword.
       367  
            *
       368   -
            * @param proxyPassword new value of proxyPassword
      +
            * @return the value of proxyPassword
       369  
            */
       370   -
           public void setProxyPassword(String proxyPassword) {
      -  371  0
               this.proxyPassword = proxyPassword;
      -  372  0
           }
      +
           public String getProxyPassword() {
      +  371  0
               return proxyPassword;
      +  372   +
           }
       373  
       
       374  
           /**
       375   -
            * The Connection Timeout.
      +
            * Set the value of proxyPassword.
       376   -
            */
      -  377   -
           private String connectionTimeout;
      -  378   -
       
      -  379   -
           /**
      -  380   -
            * Get the value of connectionTimeout.
      -  381  
            *
      -  382   -
            * @return the value of connectionTimeout
      -  383   +  377   +
            * @param proxyPassword new value of proxyPassword
      +  378  
            */
      +  379   +
           public void setProxyPassword(String proxyPassword) {
      +  380  0
               this.proxyPassword = proxyPassword;
      +  381  0
           }
      +  382   +
       
      +  383   +
           /**
       384   -
           public String getConnectionTimeout() {
      -  385  0
               return connectionTimeout;
      +
            * The Connection Timeout.
      +  385   +
            */
       386   -
           }
      +
           private String connectionTimeout;
       387  
       
       388  
           /**
       389   -
            * Set the value of connectionTimeout.
      +
            * Get the value of connectionTimeout.
       390  
            *
       391   -
            * @param connectionTimeout new value of connectionTimeout
      +
            * @return the value of connectionTimeout
       392  
            */
       393   -
           public void setConnectionTimeout(String connectionTimeout) {
      -  394  0
               this.connectionTimeout = connectionTimeout;
      -  395  0
           }
      +
           public String getConnectionTimeout() {
      +  394  0
               return connectionTimeout;
      +  395   +
           }
       396  
       
       397  
           /**
       398   -
            * The file path used for verbose logging.
      +
            * Set the value of connectionTimeout.
       399   -
            */
      -  400  0
           private String logFile = null;
      -  401   -
       
      -  402   -
           /**
      -  403   -
            * Get the value of logFile.
      -  404  
            *
      -  405   -
            * @return the value of logFile
      -  406   +  400   +
            * @param connectionTimeout new value of connectionTimeout
      +  401  
            */
      +  402   +
           public void setConnectionTimeout(String connectionTimeout) {
      +  403  0
               this.connectionTimeout = connectionTimeout;
      +  404  0
           }
      +  405   +
       
      +  406   +
           /**
       407   -
           public String getLogFile() {
      -  408  0
               return logFile;
      -  409   -
           }
      +
            * The file path used for verbose logging.
      +  408   +
            */
      +  409  0
           private String logFile = null;
       410  
       
       411  
           /**
       412   -
            * Set the value of logFile.
      +
            * Get the value of logFile.
       413  
            *
       414   -
            * @param logFile new value of logFile
      +
            * @return the value of logFile
       415  
            */
       416   -
           public void setLogFile(String logFile) {
      -  417  0
               this.logFile = logFile;
      -  418  0
           }
      +
           public String getLogFile() {
      +  417  0
               return logFile;
      +  418   +
           }
       419  
       
       420  
           /**
       421   -
            * The path to the suppression file.
      +
            * Set the value of logFile.
       422   -
            */
      -  423   -
           private String suppressionFile;
      -  424   -
       
      -  425   -
           /**
      -  426   -
            * Get the value of suppressionFile.
      -  427  
            *
      -  428   -
            * @return the value of suppressionFile
      -  429   +  423   +
            * @param logFile new value of logFile
      +  424  
            */
      +  425   +
           public void setLogFile(String logFile) {
      +  426  0
               this.logFile = logFile;
      +  427  0
           }
      +  428   +
       
      +  429   +
           /**
       430   -
           public String getSuppressionFile() {
      -  431  0
               return suppressionFile;
      +
            * The path to the suppression file.
      +  431   +
            */
       432   -
           }
      +
           private String suppressionFile;
       433  
       
       434  
           /**
       435   -
            * Set the value of suppressionFile.
      +
            * Get the value of suppressionFile.
       436  
            *
       437   -
            * @param suppressionFile new value of suppressionFile
      +
            * @return the value of suppressionFile
       438  
            */
       439   -
           public void setSuppressionFile(String suppressionFile) {
      -  440  0
               this.suppressionFile = suppressionFile;
      -  441  0
           }
      +
           public String getSuppressionFile() {
      +  440  0
               return suppressionFile;
      +  441   +
           }
       442  
       
       443  
           /**
       444   -
            * flag indicating whether or not to show a summary of findings.
      +
            * Set the value of suppressionFile.
       445   -
            */
      -  446  0
           private boolean showSummary = true;
      -  447   -
       
      -  448   -
           /**
      -  449   -
            * Get the value of showSummary.
      -  450  
            *
      -  451   -
            * @return the value of showSummary
      -  452   +  446   +
            * @param suppressionFile new value of suppressionFile
      +  447  
            */
      +  448   +
           public void setSuppressionFile(String suppressionFile) {
      +  449  0
               this.suppressionFile = suppressionFile;
      +  450  0
           }
      +  451   +
       
      +  452   +
           /**
       453   -
           public boolean isShowSummary() {
      -  454  0
               return showSummary;
      -  455   -
           }
      +
            * flag indicating whether or not to show a summary of findings.
      +  454   +
            */
      +  455  0
           private boolean showSummary = true;
       456  
       
       457  
           /**
       458   -
            * Set the value of showSummary.
      +
            * Get the value of showSummary.
       459  
            *
       460   -
            * @param showSummary new value of showSummary
      +
            * @return the value of showSummary
       461  
            */
       462   -
           public void setShowSummary(boolean showSummary) {
      -  463  0
               this.showSummary = showSummary;
      -  464  0
           }
      +
           public boolean isShowSummary() {
      +  463  0
               return showSummary;
      +  464   +
           }
       465  
       
       466  
           /**
       467   -
            * Whether or not the Maven Central analyzer is enabled.
      +
            * Set the value of showSummary.
       468   -
            */
      -  469  0
           private boolean centralAnalyzerEnabled = true;
      -  470   -
       
      -  471   -
           /**
      -  472   -
            * Get the value of centralAnalyzerEnabled.
      -  473  
            *
      -  474   -
            * @return the value of centralAnalyzerEnabled
      -  475   +  469   +
            * @param showSummary new value of showSummary
      +  470  
            */
      +  471   +
           public void setShowSummary(boolean showSummary) {
      +  472  0
               this.showSummary = showSummary;
      +  473  0
           }
      +  474   +
       
      +  475   +
           /**
       476   -
           public boolean isCentralAnalyzerEnabled() {
      -  477  0
               return centralAnalyzerEnabled;
      -  478   -
           }
      +
            * Whether or not the Maven Central analyzer is enabled.
      +  477   +
            */
      +  478  0
           private boolean centralAnalyzerEnabled = true;
       479  
       
       480  
           /**
       481   -
            * Set the value of centralAnalyzerEnabled.
      +
            * Get the value of centralAnalyzerEnabled.
       482  
            *
       483   -
            * @param centralAnalyzerEnabled new value of centralAnalyzerEnabled
      +
            * @return the value of centralAnalyzerEnabled
       484  
            */
       485   -
           public void setCentralAnalyzerEnabled(boolean centralAnalyzerEnabled) {
      -  486  0
               this.centralAnalyzerEnabled = centralAnalyzerEnabled;
      -  487  0
           }
      +
           public boolean isCentralAnalyzerEnabled() {
      +  486  0
               return centralAnalyzerEnabled;
      +  487   +
           }
       488  
       
       489  
           /**
       490   -
            * The URL of Maven Central.
      +
            * Set the value of centralAnalyzerEnabled.
       491   -
            */
      -  492   -
           private String centralUrl;
      -  493   -
       
      -  494   -
           /**
      -  495   -
            * Get the value of centralUrl.
      -  496  
            *
      -  497   -
            * @return the value of centralUrl
      -  498   +  492   +
            * @param centralAnalyzerEnabled new value of centralAnalyzerEnabled
      +  493  
            */
      +  494   +
           public void setCentralAnalyzerEnabled(boolean centralAnalyzerEnabled) {
      +  495  0
               this.centralAnalyzerEnabled = centralAnalyzerEnabled;
      +  496  0
           }
      +  497   +
       
      +  498   +
           /**
       499   -
           public String getCentralUrl() {
      -  500  0
               return centralUrl;
      +
            * The URL of Maven Central.
      +  500   +
            */
       501   -
           }
      +
           private String centralUrl;
       502  
       
       503  
           /**
       504   -
            * Set the value of centralUrl.
      +
            * Get the value of centralUrl.
       505  
            *
       506   -
            * @param centralUrl new value of centralUrl
      +
            * @return the value of centralUrl
       507  
            */
       508   -
           public void setCentralUrl(String centralUrl) {
      -  509  0
               this.centralUrl = centralUrl;
      -  510  0
           }
      +
           public String getCentralUrl() {
      +  509  0
               return centralUrl;
      +  510   +
           }
       511  
       
       512  
           /**
       513   -
            * Whether or not the nexus analyzer is enabled.
      +
            * Set the value of centralUrl.
       514   -
            */
      -  515  0
           private boolean nexusAnalyzerEnabled = true;
      -  516   -
       
      -  517   -
           /**
      -  518   -
            * Get the value of nexusAnalyzerEnabled.
      -  519  
            *
      -  520   -
            * @return the value of nexusAnalyzerEnabled
      -  521   +  515   +
            * @param centralUrl new value of centralUrl
      +  516  
            */
      +  517   +
           public void setCentralUrl(String centralUrl) {
      +  518  0
               this.centralUrl = centralUrl;
      +  519  0
           }
      +  520   +
       
      +  521   +
           /**
       522   -
           public boolean isNexusAnalyzerEnabled() {
      -  523  0
               return nexusAnalyzerEnabled;
      -  524   -
           }
      +
            * Whether or not the nexus analyzer is enabled.
      +  523   +
            */
      +  524  0
           private boolean nexusAnalyzerEnabled = true;
       525  
       
       526  
           /**
       527   -
            * Set the value of nexusAnalyzerEnabled.
      +
            * Get the value of nexusAnalyzerEnabled.
       528  
            *
       529   -
            * @param nexusAnalyzerEnabled new value of nexusAnalyzerEnabled
      +
            * @return the value of nexusAnalyzerEnabled
       530  
            */
       531   -
           public void setNexusAnalyzerEnabled(boolean nexusAnalyzerEnabled) {
      -  532  0
               this.nexusAnalyzerEnabled = nexusAnalyzerEnabled;
      -  533  0
           }
      +
           public boolean isNexusAnalyzerEnabled() {
      +  532  0
               return nexusAnalyzerEnabled;
      +  533   +
           }
       534  
       
       535  
           /**
       536   -
            * The URL of the Nexus server.
      +
            * Set the value of nexusAnalyzerEnabled.
       537   -
            */
      -  538   -
           private String nexusUrl;
      -  539   -
       
      -  540   -
           /**
      -  541   -
            * Get the value of nexusUrl.
      -  542  
            *
      -  543   -
            * @return the value of nexusUrl
      -  544   +  538   +
            * @param nexusAnalyzerEnabled new value of nexusAnalyzerEnabled
      +  539  
            */
      +  540   +
           public void setNexusAnalyzerEnabled(boolean nexusAnalyzerEnabled) {
      +  541  0
               this.nexusAnalyzerEnabled = nexusAnalyzerEnabled;
      +  542  0
           }
      +  543   +
       
      +  544   +
           /**
       545   -
           public String getNexusUrl() {
      -  546  0
               return nexusUrl;
      +
            * The URL of the Nexus server.
      +  546   +
            */
       547   -
           }
      +
           private String nexusUrl;
       548  
       
       549  
           /**
       550   -
            * Set the value of nexusUrl.
      +
            * Get the value of nexusUrl.
       551  
            *
       552   -
            * @param nexusUrl new value of nexusUrl
      +
            * @return the value of nexusUrl
       553  
            */
       554   -
           public void setNexusUrl(String nexusUrl) {
      -  555  0
               this.nexusUrl = nexusUrl;
      -  556  0
           }
      +
           public String getNexusUrl() {
      +  555  0
               return nexusUrl;
      +  556   +
           }
       557  
       
       558  
           /**
       559   -
            * Whether or not the defined proxy should be used when connecting to Nexus.
      +
            * Set the value of nexusUrl.
       560   -
            */
      -  561  0
           private boolean nexusUsesProxy = true;
      -  562   -
       
      -  563   -
           /**
      -  564   -
            * Get the value of nexusUsesProxy.
      -  565  
            *
      -  566   -
            * @return the value of nexusUsesProxy
      -  567   +  561   +
            * @param nexusUrl new value of nexusUrl
      +  562  
            */
      +  563   +
           public void setNexusUrl(String nexusUrl) {
      +  564  0
               this.nexusUrl = nexusUrl;
      +  565  0
           }
      +  566   +
       
      +  567   +
           /**
       568   -
           public boolean isNexusUsesProxy() {
      -  569  0
               return nexusUsesProxy;
      -  570   -
           }
      +
            * Whether or not the defined proxy should be used when connecting to Nexus.
      +  569   +
            */
      +  570  0
           private boolean nexusUsesProxy = true;
       571  
       
       572  
           /**
       573   -
            * Set the value of nexusUsesProxy.
      +
            * Get the value of nexusUsesProxy.
       574  
            *
       575   -
            * @param nexusUsesProxy new value of nexusUsesProxy
      +
            * @return the value of nexusUsesProxy
       576  
            */
       577   -
           public void setNexusUsesProxy(boolean nexusUsesProxy) {
      -  578  0
               this.nexusUsesProxy = nexusUsesProxy;
      -  579  0
           }
      +
           public boolean isNexusUsesProxy() {
      +  578  0
               return nexusUsesProxy;
      +  579   +
           }
       580  
       
       581  
           /**
       582   -
            * The database driver name; such as org.h2.Driver.
      +
            * Set the value of nexusUsesProxy.
       583   -
            */
      -  584   -
           private String databaseDriverName;
      -  585   -
       
      -  586   -
           /**
      -  587   -
            * Get the value of databaseDriverName.
      -  588  
            *
      -  589   -
            * @return the value of databaseDriverName
      -  590   +  584   +
            * @param nexusUsesProxy new value of nexusUsesProxy
      +  585  
            */
      +  586   +
           public void setNexusUsesProxy(boolean nexusUsesProxy) {
      +  587  0
               this.nexusUsesProxy = nexusUsesProxy;
      +  588  0
           }
      +  589   +
       
      +  590   +
           /**
       591   -
           public String getDatabaseDriverName() {
      -  592  0
               return databaseDriverName;
      +
            * The database driver name; such as org.h2.Driver.
      +  592   +
            */
       593   -
           }
      +
           private String databaseDriverName;
       594  
       
       595  
           /**
       596   -
            * Set the value of databaseDriverName.
      +
            * Get the value of databaseDriverName.
       597  
            *
       598   -
            * @param databaseDriverName new value of databaseDriverName
      +
            * @return the value of databaseDriverName
       599  
            */
       600   -
           public void setDatabaseDriverName(String databaseDriverName) {
      -  601  0
               this.databaseDriverName = databaseDriverName;
      -  602  0
           }
      +
           public String getDatabaseDriverName() {
      +  601  0
               return databaseDriverName;
      +  602   +
           }
       603  
       
       604  
           /**
       605   -
            * The path to the database driver JAR file if it is not on the class path.
      +
            * Set the value of databaseDriverName.
       606   -
            */
      -  607   -
           private String databaseDriverPath;
      -  608   -
       
      -  609   -
           /**
      -  610   -
            * Get the value of databaseDriverPath.
      -  611  
            *
      -  612   -
            * @return the value of databaseDriverPath
      -  613   +  607   +
            * @param databaseDriverName new value of databaseDriverName
      +  608  
            */
      +  609   +
           public void setDatabaseDriverName(String databaseDriverName) {
      +  610  0
               this.databaseDriverName = databaseDriverName;
      +  611  0
           }
      +  612   +
       
      +  613   +
           /**
       614   -
           public String getDatabaseDriverPath() {
      -  615  0
               return databaseDriverPath;
      +
            * The path to the database driver JAR file if it is not on the class path.
      +  615   +
            */
       616   -
           }
      +
           private String databaseDriverPath;
       617  
       
       618  
           /**
       619   -
            * Set the value of databaseDriverPath.
      +
            * Get the value of databaseDriverPath.
       620  
            *
       621   -
            * @param databaseDriverPath new value of databaseDriverPath
      +
            * @return the value of databaseDriverPath
       622  
            */
       623   -
           public void setDatabaseDriverPath(String databaseDriverPath) {
      -  624  0
               this.databaseDriverPath = databaseDriverPath;
      -  625  0
           }
      +
           public String getDatabaseDriverPath() {
      +  624  0
               return databaseDriverPath;
      +  625   +
           }
       626  
       
       627  
           /**
       628   -
            * The database connection string.
      +
            * Set the value of databaseDriverPath.
       629   -
            */
      -  630   -
           private String connectionString;
      -  631   -
       
      -  632   -
           /**
      -  633   -
            * Get the value of connectionString.
      -  634  
            *
      -  635   -
            * @return the value of connectionString
      -  636   +  630   +
            * @param databaseDriverPath new value of databaseDriverPath
      +  631  
            */
      +  632   +
           public void setDatabaseDriverPath(String databaseDriverPath) {
      +  633  0
               this.databaseDriverPath = databaseDriverPath;
      +  634  0
           }
      +  635   +
       
      +  636   +
           /**
       637   -
           public String getConnectionString() {
      -  638  0
               return connectionString;
      +
            * The database connection string.
      +  638   +
            */
       639   -
           }
      +
           private String connectionString;
       640  
       
       641  
           /**
       642   -
            * Set the value of connectionString.
      +
            * Get the value of connectionString.
       643  
            *
       644   -
            * @param connectionString new value of connectionString
      +
            * @return the value of connectionString
       645  
            */
       646   -
           public void setConnectionString(String connectionString) {
      -  647  0
               this.connectionString = connectionString;
      -  648  0
           }
      +
           public String getConnectionString() {
      +  647  0
               return connectionString;
      +  648   +
           }
       649  
       
       650  
           /**
       651   -
            * The user name for connecting to the database.
      +
            * Set the value of connectionString.
       652   -
            */
      -  653   -
           private String databaseUser;
      -  654   -
       
      -  655   -
           /**
      -  656   -
            * Get the value of databaseUser.
      -  657  
            *
      -  658   -
            * @return the value of databaseUser
      -  659   +  653   +
            * @param connectionString new value of connectionString
      +  654  
            */
      +  655   +
           public void setConnectionString(String connectionString) {
      +  656  0
               this.connectionString = connectionString;
      +  657  0
           }
      +  658   +
       
      +  659   +
           /**
       660   -
           public String getDatabaseUser() {
      -  661  0
               return databaseUser;
      +
            * The user name for connecting to the database.
      +  661   +
            */
       662   -
           }
      +
           private String databaseUser;
       663  
       
       664  
           /**
       665   -
            * Set the value of databaseUser.
      +
            * Get the value of databaseUser.
       666  
            *
       667   -
            * @param databaseUser new value of databaseUser
      +
            * @return the value of databaseUser
       668  
            */
       669   -
           public void setDatabaseUser(String databaseUser) {
      -  670  0
               this.databaseUser = databaseUser;
      -  671  0
           }
      +
           public String getDatabaseUser() {
      +  670  0
               return databaseUser;
      +  671   +
           }
       672  
       
       673  
           /**
       674   -
            * The password to use when connecting to the database.
      +
            * Set the value of databaseUser.
       675   -
            */
      -  676   -
           private String databasePassword;
      -  677   -
       
      -  678   -
           /**
      -  679   -
            * Get the value of databasePassword.
      -  680  
            *
      -  681   -
            * @return the value of databasePassword
      -  682   +  676   +
            * @param databaseUser new value of databaseUser
      +  677  
            */
      +  678   +
           public void setDatabaseUser(String databaseUser) {
      +  679  0
               this.databaseUser = databaseUser;
      +  680  0
           }
      +  681   +
       
      +  682   +
           /**
       683   -
           public String getDatabasePassword() {
      -  684  0
               return databasePassword;
      +
            * The password to use when connecting to the database.
      +  684   +
            */
       685   -
           }
      +
           private String databasePassword;
       686  
       
       687  
           /**
       688   -
            * Set the value of databasePassword.
      +
            * Get the value of databasePassword.
       689  
            *
       690   -
            * @param databasePassword new value of databasePassword
      +
            * @return the value of databasePassword
       691  
            */
       692   -
           public void setDatabasePassword(String databasePassword) {
      -  693  0
               this.databasePassword = databasePassword;
      -  694  0
           }
      +
           public String getDatabasePassword() {
      +  693  0
               return databasePassword;
      +  694   +
           }
       695  
       
       696  
           /**
       697   -
            * Additional ZIP File extensions to add analyze. This should be a comma-separated list of file extensions to treat like ZIP
      +
            * Set the value of databasePassword.
       698   -
            * files.
      -  699   -
            */
      -  700   -
           private String zipExtensions;
      -  701   -
       
      -  702   -
           /**
      -  703   -
            * Get the value of zipExtensions.
      -  704  
            *
      -  705   -
            * @return the value of zipExtensions
      -  706   +  699   +
            * @param databasePassword new value of databasePassword
      +  700  
            */
      +  701   +
           public void setDatabasePassword(String databasePassword) {
      +  702  0
               this.databasePassword = databasePassword;
      +  703  0
           }
      +  704   +
       
      +  705   +
           /**
      +  706   +
            * Additional ZIP File extensions to add analyze. This should be a
       707   -
           public String getZipExtensions() {
      -  708  0
               return zipExtensions;
      +
            * comma-separated list of file extensions to treat like ZIP files.
      +  708   +
            */
       709   -
           }
      +
           private String zipExtensions;
       710  
       
       711  
           /**
       712   -
            * Set the value of zipExtensions.
      +
            * Get the value of zipExtensions.
       713  
            *
       714   -
            * @param zipExtensions new value of zipExtensions
      +
            * @return the value of zipExtensions
       715  
            */
       716   -
           public void setZipExtensions(String zipExtensions) {
      -  717  0
               this.zipExtensions = zipExtensions;
      -  718  0
           }
      +
           public String getZipExtensions() {
      +  717  0
               return zipExtensions;
      +  718   +
           }
       719  
       
       720  
           /**
       721   -
            * The url for the modified NVD CVE (1.2 schema).
      +
            * Set the value of zipExtensions.
       722   -
            */
      -  723   -
           private String cveUrl12Modified;
      -  724   -
       
      -  725   -
           /**
      -  726   -
            * Get the value of cveUrl12Modified.
      -  727  
            *
      -  728   -
            * @return the value of cveUrl12Modified
      -  729   +  723   +
            * @param zipExtensions new value of zipExtensions
      +  724  
            */
      +  725   +
           public void setZipExtensions(String zipExtensions) {
      +  726  0
               this.zipExtensions = zipExtensions;
      +  727  0
           }
      +  728   +
       
      +  729   +
           /**
       730   -
           public String getCveUrl12Modified() {
      -  731  0
               return cveUrl12Modified;
      +
            * The url for the modified NVD CVE (1.2 schema).
      +  731   +
            */
       732   -
           }
      +
           private String cveUrl12Modified;
       733  
       
       734  
           /**
       735   -
            * Set the value of cveUrl12Modified.
      +
            * Get the value of cveUrl12Modified.
       736  
            *
       737   -
            * @param cveUrl12Modified new value of cveUrl12Modified
      +
            * @return the value of cveUrl12Modified
       738  
            */
       739   -
           public void setCveUrl12Modified(String cveUrl12Modified) {
      -  740  0
               this.cveUrl12Modified = cveUrl12Modified;
      -  741  0
           }
      +
           public String getCveUrl12Modified() {
      +  740  0
               return cveUrl12Modified;
      +  741   +
           }
       742  
       
       743  
           /**
       744   -
            * The url for the modified NVD CVE (2.0 schema).
      +
            * Set the value of cveUrl12Modified.
       745   -
            */
      -  746   -
           private String cveUrl20Modified;
      -  747   -
       
      -  748   -
           /**
      -  749   -
            * Get the value of cveUrl20Modified.
      -  750  
            *
      -  751   -
            * @return the value of cveUrl20Modified
      -  752   +  746   +
            * @param cveUrl12Modified new value of cveUrl12Modified
      +  747  
            */
      +  748   +
           public void setCveUrl12Modified(String cveUrl12Modified) {
      +  749  0
               this.cveUrl12Modified = cveUrl12Modified;
      +  750  0
           }
      +  751   +
       
      +  752   +
           /**
       753   -
           public String getCveUrl20Modified() {
      -  754  0
               return cveUrl20Modified;
      +
            * The url for the modified NVD CVE (2.0 schema).
      +  754   +
            */
       755   -
           }
      +
           private String cveUrl20Modified;
       756  
       
       757  
           /**
       758   -
            * Set the value of cveUrl20Modified.
      +
            * Get the value of cveUrl20Modified.
       759  
            *
       760   -
            * @param cveUrl20Modified new value of cveUrl20Modified
      +
            * @return the value of cveUrl20Modified
       761  
            */
       762   -
           public void setCveUrl20Modified(String cveUrl20Modified) {
      -  763  0
               this.cveUrl20Modified = cveUrl20Modified;
      -  764  0
           }
      +
           public String getCveUrl20Modified() {
      +  763  0
               return cveUrl20Modified;
      +  764   +
           }
       765  
       
       766  
           /**
       767   -
            * Base Data Mirror URL for CVE 1.2.
      +
            * Set the value of cveUrl20Modified.
       768   -
            */
      -  769   -
           private String cveUrl12Base;
      -  770   -
       
      -  771   -
           /**
      -  772   -
            * Get the value of cveUrl12Base.
      -  773  
            *
      -  774   -
            * @return the value of cveUrl12Base
      -  775   +  769   +
            * @param cveUrl20Modified new value of cveUrl20Modified
      +  770  
            */
      +  771   +
           public void setCveUrl20Modified(String cveUrl20Modified) {
      +  772  0
               this.cveUrl20Modified = cveUrl20Modified;
      +  773  0
           }
      +  774   +
       
      +  775   +
           /**
       776   -
           public String getCveUrl12Base() {
      -  777  0
               return cveUrl12Base;
      +
            * Base Data Mirror URL for CVE 1.2.
      +  777   +
            */
       778   -
           }
      +
           private String cveUrl12Base;
       779  
       
       780  
           /**
       781   -
            * Set the value of cveUrl12Base.
      +
            * Get the value of cveUrl12Base.
       782  
            *
       783   -
            * @param cveUrl12Base new value of cveUrl12Base
      +
            * @return the value of cveUrl12Base
       784  
            */
       785   -
           public void setCveUrl12Base(String cveUrl12Base) {
      -  786  0
               this.cveUrl12Base = cveUrl12Base;
      -  787  0
           }
      +
           public String getCveUrl12Base() {
      +  786  0
               return cveUrl12Base;
      +  787   +
           }
       788  
       
       789  
           /**
       790   -
            * Data Mirror URL for CVE 2.0.
      +
            * Set the value of cveUrl12Base.
       791   -
            */
      -  792   -
           private String cveUrl20Base;
      -  793   -
       
      -  794   -
           /**
      -  795   -
            * Get the value of cveUrl20Base.
      -  796  
            *
      -  797   -
            * @return the value of cveUrl20Base
      -  798   +  792   +
            * @param cveUrl12Base new value of cveUrl12Base
      +  793  
            */
      +  794   +
           public void setCveUrl12Base(String cveUrl12Base) {
      +  795  0
               this.cveUrl12Base = cveUrl12Base;
      +  796  0
           }
      +  797   +
       
      +  798   +
           /**
       799   -
           public String getCveUrl20Base() {
      -  800  0
               return cveUrl20Base;
      +
            * Data Mirror URL for CVE 2.0.
      +  800   +
            */
       801   -
           }
      +
           private String cveUrl20Base;
       802  
       
       803  
           /**
       804   -
            * Set the value of cveUrl20Base.
      +
            * Get the value of cveUrl20Base.
       805  
            *
       806   -
            * @param cveUrl20Base new value of cveUrl20Base
      +
            * @return the value of cveUrl20Base
       807  
            */
       808   -
           public void setCveUrl20Base(String cveUrl20Base) {
      -  809  0
               this.cveUrl20Base = cveUrl20Base;
      -  810  0
           }
      +
           public String getCveUrl20Base() {
      +  809  0
               return cveUrl20Base;
      +  810   +
           }
       811  
       
       812  
           /**
       813   -
            * The path to Mono for .NET assembly analysis on non-windows systems.
      +
            * Set the value of cveUrl20Base.
       814   -
            */
      -  815   -
           private String pathToMono;
      -  816   -
       
      -  817   -
           /**
      -  818   -
            * Get the value of pathToMono.
      -  819  
            *
      -  820   -
            * @return the value of pathToMono
      -  821   +  815   +
            * @param cveUrl20Base new value of cveUrl20Base
      +  816  
            */
      +  817   +
           public void setCveUrl20Base(String cveUrl20Base) {
      +  818  0
               this.cveUrl20Base = cveUrl20Base;
      +  819  0
           }
      +  820   +
       
      +  821   +
           /**
       822   -
           public String getPathToMono() {
      -  823  0
               return pathToMono;
      +
            * The path to Mono for .NET assembly analysis on non-windows systems.
      +  823   +
            */
       824   -
           }
      +
           private String pathToMono;
       825  
       
       826  
           /**
       827   -
            * Set the value of pathToMono.
      +
            * Get the value of pathToMono.
       828  
            *
       829   -
            * @param pathToMono new value of pathToMono
      +
            * @return the value of pathToMono
       830  
            */
       831   -
           public void setPathToMono(String pathToMono) {
      -  832  0
               this.pathToMono = pathToMono;
      -  833  0
           }
      +
           public String getPathToMono() {
      +  832  0
               return pathToMono;
      +  833   +
           }
       834  
       
       835  
           /**
       836   -
            * Executes the Dependency-Check on the dependent libraries.
      +
            * Set the value of pathToMono.
       837  
            *
       838   -
            * @return the Engine used to scan the dependencies.
      +
            * @param pathToMono new value of pathToMono
       839   -
            * @throws org.owasp.dependencycheck.data.nvdcve.DatabaseException thrown if there is an exception connecting to the database
      +
            */
       840   -
            */
      -  841   -
           private Engine executeDependencyCheck() throws DatabaseException {
      -  842  0
               populateSettings();
      -  843  0
               final Engine engine = new Engine();
      -  844  0
               engine.setDependencies(this.dependencies);
      -  845  0
               engine.analyzeDependencies();
      -  846  0
               return engine;
      +
           public void setPathToMono(String pathToMono) {
      +  841  0
               this.pathToMono = pathToMono;
      +  842  0
           }
      +  843   +
       
      +  844   +
           /**
      +  845   +
            * Executes the Dependency-Check on the dependent libraries.
      +  846   +
            *
       847   -
           }
      +
            * @return the Engine used to scan the dependencies.
       848   -
       
      +
            * @throws ExceptionCollection a collection of one or more exceptions that
       849   -
           /**
      +
            * occurred during analysis.
       850   -
            * Generates the reports for a given dependency-check engine.
      +
            */
       851   -
            *
      -  852   -
            * @param engine a dependency-check engine
      +
           private Engine executeDependencyCheck() throws ExceptionCollection {
      +  852  0
               populateSettings();
       853   -
            * @param outDirectory the directory to write the reports to
      +
               final Engine engine;
       854   -
            */
      -  855   -
           private void generateExternalReports(Engine engine, File outDirectory) {
      -  856  0
               DatabaseProperties prop = null;
      -  857  0
               CveDB cve = null;
      -  858  
               try {
      -  859  0
                   cve = new CveDB();
      -  860  0
                   cve.open();
      -  861  0
                   prop = cve.getDatabaseProperties();
      -  862  0
               } catch (DatabaseException ex) {
      -  863  0
                   LOGGER.debug("Unable to retrieve DB Properties", ex);
      -  864   -
               } finally {
      -  865  0
                   if (cve != null) {
      -  866  0
                       cve.close();
      -  867   -
                   }
      -  868   -
               }
      -  869  0
               final ReportGenerator r = new ReportGenerator(this.applicationName, engine.getDependencies(), engine.getAnalyzers(), prop);
      -  870   -
               try {
      -  871  0
                   r.generateReports(outDirectory.getCanonicalPath(), this.reportFormat.name());
      -  872  0
               } catch (IOException ex) {
      -  873  0
                   LOGGER.error(
      -  874   -
                           "Unexpected exception occurred during analysis; please see the verbose error log for more details.");
      -  875  0
                   LOGGER.debug("", ex);
      -  876  0
               } catch (Throwable ex) {
      -  877  0
                   LOGGER.error(
      -  878   -
                           "Unexpected exception occurred during analysis; please see the verbose error log for more details.");
      -  879  0
                   LOGGER.debug("", ex);
      -  880  0
               }
      -  881  0
           }
      -  882   -
       
      -  883   -
           /**
      -  884   -
            * Takes the properties supplied and updates the dependency-check settings. Additionally, this sets the system properties
      -  885   -
            * required to change the proxy server, port, and connection timeout.
      -  886   -
            */
      -  887   -
           private void populateSettings() {
      -  888  0
               Settings.initialize();
      -  889  0
               if (dataDirectory != null) {
      -  890  0
                   Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory);
      -  891   -
               } else {
      -  892  0
                   final File jarPath = new File(DependencyCheckScanAgent.class.getProtectionDomain().getCodeSource().getLocation().getPath());
      -  893  0
                   final File base = jarPath.getParentFile();
      -  894  0
                   final String sub = Settings.getString(Settings.KEYS.DATA_DIRECTORY);
      -  895  0
                   final File dataDir = new File(base, sub);
      -  896  0
                   Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath());
      -  897   -
               }
      -  898   -
       
      -  899  0
               Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate);
      -  900  0
               Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_SERVER, proxyServer);
      -  901  0
               Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PORT, proxyPort);
      -  902  0
               Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_USERNAME, proxyUsername);
      -  903  0
               Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PASSWORD, proxyPassword);
      -  904  0
               Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout);
      -  905  0
               Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile);
      -  906  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, centralAnalyzerEnabled);
      -  907  0
               Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_CENTRAL_URL, centralUrl);
      -  908  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled);
      -  909  0
               Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl);
      -  910  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy);
      -  911  0
               Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName);
      -  912  0
               Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath);
      -  913  0
               Settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString);
      -  914  0
               Settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser);
      -  915  0
               Settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword);
      -  916  0
               Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions);
      -  917  0
               Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_12_URL, cveUrl12Modified);
      -  918  0
               Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_20_URL, cveUrl20Modified);
      -  919  0
               Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_1_2, cveUrl12Base);
      -  920  0
               Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_2_0, cveUrl20Base);
      -  921  0
               Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono);
      -  922  0
           }
      -  923   -
       
      -  924   -
           /**
      -  925   -
            * Executes the dependency-check and generates the report.
      -  926   -
            *
      -  927   -
            * @return a reference to the engine used to perform the scan.
      -  928   -
            * @throws org.owasp.dependencycheck.exception.ScanAgentException thrown if there is an exception executing the scan.
      -  929   -
            */
      -  930   -
           public Engine execute() throws ScanAgentException {
      -  931  0
               Engine engine = null;
      -  932   -
               try {
      -  933  0
                   engine = executeDependencyCheck();
      -  934  0
                   if (this.generateReport) {
      -  935  0
                       generateExternalReports(engine, new File(this.reportOutputDirectory));
      -  936   -
                   }
      -  937  0
                   if (this.showSummary) {
      -  938  0
                       showSummary(engine.getDependencies());
      -  939   -
                   }
      -  940  0
                   if (this.failBuildOnCVSS <= 10) {
      -  941  0
                       checkForFailure(engine.getDependencies());
      -  942   -
                   }
      -  943  0
               } catch (DatabaseException ex) {
      -  944  0
                   LOGGER.error(
      -  945   -
                           "Unable to connect to the dependency-check database; analysis has stopped");
      -  946  0
                   LOGGER.debug("", ex);
      -  947   -
               } finally {
      -  948  0
                   Settings.cleanup(true);
      -  949  0
                   if (engine != null) {
      -  950  0
                       engine.cleanup();
      -  951   -
                   }
      -  952   -
               }
      -  953  0
               return engine;
      -  954   +  855  0
                   engine = new Engine();
      +  856  0
               } catch (DatabaseException ex) {
      +  857  0
                   throw new ExceptionCollection(ex, true);
      +  858  0
               }
      +  859  0
               engine.setDependencies(this.dependencies);
      +  860  0
               engine.analyzeDependencies();
      +  861  0
               return engine;
      +  862  
           }
      -  955   +  863  
       
      -  956   +  864  
           /**
      -  957   -
            * Checks to see if a vulnerability has been identified with a CVSS score that is above the threshold set in the
      -  958   -
            * configuration.
      -  959   +  865   +
            * Generates the reports for a given dependency-check engine.
      +  866  
            *
      -  960   -
            * @param dependencies the list of dependency objects
      -  961   -
            * @throws org.owasp.dependencycheck.exception.ScanAgentException thrown if there is an exception executing the scan.
      -  962   +  867   +
            * @param engine a dependency-check engine
      +  868   +
            * @param outDirectory the directory to write the reports to
      +  869  
            */
      -  963   -
           private void checkForFailure(List<Dependency> dependencies) throws ScanAgentException {
      -  964  0
               final StringBuilder ids = new StringBuilder();
      -  965  0
               for (Dependency d : dependencies) {
      -  966  0
                   boolean addName = true;
      -  967  0
                   for (Vulnerability v : d.getVulnerabilities()) {
      -  968  0
                       if (v.getCvssScore() >= failBuildOnCVSS) {
      -  969  0
                           if (addName) {
      -  970  0
                               addName = false;
      -  971  0
                               ids.append(NEW_LINE).append(d.getFileName()).append(": ");
      -  972  0
                               ids.append(v.getName());
      -  973   -
                           } else {
      -  974  0
                               ids.append(", ").append(v.getName());
      -  975   -
                           }
      -  976   -
                       }
      -  977  0
                   }
      -  978  0
               }
      -  979  0
               if (ids.length() > 0) {
      -  980  0
                   final String msg = String.format("%n%nDependency-Check Failure:%n"
      -  981   -
                           + "One or more dependencies were identified with vulnerabilities that have a CVSS score greater then '%.1f': %s%n"
      -  982  0
                           + "See the dependency-check report for more details.%n%n", failBuildOnCVSS, ids.toString());
      -  983   -
       
      -  984  0
                   throw new ScanAgentException(msg);
      -  985   -
               }
      -  986  0
           }
      -  987   -
       
      -  988   -
           /**
      -  989   -
            * Generates a warning message listing a summary of dependencies and their associated CPE and CVE entries.
      -  990   -
            *
      -  991   -
            * @param dependencies a list of dependency objects
      -  992   -
            */
      -  993   -
           private void showSummary(List<Dependency> dependencies) {
      -  994  0
               final StringBuilder summary = new StringBuilder();
      -  995  0
               for (Dependency d : dependencies) {
      -  996  0
                   boolean firstEntry = true;
      -  997  0
                   final StringBuilder ids = new StringBuilder();
      -  998  0
                   for (Vulnerability v : d.getVulnerabilities()) {
      -  999  0
                       if (firstEntry) {
      -  1000  0
                           firstEntry = false;
      -  1001   -
                       } else {
      -  1002  0
                           ids.append(", ");
      -  1003   -
                       }
      -  1004  0
                       ids.append(v.getName());
      -  1005  0
                   }
      -  1006  0
                   if (ids.length() > 0) {
      -  1007  0
                       summary.append(d.getFileName()).append(" (");
      -  1008  0
                       firstEntry = true;
      -  1009  0
                       for (Identifier id : d.getIdentifiers()) {
      -  1010  0
                           if (firstEntry) {
      -  1011  0
                               firstEntry = false;
      -  1012   -
                           } else {
      -  1013  0
                               summary.append(", ");
      -  1014   -
                           }
      -  1015  0
                           summary.append(id.getValue());
      -  1016  0
                       }
      -  1017  0
                       summary.append(") : ").append(ids).append(NEW_LINE);
      -  1018   +  870   +
           private void generateExternalReports(Engine engine, File outDirectory) {
      +  871  0
               DatabaseProperties prop = null;
      +  872  0
               CveDB cve = null;
      +  873   +
               try {
      +  874  0
                   cve = new CveDB();
      +  875  0
                   cve.open();
      +  876  0
                   prop = cve.getDatabaseProperties();
      +  877  0
               } catch (DatabaseException ex) {
      +  878  0
                   LOGGER.debug("Unable to retrieve DB Properties", ex);
      +  879   +
               } finally {
      +  880  0
                   if (cve != null) {
      +  881  0
                       cve.close();
      +  882  
                   }
      -  1019  0
               }
      -  1020  0
               if (summary.length() > 0) {
      -  1021  0
                   LOGGER.warn("\n\nOne or more dependencies were identified with known vulnerabilities:\n\n{}\n\n"
      -  1022   -
                           + "See the dependency-check report for more details.\n\n",
      -  1023  0
                           summary.toString());
      -  1024   +  883  
               }
      -  1025  0
           }
      -  1026   +  884  0
               final ReportGenerator r = new ReportGenerator(this.applicationName, engine.getDependencies(), engine.getAnalyzers(), prop);
      +  885   +
               try {
      +  886  0
                   r.generateReports(outDirectory.getCanonicalPath(), this.reportFormat.name());
      +  887  0
               } catch (IOException ex) {
      +  888  0
                   LOGGER.error(
      +  889   +
                           "Unexpected exception occurred during analysis; please see the verbose error log for more details.");
      +  890  0
                   LOGGER.debug("", ex);
      +  891  0
               } catch (Throwable ex) {
      +  892  0
                   LOGGER.error(
      +  893   +
                           "Unexpected exception occurred during analysis; please see the verbose error log for more details.");
      +  894  0
                   LOGGER.debug("", ex);
      +  895  0
               }
      +  896  0
           }
      +  897  
       
      -  1027   +  898   +
           /**
      +  899   +
            * Takes the properties supplied and updates the dependency-check settings.
      +  900   +
            * Additionally, this sets the system properties required to change the
      +  901   +
            * proxy server, port, and connection timeout.
      +  902   +
            */
      +  903   +
           private void populateSettings() {
      +  904  0
               Settings.initialize();
      +  905  0
               if (dataDirectory != null) {
      +  906  0
                   Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory);
      +  907   +
               } else {
      +  908  0
                   final File jarPath = new File(DependencyCheckScanAgent.class.getProtectionDomain().getCodeSource().getLocation().getPath());
      +  909  0
                   final File base = jarPath.getParentFile();
      +  910  0
                   final String sub = Settings.getString(Settings.KEYS.DATA_DIRECTORY);
      +  911  0
                   final File dataDir = new File(base, sub);
      +  912  0
                   Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath());
      +  913   +
               }
      +  914   +
       
      +  915  0
               Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate);
      +  916  0
               Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_SERVER, proxyServer);
      +  917  0
               Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PORT, proxyPort);
      +  918  0
               Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_USERNAME, proxyUsername);
      +  919  0
               Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PASSWORD, proxyPassword);
      +  920  0
               Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout);
      +  921  0
               Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile);
      +  922  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, centralAnalyzerEnabled);
      +  923  0
               Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_CENTRAL_URL, centralUrl);
      +  924  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled);
      +  925  0
               Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl);
      +  926  0
               Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy);
      +  927  0
               Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName);
      +  928  0
               Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath);
      +  929  0
               Settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString);
      +  930  0
               Settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser);
      +  931  0
               Settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword);
      +  932  0
               Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions);
      +  933  0
               Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_12_URL, cveUrl12Modified);
      +  934  0
               Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_20_URL, cveUrl20Modified);
      +  935  0
               Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_1_2, cveUrl12Base);
      +  936  0
               Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_2_0, cveUrl20Base);
      +  937  0
               Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono);
      +  938  0
           }
      +  939   +
       
      +  940   +
           /**
      +  941   +
            * Executes the dependency-check and generates the report.
      +  942   +
            *
      +  943   +
            * @return a reference to the engine used to perform the scan.
      +  944   +
            * @throws org.owasp.dependencycheck.exception.ScanAgentException thrown if
      +  945   +
            * there is an exception executing the scan.
      +  946   +
            */
      +  947   +
           public Engine execute() throws ScanAgentException {
      +  948  0
               Engine engine = null;
      +  949   +
               try {
      +  950  0
                   engine = executeDependencyCheck();
      +  951  0
                   if (this.generateReport) {
      +  952  0
                       generateExternalReports(engine, new File(this.reportOutputDirectory));
      +  953   +
                   }
      +  954  0
                   if (this.showSummary) {
      +  955  0
                       showSummary(engine.getDependencies());
      +  956   +
                   }
      +  957  0
                   if (this.failBuildOnCVSS <= 10) {
      +  958  0
                       checkForFailure(engine.getDependencies());
      +  959   +
                   }
      +  960  0
               } catch (ExceptionCollection ex) {
      +  961  0
                   if (ex.isFatal()) {
      +  962  0
                       LOGGER.error("A fatal exception occurred during analysis; analysis has stopped. Please see the debug log for more details.");
      +  963  0
                       LOGGER.debug("", ex);
      +  964   +
                   }
      +  965  0
                   throw new ScanAgentException("One or more exceptions occurred during analysis; please see the debug log for more details.", ex);
      +  966   +
               } finally {
      +  967  0
                   Settings.cleanup(true);
      +  968  0
                   if (engine != null) {
      +  969  0
                       engine.cleanup();
      +  970   +
                   }
      +  971   +
               }
      +  972  0
               return engine;
      +  973   +
           }
      +  974   +
       
      +  975   +
           /**
      +  976   +
            * Checks to see if a vulnerability has been identified with a CVSS score
      +  977   +
            * that is above the threshold set in the configuration.
      +  978   +
            *
      +  979   +
            * @param dependencies the list of dependency objects
      +  980   +
            * @throws org.owasp.dependencycheck.exception.ScanAgentException thrown if
      +  981   +
            * there is an exception executing the scan.
      +  982   +
            */
      +  983   +
           private void checkForFailure(List<Dependency> dependencies) throws ScanAgentException {
      +  984  0
               final StringBuilder ids = new StringBuilder();
      +  985  0
               for (Dependency d : dependencies) {
      +  986  0
                   boolean addName = true;
      +  987  0
                   for (Vulnerability v : d.getVulnerabilities()) {
      +  988  0
                       if (v.getCvssScore() >= failBuildOnCVSS) {
      +  989  0
                           if (addName) {
      +  990  0
                               addName = false;
      +  991  0
                               ids.append(NEW_LINE).append(d.getFileName()).append(": ");
      +  992  0
                               ids.append(v.getName());
      +  993   +
                           } else {
      +  994  0
                               ids.append(", ").append(v.getName());
      +  995   +
                           }
      +  996   +
                       }
      +  997  0
                   }
      +  998  0
               }
      +  999  0
               if (ids.length() > 0) {
      +  1000  0
                   final String msg = String.format("%n%nDependency-Check Failure:%n"
      +  1001   +
                           + "One or more dependencies were identified with vulnerabilities that have a CVSS score greater then '%.1f': %s%n"
      +  1002  0
                           + "See the dependency-check report for more details.%n%n", failBuildOnCVSS, ids.toString());
      +  1003   +
       
      +  1004  0
                   throw new ScanAgentException(msg);
      +  1005   +
               }
      +  1006  0
           }
      +  1007   +
       
      +  1008   +
           /**
      +  1009   +
            * Generates a warning message listing a summary of dependencies and their
      +  1010   +
            * associated CPE and CVE entries.
      +  1011   +
            *
      +  1012   +
            * @param dependencies a list of dependency objects
      +  1013   +
            */
      +  1014   +
           private void showSummary(List<Dependency> dependencies) {
      +  1015  0
               final StringBuilder summary = new StringBuilder();
      +  1016  0
               for (Dependency d : dependencies) {
      +  1017  0
                   boolean firstEntry = true;
      +  1018  0
                   final StringBuilder ids = new StringBuilder();
      +  1019  0
                   for (Vulnerability v : d.getVulnerabilities()) {
      +  1020  0
                       if (firstEntry) {
      +  1021  0
                           firstEntry = false;
      +  1022   +
                       } else {
      +  1023  0
                           ids.append(", ");
      +  1024   +
                       }
      +  1025  0
                       ids.append(v.getName());
      +  1026  0
                   }
      +  1027  0
                   if (ids.length() > 0) {
      +  1028  0
                       summary.append(d.getFileName()).append(" (");
      +  1029  0
                       firstEntry = true;
      +  1030  0
                       for (Identifier id : d.getIdentifiers()) {
      +  1031  0
                           if (firstEntry) {
      +  1032  0
                               firstEntry = false;
      +  1033   +
                           } else {
      +  1034  0
                               summary.append(", ");
      +  1035   +
                           }
      +  1036  0
                           summary.append(id.getValue());
      +  1037  0
                       }
      +  1038  0
                       summary.append(") : ").append(ids).append(NEW_LINE);
      +  1039   +
                   }
      +  1040  0
               }
      +  1041  0
               if (summary.length() > 0) {
      +  1042  0
                   LOGGER.warn("\n\nOne or more dependencies were identified with known vulnerabilities:\n\n{}\n\n"
      +  1043   +
                           + "See the dependency-check report for more details.\n\n",
      +  1044  0
                           summary.toString());
      +  1045   +
               }
      +  1046  0
           }
      +  1047   +
       
      +  1048  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AbstractAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AbstractAnalyzer.html index 4e270fef6..24c4f1bbf 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AbstractAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AbstractAnalyzer.html @@ -56,56 +56,64 @@  19  
       
       20   -
       /**
      +
       import org.owasp.dependencycheck.exception.InitializationException;
       21   -
        *
      +
       
       22   -
        * @author Jeremy Long
      +
       /**
       23   -
        */
      -  24  414
       public abstract class AbstractAnalyzer implements Analyzer {
      +
        * Base class for analyzers to avoid code duplication of initialize and close
      +  24   +
        * as most analyzers do not need these methods.
       25   -
       
      +
        *
       26   -
           /**
      +
        * @author Jeremy Long
       27   -
            * The initialize method does nothing for this Analyzer.
      -  28   -
            *
      +
        */
      +  28  207
       public abstract class AbstractAnalyzer implements Analyzer {
       29   -
            * @throws Exception thrown if there is an exception
      -  30   -
            */
      -  31   -
           @Override
      -  32   -
           public void initialize() throws Exception {
      -  33   -
               //do nothing
      -  34  32
           }
      -  35  
       
      -  36   +  30  
           /**
      -  37   -
            * The close method does nothing for this Analyzer.
      -  38   +  31   +
            * The initialize method does nothing for this Analyzer.
      +  32  
            *
      -  39   -
            * @throws Exception thrown if there is an exception
      -  40   +  33   +
            * @throws InitializationException thrown if there is an exception
      +  34  
            */
      -  41   +  35  
           @Override
      -  42   -
           public void close() throws Exception {
      -  43   +  36   +
           public void initialize() throws InitializationException {
      +  37  
               //do nothing
      -  44  162
           }
      +  38  16
           }
      +  39   +
       
      +  40   +
           /**
      +  41   +
            * The close method does nothing for this Analyzer.
      +  42   +
            *
      +  43   +
            * @throws Exception thrown if there is an exception
      +  44   +
            */
       45   +
           @Override
      +  46   +
           public void close() throws Exception {
      +  47   +
               //do nothing
      +  48  81
           }
      +  49  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AbstractFileTypeAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AbstractFileTypeAnalyzer.html index 6412d37b1..1f3daba70 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AbstractFileTypeAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AbstractFileTypeAnalyzer.html @@ -82,346 +82,368 @@  32  
       import java.util.Set;
       33   -
       
      +
       import org.owasp.dependencycheck.exception.InitializationException;
       34   -
       /**
      +
       
       35   -
        * The base FileTypeAnalyzer that all analyzers that have specific file types they analyze should extend.
      +
       /**
       36   -
        *
      +
        * The base FileTypeAnalyzer that all analyzers that have specific file types
       37   -
        * @author Jeremy Long
      +
        * they analyze should extend.
       38   -
        */
      +
        *
       39   -
       public abstract class AbstractFileTypeAnalyzer extends AbstractAnalyzer implements FileTypeAnalyzer {
      +
        * @author Jeremy Long
       40   -
       
      +
        */
       41   -
           //<editor-fold defaultstate="collapsed" desc="Constructor">
      +
       public abstract class AbstractFileTypeAnalyzer extends AbstractAnalyzer implements FileTypeAnalyzer {
       42   -
           /**
      +
       
       43   -
            * Base constructor that all children must call. This checks the configuration to determine if the analyzer is enabled.
      +
           //<editor-fold defaultstate="collapsed" desc="Constructor">
       44   +
           /**
      +  45   +
            * Base constructor that all children must call. This checks the
      +  46   +
            * configuration to determine if the analyzer is enabled.
      +  47  
            */
      -  45  304
           public AbstractFileTypeAnalyzer() {
      -  46  304
               reset();
      -  47  304
           }
      -  48   -
       //</editor-fold>
      -  49   -
       
      -  50   -
           //<editor-fold defaultstate="collapsed" desc="Field definitions">
      +  48  152
           public AbstractFileTypeAnalyzer() {
      +  49  152
               reset();
      +  50  152
           }
       51   -
           /**
      +
       //</editor-fold>
       52   -
            * The logger.
      +
       
       53   -
            */
      -  54  2
           private static final Logger LOGGER = LoggerFactory.getLogger(AbstractFileTypeAnalyzer.class);
      +
           //<editor-fold defaultstate="collapsed" desc="Field definitions">
      +  54   +
           /**
       55   -
           /**
      +
            * The logger.
       56   -
            * Whether the file type analyzer detected any files it needs to analyze.
      -  57  
            */
      -  58  304
           private boolean filesMatched = false;
      +  57  1
           private static final Logger LOGGER = LoggerFactory.getLogger(AbstractFileTypeAnalyzer.class);
      +  58   +
           /**
       59   -
       
      +
            * Whether the file type analyzer detected any files it needs to analyze.
       60   -
           /**
      -  61   -
            * Get the value of filesMatched. A flag indicating whether the scan included any file types this analyzer supports.
      +
            */
      +  61  152
           private boolean filesMatched = false;
       62   -
            *
      +
       
       63   -
            * @return the value of filesMatched
      +
           /**
       64   -
            */
      +
            * Get the value of filesMatched. A flag indicating whether the scan
       65   -
           protected boolean isFilesMatched() {
      -  66  0
               return filesMatched;
      -  67   -
           }
      -  68   -
       
      -  69   -
           /**
      -  70   -
            * Set the value of filesMatched. A flag indicating whether the scan included any file types this analyzer supports.
      -  71   +
            * included any file types this analyzer supports.
      +  66  
            *
      +  67   +
            * @return the value of filesMatched
      +  68   +
            */
      +  69   +
           protected boolean isFilesMatched() {
      +  70  0
               return filesMatched;
      +  71   +
           }
       72   -
            * @param filesMatched new value of filesMatched
      -  73   -
            */
      -  74   -
           protected void setFilesMatched(boolean filesMatched) {
      -  75  88
               this.filesMatched = filesMatched;
      -  76  88
           }
      -  77  
       
      -  78   +  73  
           /**
      -  79   -
            * A flag indicating whether or not the analyzer is enabled.
      -  80   +  74   +
            * Set the value of filesMatched. A flag indicating whether the scan
      +  75   +
            * included any file types this analyzer supports.
      +  76   +
            *
      +  77   +
            * @param filesMatched new value of filesMatched
      +  78  
            */
      -  81  304
           private boolean enabled = true;
      +  79   +
           protected void setFilesMatched(boolean filesMatched) {
      +  80  44
               this.filesMatched = filesMatched;
      +  81  44
           }
       82  
       
       83  
           /**
       84   -
            * Get the value of enabled.
      +
            * A flag indicating whether or not the analyzer is enabled.
       85   -
            *
      -  86   -
            * @return the value of enabled
      +
            */
      +  86  152
           private boolean enabled = true;
       87   -
            */
      +
       
       88   -
           public boolean isEnabled() {
      -  89  2
               return enabled;
      +
           /**
      +  89   +
            * Get the value of enabled.
       90   -
           }
      +
            *
       91   -
       
      +
            * @return the value of enabled
       92   -
           /**
      +
            */
       93   -
            * Set the value of enabled.
      -  94   -
            *
      +
           public boolean isEnabled() {
      +  94  1
               return enabled;
       95   -
            * @param enabled new value of enabled
      +
           }
       96   -
            */
      +
       
       97   -
           public void setEnabled(boolean enabled) {
      -  98  16
               this.enabled = enabled;
      -  99  16
           }
      -  100   -
       //</editor-fold>
      -  101   -
       
      -  102   -
           //<editor-fold defaultstate="collapsed" desc="Abstract methods children must implement">
      -  103  
           /**
      -  104   -
            * <p>
      -  105   -
            * Returns the {@link java.io.FileFilter} used to determine which files are to be analyzed. An example would be an analyzer
      -  106   -
            * that inspected Java jar files. Implementors may use {@link org.owasp.dependencycheck.utils.FileFilterBuilder}.</p>
      -  107   -
            * <p>
      -  108   -
            * If the analyzer returns null it will not cause additional files to be analyzed, but will be executed against every file
      -  109   -
            * loaded.</p>
      -  110   +  98   +
            * Set the value of enabled.
      +  99  
            *
      -  111   -
            * @return the file filter used to determine which files are to be analyzed
      -  112   +  100   +
            * @param enabled new value of enabled
      +  101  
            */
      -  113   -
           protected abstract FileFilter getFileFilter();
      -  114   +  102   +
           public void setEnabled(boolean enabled) {
      +  103  8
               this.enabled = enabled;
      +  104  8
           }
      +  105   +
       //</editor-fold>
      +  106  
       
      -  115   +  107   +
           //<editor-fold defaultstate="collapsed" desc="Abstract methods children must implement">
      +  108  
           /**
      +  109   +
            * <p>
      +  110   +
            * Returns the {@link java.io.FileFilter} used to determine which files are
      +  111   +
            * to be analyzed. An example would be an analyzer that inspected Java jar
      +  112   +
            * files. Implementors may use
      +  113   +
            * {@link org.owasp.dependencycheck.utils.FileFilterBuilder}.</p>
      +  114   +
            * <p>
      +  115   +
            * If the analyzer returns null it will not cause additional files to be
       116   -
            * Initializes the file type analyzer.
      +
            * analyzed, but will be executed against every file loaded.</p>
       117  
            *
       118   -
            * @throws Exception thrown if there is an exception during initialization
      +
            * @return the file filter used to determine which files are to be analyzed
       119  
            */
       120   -
           protected abstract void initializeFileTypeAnalyzer() throws Exception;
      +
           protected abstract FileFilter getFileFilter();
       121  
       
       122  
           /**
       123   -
            * Analyzes a given dependency. If the dependency is an archive, such as a WAR or EAR, the contents are extracted, scanned,
      +
            * Initializes the file type analyzer.
       124   -
            * and added to the list of dependencies within the engine.
      +
            *
       125   -
            *
      +
            * @throws InitializationException thrown if there is an exception during
       126   -
            * @param dependency the dependency to analyze
      +
            * initialization
       127   -
            * @param engine the engine scanning
      +
            */
       128   -
            * @throws AnalysisException thrown if there is an analysis exception
      +
           protected abstract void initializeFileTypeAnalyzer() throws InitializationException;
       129   -
            */
      +
       
       130   -
           protected abstract void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException;
      +
           /**
       131   -
       
      +
            * Analyzes a given dependency. If the dependency is an archive, such as a
       132   -
           /**
      +
            * WAR or EAR, the contents are extracted, scanned, and added to the list of
       133   -
            * <p>
      +
            * dependencies within the engine.
       134   -
            * Returns the setting key to determine if the analyzer is enabled.</p>
      -  135  
            *
      +  135   +
            * @param dependency the dependency to analyze
       136   -
            * @return the key for the analyzer's enabled property
      +
            * @param engine the engine scanning
       137   -
            */
      +
            * @throws AnalysisException thrown if there is an analysis exception
       138   -
           protected abstract String getAnalyzerEnabledSettingKey();
      +
            */
       139   -
       
      +
           protected abstract void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException;
       140   -
       //</editor-fold>
      +
       
       141   -
           //<editor-fold defaultstate="collapsed" desc="Final implementations for the Analyzer interface">
      -  142  
           /**
      +  142   +
            * <p>
       143   -
            * Initializes the analyzer.
      +
            * Returns the setting key to determine if the analyzer is enabled.</p>
       144  
            *
       145   -
            * @throws Exception thrown if there is an exception during initialization
      +
            * @return the key for the analyzer's enabled property
       146  
            */
       147   -
           @Override
      +
           protected abstract String getAnalyzerEnabledSettingKey();
       148   -
           public final void initialize() throws Exception {
      -  149  164
               if (filesMatched) {
      -  150  102
                   initializeFileTypeAnalyzer();
      -  151   -
               } else {
      -  152  62
                   enabled = false;
      -  153   -
               }
      -  154  156
           }
      -  155  
       
      -  156   -
           /**
      -  157   -
            * Resets the enabled flag on the analyzer.
      -  158   -
            */
      -  159   -
           @Override
      -  160   -
           public final void reset() {
      -  161  304
               final String key = getAnalyzerEnabledSettingKey();
      -  162   -
               try {
      -  163  304
                   enabled = Settings.getBoolean(key, true);
      -  164  0
               } catch (InvalidSettingException ex) {
      -  165  0
                   LOGGER.warn("Invalid setting for property '{}'", key);
      -  166  0
                   LOGGER.debug("", ex);
      -  167  0
                   LOGGER.warn("{} has been disabled", getName());
      -  168  304
               }
      -  169  304
           }
      -  170   -
       
      -  171   -
           /**
      -  172   -
            * Analyzes a given dependency. If the dependency is an archive, such as a WAR or EAR, the contents are extracted, scanned,
      -  173   -
            * and added to the list of dependencies within the engine.
      -  174   -
            *
      -  175   -
            * @param dependency the dependency to analyze
      -  176   -
            * @param engine the engine scanning
      -  177   -
            * @throws AnalysisException thrown if there is an analysis exception
      -  178   -
            */
      -  179   -
           @Override
      -  180   -
           public final void analyze(Dependency dependency, Engine engine) throws AnalysisException {
      -  181  64
               if (enabled) {
      -  182  64
                   analyzeFileType(dependency, engine);
      -  183   -
               }
      -  184  62
           }
      -  185   -
       
      -  186   -
           @Override
      -  187   -
           public boolean accept(File pathname) {
      -  188  27542
               final FileFilter filter = getFileFilter();
      -  189  27542
               boolean accepted = false;
      -  190  27542
               if (null == filter) {
      -  191  0
                   LOGGER.error("The '{}' analyzer is misconfigured and does not have a file filter; it will be disabled", getName());
      -  192  27542
               } else if (enabled) {
      -  193  24010
                   accepted = filter.accept(pathname);
      -  194  24010
                   if (accepted) {
      -  195  78
                       filesMatched = true;
      -  196   -
                   }
      -  197   -
               }
      -  198  27542
               return accepted;
      -  199   -
           }
      -  200   -
       
      -  201   -
           //</editor-fold>
      -  202   -
           //<editor-fold defaultstate="collapsed" desc="Static utility methods">
      -  203   -
           /**
      -  204   -
            * <p>
      -  205   -
            * Utility method to help in the creation of the extensions set. This constructs a new Set that can be used in a final static
      -  206   -
            * declaration.</p>
      -  207   -
            * <p>
      -  208   -
            * This implementation was copied from
      -  209   -
            * http://stackoverflow.com/questions/2041778/initialize-java-hashset-values-by-construction</p>
      -  210   -
            *
      -  211   -
            * @param strings a list of strings to add to the set.
      -  212   -
            * @return a Set of strings.
      -  213   -
            */
      -  214   -
           protected static Set<String> newHashSet(String... strings) {
      -  215  10
               final Set<String> set = new HashSet<String>(strings.length);
      -  216  10
               Collections.addAll(set, strings);
      -  217  10
               return set;
      -  218   -
           }
      -  219   -
       
      -  220   +  149  
       //</editor-fold>
      +  150   +
           //<editor-fold defaultstate="collapsed" desc="Final implementations for the Analyzer interface">
      +  151   +
           /**
      +  152   +
            * Initializes the analyzer.
      +  153   +
            *
      +  154   +
            * @throws InitializationException thrown if there is an exception during
      +  155   +
            * initialization
      +  156   +
            */
      +  157   +
           @Override
      +  158   +
           public final void initialize() throws InitializationException {
      +  159  82
               if (filesMatched) {
      +  160  51
                   initializeFileTypeAnalyzer();
      +  161   +
               } else {
      +  162  31
                   enabled = false;
      +  163   +
               }
      +  164  78
           }
      +  165   +
       
      +  166   +
           /**
      +  167   +
            * Resets the enabled flag on the analyzer.
      +  168   +
            */
      +  169   +
           @Override
      +  170   +
           public final void reset() {
      +  171  152
               final String key = getAnalyzerEnabledSettingKey();
      +  172   +
               try {
      +  173  152
                   enabled = Settings.getBoolean(key, true);
      +  174  0
               } catch (InvalidSettingException ex) {
      +  175  0
                   LOGGER.warn("Invalid setting for property '{}'", key);
      +  176  0
                   LOGGER.debug("", ex);
      +  177  0
                   LOGGER.warn("{} has been disabled", getName());
      +  178  152
               }
      +  179  152
           }
      +  180   +
       
      +  181   +
           /**
      +  182   +
            * Analyzes a given dependency. If the dependency is an archive, such as a
      +  183   +
            * WAR or EAR, the contents are extracted, scanned, and added to the list of
      +  184   +
            * dependencies within the engine.
      +  185   +
            *
      +  186   +
            * @param dependency the dependency to analyze
      +  187   +
            * @param engine the engine scanning
      +  188   +
            * @throws AnalysisException thrown if there is an analysis exception
      +  189   +
            */
      +  190   +
           @Override
      +  191   +
           public final void analyze(Dependency dependency, Engine engine) throws AnalysisException {
      +  192  32
               if (enabled) {
      +  193  32
                   analyzeFileType(dependency, engine);
      +  194   +
               }
      +  195  31
           }
      +  196   +
       
      +  197   +
           @Override
      +  198   +
           public boolean accept(File pathname) {
      +  199  185
               final FileFilter filter = getFileFilter();
      +  200  185
               boolean accepted = false;
      +  201  185
               if (null == filter) {
      +  202  0
                   LOGGER.error("The '{}' analyzer is misconfigured and does not have a file filter; it will be disabled", getName());
      +  203  185
               } else if (enabled) {
      +  204  119
                   accepted = filter.accept(pathname);
      +  205  119
                   if (accepted) {
      +  206  39
                       filesMatched = true;
      +  207   +
                   }
      +  208   +
               }
      +  209  185
               return accepted;
      +  210   +
           }
      +  211   +
       
      +  212   +
           //</editor-fold>
      +  213   +
           //<editor-fold defaultstate="collapsed" desc="Static utility methods">
      +  214   +
           /**
      +  215   +
            * <p>
      +  216   +
            * Utility method to help in the creation of the extensions set. This
      +  217   +
            * constructs a new Set that can be used in a final static declaration.</p>
      +  218   +
            * <p>
      +  219   +
            * This implementation was copied from
      +  220   +
            * http://stackoverflow.com/questions/2041778/initialize-java-hashset-values-by-construction</p>
       221   +
            *
      +  222   +
            * @param strings a list of strings to add to the set.
      +  223   +
            * @return a Set of strings.
      +  224   +
            */
      +  225   +
           protected static Set<String> newHashSet(String... strings) {
      +  226  5
               final Set<String> set = new HashSet<String>(strings.length);
      +  227  5
               Collections.addAll(set, strings);
      +  228  5
               return set;
      +  229   +
           }
      +  230   +
       
      +  231   +
       //</editor-fold>
      +  232  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AbstractSuppressionAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AbstractSuppressionAnalyzer.html index 0a4b1628b..bf66f5499 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AbstractSuppressionAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AbstractSuppressionAnalyzer.html @@ -12,7 +12,7 @@
       
      - +
      Classes in this File Line Coverage Branch Coverage Complexity
      AbstractSuppressionAnalyzer
      75%
      48/64
      71%
      10/14
      4
      AbstractSuppressionAnalyzer
      80%
      50/62
      71%
      10/14
      4.333
       
      @@ -72,257 +72,255 @@  27  
       import java.util.regex.Pattern;
       28   -
       import org.owasp.dependencycheck.suppression.SuppressionParseException;
      +
       import org.owasp.dependencycheck.exception.InitializationException;
       29   -
       import org.owasp.dependencycheck.suppression.SuppressionParser;
      +
       import org.owasp.dependencycheck.xml.suppression.SuppressionParseException;
       30   -
       import org.owasp.dependencycheck.suppression.SuppressionRule;
      +
       import org.owasp.dependencycheck.xml.suppression.SuppressionParser;
       31   -
       import org.owasp.dependencycheck.utils.DownloadFailedException;
      +
       import org.owasp.dependencycheck.xml.suppression.SuppressionRule;
       32   -
       import org.owasp.dependencycheck.utils.Downloader;
      +
       import org.owasp.dependencycheck.utils.DownloadFailedException;
       33   -
       import org.owasp.dependencycheck.utils.FileUtils;
      +
       import org.owasp.dependencycheck.utils.Downloader;
       34   -
       import org.owasp.dependencycheck.utils.Settings;
      +
       import org.owasp.dependencycheck.utils.FileUtils;
       35   -
       import org.slf4j.Logger;
      +
       import org.owasp.dependencycheck.utils.Settings;
       36   -
       import org.slf4j.LoggerFactory;
      +
       import org.slf4j.Logger;
       37   -
       import org.xml.sax.SAXException;
      +
       import org.slf4j.LoggerFactory;
       38   -
       
      +
       import org.xml.sax.SAXException;
       39   -
       /**
      +
       
       40   -
        * Abstract base suppression analyzer that contains methods for parsing the
      +
       /**
       41   -
        * suppression xml file.
      +
        * Abstract base suppression analyzer that contains methods for parsing the
       42   -
        *
      +
        * suppression xml file.
       43   -
        * @author Jeremy Long
      +
        *
       44   +
        * @author Jeremy Long
      +  45  
        */
      -  45  32
       public abstract class AbstractSuppressionAnalyzer extends AbstractAnalyzer {
      -  46   -
       
      +  46  16
       public abstract class AbstractSuppressionAnalyzer extends AbstractAnalyzer {
       47   -
           /**
      +
       
       48   -
            * The Logger for use throughout the class
      +
           /**
       49   +
            * The Logger for use throughout the class
      +  50  
            */
      -  50  2
           private static final Logger LOGGER = LoggerFactory.getLogger(AbstractSuppressionAnalyzer.class);
      -  51   -
       
      +  51  1
           private static final Logger LOGGER = LoggerFactory.getLogger(AbstractSuppressionAnalyzer.class);
       52   -
           //<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer">
      +
       
       53   -
           /**
      +
           //<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer">
       54   -
            * Returns a list of file EXTENSIONS supported by this analyzer.
      +
           /**
       55   -
            *
      +
            * Returns a list of file EXTENSIONS supported by this analyzer.
       56   -
            * @return a list of file EXTENSIONS supported by this analyzer.
      -  57   -
            */
      -  58   -
           public Set<String> getSupportedExtensions() {
      -  59  2
               return null;
      -  60   -
           }
      -  61   -
       
      -  62   -
           //</editor-fold>
      -  63   -
           /**
      -  64   -
            * The initialize method loads the suppression XML file.
      -  65  
            *
      -  66   -
            * @throws Exception thrown if there is an exception
      -  67   +  57   +
            * @return a list of file EXTENSIONS supported by this analyzer.
      +  58  
            */
      -  68   -
           @Override
      -  69   -
           public void initialize() throws Exception {
      -  70  14
               super.initialize();
      -  71  14
               loadSuppressionData();
      -  72  12
           }
      -  73   +  59   +
           public Set<String> getSupportedExtensions() {
      +  60  1
               return null;
      +  61   +
           }
      +  62  
       
      -  74   +  63   +
           //</editor-fold>
      +  64  
           /**
      -  75   -
            * The list of suppression rules
      -  76   +  65   +
            * The initialize method loads the suppression XML file.
      +  66   +
            *
      +  67   +
            * @throws InitializationException thrown if there is an exception
      +  68  
            */
      -  77   -
           private List<SuppressionRule> rules;
      +  69   +
           @Override
      +  70   +
           public void initialize() throws InitializationException {
      +  71  7
               super.initialize();
      +  72   +
               try {
      +  73  7
                   loadSuppressionData();
      +  74  1
               } catch (SuppressionParseException ex) {
      +  75  1
                   throw new InitializationException("Error initializing the suppression analyzer", ex);
      +  76  6
               }
      +  77  6
           }
       78  
       
       79  
           /**
       80   -
            * Get the value of rules.
      +
            * The list of suppression rules
       81   -
            *
      +
            */
       82   -
            * @return the value of rules
      +
           private List<SuppressionRule> rules;
       83   -
            */
      +
       
       84   -
           public List<SuppressionRule> getRules() {
      -  85  52
               return rules;
      +
           /**
      +  85   +
            * Get the value of rules.
       86   -
           }
      +
            *
       87   -
       
      +
            * @return the value of rules
       88   -
           /**
      +
            */
       89   -
            * Set the value of rules.
      -  90   -
            *
      +
           public List<SuppressionRule> getRules() {
      +  90  26
               return rules;
       91   -
            * @param rules new value of rules
      +
           }
       92   -
            */
      +
       
       93   -
           public void setRules(List<SuppressionRule> rules) {
      -  94  0
               this.rules = rules;
      -  95  0
           }
      -  96   -
       
      -  97  
           /**
      -  98   -
            * Loads the suppression rules file.
      -  99   +  94   +
            * Set the value of rules.
      +  95  
            *
      -  100   -
            * @throws SuppressionParseException thrown if the XML cannot be parsed.
      -  101   +  96   +
            * @param rules new value of rules
      +  97  
            */
      -  102   -
           private void loadSuppressionData() throws SuppressionParseException {
      -  103  14
               final SuppressionParser parser = new SuppressionParser();
      -  104  14
               File file = null;
      -  105   -
               try {
      -  106  14
                   rules = parser.parseSuppressionRules(this.getClass().getClassLoader().getResourceAsStream("dependencycheck-base-suppression.xml"));
      -  107  0
               } catch (SuppressionParseException ex) {
      -  108  0
                   LOGGER.error("Unable to parse the base suppression data file");
      -  109  0
                   LOGGER.debug("Unable to parse the base suppression data file", ex);
      -  110  0
               } catch (SAXException ex) {
      -  111  0
                   LOGGER.error("Unable to parse the base suppression data file");
      -  112  0
                   LOGGER.debug("Unable to parse the base suppression data file", ex);
      -  113  14
               }
      -  114  14
               final String suppressionFilePath = Settings.getString(Settings.KEYS.SUPPRESSION_FILE);
      -  115  14
               if (suppressionFilePath == null) {
      -  116  8
                   return;
      -  117   -
               }
      -  118  6
               boolean deleteTempFile = false;
      -  119   -
               try {
      -  120  6
                   final Pattern uriRx = Pattern.compile("^(https?|file)\\:.*", Pattern.CASE_INSENSITIVE);
      -  121  6
                   if (uriRx.matcher(suppressionFilePath).matches()) {
      -  122  2
                       deleteTempFile = true;
      -  123  2
                       file = FileUtils.getTempFile("suppression", "xml");
      -  124  2
                       final URL url = new URL(suppressionFilePath);
      -  125   -
                       try {
      -  126  2
                           Downloader.fetchFile(url, file, false);
      -  127  0
                       } catch (DownloadFailedException ex) {
      -  128  0
                           Downloader.fetchFile(url, file, true);
      -  129  2
                       }
      -  130  2
                   } else {
      -  131  4
                       file = new File(suppressionFilePath);
      -  132  4
                       if (!file.exists()) {
      -  133  4
                           final InputStream suppressionsFromClasspath = this.getClass().getClassLoader().getResourceAsStream(suppressionFilePath);
      -  134  4
                           if (suppressionsFromClasspath != null) {
      -  135  2
                               deleteTempFile = true;
      -  136  2
                               file = FileUtils.getTempFile("suppression", "xml");
      -  137   -
                               try {
      -  138  2
                                   org.apache.commons.io.FileUtils.copyInputStreamToFile(suppressionsFromClasspath, file);
      -  139  0
                               } catch (IOException ex) {
      -  140  0
                                   throwSuppressionParseException("Unable to locate suppressions file in classpath", ex);
      -  141  2
                               }
      -  142   -
                           }
      -  143   -
                       }
      -  144   -
                   }
      -  145   +  98   +
           public void setRules(List<SuppressionRule> rules) {
      +  99  0
               this.rules = rules;
      +  100  0
           }
      +  101  
       
      -  146  6
                   if (file != null) {
      +  102   +
           /**
      +  103   +
            * Loads the suppression rules file.
      +  104   +
            *
      +  105   +
            * @throws SuppressionParseException thrown if the XML cannot be parsed.
      +  106   +
            */
      +  107   +
           private void loadSuppressionData() throws SuppressionParseException {
      +  108  7
               final SuppressionParser parser = new SuppressionParser();
      +  109  7
               File file = null;
      +  110   +
               try {
      +  111  7
                   rules = parser.parseSuppressionRules(this.getClass().getClassLoader().getResourceAsStream("dependencycheck-base-suppression.xml"));
      +  112  0
               } catch (SAXException ex) {
      +  113  0
                   throw new SuppressionParseException("Unable to parse the base suppression data file", ex);
      +  114  7
               }
      +  115  7
               final String suppressionFilePath = Settings.getString(Settings.KEYS.SUPPRESSION_FILE);
      +  116  7
               if (suppressionFilePath == null) {
      +  117  4
                   return;
      +  118   +
               }
      +  119  3
               boolean deleteTempFile = false;
      +  120   +
               try {
      +  121  3
                   final Pattern uriRx = Pattern.compile("^(https?|file)\\:.*", Pattern.CASE_INSENSITIVE);
      +  122  3
                   if (uriRx.matcher(suppressionFilePath).matches()) {
      +  123  1
                       deleteTempFile = true;
      +  124  1
                       file = FileUtils.getTempFile("suppression", "xml");
      +  125  1
                       final URL url = new URL(suppressionFilePath);
      +  126   +
                       try {
      +  127  1
                           Downloader.fetchFile(url, file, false);
      +  128  0
                       } catch (DownloadFailedException ex) {
      +  129  0
                           Downloader.fetchFile(url, file, true);
      +  130  1
                       }
      +  131  1
                   } else {
      +  132  2
                       file = new File(suppressionFilePath);
      +  133  2
                       if (!file.exists()) {
      +  134  2
                           final InputStream suppressionsFromClasspath = this.getClass().getClassLoader().getResourceAsStream(suppressionFilePath);
      +  135  2
                           if (suppressionsFromClasspath != null) {
      +  136  1
                               deleteTempFile = true;
      +  137  1
                               file = FileUtils.getTempFile("suppression", "xml");
      +  138   +
                               try {
      +  139  1
                                   org.apache.commons.io.FileUtils.copyInputStreamToFile(suppressionsFromClasspath, file);
      +  140  0
                               } catch (IOException ex) {
      +  141  0
                                   throwSuppressionParseException("Unable to locate suppressions file in classpath", ex);
      +  142  1
                               }
      +  143   +
                           }
      +  144   +
                       }
      +  145   +
                   }
      +  146  3
                   if (file != null) {
       147  
                       try {
      -  148   -
                           //rules = parser.parseSuppressionRules(file);
      -  149  6
                           rules.addAll(parser.parseSuppressionRules(file));
      -  150  4
                           LOGGER.debug("{} suppression rules were loaded.", rules.size());
      -  151  2
                       } catch (SuppressionParseException ex) {
      -  152  2
                           LOGGER.warn("Unable to parse suppression xml file '{}'", file.getPath());
      -  153  2
                           LOGGER.warn(ex.getMessage());
      -  154  2
                           LOGGER.debug("", ex);
      -  155  2
                           throw ex;
      -  156  4
                       }
      -  157   +  148  3
                           rules.addAll(parser.parseSuppressionRules(file));
      +  149  2
                           LOGGER.debug("{} suppression rules were loaded.", rules.size());
      +  150  1
                       } catch (SuppressionParseException ex) {
      +  151  1
                           LOGGER.warn("Unable to parse suppression xml file '{}'", file.getPath());
      +  152  1
                           LOGGER.warn(ex.getMessage());
      +  153  1
                           throw ex;
      +  154  2
                       }
      +  155  
                   }
      -  158  0
               } catch (DownloadFailedException ex) {
      -  159  0
                   throwSuppressionParseException("Unable to fetch the configured suppression file", ex);
      -  160  0
               } catch (MalformedURLException ex) {
      -  161  0
                   throwSuppressionParseException("Configured suppression file has an invalid URL", ex);
      -  162  2
               } catch (IOException ex) {
      -  163  2
                   throwSuppressionParseException("Unable to create temp file for suppressions", ex);
      -  164   +  156  0
               } catch (DownloadFailedException ex) {
      +  157  0
                   throwSuppressionParseException("Unable to fetch the configured suppression file", ex);
      +  158  0
               } catch (MalformedURLException ex) {
      +  159  0
                   throwSuppressionParseException("Configured suppression file has an invalid URL", ex);
      +  160  1
               } catch (IOException ex) {
      +  161  1
                   throwSuppressionParseException("Unable to create temp file for suppressions", ex);
      +  162  
               } finally {
      -  165  6
                   if (deleteTempFile && file != null) {
      -  166  4
                       FileUtils.delete(file);
      -  167   +  163  3
                   if (deleteTempFile && file != null) {
      +  164  2
                       FileUtils.delete(file);
      +  165  
                   }
      -  168   +  166  
               }
      -  169  4
           }
      -  170   +  167  2
           }
      +  168  
       
      -  171   +  169  
           /**
      -  172   +  170  
            * Utility method to throw parse exceptions.
      -  173   +  171  
            *
      -  174   +  172  
            * @param message the exception message
      -  175   +  173  
            * @param exception the cause of the exception
      -  176   +  174  
            * @throws SuppressionParseException throws the generated
      -  177   +  175  
            * SuppressionParseException
      -  178   +  176  
            */
      -  179   +  177  
           private void throwSuppressionParseException(String message, Exception exception) throws SuppressionParseException {
      -  180  2
               LOGGER.warn(message);
      -  181  2
               LOGGER.debug("", exception);
      -  182  2
               throw new SuppressionParseException(message, exception);
      -  183   +  178  1
               LOGGER.warn(message);
      +  179  1
               LOGGER.debug("", exception);
      +  180  1
               throw new SuppressionParseException(message, exception);
      +  181  
           }
      -  184   +  182  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AnalysisPhase.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AnalysisPhase.html index 031b1eaa4..a30fd12fd 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AnalysisPhase.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AnalysisPhase.html @@ -65,7 +65,7 @@
        * @author Jeremy Long
       24  
        */
      -  25  40
       public enum AnalysisPhase {
      +  25  20
       public enum AnalysisPhase {
       26  
       
       27   @@ -74,74 +74,74 @@
            * Initialization phase.
       29  
            */
      -  30  2
           INITIAL,
      +  30  1
           INITIAL,
       31  
           /**
       32  
            * Pre information collection phase.
       33  
            */
      -  34  2
           PRE_INFORMATION_COLLECTION,
      +  34  1
           PRE_INFORMATION_COLLECTION,
       35  
           /**
       36  
            * Information collection phase.
       37  
            */
      -  38  2
           INFORMATION_COLLECTION,
      +  38  1
           INFORMATION_COLLECTION,
       39  
           /**
       40  
            * Pre identifier analysis phase.
       41  
            */
      -  42  2
           PRE_IDENTIFIER_ANALYSIS,
      +  42  1
           PRE_IDENTIFIER_ANALYSIS,
       43  
           /**
       44  
            * Identifier analysis phase.
       45  
            */
      -  46  2
           IDENTIFIER_ANALYSIS,
      +  46  1
           IDENTIFIER_ANALYSIS,
       47  
           /**
       48  
            * Post identifier analysis phase.
       49  
            */
      -  50  2
           POST_IDENTIFIER_ANALYSIS,
      +  50  1
           POST_IDENTIFIER_ANALYSIS,
       51  
           /**
       52  
            * Pre finding analysis phase.
       53  
            */
      -  54  2
           PRE_FINDING_ANALYSIS,
      +  54  1
           PRE_FINDING_ANALYSIS,
       55  
           /**
       56  
            * Finding analysis phase.
       57  
            */
      -  58  2
           FINDING_ANALYSIS,
      +  58  1
           FINDING_ANALYSIS,
       59  
           /**
       60  
            * Post analysis phase.
       61  
            */
      -  62  2
           POST_FINDING_ANALYSIS,
      +  62  1
           POST_FINDING_ANALYSIS,
       63  
           /**
       64  
            * The final analysis phase.
       65  
            */
      -  66  2
           FINAL
      +  66  1
           FINAL
       67  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.Analyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.Analyzer.html index b656e1876..f5468d744 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.Analyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.Analyzer.html @@ -62,105 +62,119 @@  22  
       import org.owasp.dependencycheck.dependency.Dependency;
       23   -
       
      +
       import org.owasp.dependencycheck.exception.InitializationException;
       24   -
       /**
      +
       
       25   -
        * An interface that defines an Analyzer that is used to identify Dependencies. An analyzer will collect information
      +
       /**
       26   -
        * about the dependency in the form of Evidence.
      +
        * An interface that defines an Analyzer that is used to identify Dependencies.
       27   -
        *
      +
        * An analyzer will collect information about the dependency in the form of
       28   -
        * @author Jeremy Long
      +
        * Evidence.
       29   -
        */
      +
        *
       30   -
       public interface Analyzer {
      +
        * @author Jeremy Long
       31   -
       
      +
        */
       32   -
           /**
      +
       public interface Analyzer {
       33   -
            * Analyzes the given dependency. The analysis could be anything from identifying an Identifier for the dependency,
      +
       
       34   -
            * to finding vulnerabilities, etc. Additionally, if the analyzer collects enough information to add a description
      +
           /**
       35   -
            * or license information for the dependency it should be added.
      +
            * Analyzes the given dependency. The analysis could be anything from
       36   -
            *
      +
            * identifying an Identifier for the dependency, to finding vulnerabilities,
       37   -
            * @param dependency a dependency to analyze.
      +
            * etc. Additionally, if the analyzer collects enough information to add a
       38   -
            * @param engine the engine that is scanning the dependencies - this is useful if we need to check other
      +
            * description or license information for the dependency it should be added.
       39   -
            * dependencies
      +
            *
       40   -
            * @throws AnalysisException is thrown if there is an error analyzing the dependency file
      +
            * @param dependency a dependency to analyze.
       41   -
            */
      +
            * @param engine the engine that is scanning the dependencies - this is
       42   -
           void analyze(Dependency dependency, Engine engine) throws AnalysisException;
      +
            * useful if we need to check other dependencies
       43   -
       
      +
            * @throws AnalysisException is thrown if there is an error analyzing the
       44   -
           /**
      +
            * dependency file
       45   -
            * Returns the name of the analyzer.
      +
            */
       46   -
            *
      +
           void analyze(Dependency dependency, Engine engine) throws AnalysisException;
       47   -
            * @return the name of the analyzer.
      +
       
       48   -
            */
      +
           /**
       49   -
           String getName();
      +
            * Returns the name of the analyzer.
       50   -
       
      +
            *
       51   -
           /**
      +
            * @return the name of the analyzer.
       52   -
            * Returns the phase that the analyzer is intended to run in.
      +
            */
       53   -
            *
      +
           String getName();
       54   -
            * @return the phase that the analyzer is intended to run in.
      +
       
       55   -
            */
      +
           /**
       56   -
           AnalysisPhase getAnalysisPhase();
      +
            * Returns the phase that the analyzer is intended to run in.
       57   -
       
      +
            *
       58   -
           /**
      +
            * @return the phase that the analyzer is intended to run in.
       59   -
            * The initialize method is called (once) prior to the analyze method being called on all of the dependencies.
      +
            */
       60   -
            *
      +
           AnalysisPhase getAnalysisPhase();
       61   -
            * @throws Exception is thrown if an exception occurs initializing the analyzer.
      -  62   -
            */
      -  63   -
           void initialize() throws Exception;
      -  64  
       
      -  65   +  62  
           /**
      -  66   -
            * The close method is called after all of the dependencies have been analyzed.
      -  67   +  63   +
            * The initialize method is called (once) prior to the analyze method being
      +  64   +
            * called on all of the dependencies.
      +  65  
            *
      +  66   +
            * @throws InitializationException is thrown if an exception occurs
      +  67   +
            * initializing the analyzer.
       68   -
            * @throws Exception is thrown if an exception occurs closing the analyzer.
      -  69  
            */
      +  69   +
           void initialize() throws InitializationException;
       70   -
           void close() throws Exception;
      +
       
       71   +
           /**
      +  72   +
            * The close method is called after all of the dependencies have been
      +  73   +
            * analyzed.
      +  74   +
            *
      +  75   +
            * @throws Exception is thrown if an exception occurs closing the analyzer.
      +  76   +
            */
      +  77   +
           void close() throws Exception;
      +  78  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AnalyzerService.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AnalyzerService.html index 66b6502b9..b1cbed8d0 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AnalyzerService.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AnalyzerService.html @@ -91,7 +91,7 @@
            * The Logger for use throughout the class.
       37  
            */
      -  38  2
           private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(AnalyzerService.class);
      +  38  1
           private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(AnalyzerService.class);
       39  
       
       40   @@ -114,9 +114,9 @@
            * @param classLoader the ClassLoader to use when dynamically loading Analyzer and Update services
       49  
            */
      -  50  12
           public AnalyzerService(ClassLoader classLoader) {
      -  51  12
               service = ServiceLoader.load(Analyzer.class, classLoader);
      -  52  12
           }
      +  50  6
           public AnalyzerService(ClassLoader classLoader) {
      +  51  6
               service = ServiceLoader.load(Analyzer.class, classLoader);
      +  52  6
           }
       53  
       
       54   @@ -131,31 +131,31 @@
            */
       59  
           public List<Analyzer> getAnalyzers() {
      -  60  14
               final List<Analyzer> analyzers = new ArrayList<Analyzer>();
      -  61  14
               final Iterator<Analyzer> iterator = service.iterator();
      -  62  14
               boolean experimentalEnabled = false;
      +  60  7
               final List<Analyzer> analyzers = new ArrayList<Analyzer>();
      +  61  7
               final Iterator<Analyzer> iterator = service.iterator();
      +  62  7
               boolean experimentalEnabled = false;
       63  
               try {
      -  64  14
                   experimentalEnabled = Settings.getBoolean(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, false);
      +  64  7
                   experimentalEnabled = Settings.getBoolean(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, false);
       65  0
               } catch (InvalidSettingException ex) {
       66  0
                   LOGGER.error("invalide experimental setting", ex);
      -  67  14
               }
      -  68  350
               while (iterator.hasNext()) {
      -  69  336
                   final Analyzer a = iterator.next();
      -  70  336
                   if (!experimentalEnabled && a.getClass().isAnnotationPresent(Experimental.class)) {
      -  71  18
                       continue;
      +  67  7
               }
      +  68  175
               while (iterator.hasNext()) {
      +  69  168
                   final Analyzer a = iterator.next();
      +  70  168
                   if (!experimentalEnabled && a.getClass().isAnnotationPresent(Experimental.class)) {
      +  71  9
                       continue;
       72  
                   }
      -  73  318
                   LOGGER.debug("Loaded Analyzer {}", a.getName());
      -  74  318
                   analyzers.add(a);
      -  75  318
               }
      -  76  14
               return analyzers;
      +  73  159
                   LOGGER.debug("Loaded Analyzer {}", a.getName());
      +  74  159
                   analyzers.add(a);
      +  75  159
               }
      +  76  7
               return analyzers;
       77  
           }
       78  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.ArchiveAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.ArchiveAnalyzer.html index 9c5baf4ab..543b99e2c 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.ArchiveAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.ArchiveAnalyzer.html @@ -12,7 +12,7 @@
       
      - +
      Classes in this File Line Coverage Branch Coverage Complexity
      ArchiveAnalyzer
      36%
      73/200
      25%
      23/90
      5.188
      ArchiveAnalyzer
      34%
      78/225
      14%
      20/136
      6.412
       
      @@ -120,729 +120,846 @@  51  
       import org.owasp.dependencycheck.dependency.Dependency;
       52   -
       import org.owasp.dependencycheck.utils.FileFilterBuilder;
      +
       import org.owasp.dependencycheck.exception.InitializationException;
       53   -
       import org.owasp.dependencycheck.utils.FileUtils;
      +
       import org.owasp.dependencycheck.utils.FileFilterBuilder;
       54   -
       import org.owasp.dependencycheck.utils.Settings;
      +
       import org.owasp.dependencycheck.utils.FileUtils;
       55   -
       
      +
       import org.owasp.dependencycheck.utils.Settings;
       56   -
       import org.slf4j.Logger;
      +
       
       57   -
       import org.slf4j.LoggerFactory;
      +
       import org.slf4j.Logger;
       58   -
       
      +
       import org.slf4j.LoggerFactory;
       59   -
       /**
      +
       
       60   -
        * <p>
      +
       /**
       61   -
        * An analyzer that extracts files from archives and ensures any supported files contained within the archive are added to the
      +
        * <p>
       62   -
        * dependency list.</p>
      +
        * An analyzer that extracts files from archives and ensures any supported files
       63   -
        *
      +
        * contained within the archive are added to the dependency list.</p>
       64   -
        * @author Jeremy Long
      +
        *
       65   +
        * @author Jeremy Long
      +  66  
        */
      -  66  12
       public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
      -  67   -
       
      +  67  6
       public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
       68   -
           /**
      +
       
       69   -
            * The logger.
      +
           /**
       70   +
            * The logger.
      +  71  
            */
      -  71  2
           private static final Logger LOGGER = LoggerFactory.getLogger(ArchiveAnalyzer.class);
      -  72   -
           /**
      +  72  1
           private static final Logger LOGGER = LoggerFactory.getLogger(ArchiveAnalyzer.class);
       73   -
            * The count of directories created during analysis. This is used for creating temporary directories.
      +
           /**
       74   -
            */
      -  75  2
           private static int dirCount = 0;
      +
            * The count of directories created during analysis. This is used for
      +  75   +
            * creating temporary directories.
       76   -
           /**
      -  77   -
            * The parent directory for the individual directories per archive.
      +
            */
      +  77  1
           private static int dirCount = 0;
       78   -
            */
      -  79  12
           private File tempFileLocation = null;
      +
           /**
      +  79   +
            * The parent directory for the individual directories per archive.
       80   -
           /**
      -  81   -
            * The max scan depth that the analyzer will recursively extract nested archives.
      +
            */
      +  81  6
           private File tempFileLocation = null;
       82   -
            */
      -  83  2
           private static final int MAX_SCAN_DEPTH = Settings.getInt("archive.scan.depth", 3);
      +
           /**
      +  83   +
            * The max scan depth that the analyzer will recursively extract nested
       84   -
           /**
      +
            * archives.
       85   -
            * Tracks the current scan/extraction depth for nested archives.
      -  86  
            */
      -  87  12
           private int scanDepth = 0;
      +  86  1
           private static final int MAX_SCAN_DEPTH = Settings.getInt("archive.scan.depth", 3);
      +  87   +
           /**
       88   -
       
      +
            * Tracks the current scan/extraction depth for nested archives.
       89   -
           //<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer">
      -  90   -
           /**
      +
            */
      +  90  6
           private int scanDepth = 0;
       91   -
            * The name of the analyzer.
      +
       
       92   -
            */
      +
           //<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer">
       93   -
           private static final String ANALYZER_NAME = "Archive Analyzer";
      +
           /**
       94   -
           /**
      +
            * The name of the analyzer.
       95   -
            * The phase that this analyzer is intended to run in.
      +
            */
       96   -
            */
      -  97  2
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INITIAL;
      +
           private static final String ANALYZER_NAME = "Archive Analyzer";
      +  97   +
           /**
       98   -
           /**
      +
            * The phase that this analyzer is intended to run in.
       99   -
            * The set of things we can handle with Zip methods
      -  100  
            */
      -  101  2
           private static final Set<String> ZIPPABLES = newHashSet("zip", "ear", "war", "jar", "sar", "apk", "nupkg");
      +  100  1
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INITIAL;
      +  101   +
           /**
       102   -
           /**
      +
            * The set of things we can handle with Zip methods
       103   -
            * The set of file extensions supported by this analyzer. Note for developers, any additions to this list will need to be
      -  104   -
            * explicitly handled in {@link #extractFiles(File, File, Engine)}.
      +
            */
      +  104  1
           private static final Set<String> ZIPPABLES = newHashSet("zip", "ear", "war", "jar", "sar", "apk", "nupkg");
       105   -
            */
      -  106  2
           private static final Set<String> EXTENSIONS = newHashSet("tar", "gz", "tgz", "bz2", "tbz2");
      +
           /**
      +  106   +
            * The set of file extensions supported by this analyzer. Note for
       107   -
       
      +
            * developers, any additions to this list will need to be explicitly handled
       108   -
           /**
      +
            * in {@link #extractFiles(File, File, Engine)}.
       109   -
            * Detects files with extensions to remove from the engine's collection of dependencies.
      -  110  
            */
      -  111  2
           private static final FileFilter REMOVE_FROM_ANALYSIS = FileFilterBuilder.newInstance().addExtensions("zip", "tar", "gz", "tgz", "bz2", "tbz2")
      -  112  2
                   .build();
      -  113   +  110  1
           private static final Set<String> EXTENSIONS = newHashSet("tar", "gz", "tgz", "bz2", "tbz2");
      +  111  
       
      -  114   -
           static {
      -  115  2
               final String additionalZipExt = Settings.getString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS);
      -  116  2
               if (additionalZipExt != null) {
      -  117  0
                   final String[] ext = additionalZipExt.split("\\s*,\\s*");
      -  118  0
                   Collections.addAll(ZIPPABLES, ext);
      -  119   -
               }
      -  120  2
               EXTENSIONS.addAll(ZIPPABLES);
      -  121   -
           }
      -  122   -
       
      -  123   +  112  
           /**
      -  124   -
            * The file filter used to filter supported files.
      -  125   +  113   +
            * Detects files with extensions to remove from the engine's collection of
      +  114   +
            * dependencies.
      +  115  
            */
      -  126  2
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(EXTENSIONS).build();
      +  116  1
           private static final FileFilter REMOVE_FROM_ANALYSIS = FileFilterBuilder.newInstance().addExtensions("zip", "tar", "gz", "tgz", "bz2", "tbz2")
      +  117  1
                   .build();
      +  118   +
       
      +  119   +
           static {
      +  120  1
               final String additionalZipExt = Settings.getString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS);
      +  121  1
               if (additionalZipExt != null) {
      +  122  0
                   final String[] ext = additionalZipExt.split("\\s*,\\s*");
      +  123  0
                   Collections.addAll(ZIPPABLES, ext);
      +  124   +
               }
      +  125  1
               EXTENSIONS.addAll(ZIPPABLES);
      +  126   +
           }
       127  
       
       128   -
           @Override
      +
           /**
       129   -
           protected FileFilter getFileFilter() {
      -  130  1718
               return FILTER;
      -  131   -
           }
      +
            * The file filter used to filter supported files.
      +  130   +
            */
      +  131  1
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(EXTENSIONS).build();
       132  
       
       133   -
           /**
      +
           @Override
       134   -
            * Detects files with .zip extension.
      -  135   -
            */
      -  136  2
           private static final FileFilter ZIP_FILTER = FileFilterBuilder.newInstance().addExtensions("zip").build();
      +
           protected FileFilter getFileFilter() {
      +  135  10
               return FILTER;
      +  136   +
           }
       137  
       
       138  
           /**
       139   -
            * Returns the name of the analyzer.
      +
            * Detects files with .zip extension.
       140   -
            *
      -  141   -
            * @return the name of the analyzer.
      +
            */
      +  141  1
           private static final FileFilter ZIP_FILTER = FileFilterBuilder.newInstance().addExtensions("zip").build();
       142   -
            */
      +
       
       143   -
           @Override
      +
           /**
       144   -
           public String getName() {
      -  145  32
               return ANALYZER_NAME;
      +
            * Returns the name of the analyzer.
      +  145   +
            *
       146   -
           }
      +
            * @return the name of the analyzer.
       147   -
       
      +
            */
       148   -
           /**
      +
           @Override
       149   -
            * Returns the phase that the analyzer is intended to run in.
      -  150   -
            *
      +
           public String getName() {
      +  150  16
               return ANALYZER_NAME;
       151   -
            * @return the phase that the analyzer is intended to run in.
      +
           }
       152   -
            */
      +
       
       153   -
           @Override
      +
           /**
       154   -
           public AnalysisPhase getAnalysisPhase() {
      -  155  8
               return ANALYSIS_PHASE;
      +
            * Returns the phase that the analyzer is intended to run in.
      +  155   +
            *
       156   -
           }
      +
            * @return the phase that the analyzer is intended to run in.
       157   -
           //</editor-fold>
      +
            */
       158   -
       
      +
           @Override
       159   -
           /**
      -  160   -
            * Returns the key used in the properties file to reference the analyzer's enabled property.
      +
           public AnalysisPhase getAnalysisPhase() {
      +  160  4
               return ANALYSIS_PHASE;
       161   -
            *
      +
           }
       162   -
            * @return the analyzer's enabled property setting key
      +
           //</editor-fold>
       163   -
            */
      +
       
       164   -
           @Override
      +
           /**
       165   -
           protected String getAnalyzerEnabledSettingKey() {
      -  166  12
               return Settings.KEYS.ANALYZER_ARCHIVE_ENABLED;
      +
            * Returns the key used in the properties file to reference the analyzer's
      +  166   +
            * enabled property.
       167   -
           }
      +
            *
       168   -
       
      +
            * @return the analyzer's enabled property setting key
       169   -
           /**
      +
            */
       170   -
            * The initialize method does nothing for this Analyzer.
      +
           @Override
       171   -
            *
      -  172   -
            * @throws Exception is thrown if there is an exception deleting or creating temporary files
      +
           protected String getAnalyzerEnabledSettingKey() {
      +  172  6
               return Settings.KEYS.ANALYZER_ARCHIVE_ENABLED;
       173   -
            */
      +
           }
       174   -
           @Override
      +
       
       175   -
           public void initializeFileTypeAnalyzer() throws Exception {
      -  176  2
               final File baseDir = Settings.getTempDirectory();
      -  177  2
               tempFileLocation = File.createTempFile("check", "tmp", baseDir);
      -  178  2
               if (!tempFileLocation.delete()) {
      -  179  0
                   final String msg = String.format("Unable to delete temporary file '%s'.", tempFileLocation.getAbsolutePath());
      -  180  0
                   throw new AnalysisException(msg);
      +
           /**
      +  176   +
            * The initialize method does nothing for this Analyzer.
      +  177   +
            *
      +  178   +
            * @throws InitializationException is thrown if there is an exception
      +  179   +
            * deleting or creating temporary files
      +  180   +
            */
       181   -
               }
      -  182  2
               if (!tempFileLocation.mkdirs()) {
      -  183  0
                   final String msg = String.format("Unable to create directory '%s'.", tempFileLocation.getAbsolutePath());
      -  184  0
                   throw new AnalysisException(msg);
      -  185   -
               }
      -  186  2
           }
      -  187   -
       
      -  188   -
           /**
      -  189   -
            * The close method deletes any temporary files and directories created during analysis.
      +
           @Override
      +  182   +
           public void initializeFileTypeAnalyzer() throws InitializationException {
      +  183   +
               try {
      +  184  1
                   final File baseDir = Settings.getTempDirectory();
      +  185  1
                   tempFileLocation = File.createTempFile("check", "tmp", baseDir);
      +  186  1
                   if (!tempFileLocation.delete()) {
      +  187  0
                       setEnabled(false);
      +  188  0
                       final String msg = String.format("Unable to delete temporary file '%s'.", tempFileLocation.getAbsolutePath());
      +  189  0
                       throw new InitializationException(msg);
       190   -
            *
      -  191   -
            * @throws Exception thrown if there is an exception deleting temporary files
      -  192   -
            */
      -  193   -
           @Override
      -  194   -
           public void close() throws Exception {
      -  195  4
               if (tempFileLocation != null && tempFileLocation.exists()) {
      -  196  2
                   LOGGER.debug("Attempting to delete temporary files");
      -  197  2
                   final boolean success = FileUtils.delete(tempFileLocation);
      -  198  2
                   if (!success && tempFileLocation.exists()) {
      -  199  0
                       final String[] l = tempFileLocation.list();
      -  200  0
                       if (l != null && l.length > 0) {
      -  201  0
                           LOGGER.warn("Failed to delete some temporary files, see the log for more details");
      +
                   }
      +  191  1
                   if (!tempFileLocation.mkdirs()) {
      +  192  0
                       setEnabled(false);
      +  193  0
                       final String msg = String.format("Unable to create directory '%s'.", tempFileLocation.getAbsolutePath());
      +  194  0
                       throw new InitializationException(msg);
      +  195   +
                   }
      +  196  0
               } catch (IOException ex) {
      +  197  0
                   setEnabled(false);
      +  198  0
                   throw new InitializationException("Unable to create a temporary file", ex);
      +  199  1
               }
      +  200  1
           }
      +  201   +
       
       202   -
                       }
      +
           /**
       203   -
                   }
      +
            * The close method deletes any temporary files and directories created
       204   -
               }
      -  205  4
           }
      +
            * during analysis.
      +  205   +
            *
       206   -
       
      +
            * @throws Exception thrown if there is an exception deleting temporary
       207   -
           /**
      +
            * files
       208   -
            * Analyzes a given dependency. If the dependency is an archive, such as a WAR or EAR, the contents are extracted, scanned,
      +
            */
       209   -
            * and added to the list of dependencies within the engine.
      -  210   -
            *
      -  211   -
            * @param dependency the dependency to analyze
      -  212   -
            * @param engine the engine scanning
      -  213   -
            * @throws AnalysisException thrown if there is an analysis exception
      -  214   -
            */
      -  215  
           @Override
      -  216   -
           public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException {
      -  217  4
               final File f = new File(dependency.getActualFilePath());
      -  218  4
               final File tmpDir = getNextTempDirectory();
      -  219  4
               extractFiles(f, tmpDir, engine);
      -  220   -
       
      -  221   -
               //make a copy
      -  222  4
               final Set<Dependency> dependencySet = findMoreDependencies(engine, tmpDir);
      -  223  4
               if (!dependencySet.isEmpty()) {
      -  224  0
                   for (Dependency d : dependencySet) {
      -  225   -
                       //fix the dependency's display name and path
      -  226  0
                       final String displayPath = String.format("%s%s",
      -  227  0
                               dependency.getFilePath(),
      -  228  0
                               d.getActualFilePath().substring(tmpDir.getAbsolutePath().length()));
      -  229  0
                       final String displayName = String.format("%s: %s",
      -  230  0
                               dependency.getFileName(),
      -  231  0
                               d.getFileName());
      -  232  0
                       d.setFilePath(displayPath);
      -  233  0
                       d.setFileName(displayName);
      -  234   -
       
      -  235   -
                       //TODO - can we get more evidence from the parent? EAR contains module name, etc.
      -  236   -
                       //analyze the dependency (i.e. extract files) if it is a supported type.
      -  237  0
                       if (this.accept(d.getActualFile()) && scanDepth < MAX_SCAN_DEPTH) {
      -  238  0
                           scanDepth += 1;
      -  239  0
                           analyze(d, engine);
      -  240  0
                           scanDepth -= 1;
      -  241   +  210   +
           public void close() throws Exception {
      +  211  2
               if (tempFileLocation != null && tempFileLocation.exists()) {
      +  212  1
                   LOGGER.debug("Attempting to delete temporary files");
      +  213  1
                   final boolean success = FileUtils.delete(tempFileLocation);
      +  214  1
                   if (!success && tempFileLocation.exists()) {
      +  215  0
                       final String[] l = tempFileLocation.list();
      +  216  0
                       if (l != null && l.length > 0) {
      +  217  0
                           LOGGER.warn("Failed to delete some temporary files, see the log for more details");
      +  218  
                       }
      -  242  0
                   }
      -  243   -
               }
      -  244  4
               if (REMOVE_FROM_ANALYSIS.accept(dependency.getActualFile())) {
      -  245  0
                   addDisguisedJarsToDependencies(dependency, engine);
      -  246  0
                   engine.getDependencies().remove(dependency);
      -  247   -
               }
      -  248  4
               Collections.sort(engine.getDependencies());
      -  249  4
           }
      -  250   -
       
      -  251   -
           /**
      -  252   -
            * If a zip file was identified as a possible JAR, this method will add the zip to the list of dependencies.
      -  253   -
            *
      -  254   -
            * @param dependency the zip file
      -  255   -
            * @param engine the engine
      -  256   -
            * @throws AnalysisException thrown if there is an issue
      -  257   -
            */
      -  258   -
           private void addDisguisedJarsToDependencies(Dependency dependency, Engine engine) throws AnalysisException {
      -  259  0
               if (ZIP_FILTER.accept(dependency.getActualFile()) && isZipFileActuallyJarFile(dependency)) {
      -  260  0
                   final File tdir = getNextTempDirectory();
      -  261  0
                   final String fileName = dependency.getFileName();
      -  262   -
       
      -  263  0
                   LOGGER.info("The zip file '{}' appears to be a JAR file, making a copy and analyzing it as a JAR.", fileName);
      -  264   -
       
      -  265  0
                   final File tmpLoc = new File(tdir, fileName.substring(0, fileName.length() - 3) + "jar");
      -  266   -
                   try {
      -  267  0
                       org.apache.commons.io.FileUtils.copyFile(tdir, tmpLoc);
      -  268  0
                       final Set<Dependency> dependencySet = findMoreDependencies(engine, tmpLoc);
      -  269  0
                       if (!dependencySet.isEmpty()) {
      -  270  0
                           if (dependencySet.size() != 1) {
      -  271  0
                               LOGGER.info("Deep copy of ZIP to JAR file resulted in more than one dependency?");
      -  272   -
                           }
      -  273  0
                           for (Dependency d : dependencySet) {
      -  274   -
                               //fix the dependency's display name and path
      -  275  0
                               d.setFilePath(dependency.getFilePath());
      -  276  0
                               d.setDisplayFileName(dependency.getFileName());
      -  277  0
                           }
      -  278   -
                       }
      -  279  0
                   } catch (IOException ex) {
      -  280  0
                       LOGGER.debug("Unable to perform deep copy on '{}'", dependency.getActualFile().getPath(), ex);
      -  281  0
                   }
      -  282   -
               }
      -  283  0
           }
      -  284   -
           /**
      -  285   -
            * An empty dependency set.
      -  286   -
            */
      -  287  2
           private static final Set<Dependency> EMPTY_DEPENDENCY_SET = Collections.emptySet();
      -  288   -
       
      -  289   -
           /**
      -  290   -
            * Scan the given file/folder, and return any new dependencies found.
      -  291   -
            *
      -  292   -
            * @param engine used to scan
      -  293   -
            * @param file target of scanning
      -  294   -
            * @return any dependencies that weren't known to the engine before
      -  295   -
            */
      -  296   -
           private static Set<Dependency> findMoreDependencies(Engine engine, File file) {
      -  297  4
               final List<Dependency> before = new ArrayList<Dependency>(engine.getDependencies());
      -  298  4
               engine.scan(file);
      -  299  4
               final List<Dependency> after = engine.getDependencies();
      -  300  4
               final boolean sizeChanged = before.size() != after.size();
      -  301   -
               final Set<Dependency> newDependencies;
      -  302  4
               if (sizeChanged) {
      -  303   -
                   //get the new dependencies
      -  304  0
                   newDependencies = new HashSet<Dependency>(after);
      -  305  0
                   newDependencies.removeAll(before);
      -  306   -
               } else {
      -  307  4
                   newDependencies = EMPTY_DEPENDENCY_SET;
      -  308   -
               }
      -  309  4
               return newDependencies;
      -  310   -
           }
      -  311   -
       
      -  312   -
           /**
      -  313   -
            * Retrieves the next temporary directory to extract an archive too.
      -  314   -
            *
      -  315   -
            * @return a directory
      -  316   -
            * @throws AnalysisException thrown if unable to create temporary directory
      -  317   -
            */
      -  318   -
           private File getNextTempDirectory() throws AnalysisException {
      -  319  4
               dirCount += 1;
      -  320  4
               final File directory = new File(tempFileLocation, String.valueOf(dirCount));
      -  321   -
               //getting an exception for some directories not being able to be created; might be because the directory already exists?
      -  322  4
               if (directory.exists()) {
      -  323  0
                   return getNextTempDirectory();
      -  324   -
               }
      -  325  4
               if (!directory.mkdirs()) {
      -  326  0
                   final String msg = String.format("Unable to create temp directory '%s'.", directory.getAbsolutePath());
      -  327  0
                   throw new AnalysisException(msg);
      -  328   -
               }
      -  329  4
               return directory;
      -  330   -
           }
      -  331   -
       
      -  332   -
           /**
      -  333   -
            * Extracts the contents of an archive into the specified directory.
      -  334   -
            *
      -  335   -
            * @param archive an archive file such as a WAR or EAR
      -  336   -
            * @param destination a directory to extract the contents to
      -  337   -
            * @param engine the scanning engine
      -  338   -
            * @throws AnalysisException thrown if the archive is not found
      -  339   -
            */
      -  340   -
           private void extractFiles(File archive, File destination, Engine engine) throws AnalysisException {
      -  341  4
               if (archive != null && destination != null) {
      -  342   -
                   FileInputStream fis;
      -  343   -
                   try {
      -  344  4
                       fis = new FileInputStream(archive);
      -  345  0
                   } catch (FileNotFoundException ex) {
      -  346  0
                       LOGGER.debug("", ex);
      -  347  0
                       throw new AnalysisException("Archive file was not found.", ex);
      -  348  4
                   }
      -  349  4
                   final String archiveExt = FileUtils.getFileExtension(archive.getName()).toLowerCase();
      -  350   -
                   try {
      -  351  4
                       if (ZIPPABLES.contains(archiveExt)) {
      -  352  4
                           extractArchive(new ZipArchiveInputStream(new BufferedInputStream(fis)), destination, engine);
      -  353  0
                       } else if ("tar".equals(archiveExt)) {
      -  354  0
                           extractArchive(new TarArchiveInputStream(new BufferedInputStream(fis)), destination, engine);
      -  355  0
                       } else if ("gz".equals(archiveExt) || "tgz".equals(archiveExt)) {
      -  356  0
                           final String uncompressedName = GzipUtils.getUncompressedFilename(archive.getName());
      -  357  0
                           final File f = new File(destination, uncompressedName);
      -  358  0
                           if (engine.accept(f)) {
      -  359  0
                               decompressFile(new GzipCompressorInputStream(new BufferedInputStream(fis)), f);
      -  360   -
                           }
      -  361  0
                       } else if ("bz2".equals(archiveExt) || "tbz2".equals(archiveExt)) {
      -  362  0
                           final String uncompressedName = BZip2Utils.getUncompressedFilename(archive.getName());
      -  363  0
                           final File f = new File(destination, uncompressedName);
      -  364  0
                           if (engine.accept(f)) {
      -  365  0
                               decompressFile(new BZip2CompressorInputStream(new BufferedInputStream(fis)), f);
      -  366   -
                           }
      -  367   -
                       }
      -  368  0
                   } catch (ArchiveExtractionException ex) {
      -  369  0
                       LOGGER.warn("Exception extracting archive '{}'.", archive.getName());
      -  370  0
                       LOGGER.debug("", ex);
      -  371  0
                   } catch (IOException ex) {
      -  372  0
                       LOGGER.warn("Exception reading archive '{}'.", archive.getName());
      -  373  0
                       LOGGER.debug("", ex);
      -  374   -
                   } finally {
      -  375  4
                       close(fis);
      -  376  4
                   }
      -  377   -
               }
      -  378  4
           }
      -  379   -
       
      -  380   -
           /**
      -  381   -
            * Extracts files from an archive.
      -  382   -
            *
      -  383   -
            * @param input the archive to extract files from
      -  384   -
            * @param destination the location to write the files too
      -  385   -
            * @param engine the dependency-check engine
      -  386   -
            * @throws ArchiveExtractionException thrown if there is an exception extracting files from the archive
      -  387   -
            */
      -  388   -
           private void extractArchive(ArchiveInputStream input, File destination, Engine engine) throws ArchiveExtractionException {
      -  389   -
               ArchiveEntry entry;
      -  390   -
               try {
      -  391  1774
                   while ((entry = input.getNextEntry()) != null) {
      -  392  1770
                       final File file = new File(destination, entry.getName());
      -  393  1770
                       if (entry.isDirectory()) {
      -  394  72
                           if (!file.exists() && !file.mkdirs()) {
      -  395  0
                               final String msg = String.format("Unable to create directory '%s'.", file.getAbsolutePath());
      -  396  0
                               throw new AnalysisException(msg);
      -  397   -
                           }
      -  398  1698
                       } else if (engine.accept(file)) {
      -  399  0
                           extractAcceptedFile(input, file);
      -  400   -
                       }
      -  401  1770
                   }
      -  402  0
               } catch (Throwable ex) {
      -  403  0
                   throw new ArchiveExtractionException(ex);
      -  404   -
               } finally {
      -  405  4
                   close(input);
      -  406  4
               }
      -  407  4
           }
      -  408   -
       
      -  409   -
           /**
      -  410   -
            * Extracts a file from an archive.
      -  411   -
            *
      -  412   -
            * @param input the archives input stream
      -  413   -
            * @param file the file to extract
      -  414   -
            * @throws AnalysisException thrown if there is an error
      -  415   -
            */
      -  416   -
           private static void extractAcceptedFile(ArchiveInputStream input, File file) throws AnalysisException {
      -  417  0
               LOGGER.debug("Extracting '{}'", file.getPath());
      -  418  0
               FileOutputStream fos = null;
      -  419   -
               try {
      -  420  0
                   final File parent = file.getParentFile();
      -  421  0
                   if (!parent.isDirectory() && !parent.mkdirs()) {
      -  422  0
                       final String msg = String.format("Unable to build directory '%s'.", parent.getAbsolutePath());
      -  423  0
                       throw new AnalysisException(msg);
      -  424   +  219  
                   }
      -  425  0
                   fos = new FileOutputStream(file);
      -  426  0
                   IOUtils.copy(input, fos);
      -  427  0
               } catch (FileNotFoundException ex) {
      -  428  0
                   LOGGER.debug("", ex);
      -  429  0
                   final String msg = String.format("Unable to find file '%s'.", file.getName());
      -  430  0
                   throw new AnalysisException(msg, ex);
      -  431  0
               } catch (IOException ex) {
      -  432  0
                   LOGGER.debug("", ex);
      -  433  0
                   final String msg = String.format("IO Exception while parsing file '%s'.", file.getName());
      -  434  0
                   throw new AnalysisException(msg, ex);
      -  435   -
               } finally {
      -  436  0
                   close(fos);
      -  437  0
               }
      -  438  0
           }
      -  439   -
       
      -  440   -
           /**
      -  441   -
            * Decompresses a file.
      -  442   -
            *
      -  443   -
            * @param inputStream the compressed file
      -  444   -
            * @param outputFile the location to write the decompressed file
      -  445   -
            * @throws ArchiveExtractionException thrown if there is an exception decompressing the file
      -  446   -
            */
      -  447   -
           private void decompressFile(CompressorInputStream inputStream, File outputFile) throws ArchiveExtractionException {
      -  448  0
               LOGGER.debug("Decompressing '{}'", outputFile.getPath());
      -  449  0
               FileOutputStream out = null;
      -  450   -
               try {
      -  451  0
                   out = new FileOutputStream(outputFile);
      -  452  0
                   IOUtils.copy(inputStream, out);
      -  453  0
               } catch (FileNotFoundException ex) {
      -  454  0
                   LOGGER.debug("", ex);
      -  455  0
                   throw new ArchiveExtractionException(ex);
      -  456  0
               } catch (IOException ex) {
      -  457  0
                   LOGGER.debug("", ex);
      -  458  0
                   throw new ArchiveExtractionException(ex);
      -  459   -
               } finally {
      -  460  0
                   close(out);
      -  461  0
               }
      -  462  0
           }
      -  463   -
       
      -  464   -
           /**
      -  465   -
            * Close the given {@link Closeable} instance, ignoring nulls, and logging any thrown {@link IOException}.
      -  466   -
            *
      -  467   -
            * @param closeable to be closed
      -  468   -
            */
      -  469   -
           private static void close(Closeable closeable) {
      -  470  8
               if (null != closeable) {
      -  471   -
                   try {
      -  472  8
                       closeable.close();
      -  473  0
                   } catch (IOException ex) {
      -  474  0
                       LOGGER.trace("", ex);
      -  475  8
                   }
      -  476   +  220  
               }
      -  477  8
           }
      -  478   +  221  2
           }
      +  222  
       
      -  479   +  223  
           /**
      -  480   -
            * Attempts to determine if a zip file is actually a JAR file.
      -  481   +  224   +
            * Analyzes a given dependency. If the dependency is an archive, such as a
      +  225   +
            * WAR or EAR, the contents are extracted, scanned, and added to the list of
      +  226   +
            * dependencies within the engine.
      +  227  
            *
      +  228   +
            * @param dependency the dependency to analyze
      +  229   +
            * @param engine the engine scanning
      +  230   +
            * @throws AnalysisException thrown if there is an analysis exception
      +  231   +
            */
      +  232   +
           @Override
      +  233   +
           public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException {
      +  234  2
               final File f = new File(dependency.getActualFilePath());
      +  235  2
               final File tmpDir = getNextTempDirectory();
      +  236  2
               extractFiles(f, tmpDir, engine);
      +  237   +
       
      +  238   +
               //make a copy
      +  239  2
               final Set<Dependency> dependencySet = findMoreDependencies(engine, tmpDir);
      +  240  2
               if (!dependencySet.isEmpty()) {
      +  241  0
                   for (Dependency d : dependencySet) {
      +  242   +
                       //fix the dependency's display name and path
      +  243  0
                       final String displayPath = String.format("%s%s",
      +  244  0
                               dependency.getFilePath(),
      +  245  0
                               d.getActualFilePath().substring(tmpDir.getAbsolutePath().length()));
      +  246  0
                       final String displayName = String.format("%s: %s",
      +  247  0
                               dependency.getFileName(),
      +  248  0
                               d.getFileName());
      +  249  0
                       d.setFilePath(displayPath);
      +  250  0
                       d.setFileName(displayName);
      +  251   +
       
      +  252   +
                       //TODO - can we get more evidence from the parent? EAR contains module name, etc.
      +  253   +
                       //analyze the dependency (i.e. extract files) if it is a supported type.
      +  254  0
                       if (this.accept(d.getActualFile()) && scanDepth < MAX_SCAN_DEPTH) {
      +  255  0
                           scanDepth += 1;
      +  256  0
                           analyze(d, engine);
      +  257  0
                           scanDepth -= 1;
      +  258   +
                       }
      +  259  0
                   }
      +  260   +
               }
      +  261  2
               if (REMOVE_FROM_ANALYSIS.accept(dependency.getActualFile())) {
      +  262  0
                   addDisguisedJarsToDependencies(dependency, engine);
      +  263  0
                   engine.getDependencies().remove(dependency);
      +  264   +
               }
      +  265  2
               Collections.sort(engine.getDependencies());
      +  266  2
           }
      +  267   +
       
      +  268   +
           /**
      +  269   +
            * If a zip file was identified as a possible JAR, this method will add the
      +  270   +
            * zip to the list of dependencies.
      +  271   +
            *
      +  272   +
            * @param dependency the zip file
      +  273   +
            * @param engine the engine
      +  274   +
            * @throws AnalysisException thrown if there is an issue
      +  275   +
            */
      +  276   +
           private void addDisguisedJarsToDependencies(Dependency dependency, Engine engine) throws AnalysisException {
      +  277  0
               if (ZIP_FILTER.accept(dependency.getActualFile()) && isZipFileActuallyJarFile(dependency)) {
      +  278  0
                   final File tdir = getNextTempDirectory();
      +  279  0
                   final String fileName = dependency.getFileName();
      +  280   +
       
      +  281  0
                   LOGGER.info("The zip file '{}' appears to be a JAR file, making a copy and analyzing it as a JAR.", fileName);
      +  282   +
       
      +  283  0
                   final File tmpLoc = new File(tdir, fileName.substring(0, fileName.length() - 3) + "jar");
      +  284   +
                   try {
      +  285  0
                       org.apache.commons.io.FileUtils.copyFile(tdir, tmpLoc);
      +  286  0
                       final Set<Dependency> dependencySet = findMoreDependencies(engine, tmpLoc);
      +  287  0
                       if (!dependencySet.isEmpty()) {
      +  288  0
                           if (dependencySet.size() != 1) {
      +  289  0
                               LOGGER.info("Deep copy of ZIP to JAR file resulted in more than one dependency?");
      +  290   +
                           }
      +  291  0
                           for (Dependency d : dependencySet) {
      +  292   +
                               //fix the dependency's display name and path
      +  293  0
                               d.setFilePath(dependency.getFilePath());
      +  294  0
                               d.setDisplayFileName(dependency.getFileName());
      +  295  0
                           }
      +  296   +
                       }
      +  297  0
                   } catch (IOException ex) {
      +  298  0
                       LOGGER.debug("Unable to perform deep copy on '{}'", dependency.getActualFile().getPath(), ex);
      +  299  0
                   }
      +  300   +
               }
      +  301  0
           }
      +  302   +
           /**
      +  303   +
            * An empty dependency set.
      +  304   +
            */
      +  305  1
           private static final Set<Dependency> EMPTY_DEPENDENCY_SET = Collections.emptySet();
      +  306   +
       
      +  307   +
           /**
      +  308   +
            * Scan the given file/folder, and return any new dependencies found.
      +  309   +
            *
      +  310   +
            * @param engine used to scan
      +  311   +
            * @param file target of scanning
      +  312   +
            * @return any dependencies that weren't known to the engine before
      +  313   +
            */
      +  314   +
           private static Set<Dependency> findMoreDependencies(Engine engine, File file) {
      +  315  2
               final List<Dependency> before = new ArrayList<Dependency>(engine.getDependencies());
      +  316  2
               engine.scan(file);
      +  317  2
               final List<Dependency> after = engine.getDependencies();
      +  318  2
               final boolean sizeChanged = before.size() != after.size();
      +  319   +
               final Set<Dependency> newDependencies;
      +  320  2
               if (sizeChanged) {
      +  321   +
                   //get the new dependencies
      +  322  0
                   newDependencies = new HashSet<Dependency>(after);
      +  323  0
                   newDependencies.removeAll(before);
      +  324   +
               } else {
      +  325  2
                   newDependencies = EMPTY_DEPENDENCY_SET;
      +  326   +
               }
      +  327  2
               return newDependencies;
      +  328   +
           }
      +  329   +
       
      +  330   +
           /**
      +  331   +
            * Retrieves the next temporary directory to extract an archive too.
      +  332   +
            *
      +  333   +
            * @return a directory
      +  334   +
            * @throws AnalysisException thrown if unable to create temporary directory
      +  335   +
            */
      +  336   +
           private File getNextTempDirectory() throws AnalysisException {
      +  337  2
               dirCount += 1;
      +  338  2
               final File directory = new File(tempFileLocation, String.valueOf(dirCount));
      +  339   +
               //getting an exception for some directories not being able to be created; might be because the directory already exists?
      +  340  2
               if (directory.exists()) {
      +  341  0
                   return getNextTempDirectory();
      +  342   +
               }
      +  343  2
               if (!directory.mkdirs()) {
      +  344  0
                   final String msg = String.format("Unable to create temp directory '%s'.", directory.getAbsolutePath());
      +  345  0
                   throw new AnalysisException(msg);
      +  346   +
               }
      +  347  2
               return directory;
      +  348   +
           }
      +  349   +
       
      +  350   +
           /**
      +  351   +
            * Extracts the contents of an archive into the specified directory.
      +  352   +
            *
      +  353   +
            * @param archive an archive file such as a WAR or EAR
      +  354   +
            * @param destination a directory to extract the contents to
      +  355   +
            * @param engine the scanning engine
      +  356   +
            * @throws AnalysisException thrown if the archive is not found
      +  357   +
            */
      +  358   +
           private void extractFiles(File archive, File destination, Engine engine) throws AnalysisException {
      +  359  2
               if (archive != null && destination != null) {
      +  360   +
                   FileInputStream fis;
      +  361   +
                   try {
      +  362  2
                       fis = new FileInputStream(archive);
      +  363  0
                   } catch (FileNotFoundException ex) {
      +  364  0
                       LOGGER.debug("", ex);
      +  365  0
                       throw new AnalysisException("Archive file was not found.", ex);
      +  366  2
                   }
      +  367  2
                   final String archiveExt = FileUtils.getFileExtension(archive.getName()).toLowerCase();
      +  368   +
                   try {
      +  369  2
                       if (ZIPPABLES.contains(archiveExt)) {
      +  370  2
                           final BufferedInputStream in = new BufferedInputStream(fis);
      +  371  2
                           ensureReadableJar(archiveExt, in);
      +  372  2
                           extractArchive(new ZipArchiveInputStream(in), destination, engine);
      +  373  2
                       } else if ("tar".equals(archiveExt)) {
      +  374  0
                           extractArchive(new TarArchiveInputStream(new BufferedInputStream(fis)), destination, engine);
      +  375  0
                       } else if ("gz".equals(archiveExt) || "tgz".equals(archiveExt)) {
      +  376  0
                           final String uncompressedName = GzipUtils.getUncompressedFilename(archive.getName());
      +  377  0
                           final File f = new File(destination, uncompressedName);
      +  378  0
                           if (engine.accept(f)) {
      +  379  0
                               decompressFile(new GzipCompressorInputStream(new BufferedInputStream(fis)), f);
      +  380   +
                           }
      +  381  0
                       } else if ("bz2".equals(archiveExt) || "tbz2".equals(archiveExt)) {
      +  382  0
                           final String uncompressedName = BZip2Utils.getUncompressedFilename(archive.getName());
      +  383  0
                           final File f = new File(destination, uncompressedName);
      +  384  0
                           if (engine.accept(f)) {
      +  385  0
                               decompressFile(new BZip2CompressorInputStream(new BufferedInputStream(fis)), f);
      +  386   +
                           }
      +  387   +
                       }
      +  388  0
                   } catch (ArchiveExtractionException ex) {
      +  389  0
                       LOGGER.warn("Exception extracting archive '{}'.", archive.getName());
      +  390  0
                       LOGGER.debug("", ex);
      +  391  0
                   } catch (IOException ex) {
      +  392  0
                       LOGGER.warn("Exception reading archive '{}'.", archive.getName());
      +  393  0
                       LOGGER.debug("", ex);
      +  394   +
                   } finally {
      +  395  2
                       close(fis);
      +  396  2
                   }
      +  397   +
               }
      +  398  2
           }
      +  399   +
       
      +  400   +
           /**
      +  401   +
            * Checks if the file being scanned is a JAR that begins with '#!/bin' which
      +  402   +
            * indicates it is a fully executable jar. If a fully executable JAR is
      +  403   +
            * identified the input stream will be advanced to the start of the actual
      +  404   +
            * JAR file ( skipping the script).
      +  405   +
            *
      +  406   +
            * @see
      +  407   +
            * <a href="http://docs.spring.io/spring-boot/docs/1.3.0.BUILD-SNAPSHOT/reference/htmlsingle/#deployment-install">Installing
      +  408   +
            * Spring Boot Applications</a>
      +  409   +
            * @param archiveExt the file extension
      +  410   +
            * @param in the input stream
      +  411   +
            * @throws IOException thrown if there is an error reading the stream
      +  412   +
            */
      +  413   +
           private void ensureReadableJar(final String archiveExt, BufferedInputStream in) throws IOException {
      +  414  2
               if ("jar".equals(archiveExt) && in.markSupported()) {
      +  415  2
                   in.mark(7);
      +  416  2
                   final byte[] b = new byte[7];
      +  417  2
                   in.read(b);
      +  418  2
                   if (b[0] == '#'
      +  419   +
                           && b[1] == '!'
      +  420   +
                           && b[2] == '/'
      +  421   +
                           && b[3] == 'b'
      +  422   +
                           && b[4] == 'i'
      +  423   +
                           && b[5] == 'n'
      +  424   +
                           && b[6] == '/') {
      +  425  0
                       boolean stillLooking = true;
      +  426   +
                       int chr, nxtChr;
      +  427  0
                       while (stillLooking && (chr = in.read()) != -1) {
      +  428  0
                           if (chr == '\n' || chr == '\r') {
      +  429  0
                               in.mark(4);
      +  430  0
                               if ((chr = in.read()) != -1) {
      +  431  0
                                   if (chr == 'P' && (chr = in.read()) != -1) {
      +  432  0
                                       if (chr == 'K' && (chr = in.read()) != -1) {
      +  433  0
                                           if ((chr == 3 || chr == 5 || chr == 7) && (nxtChr = in.read()) != -1) {
      +  434  0
                                               if (nxtChr == chr + 1) {
      +  435  0
                                                   stillLooking = false;
      +  436  0
                                                   in.reset();
      +  437   +
                                               }
      +  438   +
                                           }
      +  439   +
                                       }
      +  440   +
                                   }
      +  441   +
                               }
      +  442   +
                           }
      +  443   +
                       }
      +  444   +
                   }
      +  445   +
               }
      +  446  2
           }
      +  447   +
       
      +  448   +
           /**
      +  449   +
            * Extracts files from an archive.
      +  450   +
            *
      +  451   +
            * @param input the archive to extract files from
      +  452   +
            * @param destination the location to write the files too
      +  453   +
            * @param engine the dependency-check engine
      +  454   +
            * @throws ArchiveExtractionException thrown if there is an exception
      +  455   +
            * extracting files from the archive
      +  456   +
            */
      +  457   +
           private void extractArchive(ArchiveInputStream input, File destination, Engine engine) throws ArchiveExtractionException {
      +  458   +
               ArchiveEntry entry;
      +  459   +
               try {
      +  460  2
                   while ((entry = input.getNextEntry()) != null) {
      +  461  0
                       final File file = new File(destination, entry.getName());
      +  462  0
                       if (entry.isDirectory()) {
      +  463  0
                           if (!file.exists() && !file.mkdirs()) {
      +  464  0
                               final String msg = String.format("Unable to create directory '%s'.", file.getAbsolutePath());
      +  465  0
                               throw new AnalysisException(msg);
      +  466   +
                           }
      +  467  0
                       } else if (engine.accept(file)) {
      +  468  0
                           extractAcceptedFile(input, file);
      +  469   +
                       }
      +  470  0
                   }
      +  471  0
               } catch (Throwable ex) {
      +  472  0
                   throw new ArchiveExtractionException(ex);
      +  473   +
               } finally {
      +  474  2
                   close(input);
      +  475  2
               }
      +  476  2
           }
      +  477   +
       
      +  478   +
           /**
      +  479   +
            * Extracts a file from an archive.
      +  480   +
            *
      +  481   +
            * @param input the archives input stream
       482   -
            * @param dependency the dependency to check
      +
            * @param file the file to extract
       483   -
            * @return true if the dependency appears to be a JAR file; otherwise false
      +
            * @throws AnalysisException thrown if there is an error
       484  
            */
       485   -
           private boolean isZipFileActuallyJarFile(Dependency dependency) {
      -  486  0
               boolean isJar = false;
      -  487  0
               ZipFile zip = null;
      +
           private static void extractAcceptedFile(ArchiveInputStream input, File file) throws AnalysisException {
      +  486  0
               LOGGER.debug("Extracting '{}'", file.getPath());
      +  487  0
               FileOutputStream fos = null;
       488  
               try {
      -  489  0
                   zip = new ZipFile(dependency.getActualFilePath());
      -  490  0
                   if (zip.getEntry("META-INF/MANIFEST.MF") != null
      -  491  0
                           || zip.getEntry("META-INF/maven") != null) {
      -  492  0
                       final Enumeration<ZipArchiveEntry> entries = zip.getEntries();
      -  493  0
                       while (entries.hasMoreElements()) {
      -  494  0
                           final ZipArchiveEntry entry = entries.nextElement();
      -  495  0
                           if (!entry.isDirectory()) {
      -  496  0
                               final String name = entry.getName().toLowerCase();
      -  497  0
                               if (name.endsWith(".class")) {
      -  498  0
                                   isJar = true;
      -  499  0
                                   break;
      -  500   -
                               }
      -  501   -
                           }
      -  502  0
                       }
      -  503   +  489  0
                   final File parent = file.getParentFile();
      +  490  0
                   if (!parent.isDirectory() && !parent.mkdirs()) {
      +  491  0
                       final String msg = String.format("Unable to build directory '%s'.", parent.getAbsolutePath());
      +  492  0
                       throw new AnalysisException(msg);
      +  493  
                   }
      -  504  0
               } catch (IOException ex) {
      -  505  0
                   LOGGER.debug("Unable to unzip zip file '{}'", dependency.getFilePath(), ex);
      -  506   +  494  0
                   fos = new FileOutputStream(file);
      +  495  0
                   IOUtils.copy(input, fos);
      +  496  0
               } catch (FileNotFoundException ex) {
      +  497  0
                   LOGGER.debug("", ex);
      +  498  0
                   final String msg = String.format("Unable to find file '%s'.", file.getName());
      +  499  0
                   throw new AnalysisException(msg, ex);
      +  500  0
               } catch (IOException ex) {
      +  501  0
                   LOGGER.debug("", ex);
      +  502  0
                   final String msg = String.format("IO Exception while parsing file '%s'.", file.getName());
      +  503  0
                   throw new AnalysisException(msg, ex);
      +  504  
               } finally {
      -  507  0
                   ZipFile.closeQuietly(zip);
      -  508  0
               }
      -  509   +  505  0
                   close(fos);
      +  506  0
               }
      +  507  0
           }
      +  508  
       
      -  510  0
               return isJar;
      +  509   +
           /**
      +  510   +
            * Decompresses a file.
       511   -
           }
      +
            *
       512   +
            * @param inputStream the compressed file
      +  513   +
            * @param outputFile the location to write the decompressed file
      +  514   +
            * @throws ArchiveExtractionException thrown if there is an exception
      +  515   +
            * decompressing the file
      +  516   +
            */
      +  517   +
           private void decompressFile(CompressorInputStream inputStream, File outputFile) throws ArchiveExtractionException {
      +  518  0
               LOGGER.debug("Decompressing '{}'", outputFile.getPath());
      +  519  0
               FileOutputStream out = null;
      +  520   +
               try {
      +  521  0
                   out = new FileOutputStream(outputFile);
      +  522  0
                   IOUtils.copy(inputStream, out);
      +  523  0
               } catch (FileNotFoundException ex) {
      +  524  0
                   LOGGER.debug("", ex);
      +  525  0
                   throw new ArchiveExtractionException(ex);
      +  526  0
               } catch (IOException ex) {
      +  527  0
                   LOGGER.debug("", ex);
      +  528  0
                   throw new ArchiveExtractionException(ex);
      +  529   +
               } finally {
      +  530  0
                   close(out);
      +  531  0
               }
      +  532  0
           }
      +  533   +
       
      +  534   +
           /**
      +  535   +
            * Close the given {@link Closeable} instance, ignoring nulls, and logging
      +  536   +
            * any thrown {@link IOException}.
      +  537   +
            *
      +  538   +
            * @param closeable to be closed
      +  539   +
            */
      +  540   +
           private static void close(Closeable closeable) {
      +  541  4
               if (null != closeable) {
      +  542   +
                   try {
      +  543  4
                       closeable.close();
      +  544  0
                   } catch (IOException ex) {
      +  545  0
                       LOGGER.trace("", ex);
      +  546  4
                   }
      +  547   +
               }
      +  548  4
           }
      +  549   +
       
      +  550   +
           /**
      +  551   +
            * Attempts to determine if a zip file is actually a JAR file.
      +  552   +
            *
      +  553   +
            * @param dependency the dependency to check
      +  554   +
            * @return true if the dependency appears to be a JAR file; otherwise false
      +  555   +
            */
      +  556   +
           private boolean isZipFileActuallyJarFile(Dependency dependency) {
      +  557  0
               boolean isJar = false;
      +  558  0
               ZipFile zip = null;
      +  559   +
               try {
      +  560  0
                   zip = new ZipFile(dependency.getActualFilePath());
      +  561  0
                   if (zip.getEntry("META-INF/MANIFEST.MF") != null
      +  562  0
                           || zip.getEntry("META-INF/maven") != null) {
      +  563  0
                       final Enumeration<ZipArchiveEntry> entries = zip.getEntries();
      +  564  0
                       while (entries.hasMoreElements()) {
      +  565  0
                           final ZipArchiveEntry entry = entries.nextElement();
      +  566  0
                           if (!entry.isDirectory()) {
      +  567  0
                               final String name = entry.getName().toLowerCase();
      +  568  0
                               if (name.endsWith(".class")) {
      +  569  0
                                   isJar = true;
      +  570  0
                                   break;
      +  571   +
                               }
      +  572   +
                           }
      +  573  0
                       }
      +  574   +
                   }
      +  575  0
               } catch (IOException ex) {
      +  576  0
                   LOGGER.debug("Unable to unzip zip file '{}'", dependency.getFilePath(), ex);
      +  577   +
               } finally {
      +  578  0
                   ZipFile.closeQuietly(zip);
      +  579  0
               }
      +  580   +
       
      +  581  0
               return isJar;
      +  582   +
           }
      +  583  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AssemblyAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AssemblyAnalyzer.html index 85b6114a6..64aa33ff8 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AssemblyAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AssemblyAnalyzer.html @@ -12,7 +12,7 @@
       
      - +
      Classes in this File Line Coverage Branch Coverage Complexity
      AssemblyAnalyzer
      65%
      75/115
      55%
      21/38
      6
      AssemblyAnalyzer
      62%
      77/123
      55%
      21/38
      6.5
       
      @@ -108,416 +108,440 @@  45  
       import java.util.List;
       46   -
       
      +
       import javax.xml.parsers.ParserConfigurationException;
       47   -
       /**
      +
       import org.owasp.dependencycheck.exception.InitializationException;
       48   -
        * Analyzer for getting company, product, and version information from a .NET assembly.
      +
       
       49   -
        *
      +
       /**
       50   -
        * @author colezlaw
      +
        * Analyzer for getting company, product, and version information from a .NET
       51   -
        *
      +
        * assembly.
       52   -
        */
      -  53  22
       public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer {
      +
        *
      +  53   +
        * @author colezlaw
       54   -
       
      +
        *
       55   -
           /**
      -  56   -
            * The analyzer name
      +
        */
      +  56  11
       public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer {
       57   -
            */
      +
       
       58   -
           private static final String ANALYZER_NAME = "Assembly Analyzer";
      +
           /**
       59   -
           /**
      +
            * The analyzer name
       60   -
            * The analysis phase
      +
            */
       61   -
            */
      -  62  2
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
      +
           private static final String ANALYZER_NAME = "Assembly Analyzer";
      +  62   +
           /**
       63   -
           /**
      +
            * The analysis phase
       64   -
            * The list of supported extensions
      -  65  
            */
      -  66  2
           private static final String[] SUPPORTED_EXTENSIONS = {"dll", "exe"};
      +  65  1
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
      +  66   +
           /**
       67   -
           /**
      +
            * The list of supported extensions
       68   -
            * The temp value for GrokAssembly.exe
      -  69  
            */
      -  70  22
           private File grokAssemblyExe = null;
      +  69  1
           private static final String[] SUPPORTED_EXTENSIONS = {"dll", "exe"};
      +  70   +
           /**
       71   -
           /**
      +
            * The temp value for GrokAssembly.exe
       72   -
            * The DocumentBuilder for parsing the XML
      -  73  
            */
      +  73  11
           private File grokAssemblyExe = null;
       74   -
           private DocumentBuilder builder;
      +
           /**
       75   -
           /**
      +
            * The DocumentBuilder for parsing the XML
       76   -
            * Logger
      +
            */
       77   -
            */
      -  78  2
           private static final Logger LOGGER = LoggerFactory.getLogger(AssemblyAnalyzer.class);
      -  79   -
       
      -  80   +
           private DocumentBuilder builder;
      +  78  
           /**
      -  81   -
            * Builds the beginnings of a List for ProcessBuilder
      -  82   -
            *
      -  83   -
            * @return the list of arguments to begin populating the ProcessBuilder
      -  84   +  79   +
            * Logger
      +  80  
            */
      -  85   -
           private List<String> buildArgumentList() {
      -  86   -
               // Use file.separator as a wild guess as to whether this is Windows
      -  87  16
               final List<String> args = new ArrayList<String>();
      -  88  16
               if (!"\\".equals(System.getProperty("file.separator"))) {
      -  89  0
                   if (Settings.getString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH) != null) {
      -  90  0
                       args.add(Settings.getString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH));
      -  91   -
                   } else {
      -  92  0
                       args.add("mono");
      -  93   -
                   }
      -  94   -
               }
      -  95  16
               args.add(grokAssemblyExe.getPath());
      -  96   +  81  1
           private static final Logger LOGGER = LoggerFactory.getLogger(AssemblyAnalyzer.class);
      +  82  
       
      -  97  16
               return args;
      -  98   -
           }
      +  83   +
           /**
      +  84   +
            * Builds the beginnings of a List for ProcessBuilder
      +  85   +
            *
      +  86   +
            * @return the list of arguments to begin populating the ProcessBuilder
      +  87   +
            */
      +  88   +
           private List<String> buildArgumentList() {
      +  89   +
               // Use file.separator as a wild guess as to whether this is Windows
      +  90  8
               final List<String> args = new ArrayList<String>();
      +  91  8
               if (!"\\".equals(System.getProperty("file.separator"))) {
      +  92  0
                   if (Settings.getString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH) != null) {
      +  93  0
                       args.add(Settings.getString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH));
      +  94   +
                   } else {
      +  95  0
                       args.add("mono");
      +  96   +
                   }
      +  97   +
               }
      +  98  8
               args.add(grokAssemblyExe.getPath());
       99  
       
      -  100   -
           /**
      +  100  8
               return args;
       101   -
            * Performs the analysis on a single Dependency.
      +
           }
       102   -
            *
      +
       
       103   -
            * @param dependency the dependency to analyze
      +
           /**
       104   -
            * @param engine the engine to perform the analysis under
      +
            * Performs the analysis on a single Dependency.
       105   -
            * @throws AnalysisException if anything goes sideways
      +
            *
       106   -
            */
      +
            * @param dependency the dependency to analyze
       107   -
           @Override
      +
            * @param engine the engine to perform the analysis under
       108   -
           public void analyzeFileType(Dependency dependency, Engine engine)
      +
            * @throws AnalysisException if anything goes sideways
       109   +
            */
      +  110   +
           @Override
      +  111   +
           public void analyzeFileType(Dependency dependency, Engine engine)
      +  112  
                   throws AnalysisException {
      -  110  6
               if (grokAssemblyExe == null) {
      -  111  0
                   LOGGER.warn("GrokAssembly didn't get deployed");
      -  112  0
                   return;
      -  113   +  113  3
               if (grokAssemblyExe == null) {
      +  114  0
                   LOGGER.warn("GrokAssembly didn't get deployed");
      +  115  0
                   return;
      +  116  
               }
      -  114   +  117  
       
      -  115  6
               final List<String> args = buildArgumentList();
      -  116  6
               args.add(dependency.getActualFilePath());
      -  117  6
               final ProcessBuilder pb = new ProcessBuilder(args);
      -  118  6
               Document doc = null;
      -  119   +  118  3
               final List<String> args = buildArgumentList();
      +  119  3
               args.add(dependency.getActualFilePath());
      +  120  3
               final ProcessBuilder pb = new ProcessBuilder(args);
      +  121  3
               Document doc = null;
      +  122  
               try {
      -  120  6
                   final Process proc = pb.start();
      -  121   -
       
      -  122  6
                   doc = builder.parse(proc.getInputStream());
      -  123   -
       
      +  123  3
                   final Process proc = pb.start();
       124   -
                   // Try evacuating the error stream
      -  125  6
                   final String errorStream = IOUtils.toString(proc.getErrorStream(), "UTF-8");
      -  126  6
                   if (null != errorStream && !errorStream.isEmpty()) {
      -  127  0
                       LOGGER.warn("Error from GrokAssembly: {}", errorStream);
      -  128   -
                   }
      -  129  
       
      -  130  6
                   int rc = 0;
      +  125  3
                   doc = builder.parse(proc.getInputStream());
      +  126   +
       
      +  127   +
                   // Try evacuating the error stream
      +  128  3
                   final String errorStream = IOUtils.toString(proc.getErrorStream(), "UTF-8");
      +  129  3
                   if (null != errorStream && !errorStream.isEmpty()) {
      +  130  0
                       LOGGER.warn("Error from GrokAssembly: {}", errorStream);
       131   +
                   }
      +  132   +
       
      +  133  3
                   int rc = 0;
      +  134  
                   try {
      -  132  6
                       rc = proc.waitFor();
      -  133  0
                   } catch (InterruptedException ie) {
      -  134  0
                       return;
      -  135  6
                   }
      -  136  6
                   if (rc == 3) {
      -  137  0
                       LOGGER.debug("{} is not a .NET assembly or executable and as such cannot be analyzed by dependency-check",
      -  138  0
                               dependency.getActualFilePath());
      -  139  0
                       return;
      -  140  6
                   } else if (rc != 0) {
      -  141  2
                       LOGGER.warn("Return code {} from GrokAssembly", rc);
      -  142   -
                   }
      -  143   -
       
      -  144  6
                   final XPath xpath = XPathFactory.newInstance().newXPath();
      +  135  3
                       rc = proc.waitFor();
      +  136  0
                   } catch (InterruptedException ie) {
      +  137  0
                       return;
      +  138  3
                   }
      +  139  3
                   if (rc == 3) {
      +  140  0
                       LOGGER.debug("{} is not a .NET assembly or executable and as such cannot be analyzed by dependency-check",
      +  141  0
                               dependency.getActualFilePath());
      +  142  0
                       return;
      +  143  3
                   } else if (rc != 0) {
      +  144  1
                       LOGGER.warn("Return code {} from GrokAssembly", rc);
       145   -
       
      +
                   }
       146   +
       
      +  147  3
                   final XPath xpath = XPathFactory.newInstance().newXPath();
      +  148   +
       
      +  149  
                   // First, see if there was an error
      -  147  6
                   final String error = xpath.evaluate("/assembly/error", doc);
      -  148  6
                   if (error != null && !error.isEmpty()) {
      -  149  2
                       throw new AnalysisException(error);
      -  150   +  150  3
                   final String error = xpath.evaluate("/assembly/error", doc);
      +  151  3
                   if (error != null && !error.isEmpty()) {
      +  152  1
                       throw new AnalysisException(error);
      +  153  
                   }
      -  151   +  154  
       
      -  152  4
                   final String version = xpath.evaluate("/assembly/version", doc);
      -  153  4
                   if (version != null) {
      -  154  4
                       dependency.getVersionEvidence().addEvidence(new Evidence("grokassembly", "version",
      -  155   +  155  2
                   final String version = xpath.evaluate("/assembly/version", doc);
      +  156  2
                   if (version != null) {
      +  157  2
                       dependency.getVersionEvidence().addEvidence(new Evidence("grokassembly", "version",
      +  158  
                               version, Confidence.HIGHEST));
      -  156   +  159  
                   }
      -  157   +  160  
       
      -  158  4
                   final String vendor = xpath.evaluate("/assembly/company", doc);
      -  159  4
                   if (vendor != null) {
      -  160  4
                       dependency.getVendorEvidence().addEvidence(new Evidence("grokassembly", "vendor",
      -  161   +  161  2
                   final String vendor = xpath.evaluate("/assembly/company", doc);
      +  162  2
                   if (vendor != null) {
      +  163  2
                       dependency.getVendorEvidence().addEvidence(new Evidence("grokassembly", "vendor",
      +  164  
                               vendor, Confidence.HIGH));
      -  162   +  165  
                   }
      -  163   +  166  
       
      -  164  4
                   final String product = xpath.evaluate("/assembly/product", doc);
      -  165  4
                   if (product != null) {
      -  166  4
                       dependency.getProductEvidence().addEvidence(new Evidence("grokassembly", "product",
      -  167   +  167  2
                   final String product = xpath.evaluate("/assembly/product", doc);
      +  168  2
                   if (product != null) {
      +  169  2
                       dependency.getProductEvidence().addEvidence(new Evidence("grokassembly", "product",
      +  170  
                               product, Confidence.HIGH));
      -  168   +  171  
                   }
      -  169   +  172  
       
      -  170  0
               } catch (IOException ioe) {
      -  171  0
                   throw new AnalysisException(ioe);
      -  172  0
               } catch (SAXException saxe) {
      -  173  0
                   throw new AnalysisException("Couldn't parse GrokAssembly result", saxe);
      -  174  0
               } catch (XPathExpressionException xpe) {
      -  175   +  173  0
               } catch (IOException ioe) {
      +  174  0
                   throw new AnalysisException(ioe);
      +  175  0
               } catch (SAXException saxe) {
      +  176  0
                   throw new AnalysisException("Couldn't parse GrokAssembly result", saxe);
      +  177  0
               } catch (XPathExpressionException xpe) {
      +  178  
                   // This shouldn't happen
      -  176  0
                   throw new AnalysisException(xpe);
      -  177  4
               }
      -  178  4
           }
      -  179   -
       
      -  180   -
           /**
      -  181   -
            * Initialize the analyzer. In this case, extract GrokAssembly.exe to a temporary location.
      +  179  0
                   throw new AnalysisException(xpe);
      +  180  2
               }
      +  181  2
           }
       182   -
            *
      +
       
       183   -
            * @throws Exception if anything goes wrong
      +
           /**
       184   -
            */
      +
            * Initialize the analyzer. In this case, extract GrokAssembly.exe to a
       185   -
           @Override
      +
            * temporary location.
       186   -
           public void initializeFileTypeAnalyzer() throws Exception {
      -  187  10
               final File tempFile = File.createTempFile("GKA", ".exe", Settings.getTempDirectory());
      -  188  10
               FileOutputStream fos = null;
      -  189  10
               InputStream is = null;
      -  190   -
               try {
      -  191  10
                   fos = new FileOutputStream(tempFile);
      -  192  10
                   is = AssemblyAnalyzer.class.getClassLoader().getResourceAsStream("GrokAssembly.exe");
      -  193  10
                   IOUtils.copy(is, fos);
      -  194   -
       
      -  195  10
                   grokAssemblyExe = tempFile;
      -  196   -
                   // Set the temp file to get deleted when we're done
      -  197  10
                   grokAssemblyExe.deleteOnExit();
      -  198  10
                   LOGGER.debug("Extracted GrokAssembly.exe to {}", grokAssemblyExe.getPath());
      -  199  0
               } catch (IOException ioe) {
      -  200  0
                   this.setEnabled(false);
      -  201  0
                   LOGGER.warn("Could not extract GrokAssembly.exe: {}", ioe.getMessage());
      -  202  0
                   throw new AnalysisException("Could not extract GrokAssembly.exe", ioe);
      -  203   -
               } finally {
      -  204  10
                   if (fos != null) {
      -  205   -
                       try {
      -  206  10
                           fos.close();
      -  207  0
                       } catch (Throwable e) {
      -  208  0
                           LOGGER.debug("Error closing output stream");
      -  209  10
                       }
      -  210   -
                   }
      -  211  10
                   if (is != null) {
      -  212   -
                       try {
      -  213  10
                           is.close();
      -  214  0
                       } catch (Throwable e) {
      -  215  0
                           LOGGER.debug("Error closing input stream");
      -  216  10
                       }
      -  217   -
                   }
      -  218   -
               }
      -  219   -
       
      -  220   -
               // Now, need to see if GrokAssembly actually runs from this location.
      -  221  10
               final List<String> args = buildArgumentList();
      -  222   -
               try {
      -  223  10
                   final ProcessBuilder pb = new ProcessBuilder(args);
      -  224  10
                   final Process p = pb.start();
      -  225   -
                   // Try evacuating the error stream
      -  226  10
                   IOUtils.copy(p.getErrorStream(), NullOutputStream.NULL_OUTPUT_STREAM);
      -  227   -
       
      -  228  10
                   final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(p.getInputStream());
      -  229  10
                   final XPath xpath = XPathFactory.newInstance().newXPath();
      -  230  10
                   final String error = xpath.evaluate("/assembly/error", doc);
      -  231  10
                   if (p.waitFor() != 1 || error == null || error.isEmpty()) {
      -  232  0
                       LOGGER.warn("An error occurred with the .NET AssemblyAnalyzer, please see the log for more details.");
      -  233  0
                       LOGGER.debug("GrokAssembly.exe is not working properly");
      -  234  0
                       grokAssemblyExe = null;
      -  235  0
                       this.setEnabled(false);
      -  236  0
                       throw new AnalysisException("Could not execute .NET AssemblyAnalyzer");
      -  237   -
                   }
      -  238  0
               } catch (AnalysisException e) {
      -  239  0
                   throw e;
      -  240  0
               } catch (Throwable e) {
      -  241  0
                   LOGGER.warn("An error occurred with the .NET AssemblyAnalyzer;\n"
      -  242   -
                           + "this can be ignored unless you are scanning .NET DLLs. Please see the log for more details.");
      -  243  0
                   LOGGER.debug("Could not execute GrokAssembly {}", e.getMessage());
      -  244  0
                   this.setEnabled(false);
      -  245  0
                   throw new AnalysisException("An error occurred with the .NET AssemblyAnalyzer", e);
      -  246  10
               }
      -  247  10
               builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
      -  248  10
           }
      -  249   -
       
      -  250   -
           /**
      -  251   -
            * Removes resources used from the local file system.
      -  252  
            *
      -  253   -
            * @throws Exception thrown if there is a problem closing the analyzer
      -  254   +  187   +
            * @throws InitializationException thrown if anything goes wrong
      +  188  
            */
      -  255   +  189  
           @Override
      -  256   -
           public void close() throws Exception {
      -  257  14
               super.close();
      -  258   +  190   +
           public void initializeFileTypeAnalyzer() throws InitializationException {
      +  191   +
               final File tempFile;
      +  192  
               try {
      -  259  14
                   if (grokAssemblyExe != null && !grokAssemblyExe.delete()) {
      -  260  0
                       grokAssemblyExe.deleteOnExit();
      -  261   -
                   }
      -  262  0
               } catch (SecurityException se) {
      -  263  0
                   LOGGER.debug("Can't delete temporary GrokAssembly.exe");
      -  264  14
               }
      -  265  14
           }
      -  266   +  193  5
                   tempFile = File.createTempFile("GKA", ".exe", Settings.getTempDirectory());
      +  194  0
               } catch (IOException ex) {
      +  195  0
                   setEnabled(false);
      +  196  0
                   throw new InitializationException("Unable to create temporary file for the assembly analyzerr", ex);
      +  197  5
               }
      +  198  5
               FileOutputStream fos = null;
      +  199  5
               InputStream is = null;
      +  200   +
               try {
      +  201  5
                   fos = new FileOutputStream(tempFile);
      +  202  5
                   is = AssemblyAnalyzer.class.getClassLoader().getResourceAsStream("GrokAssembly.exe");
      +  203  5
                   IOUtils.copy(is, fos);
      +  204  
       
      -  267   +  205  5
                   grokAssemblyExe = tempFile;
      +  206   +
                   // Set the temp file to get deleted when we're done
      +  207  5
                   grokAssemblyExe.deleteOnExit();
      +  208  5
                   LOGGER.debug("Extracted GrokAssembly.exe to {}", grokAssemblyExe.getPath());
      +  209  0
               } catch (IOException ioe) {
      +  210  0
                   this.setEnabled(false);
      +  211  0
                   LOGGER.warn("Could not extract GrokAssembly.exe: {}", ioe.getMessage());
      +  212  0
                   throw new InitializationException("Could not extract GrokAssembly.exe", ioe);
      +  213   +
               } finally {
      +  214  5
                   if (fos != null) {
      +  215   +
                       try {
      +  216  5
                           fos.close();
      +  217  0
                       } catch (Throwable e) {
      +  218  0
                           LOGGER.debug("Error closing output stream");
      +  219  5
                       }
      +  220   +
                   }
      +  221  5
                   if (is != null) {
      +  222   +
                       try {
      +  223  5
                           is.close();
      +  224  0
                       } catch (Throwable e) {
      +  225  0
                           LOGGER.debug("Error closing input stream");
      +  226  5
                       }
      +  227   +
                   }
      +  228   +
               }
      +  229   +
       
      +  230   +
               // Now, need to see if GrokAssembly actually runs from this location.
      +  231  5
               final List<String> args = buildArgumentList();
      +  232   +
               try {
      +  233  5
                   final ProcessBuilder pb = new ProcessBuilder(args);
      +  234  5
                   final Process p = pb.start();
      +  235   +
                   // Try evacuating the error stream
      +  236  5
                   IOUtils.copy(p.getErrorStream(), NullOutputStream.NULL_OUTPUT_STREAM);
      +  237   +
       
      +  238  5
                   final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(p.getInputStream());
      +  239  5
                   final XPath xpath = XPathFactory.newInstance().newXPath();
      +  240  5
                   final String error = xpath.evaluate("/assembly/error", doc);
      +  241  5
                   if (p.waitFor() != 1 || error == null || error.isEmpty()) {
      +  242  0
                       LOGGER.warn("An error occurred with the .NET AssemblyAnalyzer, please see the log for more details.");
      +  243  0
                       LOGGER.debug("GrokAssembly.exe is not working properly");
      +  244  0
                       grokAssemblyExe = null;
      +  245  0
                       setEnabled(false);
      +  246  0
                       throw new InitializationException("Could not execute .NET AssemblyAnalyzer");
      +  247   +
                   }
      +  248  0
               } catch (InitializationException e) {
      +  249  0
                   throw e;
      +  250  0
               } catch (Throwable e) {
      +  251  0
                   LOGGER.warn("An error occurred with the .NET AssemblyAnalyzer;\n"
      +  252   +
                           + "this can be ignored unless you are scanning .NET DLLs. Please see the log for more details.");
      +  253  0
                   LOGGER.debug("Could not execute GrokAssembly {}", e.getMessage());
      +  254  0
                   setEnabled(false);
      +  255  0
                   throw new InitializationException("An error occurred with the .NET AssemblyAnalyzer", e);
      +  256  5
               }
      +  257   +
               try {
      +  258  5
                   builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
      +  259  0
               } catch (ParserConfigurationException ex) {
      +  260  0
                   setEnabled(false);
      +  261  0
                   throw new InitializationException("Error initializing the assembly analyzer", ex);
      +  262  5
               }
      +  263  5
           }
      +  264   +
       
      +  265  
           /**
      +  266   +
            * Removes resources used from the local file system.
      +  267   +
            *
       268   -
            * The File Filter used to filter supported extensions.
      +
            * @throws Exception thrown if there is a problem closing the analyzer
       269  
            */
      -  270  4
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(
      -  271  2
                   SUPPORTED_EXTENSIONS).build();
      -  272   -
       
      +  270   +
           @Override
      +  271   +
           public void close() throws Exception {
      +  272  7
               super.close();
       273   -
           @Override
      -  274   -
           protected FileFilter getFileFilter() {
      -  275  1728
               return FILTER;
      +
               try {
      +  274  7
                   if (grokAssemblyExe != null && !grokAssemblyExe.delete()) {
      +  275  0
                       grokAssemblyExe.deleteOnExit();
       276   -
           }
      -  277   -
       
      -  278   -
           /**
      -  279   -
            * Gets this analyzer's name.
      -  280   -
            *
      +
                   }
      +  277  0
               } catch (SecurityException se) {
      +  278  0
                   LOGGER.debug("Can't delete temporary GrokAssembly.exe");
      +  279  7
               }
      +  280  7
           }
       281   -
            * @return the analyzer name
      +
       
       282   -
            */
      +
           /**
       283   -
           @Override
      +
            * The File Filter used to filter supported extensions.
       284   -
           public String getName() {
      -  285  34
               return ANALYZER_NAME;
      -  286   -
           }
      +
            */
      +  285  2
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(
      +  286  1
                   SUPPORTED_EXTENSIONS).build();
       287  
       
       288   -
           /**
      +
           @Override
       289   -
            * Returns the phase this analyzer runs under.
      -  290   -
            *
      +
           protected FileFilter getFileFilter() {
      +  290  15
               return FILTER;
       291   -
            * @return the phase this runs under
      +
           }
       292   -
            */
      -  293   -
           @Override
      -  294   -
           public AnalysisPhase getAnalysisPhase() {
      -  295  8
               return ANALYSIS_PHASE;
      -  296   -
           }
      -  297  
       
      -  298   +  293  
           /**
      -  299   -
            * Returns the key used in the properties file to reference the analyzer's enabled property.
      -  300   +  294   +
            * Gets this analyzer's name.
      +  295  
            *
      -  301   -
            * @return the analyzer's enabled property setting key
      -  302   +  296   +
            * @return the analyzer name
      +  297  
            */
      -  303   +  298  
           @Override
      -  304   -
           protected String getAnalyzerEnabledSettingKey() {
      -  305  22
               return Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED;
      -  306   +  299   +
           public String getName() {
      +  300  17
               return ANALYZER_NAME;
      +  301  
           }
      +  302   +
       
      +  303   +
           /**
      +  304   +
            * Returns the phase this analyzer runs under.
      +  305   +
            *
      +  306   +
            * @return the phase this runs under
       307   +
            */
      +  308   +
           @Override
      +  309   +
           public AnalysisPhase getAnalysisPhase() {
      +  310  4
               return ANALYSIS_PHASE;
      +  311   +
           }
      +  312   +
       
      +  313   +
           /**
      +  314   +
            * Returns the key used in the properties file to reference the analyzer's
      +  315   +
            * enabled property.
      +  316   +
            *
      +  317   +
            * @return the analyzer's enabled property setting key
      +  318   +
            */
      +  319   +
           @Override
      +  320   +
           protected String getAnalyzerEnabledSettingKey() {
      +  321  11
               return Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED;
      +  322   +
           }
      +  323  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AutoconfAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AutoconfAnalyzer.html index 8ba0b0b1a..f763d1f77 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AutoconfAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AutoconfAnalyzer.html @@ -92,420 +92,430 @@  37  
       import java.util.regex.Pattern;
       38   -
       
      +
       import org.owasp.dependencycheck.exception.InitializationException;
       39   -
       /**
      +
       
       40   -
        * Used to analyze Autoconf input files named configure.ac or configure.in. Files simply named "configure" are also analyzed,
      +
       /**
       41   -
        * assuming they are generated by Autoconf, and contain certain special package descriptor variables.
      +
        * Used to analyze Autoconf input files named configure.ac or configure.in.
       42   -
        *
      +
        * Files simply named "configure" are also analyzed, assuming they are generated
       43   -
        * @author Dale Visser
      +
        * by Autoconf, and contain certain special package descriptor variables.
       44   -
        * @see <a href="https://www.gnu.org/software/autoconf/">Autoconf - GNU Project - Free Software Foundation (FSF)</a>
      +
        *
       45   -
        */
      +
        * @author Dale Visser
       46   -
       @Experimental
      -  47  24
       public class AutoconfAnalyzer extends AbstractFileTypeAnalyzer {
      +
        * @see <a href="https://www.gnu.org/software/autoconf/">Autoconf - GNU Project
      +  47   +
        * - Free Software Foundation (FSF)</a>
       48   -
       
      +
        */
       49   -
           /**
      -  50   -
            * Autoconf output filename.
      +
       @Experimental
      +  50  12
       public class AutoconfAnalyzer extends AbstractFileTypeAnalyzer {
       51   -
            */
      +
       
       52   -
           private static final String CONFIGURE = "configure";
      +
           /**
       53   -
       
      +
            * Autoconf output filename.
       54   -
           /**
      +
            */
       55   -
            * Autoconf input filename.
      +
           private static final String CONFIGURE = "configure";
       56   -
            */
      +
       
       57   -
           private static final String CONFIGURE_IN = "configure.in";
      +
           /**
       58   -
       
      -  59   -
           /**
      -  60  
            * Autoconf input filename.
      +  59   +
            */
      +  60   +
           private static final String CONFIGURE_IN = "configure.in";
       61   -
            */
      +
       
       62   -
           private static final String CONFIGURE_AC = "configure.ac";
      +
           /**
       63   -
       
      +
            * Autoconf input filename.
       64   -
           /**
      +
            */
       65   -
            * The name of the analyzer.
      +
           private static final String CONFIGURE_AC = "configure.ac";
       66   -
            */
      +
       
       67   -
           private static final String ANALYZER_NAME = "Autoconf Analyzer";
      +
           /**
       68   -
       
      +
            * The name of the analyzer.
       69   -
           /**
      +
            */
       70   -
            * The phase that this analyzer is intended to run in.
      +
           private static final String ANALYZER_NAME = "Autoconf Analyzer";
       71   -
            */
      -  72  2
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
      +
       
      +  72   +
           /**
       73   -
       
      +
            * The phase that this analyzer is intended to run in.
       74   -
           /**
      -  75   -
            * The set of file extensions supported by this analyzer.
      +
            */
      +  75  1
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
       76   -
            */
      -  77  2
           private static final String[] EXTENSIONS = {"ac", "in"};
      +
       
      +  77   +
           /**
       78   -
       
      +
            * The set of file extensions supported by this analyzer.
       79   -
           /**
      -  80   -
            * Matches AC_INIT variables in the output configure script.
      +
            */
      +  80  1
           private static final String[] EXTENSIONS = {"ac", "in"};
       81   -
            */
      -  82  2
           private static final Pattern PACKAGE_VAR = Pattern.compile(
      +
       
      +  82   +
           /**
       83   -
                   "PACKAGE_(.+?)='(.*?)'", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
      +
            * Matches AC_INIT variables in the output configure script.
       84   -
       
      -  85   -
           /**
      +
            */
      +  85  1
           private static final Pattern PACKAGE_VAR = Pattern.compile(
       86   -
            * Matches AC_INIT statement in configure.ac file.
      +
                   "PACKAGE_(.+?)='(.*?)'", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
       87   -
            */
      +
       
       88   -
           private static final Pattern AC_INIT_PATTERN;
      +
           /**
       89   -
       
      +
            * Matches AC_INIT statement in configure.ac file.
       90   -
           static {
      +
            */
       91   -
               // each instance of param or sep_param has a capture group
      -  92  2
               final String param = "\\[{0,2}(.+?)\\]{0,2}";
      -  93  2
               final String sepParam = "\\s*,\\s*" + param;
      +
           private static final Pattern AC_INIT_PATTERN;
      +  92   +
       
      +  93   +
           static {
       94   -
               // Group 1: Package
      -  95   -
               // Group 2: Version
      -  96   -
               // Group 3: optional
      +
               // each instance of param or sep_param has a capture group
      +  95  1
               final String param = "\\[{0,2}(.+?)\\]{0,2}";
      +  96  1
               final String sepParam = "\\s*,\\s*" + param;
       97   -
               // Group 4: Bug report address (if it exists)
      +
               // Group 1: Package
       98   -
               // Group 5: optional
      +
               // Group 2: Version
       99   -
               // Group 6: Tarname (if it exists)
      +
               // Group 3: optional
       100   -
               // Group 7: optional
      +
               // Group 4: Bug report address (if it exists)
       101   -
               // Group 8: URL (if it exists)
      -  102  2
               AC_INIT_PATTERN = Pattern.compile(String.format(
      +
               // Group 5: optional
      +  102   +
               // Group 6: Tarname (if it exists)
       103   -
                       "AC_INIT\\(%s%s(%s)?(%s)?(%s)?\\s*\\)", param, sepParam,
      +
               // Group 7: optional
       104   -
                       sepParam, sepParam, sepParam), Pattern.DOTALL
      -  105   -
                       | Pattern.CASE_INSENSITIVE);
      +
               // Group 8: URL (if it exists)
      +  105  1
               AC_INIT_PATTERN = Pattern.compile(String.format(
       106   -
           }
      +
                       "AC_INIT\\(%s%s(%s)?(%s)?(%s)?\\s*\\)", param, sepParam,
       107   -
       
      +
                       sepParam, sepParam, sepParam), Pattern.DOTALL
       108   -
           /**
      +
                       | Pattern.CASE_INSENSITIVE);
       109   -
            * The file filter used to determine which files this analyzer supports.
      +
           }
       110   -
            */
      -  111  4
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addFilenames(CONFIGURE).addExtensions(
      -  112  2
                   EXTENSIONS).build();
      +
       
      +  111   +
           /**
      +  112   +
            * The file filter used to determine which files this analyzer supports.
       113   -
       
      -  114   -
           /**
      -  115   -
            * Returns the FileFilter
      +
            */
      +  114  2
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addFilenames(CONFIGURE).addExtensions(
      +  115  1
                   EXTENSIONS).build();
       116   -
            *
      +
       
       117   -
            * @return the FileFilter
      +
           /**
       118   -
            */
      +
            * Returns the FileFilter
       119   -
           @Override
      +
            *
       120   -
           protected FileFilter getFileFilter() {
      -  121  1724
               return FILTER;
      +
            * @return the FileFilter
      +  121   +
            */
       122   -
           }
      +
           @Override
       123   -
       
      -  124   -
           /**
      +
           protected FileFilter getFileFilter() {
      +  124  13
               return FILTER;
       125   -
            * Returns the name of the analyzer.
      +
           }
       126   -
            *
      +
       
       127   -
            * @return the name of the analyzer.
      +
           /**
       128   -
            */
      +
            * Returns the name of the analyzer.
       129   -
           @Override
      +
            *
       130   -
           public String getName() {
      -  131  30
               return ANALYZER_NAME;
      +
            * @return the name of the analyzer.
      +  131   +
            */
       132   -
           }
      +
           @Override
       133   -
       
      -  134   -
           /**
      +
           public String getName() {
      +  134  15
               return ANALYZER_NAME;
       135   -
            * Returns the phase that the analyzer is intended to run in.
      +
           }
       136   -
            *
      +
       
       137   -
            * @return the phase that the analyzer is intended to run in.
      +
           /**
       138   -
            */
      +
            * Returns the phase that the analyzer is intended to run in.
       139   -
           @Override
      +
            *
       140   -
           public AnalysisPhase getAnalysisPhase() {
      -  141  8
               return ANALYSIS_PHASE;
      +
            * @return the phase that the analyzer is intended to run in.
      +  141   +
            */
       142   -
           }
      +
           @Override
       143   -
       
      -  144   -
           /**
      +
           public AnalysisPhase getAnalysisPhase() {
      +  144  4
               return ANALYSIS_PHASE;
       145   -
            * Returns the key used in the properties file to reference the analyzer's enabled property.
      +
           }
       146   -
            *
      +
       
       147   -
            * @return the analyzer's enabled property setting key
      +
           /**
       148   -
            */
      +
            * Returns the key used in the properties file to reference the analyzer's
       149   -
           @Override
      +
            * enabled property.
       150   -
           protected String getAnalyzerEnabledSettingKey() {
      -  151  24
               return Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED;
      +
            *
      +  151   +
            * @return the analyzer's enabled property setting key
       152   -
           }
      +
            */
       153   -
       
      -  154  
           @Override
      -  155   -
           protected void analyzeFileType(Dependency dependency, Engine engine)
      +  154   +
           protected String getAnalyzerEnabledSettingKey() {
      +  155  12
               return Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED;
       156   -
                   throws AnalysisException {
      -  157  8
               final File actualFile = dependency.getActualFile();
      -  158  8
               final String name = actualFile.getName();
      -  159  8
               if (name.startsWith(CONFIGURE)) {
      -  160  8
                   final File parent = actualFile.getParentFile();
      -  161  8
                   final String parentName = parent.getName();
      -  162  8
                   dependency.setDisplayFileName(parentName + "/" + name);
      -  163  8
                   final boolean isOutputScript = CONFIGURE.equals(name);
      -  164  8
                   if (isOutputScript || CONFIGURE_AC.equals(name)
      -  165  0
                           || CONFIGURE_IN.equals(name)) {
      -  166  8
                       final String contents = getFileContents(actualFile);
      -  167  8
                       if (!contents.isEmpty()) {
      -  168  8
                           if (isOutputScript) {
      -  169  4
                               extractConfigureScriptEvidence(dependency, name,
      -  170   -
                                       contents);
      -  171   -
                           } else {
      -  172  4
                               gatherEvidence(dependency, name, contents);
      -  173   -
                           }
      -  174   -
                       }
      -  175   -
                   }
      -  176  8
               } else {
      -  177   -
                   // copy, alter and set in case some other thread is iterating over
      -  178  0
                   final List<Dependency> dependencies = new ArrayList<Dependency>(
      -  179  0
                           engine.getDependencies());
      -  180  0
                   dependencies.remove(dependency);
      -  181  0
                   engine.setDependencies(dependencies);
      -  182   -
               }
      -  183  8
           }
      -  184   -
       
      -  185   -
           /**
      -  186   -
            * Extracts evidence from the configuration.
      -  187   -
            *
      -  188   -
            * @param dependency the dependency being analyzed
      -  189   -
            * @param name the name of the source of evidence
      -  190   -
            * @param contents the contents to analyze for evidence
      -  191   -
            */
      -  192   -
           private void extractConfigureScriptEvidence(Dependency dependency,
      -  193   -
                   final String name, final String contents) {
      -  194  4
               final Matcher matcher = PACKAGE_VAR.matcher(contents);
      -  195  40
               while (matcher.find()) {
      -  196  36
                   final String variable = matcher.group(1);
      -  197  36
                   final String value = matcher.group(2);
      -  198  36
                   if (!value.isEmpty()) {
      -  199  28
                       if (variable.endsWith("NAME")) {
      -  200  8
                           dependency.getProductEvidence().addEvidence(name, variable,
      -  201   -
                                   value, Confidence.HIGHEST);
      -  202  20
                       } else if ("VERSION".equals(variable)) {
      -  203  4
                           dependency.getVersionEvidence().addEvidence(name, variable,
      -  204   -
                                   value, Confidence.HIGHEST);
      -  205  16
                       } else if ("BUGREPORT".equals(variable)) {
      -  206  2
                           dependency.getVendorEvidence().addEvidence(name, variable,
      -  207   -
                                   value, Confidence.HIGH);
      -  208  14
                       } else if ("URL".equals(variable)) {
      -  209  2
                           dependency.getVendorEvidence().addEvidence(name, variable,
      -  210   -
                                   value, Confidence.HIGH);
      -  211   -
                       }
      -  212   -
                   }
      -  213  36
               }
      -  214  4
           }
      -  215   -
       
      -  216   -
           /**
      -  217   -
            * Retrieves the contents of a given file.
      -  218   -
            *
      -  219   -
            * @param actualFile the file to read
      -  220   -
            * @return the contents of the file
      -  221   -
            * @throws AnalysisException thrown if there is an IO Exception
      -  222   -
            */
      -  223   -
           private String getFileContents(final File actualFile)
      -  224   -
                   throws AnalysisException {
      -  225   -
               try {
      -  226  8
                   return FileUtils.readFileToString(actualFile, Charset.defaultCharset()).trim();
      -  227  0
               } catch (IOException e) {
      -  228  0
                   throw new AnalysisException(
      -  229   -
                           "Problem occurred while reading dependency file.", e);
      -  230   -
               }
      -  231  
           }
      -  232   +  157  
       
      -  233   -
           /**
      -  234   -
            * Gathers evidence from a given file
      -  235   -
            *
      -  236   -
            * @param dependency the dependency to add evidence to
      -  237   -
            * @param name the source of the evidence
      -  238   -
            * @param contents the evidence to analyze
      -  239   -
            */
      -  240   -
           private void gatherEvidence(Dependency dependency, final String name,
      -  241   -
                   String contents) {
      -  242  4
               final Matcher matcher = AC_INIT_PATTERN.matcher(contents);
      -  243  4
               if (matcher.find()) {
      -  244  4
                   final EvidenceCollection productEvidence = dependency
      -  245  4
                           .getProductEvidence();
      -  246  4
                   productEvidence.addEvidence(name, "Package", matcher.group(1),
      -  247   -
                           Confidence.HIGHEST);
      -  248  8
                   dependency.getVersionEvidence().addEvidence(name,
      -  249  4
                           "Package Version", matcher.group(2), Confidence.HIGHEST);
      -  250  4
                   final EvidenceCollection vendorEvidence = dependency
      -  251  4
                           .getVendorEvidence();
      -  252  4
                   if (null != matcher.group(3)) {
      -  253  8
                       vendorEvidence.addEvidence(name, "Bug report address",
      -  254  4
                               matcher.group(4), Confidence.HIGH);
      -  255   +  158   +
           @Override
      +  159   +
           protected void analyzeFileType(Dependency dependency, Engine engine)
      +  160   +
                   throws AnalysisException {
      +  161  4
               final File actualFile = dependency.getActualFile();
      +  162  4
               final String name = actualFile.getName();
      +  163  4
               if (name.startsWith(CONFIGURE)) {
      +  164  4
                   final File parent = actualFile.getParentFile();
      +  165  4
                   final String parentName = parent.getName();
      +  166  4
                   dependency.setDisplayFileName(parentName + "/" + name);
      +  167  4
                   final boolean isOutputScript = CONFIGURE.equals(name);
      +  168  4
                   if (isOutputScript || CONFIGURE_AC.equals(name)
      +  169  0
                           || CONFIGURE_IN.equals(name)) {
      +  170  4
                       final String contents = getFileContents(actualFile);
      +  171  4
                       if (!contents.isEmpty()) {
      +  172  4
                           if (isOutputScript) {
      +  173  2
                               extractConfigureScriptEvidence(dependency, name,
      +  174   +
                                       contents);
      +  175   +
                           } else {
      +  176  2
                               gatherEvidence(dependency, name, contents);
      +  177   +
                           }
      +  178   +
                       }
      +  179  
                   }
      -  256  4
                   if (null != matcher.group(5)) {
      -  257  2
                       productEvidence.addEvidence(name, "Tarname", matcher.group(6),
      -  258   -
                               Confidence.HIGH);
      +  180  4
               } else {
      +  181   +
                   // copy, alter and set in case some other thread is iterating over
      +  182  0
                   final List<Dependency> dependencies = new ArrayList<Dependency>(
      +  183  0
                           engine.getDependencies());
      +  184  0
                   dependencies.remove(dependency);
      +  185  0
                   engine.setDependencies(dependencies);
      +  186   +
               }
      +  187  4
           }
      +  188   +
       
      +  189   +
           /**
      +  190   +
            * Extracts evidence from the configuration.
      +  191   +
            *
      +  192   +
            * @param dependency the dependency being analyzed
      +  193   +
            * @param name the name of the source of evidence
      +  194   +
            * @param contents the contents to analyze for evidence
      +  195   +
            */
      +  196   +
           private void extractConfigureScriptEvidence(Dependency dependency,
      +  197   +
                   final String name, final String contents) {
      +  198  2
               final Matcher matcher = PACKAGE_VAR.matcher(contents);
      +  199  20
               while (matcher.find()) {
      +  200  18
                   final String variable = matcher.group(1);
      +  201  18
                   final String value = matcher.group(2);
      +  202  18
                   if (!value.isEmpty()) {
      +  203  14
                       if (variable.endsWith("NAME")) {
      +  204  4
                           dependency.getProductEvidence().addEvidence(name, variable,
      +  205   +
                                   value, Confidence.HIGHEST);
      +  206  10
                       } else if ("VERSION".equals(variable)) {
      +  207  2
                           dependency.getVersionEvidence().addEvidence(name, variable,
      +  208   +
                                   value, Confidence.HIGHEST);
      +  209  8
                       } else if ("BUGREPORT".equals(variable)) {
      +  210  1
                           dependency.getVendorEvidence().addEvidence(name, variable,
      +  211   +
                                   value, Confidence.HIGH);
      +  212  7
                       } else if ("URL".equals(variable)) {
      +  213  1
                           dependency.getVendorEvidence().addEvidence(name, variable,
      +  214   +
                                   value, Confidence.HIGH);
      +  215   +
                       }
      +  216   +
                   }
      +  217  18
               }
      +  218  2
           }
      +  219   +
       
      +  220   +
           /**
      +  221   +
            * Retrieves the contents of a given file.
      +  222   +
            *
      +  223   +
            * @param actualFile the file to read
      +  224   +
            * @return the contents of the file
      +  225   +
            * @throws AnalysisException thrown if there is an IO Exception
      +  226   +
            */
      +  227   +
           private String getFileContents(final File actualFile)
      +  228   +
                   throws AnalysisException {
      +  229   +
               try {
      +  230  4
                   return FileUtils.readFileToString(actualFile, Charset.defaultCharset()).trim();
      +  231  0
               } catch (IOException e) {
      +  232  0
                   throw new AnalysisException(
      +  233   +
                           "Problem occurred while reading dependency file.", e);
      +  234   +
               }
      +  235   +
           }
      +  236   +
       
      +  237   +
           /**
      +  238   +
            * Gathers evidence from a given file
      +  239   +
            *
      +  240   +
            * @param dependency the dependency to add evidence to
      +  241   +
            * @param name the source of the evidence
      +  242   +
            * @param contents the evidence to analyze
      +  243   +
            */
      +  244   +
           private void gatherEvidence(Dependency dependency, final String name,
      +  245   +
                   String contents) {
      +  246  2
               final Matcher matcher = AC_INIT_PATTERN.matcher(contents);
      +  247  2
               if (matcher.find()) {
      +  248  2
                   final EvidenceCollection productEvidence = dependency
      +  249  2
                           .getProductEvidence();
      +  250  2
                   productEvidence.addEvidence(name, "Package", matcher.group(1),
      +  251   +
                           Confidence.HIGHEST);
      +  252  4
                   dependency.getVersionEvidence().addEvidence(name,
      +  253  2
                           "Package Version", matcher.group(2), Confidence.HIGHEST);
      +  254  2
                   final EvidenceCollection vendorEvidence = dependency
      +  255  2
                           .getVendorEvidence();
      +  256  2
                   if (null != matcher.group(3)) {
      +  257  4
                       vendorEvidence.addEvidence(name, "Bug report address",
      +  258  2
                               matcher.group(4), Confidence.HIGH);
       259  
                   }
      -  260  4
                   if (null != matcher.group(7)) {
      -  261  2
                       final String url = matcher.group(8);
      -  262  2
                       if (UrlStringUtils.isUrl(url)) {
      -  263  2
                           vendorEvidence.addEvidence(name, "URL", url,
      -  264   -
                                   Confidence.HIGH);
      -  265   -
                       }
      -  266   +  260  2
                   if (null != matcher.group(5)) {
      +  261  1
                       productEvidence.addEvidence(name, "Tarname", matcher.group(6),
      +  262   +
                               Confidence.HIGH);
      +  263  
                   }
      -  267   -
               }
      -  268  4
           }
      +  264  2
                   if (null != matcher.group(7)) {
      +  265  1
                       final String url = matcher.group(8);
      +  266  1
                       if (UrlStringUtils.isUrl(url)) {
      +  267  1
                           vendorEvidence.addEvidence(name, "URL", url,
      +  268   +
                                   Confidence.HIGH);
       269   -
       
      +
                       }
       270   -
           /**
      +
                   }
       271   -
            * Initializes the file type analyzer.
      -  272   -
            *
      +
               }
      +  272  2
           }
       273   -
            * @throws Exception thrown if there is an exception during initialization
      +
       
       274   -
            */
      +
           /**
       275   -
           @Override
      +
            * Initializes the file type analyzer.
       276   -
           protected void initializeFileTypeAnalyzer() throws Exception {
      +
            *
       277   -
               // No initialization needed.
      -  278  12
           }
      +
            * @throws InitializationException thrown if there is an exception during
      +  278   +
            * initialization
       279   +
            */
      +  280   +
           @Override
      +  281   +
           protected void initializeFileTypeAnalyzer() throws InitializationException {
      +  282   +
               // No initialization needed.
      +  283  6
           }
      +  284  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.CMakeAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.CMakeAnalyzer.html index 2f52b3b18..fd8783fd7 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.CMakeAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.CMakeAnalyzer.html @@ -98,334 +98,346 @@  40  
       import java.util.regex.Pattern;
       41   -
       
      +
       import org.owasp.dependencycheck.exception.InitializationException;
       42   -
       /**
      +
       
       43   -
        * <p>
      +
       /**
       44   -
        * Used to analyze CMake build files, and collect information that can be used to determine the associated CPE.</p>
      -  45  
        * <p>
      +  45   +
        * Used to analyze CMake build files, and collect information that can be used
       46   -
        * Note: This analyzer catches straightforward invocations of the project command, plus some other observed patterns of version
      +
        * to determine the associated CPE.</p>
       47   -
        * inclusion in real CMake projects. Many projects make use of older versions of CMake and/or use custom "homebrew" ways to insert
      +
        * <p>
       48   -
        * version information. Hopefully as the newer CMake call pattern grows in usage, this analyzer allow more CPEs to be
      +
        * Note: This analyzer catches straightforward invocations of the project
       49   -
        * identified.</p>
      +
        * command, plus some other observed patterns of version inclusion in real CMake
       50   -
        *
      +
        * projects. Many projects make use of older versions of CMake and/or use custom
       51   -
        * @author Dale Visser
      +
        * "homebrew" ways to insert version information. Hopefully as the newer CMake
       52   -
        */
      +
        * call pattern grows in usage, this analyzer allow more CPEs to be
       53   -
       @Experimental
      -  54  22
       public class CMakeAnalyzer extends AbstractFileTypeAnalyzer {
      +
        * identified.</p>
      +  54   +
        *
       55   -
       
      +
        * @author Dale Visser
       56   -
           /**
      +
        */
       57   -
            * The logger.
      -  58   -
            */
      -  59  2
           private static final Logger LOGGER = LoggerFactory.getLogger(CMakeAnalyzer.class);
      +
       @Experimental
      +  58  11
       public class CMakeAnalyzer extends AbstractFileTypeAnalyzer {
      +  59   +
       
       60   -
       
      +
           /**
       61   -
           /**
      +
            * The logger.
       62   -
            * Used when compiling file scanning regex patterns.
      -  63  
            */
      +  63  1
           private static final Logger LOGGER = LoggerFactory.getLogger(CMakeAnalyzer.class);
       64   -
           private static final int REGEX_OPTIONS = Pattern.DOTALL
      +
       
       65   -
                   | Pattern.CASE_INSENSITIVE | Pattern.MULTILINE;
      +
           /**
       66   -
       
      +
            * Used when compiling file scanning regex patterns.
       67   -
           /**
      +
            */
       68   -
            * Regex to extract the product information.
      +
           private static final int REGEX_OPTIONS = Pattern.DOTALL
       69   -
            */
      -  70  2
           private static final Pattern PROJECT = Pattern.compile(
      +
                   | Pattern.CASE_INSENSITIVE | Pattern.MULTILINE;
      +  70   +
       
       71   -
                   "^ *project *\\([ \\n]*(\\w+)[ \\n]*.*?\\)", REGEX_OPTIONS);
      +
           /**
       72   -
       
      +
            * Regex to extract the product information.
       73   -
           /**
      -  74   -
            * Regex to extract product and version information.
      +
            */
      +  74  1
           private static final Pattern PROJECT = Pattern.compile(
       75   -
            *
      +
                   "^ *project *\\([ \\n]*(\\w+)[ \\n]*.*?\\)", REGEX_OPTIONS);
       76   -
            * Group 1: Product
      +
       
       77   -
            *
      +
           /**
       78   -
            * Group 2: Version
      +
            * Regex to extract product and version information.
       79   -
            */
      -  80  2
           private static final Pattern SET_VERSION = Pattern
      -  81  2
                   .compile(
      +
            *
      +  80   +
            * Group 1: Product
      +  81   +
            *
       82   -
                           "^ *set\\s*\\(\\s*(\\w+)_version\\s+\"?(\\d+(?:\\.\\d+)+)[\\s\"]?\\)",
      +
            * Group 2: Version
       83   -
                           REGEX_OPTIONS);
      -  84   -
       
      -  85   -
           /**
      +
            */
      +  84  1
           private static final Pattern SET_VERSION = Pattern
      +  85  1
                   .compile(
       86   -
            * Detects files that can be analyzed.
      +
                           "^ *set\\s*\\(\\s*(\\w+)_version\\s+\"?(\\d+(?:\\.\\d+)+)[\\s\"]?\\)",
       87   -
            */
      -  88  2
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(".cmake")
      -  89  2
                   .addFilenames("CMakeLists.txt").build();
      +
                           REGEX_OPTIONS);
      +  88   +
       
      +  89   +
           /**
       90   -
       
      +
            * Detects files that can be analyzed.
       91   -
           /**
      -  92   -
            * A reference to SHA1 message digest.
      -  93  
            */
      -  94  2
           private static MessageDigest sha1 = null;
      +  92  1
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(".cmake")
      +  93  1
                   .addFilenames("CMakeLists.txt").build();
      +  94   +
       
       95   -
       
      +
           /**
       96   -
           static {
      +
            * A reference to SHA1 message digest.
       97   -
               try {
      -  98  2
                   sha1 = MessageDigest.getInstance("SHA1");
      -  99  0
               } catch (NoSuchAlgorithmException e) {
      -  100  0
                   LOGGER.error(e.getMessage());
      -  101  2
               }
      -  102  2
           }
      -  103   +
            */
      +  98  1
           private static MessageDigest sha1 = null;
      +  99  
       
      -  104   -
           /**
      -  105   -
            * Returns the name of the CMake analyzer.
      -  106   -
            *
      +  100   +
           static {
      +  101   +
               try {
      +  102  1
                   sha1 = MessageDigest.getInstance("SHA1");
      +  103  0
               } catch (NoSuchAlgorithmException e) {
      +  104  0
                   LOGGER.error(e.getMessage());
      +  105  1
               }
      +  106  1
           }
       107   -
            * @return the name of the analyzer
      +
       
       108   -
            *
      +
           /**
       109   -
            */
      +
            * Returns the name of the CMake analyzer.
       110   -
           @Override
      +
            *
       111   -
           public String getName() {
      -  112  30
               return "CMake Analyzer";
      +
            * @return the name of the analyzer
      +  112   +
            *
       113   -
           }
      +
            */
       114   -
       
      +
           @Override
       115   -
           /**
      -  116   -
            * Tell that we are used for information collection.
      +
           public String getName() {
      +  116  15
               return "CMake Analyzer";
       117   -
            *
      +
           }
       118   -
            * @return INFORMATION_COLLECTION
      +
       
       119   -
            */
      +
           /**
       120   -
           @Override
      +
            * Tell that we are used for information collection.
       121   -
           public AnalysisPhase getAnalysisPhase() {
      -  122  8
               return AnalysisPhase.INFORMATION_COLLECTION;
      +
            *
      +  122   +
            * @return INFORMATION_COLLECTION
       123   -
           }
      +
            */
       124   -
       
      +
           @Override
       125   -
           /**
      -  126   -
            * Returns the set of supported file extensions.
      +
           public AnalysisPhase getAnalysisPhase() {
      +  126  4
               return AnalysisPhase.INFORMATION_COLLECTION;
       127   -
            *
      +
           }
       128   -
            * @return the set of supported file extensions
      +
       
       129   -
            */
      +
           /**
       130   -
           @Override
      +
            * Returns the set of supported file extensions.
       131   -
           protected FileFilter getFileFilter() {
      -  132  1722
               return FILTER;
      +
            *
      +  132   +
            * @return the set of supported file extensions
       133   -
           }
      +
            */
       134   -
       
      +
           @Override
       135   -
           /**
      -  136   -
            * No-op initializer implementation.
      +
           protected FileFilter getFileFilter() {
      +  136  12
               return FILTER;
       137   -
            *
      -  138   -
            * @throws Exception never thrown
      -  139   -
            */
      -  140   -
           @Override
      -  141   -
           protected void initializeFileTypeAnalyzer() throws Exception {
      -  142   -
               // Nothing to do here.
      -  143  10
           }
      -  144   -
       
      -  145   -
           /**
      -  146   -
            * Analyzes python packages and adds evidence to the dependency.
      -  147   -
            *
      -  148   -
            * @param dependency the dependency being analyzed
      -  149   -
            * @param engine the engine being used to perform the scan
      -  150   -
            * @throws AnalysisException thrown if there is an unrecoverable error analyzing the dependency
      -  151   -
            */
      -  152   -
           @Override
      -  153   -
           protected void analyzeFileType(Dependency dependency, Engine engine)
      -  154   -
                   throws AnalysisException {
      -  155  6
               final File file = dependency.getActualFile();
      -  156  6
               final String parentName = file.getParentFile().getName();
      -  157  6
               final String name = file.getName();
      -  158  6
               dependency.setDisplayFileName(String.format("%s%c%s", parentName, File.separatorChar, name));
      -  159   -
               String contents;
      -  160   -
               try {
      -  161  6
                   contents = FileUtils.readFileToString(file, Charset.defaultCharset()).trim();
      -  162  0
               } catch (IOException e) {
      -  163  0
                   throw new AnalysisException(
      -  164   -
                           "Problem occurred while reading dependency file.", e);
      -  165  6
               }
      -  166   -
       
      -  167  6
               if (StringUtils.isNotBlank(contents)) {
      -  168  6
                   final Matcher m = PROJECT.matcher(contents);
      -  169  6
                   int count = 0;
      -  170  10
                   while (m.find()) {
      -  171  4
                       count++;
      -  172  8
                       LOGGER.debug(String.format(
      -  173   -
                               "Found project command match with %d groups: %s",
      -  174  4
                               m.groupCount(), m.group(0)));
      -  175  4
                       final String group = m.group(1);
      -  176  4
                       LOGGER.debug("Group 1: " + group);
      -  177  4
                       dependency.getProductEvidence().addEvidence(name, "Project",
      -  178   -
                               group, Confidence.HIGH);
      -  179  4
                   }
      -  180  6
                   LOGGER.debug("Found {} matches.", count);
      -  181  6
                   analyzeSetVersionCommand(dependency, engine, contents);
      -  182   -
               }
      -  183  6
           }
      -  184   -
       
      -  185   -
           /**
      -  186   -
            * Extracts the version information from the contents. If more then one version is found additional dependencies are added to
      -  187   -
            * the dependency list.
      -  188   -
            *
      -  189   -
            * @param dependency the dependency being analyzed
      -  190   -
            * @param engine the dependency-check engine
      -  191   -
            * @param contents the version information
      -  192   -
            */
      -  193   -
           private void analyzeSetVersionCommand(Dependency dependency, Engine engine, String contents) {
      -  194  6
               Dependency currentDep = dependency;
      -  195   -
       
      -  196  6
               final Matcher m = SET_VERSION.matcher(contents);
      -  197  6
               int count = 0;
      -  198  16
               while (m.find()) {
      -  199  10
                   count++;
      -  200  20
                   LOGGER.debug("Found project command match with {} groups: {}",
      -  201  10
                           m.groupCount(), m.group(0));
      -  202  10
                   String product = m.group(1);
      -  203  10
                   final String version = m.group(2);
      -  204  10
                   LOGGER.debug("Group 1: " + product);
      -  205  10
                   LOGGER.debug("Group 2: " + version);
      -  206  10
                   final String aliasPrefix = "ALIASOF_";
      -  207  10
                   if (product.startsWith(aliasPrefix)) {
      -  208  10
                       product = product.replaceFirst(aliasPrefix, "");
      -  209   -
                   }
      -  210  10
                   if (count > 1) {
      -  211   -
                       //TODO - refactor so we do not assign to the parameter (checkstyle)
      -  212  8
                       currentDep = new Dependency(dependency.getActualFile());
      -  213  8
                       currentDep.setDisplayFileName(String.format("%s:%s", dependency.getDisplayFileName(), product));
      -  214  8
                       final String filePath = String.format("%s:%s", dependency.getFilePath(), product);
      -  215  8
                       currentDep.setFilePath(filePath);
      -  216   -
       
      -  217   -
                       byte[] path;
      -  218   -
                       try {
      -  219  8
                           path = filePath.getBytes("UTF-8");
      -  220  0
                       } catch (UnsupportedEncodingException ex) {
      -  221  0
                           path = filePath.getBytes();
      -  222  8
                       }
      -  223  8
                       currentDep.setSha1sum(Checksum.getHex(sha1.digest(path)));
      -  224  8
                       engine.getDependencies().add(currentDep);
      -  225   -
                   }
      -  226  10
                   final String source = currentDep.getDisplayFileName();
      -  227  10
                   currentDep.getProductEvidence().addEvidence(source, "Product",
      -  228   -
                           product, Confidence.MEDIUM);
      -  229  10
                   currentDep.getVersionEvidence().addEvidence(source, "Version",
      -  230   -
                           version, Confidence.MEDIUM);
      -  231  10
               }
      -  232  6
               LOGGER.debug(String.format("Found %d matches.", count));
      -  233  6
           }
      -  234   -
       
      -  235   -
           @Override
      -  236   -
           protected String getAnalyzerEnabledSettingKey() {
      -  237  22
               return Settings.KEYS.ANALYZER_CMAKE_ENABLED;
      -  238  
           }
      -  239   +  138   +
       
      +  139   +
           /**
      +  140   +
            * No-op initializer implementation.
      +  141   +
            *
      +  142   +
            * @throws InitializationException never thrown
      +  143   +
            */
      +  144   +
           @Override
      +  145   +
           protected void initializeFileTypeAnalyzer() throws InitializationException {
      +  146   +
               // Nothing to do here.
      +  147  5
           }
      +  148   +
       
      +  149   +
           /**
      +  150   +
            * Analyzes python packages and adds evidence to the dependency.
      +  151   +
            *
      +  152   +
            * @param dependency the dependency being analyzed
      +  153   +
            * @param engine the engine being used to perform the scan
      +  154   +
            * @throws AnalysisException thrown if there is an unrecoverable error
      +  155   +
            * analyzing the dependency
      +  156   +
            */
      +  157   +
           @Override
      +  158   +
           protected void analyzeFileType(Dependency dependency, Engine engine)
      +  159   +
                   throws AnalysisException {
      +  160  3
               final File file = dependency.getActualFile();
      +  161  3
               final String parentName = file.getParentFile().getName();
      +  162  3
               final String name = file.getName();
      +  163  3
               dependency.setDisplayFileName(String.format("%s%c%s", parentName, File.separatorChar, name));
      +  164   +
               String contents;
      +  165   +
               try {
      +  166  3
                   contents = FileUtils.readFileToString(file, Charset.defaultCharset()).trim();
      +  167  0
               } catch (IOException e) {
      +  168  0
                   throw new AnalysisException(
      +  169   +
                           "Problem occurred while reading dependency file.", e);
      +  170  3
               }
      +  171   +
       
      +  172  3
               if (StringUtils.isNotBlank(contents)) {
      +  173  3
                   final Matcher m = PROJECT.matcher(contents);
      +  174  3
                   int count = 0;
      +  175  5
                   while (m.find()) {
      +  176  2
                       count++;
      +  177  4
                       LOGGER.debug(String.format(
      +  178   +
                               "Found project command match with %d groups: %s",
      +  179  2
                               m.groupCount(), m.group(0)));
      +  180  2
                       final String group = m.group(1);
      +  181  2
                       LOGGER.debug("Group 1: " + group);
      +  182  2
                       dependency.getProductEvidence().addEvidence(name, "Project",
      +  183   +
                               group, Confidence.HIGH);
      +  184  2
                   }
      +  185  3
                   LOGGER.debug("Found {} matches.", count);
      +  186  3
                   analyzeSetVersionCommand(dependency, engine, contents);
      +  187   +
               }
      +  188  3
           }
      +  189   +
       
      +  190   +
           /**
      +  191   +
            * Extracts the version information from the contents. If more then one
      +  192   +
            * version is found additional dependencies are added to the dependency
      +  193   +
            * list.
      +  194   +
            *
      +  195   +
            * @param dependency the dependency being analyzed
      +  196   +
            * @param engine the dependency-check engine
      +  197   +
            * @param contents the version information
      +  198   +
            */
      +  199   +
           private void analyzeSetVersionCommand(Dependency dependency, Engine engine, String contents) {
      +  200  3
               Dependency currentDep = dependency;
      +  201   +
       
      +  202  3
               final Matcher m = SET_VERSION.matcher(contents);
      +  203  3
               int count = 0;
      +  204  8
               while (m.find()) {
      +  205  5
                   count++;
      +  206  10
                   LOGGER.debug("Found project command match with {} groups: {}",
      +  207  5
                           m.groupCount(), m.group(0));
      +  208  5
                   String product = m.group(1);
      +  209  5
                   final String version = m.group(2);
      +  210  5
                   LOGGER.debug("Group 1: " + product);
      +  211  5
                   LOGGER.debug("Group 2: " + version);
      +  212  5
                   final String aliasPrefix = "ALIASOF_";
      +  213  5
                   if (product.startsWith(aliasPrefix)) {
      +  214  5
                       product = product.replaceFirst(aliasPrefix, "");
      +  215   +
                   }
      +  216  5
                   if (count > 1) {
      +  217   +
                       //TODO - refactor so we do not assign to the parameter (checkstyle)
      +  218  4
                       currentDep = new Dependency(dependency.getActualFile());
      +  219  4
                       currentDep.setDisplayFileName(String.format("%s:%s", dependency.getDisplayFileName(), product));
      +  220  4
                       final String filePath = String.format("%s:%s", dependency.getFilePath(), product);
      +  221  4
                       currentDep.setFilePath(filePath);
      +  222   +
       
      +  223   +
                       byte[] path;
      +  224   +
                       try {
      +  225  4
                           path = filePath.getBytes("UTF-8");
      +  226  0
                       } catch (UnsupportedEncodingException ex) {
      +  227  0
                           path = filePath.getBytes();
      +  228  4
                       }
      +  229  4
                       currentDep.setSha1sum(Checksum.getHex(sha1.digest(path)));
      +  230  4
                       engine.getDependencies().add(currentDep);
      +  231   +
                   }
      +  232  5
                   final String source = currentDep.getDisplayFileName();
      +  233  5
                   currentDep.getProductEvidence().addEvidence(source, "Product",
      +  234   +
                           product, Confidence.MEDIUM);
      +  235  5
                   currentDep.getVersionEvidence().addEvidence(source, "Version",
      +  236   +
                           version, Confidence.MEDIUM);
      +  237  5
               }
      +  238  3
               LOGGER.debug(String.format("Found %d matches.", count));
      +  239  3
           }
      +  240   +
       
      +  241   +
           @Override
      +  242   +
           protected String getAnalyzerEnabledSettingKey() {
      +  243  11
               return Settings.KEYS.ANALYZER_CMAKE_ENABLED;
      +  244   +
           }
      +  245  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.CPEAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.CPEAnalyzer.html index 87e9f5ae9..7c4057885 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.CPEAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.CPEAnalyzer.html @@ -12,9 +12,9 @@
       
      - - - + + +
      Classes in this File Line Coverage Branch Coverage Complexity
      CPEAnalyzer
      83%
      194/232
      76%
      103/134
      4.607
      CPEAnalyzer$IdentifierConfidence
      100%
      4/4
      N/A
      4.607
      CPEAnalyzer$IdentifierMatch
      38%
      15/39
      16%
      4/24
      4.607
      CPEAnalyzer
      81%
      194/238
      76%
      103/134
      4.75
      CPEAnalyzer$IdentifierConfidence
      100%
      4/4
      N/A
      4.75
      CPEAnalyzer$IdentifierMatch
      38%
      15/39
      16%
      4/24
      4.75
       
      @@ -114,1244 +114,1260 @@  47  
       import org.owasp.dependencycheck.dependency.VulnerableSoftware;
       48   -
       import org.owasp.dependencycheck.utils.DependencyVersion;
      +
       import org.owasp.dependencycheck.exception.InitializationException;
       49   -
       import org.owasp.dependencycheck.utils.DependencyVersionUtil;
      +
       import org.owasp.dependencycheck.utils.DependencyVersion;
       50   -
       import org.slf4j.Logger;
      +
       import org.owasp.dependencycheck.utils.DependencyVersionUtil;
       51   -
       import org.slf4j.LoggerFactory;
      +
       import org.slf4j.Logger;
       52   -
       
      +
       import org.slf4j.LoggerFactory;
       53   -
       /**
      +
       
       54   -
        * CPEAnalyzer is a utility class that takes a project dependency and attempts
      +
       /**
       55   -
        * to discern if there is an associated CPE. It uses the evidence contained
      +
        * CPEAnalyzer is a utility class that takes a project dependency and attempts
       56   -
        * within the dependency to search the Lucene index.
      +
        * to discern if there is an associated CPE. It uses the evidence contained
       57   -
        *
      +
        * within the dependency to search the Lucene index.
       58   -
        * @author Jeremy Long
      +
        *
       59   +
        * @author Jeremy Long
      +  60  
        */
      -  60  12
       public class CPEAnalyzer implements Analyzer {
      -  61   -
       
      +  61  6
       public class CPEAnalyzer implements Analyzer {
       62   -
           /**
      +
       
       63   -
            * The Logger.
      +
           /**
       64   +
            * The Logger.
      +  65  
            */
      -  65  2
           private static final Logger LOGGER = LoggerFactory.getLogger(CPEAnalyzer.class);
      -  66   -
           /**
      +  66  1
           private static final Logger LOGGER = LoggerFactory.getLogger(CPEAnalyzer.class);
       67   -
            * The maximum number of query results to return.
      +
           /**
       68   -
            */
      +
            * The maximum number of query results to return.
       69   -
           static final int MAX_QUERY_RESULTS = 25;
      +
            */
       70   -
           /**
      +
           static final int MAX_QUERY_RESULTS = 25;
       71   -
            * The weighting boost to give terms when constructing the Lucene query.
      +
           /**
       72   -
            */
      +
            * The weighting boost to give terms when constructing the Lucene query.
       73   -
           static final String WEIGHTING_BOOST = "^5";
      +
            */
       74   -
           /**
      +
           static final String WEIGHTING_BOOST = "^5";
       75   -
            * A string representation of a regular expression defining characters
      +
           /**
       76   -
            * utilized within the CPE Names.
      +
            * A string representation of a regular expression defining characters
       77   -
            */
      +
            * utilized within the CPE Names.
       78   -
           static final String CLEANSE_CHARACTER_RX = "[^A-Za-z0-9 ._-]";
      +
            */
       79   -
           /**
      +
           static final String CLEANSE_CHARACTER_RX = "[^A-Za-z0-9 ._-]";
       80   -
            * A string representation of a regular expression used to remove all but
      +
           /**
       81   -
            * alpha characters.
      +
            * A string representation of a regular expression used to remove all but
       82   -
            */
      +
            * alpha characters.
       83   -
           static final String CLEANSE_NONALPHA_RX = "[^A-Za-z]*";
      +
            */
       84   -
           /**
      +
           static final String CLEANSE_NONALPHA_RX = "[^A-Za-z]*";
       85   -
            * The additional size to add to a new StringBuilder to account for extra
      +
           /**
       86   -
            * data that will be written into the string.
      +
            * The additional size to add to a new StringBuilder to account for extra
       87   -
            */
      +
            * data that will be written into the string.
       88   -
           static final int STRING_BUILDER_BUFFER = 20;
      +
            */
       89   -
           /**
      +
           static final int STRING_BUILDER_BUFFER = 20;
       90   -
            * The CPE in memory index.
      +
           /**
       91   -
            */
      +
            * The CPE in memory index.
       92   -
           private CpeMemoryIndex cpe;
      +
            */
       93   -
           /**
      +
           private CpeMemoryIndex cpe;
       94   -
            * The CVE Database.
      +
           /**
       95   -
            */
      +
            * The CVE Database.
       96   -
           private CveDB cve;
      +
            */
       97   -
       
      +
           private CveDB cve;
       98   -
           /**
      +
       
       99   -
            * The URL to perform a search of the NVD CVE data at NIST.
      +
           /**
       100   -
            */
      +
            * The URL to perform a search of the NVD CVE data at NIST.
       101   -
           public static final String NVD_SEARCH_URL = "https://web.nvd.nist.gov/view/vuln/search-results?adv_search=true&cves=on&cpe_version=%s";
      +
            */
       102   -
       
      +
           public static final String NVD_SEARCH_URL = "https://web.nvd.nist.gov/view/vuln/search-results?adv_search=true&cves=on&cpe_version=%s";
       103   -
           /**
      +
       
       104   -
            * Returns the name of this analyzer.
      +
           /**
       105   -
            *
      +
            * Returns the name of this analyzer.
       106   -
            * @return the name of this analyzer.
      +
            *
       107   -
            */
      +
            * @return the name of this analyzer.
       108   -
           @Override
      +
            */
       109   +
           @Override
      +  110  
           public String getName() {
      -  110  32
               return "CPE Analyzer";
      -  111   -
           }
      +  111  16
               return "CPE Analyzer";
       112   -
       
      +
           }
       113   -
           /**
      +
       
       114   -
            * Returns the analysis phase that this analyzer should run in.
      +
           /**
       115   -
            *
      +
            * Returns the analysis phase that this analyzer should run in.
       116   -
            * @return the analysis phase that this analyzer should run in.
      +
            *
       117   -
            */
      +
            * @return the analysis phase that this analyzer should run in.
       118   -
           @Override
      +
            */
       119   +
           @Override
      +  120  
           public AnalysisPhase getAnalysisPhase() {
      -  120  8
               return AnalysisPhase.IDENTIFIER_ANALYSIS;
      -  121   -
           }
      +  121  4
               return AnalysisPhase.IDENTIFIER_ANALYSIS;
       122   -
       
      +
           }
       123   -
           /**
      +
       
       124   -
            * Creates the CPE Lucene Index.
      +
           /**
       125   -
            *
      +
            * Creates the CPE Lucene Index.
       126   -
            * @throws Exception is thrown if there is an issue opening the index.
      +
            *
       127   -
            */
      +
            * @throws InitializationException is thrown if there is an issue opening
       128   -
           @Override
      +
            * the index.
       129   -
           public void initialize() throws Exception {
      -  130  4
               this.open();
      -  131  4
           }
      -  132   -
       
      -  133   -
           /**
      -  134   -
            * Opens the data source.
      -  135   -
            *
      -  136   -
            * @throws IOException when the Lucene directory to be queried does not
      -  137   -
            * exist or is corrupt.
      -  138   -
            * @throws DatabaseException when the database throws an exception. This
      -  139   -
            * usually occurs when the database is in use by another process.
      -  140  
            */
      -  141   -
           public void open() throws IOException, DatabaseException {
      -  142  4
               if (!isOpen()) {
      -  143  4
                   cve = new CveDB();
      -  144  4
                   cve.open();
      -  145  4
                   cpe = CpeMemoryIndex.getInstance();
      -  146   -
                   try {
      -  147  4
                       LOGGER.info("Creating the CPE Index");
      -  148  4
                       final long creationStart = System.currentTimeMillis();
      -  149  4
                       cpe.open(cve);
      -  150  4
                       LOGGER.info("CPE Index Created ({} ms)", System.currentTimeMillis() - creationStart);
      -  151  0
                   } catch (IndexException ex) {
      -  152  0
                       LOGGER.debug("IndexException", ex);
      -  153  0
                       throw new DatabaseException(ex);
      -  154  4
                   }
      -  155   -
               }
      -  156  4
           }
      -  157   -
       
      -  158   -
           /**
      -  159   -
            * Closes the data sources.
      -  160   -
            */
      -  161   +  130  
           @Override
      -  162   -
           public void close() {
      -  163  4
               if (cpe != null) {
      -  164  4
                   cpe.close();
      -  165  4
                   cpe = null;
      -  166   -
               }
      -  167  4
               if (cve != null) {
      -  168  4
                   cve.close();
      -  169  4
                   cve = null;
      -  170   -
               }
      -  171  4
           }
      -  172   -
       
      -  173   -
           public boolean isOpen() {
      -  174  4
               return cpe != null && cpe.isOpen();
      -  175   -
           }
      -  176   -
       
      -  177   -
           /**
      -  178   -
            * Searches the data store of CPE entries, trying to identify the CPE for
      -  179   -
            * the given dependency based on the evidence contained within. The
      -  180   -
            * dependency passed in is updated with any identified CPE values.
      -  181   -
            *
      -  182   -
            * @param dependency the dependency to search for CPE entries on.
      -  183   -
            * @throws CorruptIndexException is thrown when the Lucene index is corrupt.
      -  184   -
            * @throws IOException is thrown when an IOException occurs.
      -  185   -
            * @throws ParseException is thrown when the Lucene query cannot be parsed.
      -  186   -
            */
      -  187   -
           protected void determineCPE(Dependency dependency) throws CorruptIndexException, IOException, ParseException {
      -  188   -
               //TODO test dojo-war against this. we shold get dojo-toolkit:dojo-toolkit AND dojo-toolkit:toolkit
      -  189  8
               String vendors = "";
      -  190  8
               String products = "";
      -  191  34
               for (Confidence confidence : Confidence.values()) {
      -  192  28
                   if (dependency.getVendorEvidence().contains(confidence)) {
      -  193  18
                       vendors = addEvidenceWithoutDuplicateTerms(vendors, dependency.getVendorEvidence(), confidence);
      -  194  18
                       LOGGER.debug("vendor search: {}", vendors);
      -  195   -
                   }
      -  196  28
                   if (dependency.getProductEvidence().contains(confidence)) {
      -  197  16
                       products = addEvidenceWithoutDuplicateTerms(products, dependency.getProductEvidence(), confidence);
      -  198  16
                       LOGGER.debug("product search: {}", products);
      -  199   -
                   }
      -  200  28
                   if (!vendors.isEmpty() && !products.isEmpty()) {
      -  201  44
                       final List<IndexEntry> entries = searchCPE(vendors, products, dependency.getVendorEvidence().getWeighting(),
      -  202  22
                               dependency.getProductEvidence().getWeighting());
      -  203  22
                       if (entries == null) {
      -  204  0
                           continue;
      -  205   -
                       }
      -  206  22
                       boolean identifierAdded = false;
      -  207  22
                       for (IndexEntry e : entries) {
      -  208  90
                           LOGGER.debug("Verifying entry: {}", e);
      -  209  90
                           if (verifyEntry(e, dependency)) {
      -  210  6
                               final String vendor = e.getVendor();
      -  211  6
                               final String product = e.getProduct();
      -  212  6
                               LOGGER.debug("identified vendor/product: {}/{}", vendor, product);
      -  213  6
                               identifierAdded |= determineIdentifiers(dependency, vendor, product, confidence);
      -  214   -
                           }
      -  215  90
                       }
      -  216  22
                       if (identifierAdded) {
      -  217  2
                           break;
      -  218   -
                       }
      -  219   -
                   }
      -  220   -
               }
      -  221  8
           }
      -  222   -
       
      -  223   -
           /**
      -  224   -
            * Returns the text created by concatenating the text and the values from
      -  225   -
            * the EvidenceCollection (filtered for a specific confidence). This
      -  226   -
            * attempts to prevent duplicate terms from being added.<br/<br/> Note, if
      -  227   -
            * the evidence is longer then 200 characters it will be truncated.
      -  228   -
            *
      -  229   -
            * @param text the base text.
      -  230   -
            * @param ec an EvidenceCollection
      -  231   -
            * @param confidenceFilter a Confidence level to filter the evidence by.
      -  232   -
            * @return the new evidence text
      -  233   -
            */
      -  234   -
           private String addEvidenceWithoutDuplicateTerms(final String text, final EvidenceCollection ec, Confidence confidenceFilter) {
      -  235  34
               final String txt = (text == null) ? "" : text;
      -  236  34
               final StringBuilder sb = new StringBuilder(txt.length() + (20 * ec.size()));
      -  237  34
               sb.append(' ').append(txt).append(' ');
      -  238  34
               for (Evidence e : ec.iterator(confidenceFilter)) {
      -  239  74
                   String value = e.getValue();
      -  240   -
       
      -  241   -
                   //hack to get around the fact that lucene does a really good job of recognizing domains and not
      -  242   -
                   // splitting them. TODO - put together a better lucene analyzer specific to the domain.
      -  243  74
                   if (value.startsWith("http://")) {
      -  244  4
                       value = value.substring(7).replaceAll("\\.", " ");
      -  245   -
                   }
      -  246  74
                   if (value.startsWith("https://")) {
      -  247  2
                       value = value.substring(8).replaceAll("\\.", " ");
      -  248   -
                   }
      -  249  74
                   if (sb.indexOf(" " + value + " ") < 0) {
      -  250  74
                       sb.append(value).append(' ');
      -  251   -
                   }
      -  252  74
               }
      -  253  34
               return sb.toString().trim();
      -  254   -
           }
      -  255   -
       
      -  256   -
           /**
      -  257   -
            * <p>
      -  258   -
            * Searches the Lucene CPE index to identify possible CPE entries associated
      -  259   -
            * with the supplied vendor, product, and version.</p>
      -  260   -
            *
      -  261   -
            * <p>
      -  262   -
            * If either the vendorWeightings or productWeightings lists have been
      -  263   -
            * populated this data is used to add weighting factors to the search.</p>
      -  264   -
            *
      -  265   -
            * @param vendor the text used to search the vendor field
      -  266   -
            * @param product the text used to search the product field
      -  267   -
            * @param vendorWeightings a list of strings to use to add weighting factors
      -  268   -
            * to the vendor field
      -  269   -
            * @param productWeightings Adds a list of strings that will be used to add
      -  270   -
            * weighting factors to the product search
      -  271   -
            * @return a list of possible CPE values
      -  272   -
            */
      -  273   -
           protected List<IndexEntry> searchCPE(String vendor, String product,
      -  274   -
                   Set<String> vendorWeightings, Set<String> productWeightings) {
      -  275   -
       
      -  276  22
               final List<IndexEntry> ret = new ArrayList<IndexEntry>(MAX_QUERY_RESULTS);
      -  277   -
       
      -  278  22
               final String searchString = buildSearch(vendor, product, vendorWeightings, productWeightings);
      -  279  22
               if (searchString == null) {
      -  280  0
                   return ret;
      -  281   -
               }
      -  282   +  131   +
           public void initialize() throws InitializationException {
      +  132  
               try {
      -  283  22
                   final TopDocs docs = cpe.search(searchString, MAX_QUERY_RESULTS);
      -  284  372
                   for (ScoreDoc d : docs.scoreDocs) {
      -  285  350
                       if (d.score >= 0.08) {
      -  286  90
                           final Document doc = cpe.getDocument(d.doc);
      -  287  90
                           final IndexEntry entry = new IndexEntry();
      -  288  90
                           entry.setVendor(doc.get(Fields.VENDOR));
      -  289  90
                           entry.setProduct(doc.get(Fields.PRODUCT));
      -  290  90
                           entry.setSearchScore(d.score);
      -  291  90
                           if (!ret.contains(entry)) {
      -  292  90
                               ret.add(entry);
      -  293   -
                           }
      -  294   -
                       }
      -  295   -
                   }
      -  296  22
                   return ret;
      -  297  0
               } catch (ParseException ex) {
      -  298  0
                   LOGGER.warn("An error occurred querying the CPE data. See the log for more details.");
      -  299  0
                   LOGGER.info("Unable to parse: {}", searchString, ex);
      -  300  0
               } catch (IOException ex) {
      -  301  0
                   LOGGER.warn("An error occurred reading CPE data. See the log for more details.");
      -  302  0
                   LOGGER.info("IO Error with search string: {}", searchString, ex);
      -  303  0
               }
      -  304  0
               return null;
      -  305   -
           }
      -  306   +  133  2
                   this.open();
      +  134  0
               } catch (IOException ex) {
      +  135  0
                   LOGGER.debug("Exception initializing the Lucene Index", ex);
      +  136  0
                   throw new InitializationException("An exception occurred initializing the Lucene Index", ex);
      +  137  0
               } catch (DatabaseException ex) {
      +  138  0
                   LOGGER.debug("Exception accessing the database", ex);
      +  139  0
                   throw new InitializationException("An exception occurred accessing the database", ex);
      +  140  2
               }
      +  141  2
           }
      +  142  
       
      -  307   +  143  
           /**
      -  308   -
            * <p>
      -  309   -
            * Builds a Lucene search string by properly escaping data and constructing
      -  310   -
            * a valid search query.</p>
      -  311   +  144   +
            * Opens the data source.
      +  145  
            *
      -  312   -
            * <p>
      -  313   -
            * If either the possibleVendor or possibleProducts lists have been
      -  314   -
            * populated this data is used to add weighting factors to the search string
      -  315   -
            * generated.</p>
      -  316   -
            *
      -  317   -
            * @param vendor text to search the vendor field
      -  318   -
            * @param product text to search the product field
      -  319   -
            * @param vendorWeighting a list of strings to apply to the vendor to boost
      -  320   -
            * the terms weight
      -  321   -
            * @param productWeightings a list of strings to apply to the product to
      -  322   -
            * boost the terms weight
      -  323   -
            * @return the Lucene query
      -  324   +  146   +
            * @throws IOException when the Lucene directory to be queried does not
      +  147   +
            * exist or is corrupt.
      +  148   +
            * @throws DatabaseException when the database throws an exception. This
      +  149   +
            * usually occurs when the database is in use by another process.
      +  150  
            */
      -  325   -
           protected String buildSearch(String vendor, String product,
      -  326   -
                   Set<String> vendorWeighting, Set<String> productWeightings) {
      -  327  22
               final String v = vendor; //.replaceAll("[^\\w\\d]", " ");
      -  328  22
               final String p = product; //.replaceAll("[^\\w\\d]", " ");
      -  329  22
               final StringBuilder sb = new StringBuilder(v.length() + p.length()
      -  330  22
                       + Fields.PRODUCT.length() + Fields.VENDOR.length() + STRING_BUILDER_BUFFER);
      -  331   +  151   +
           public void open() throws IOException, DatabaseException {
      +  152  2
               if (!isOpen()) {
      +  153  2
                   cve = new CveDB();
      +  154  2
                   cve.open();
      +  155  2
                   cpe = CpeMemoryIndex.getInstance();
      +  156   +
                   try {
      +  157  2
                       LOGGER.info("Creating the CPE Index");
      +  158  2
                       final long creationStart = System.currentTimeMillis();
      +  159  2
                       cpe.open(cve);
      +  160  2
                       LOGGER.info("CPE Index Created ({} ms)", System.currentTimeMillis() - creationStart);
      +  161  0
                   } catch (IndexException ex) {
      +  162  0
                       LOGGER.debug("IndexException", ex);
      +  163  0
                       throw new DatabaseException(ex);
      +  164  2
                   }
      +  165   +
               }
      +  166  2
           }
      +  167  
       
      -  332  22
               if (!appendWeightedSearch(sb, Fields.PRODUCT, p, productWeightings)) {
      -  333  0
                   return null;
      -  334   +  168   +
           /**
      +  169   +
            * Closes the data sources.
      +  170   +
            */
      +  171   +
           @Override
      +  172   +
           public void close() {
      +  173  2
               if (cpe != null) {
      +  174  2
                   cpe.close();
      +  175  2
                   cpe = null;
      +  176  
               }
      -  335  22
               sb.append(" AND ");
      -  336  22
               if (!appendWeightedSearch(sb, Fields.VENDOR, v, vendorWeighting)) {
      -  337  0
                   return null;
      -  338   +  177  2
               if (cve != null) {
      +  178  2
                   cve.close();
      +  179  2
                   cve = null;
      +  180  
               }
      -  339  22
               return sb.toString();
      -  340   +  181  2
           }
      +  182   +
       
      +  183   +
           public boolean isOpen() {
      +  184  2
               return cpe != null && cpe.isOpen();
      +  185  
           }
      +  186   +
       
      +  187   +
           /**
      +  188   +
            * Searches the data store of CPE entries, trying to identify the CPE for
      +  189   +
            * the given dependency based on the evidence contained within. The
      +  190   +
            * dependency passed in is updated with any identified CPE values.
      +  191   +
            *
      +  192   +
            * @param dependency the dependency to search for CPE entries on.
      +  193   +
            * @throws CorruptIndexException is thrown when the Lucene index is corrupt.
      +  194   +
            * @throws IOException is thrown when an IOException occurs.
      +  195   +
            * @throws ParseException is thrown when the Lucene query cannot be parsed.
      +  196   +
            */
      +  197   +
           protected void determineCPE(Dependency dependency) throws CorruptIndexException, IOException, ParseException {
      +  198   +
               //TODO test dojo-war against this. we shold get dojo-toolkit:dojo-toolkit AND dojo-toolkit:toolkit
      +  199  4
               String vendors = "";
      +  200  4
               String products = "";
      +  201  17
               for (Confidence confidence : Confidence.values()) {
      +  202  14
                   if (dependency.getVendorEvidence().contains(confidence)) {
      +  203  9
                       vendors = addEvidenceWithoutDuplicateTerms(vendors, dependency.getVendorEvidence(), confidence);
      +  204  9
                       LOGGER.debug("vendor search: {}", vendors);
      +  205   +
                   }
      +  206  14
                   if (dependency.getProductEvidence().contains(confidence)) {
      +  207  8
                       products = addEvidenceWithoutDuplicateTerms(products, dependency.getProductEvidence(), confidence);
      +  208  8
                       LOGGER.debug("product search: {}", products);
      +  209   +
                   }
      +  210  14
                   if (!vendors.isEmpty() && !products.isEmpty()) {
      +  211  22
                       final List<IndexEntry> entries = searchCPE(vendors, products, dependency.getVendorEvidence().getWeighting(),
      +  212  11
                               dependency.getProductEvidence().getWeighting());
      +  213  11
                       if (entries == null) {
      +  214  0
                           continue;
      +  215   +
                       }
      +  216  11
                       boolean identifierAdded = false;
      +  217  11
                       for (IndexEntry e : entries) {
      +  218  46
                           LOGGER.debug("Verifying entry: {}", e);
      +  219  46
                           if (verifyEntry(e, dependency)) {
      +  220  3
                               final String vendor = e.getVendor();
      +  221  3
                               final String product = e.getProduct();
      +  222  3
                               LOGGER.debug("identified vendor/product: {}/{}", vendor, product);
      +  223  3
                               identifierAdded |= determineIdentifiers(dependency, vendor, product, confidence);
      +  224   +
                           }
      +  225  46
                       }
      +  226  11
                       if (identifierAdded) {
      +  227  1
                           break;
      +  228   +
                       }
      +  229   +
                   }
      +  230   +
               }
      +  231  4
           }
      +  232   +
       
      +  233   +
           /**
      +  234   +
            * Returns the text created by concatenating the text and the values from
      +  235   +
            * the EvidenceCollection (filtered for a specific confidence). This
      +  236   +
            * attempts to prevent duplicate terms from being added.<br/<br/> Note, if
      +  237   +
            * the evidence is longer then 200 characters it will be truncated.
      +  238   +
            *
      +  239   +
            * @param text the base text.
      +  240   +
            * @param ec an EvidenceCollection
      +  241   +
            * @param confidenceFilter a Confidence level to filter the evidence by.
      +  242   +
            * @return the new evidence text
      +  243   +
            */
      +  244   +
           private String addEvidenceWithoutDuplicateTerms(final String text, final EvidenceCollection ec, Confidence confidenceFilter) {
      +  245  17
               final String txt = (text == null) ? "" : text;
      +  246  17
               final StringBuilder sb = new StringBuilder(txt.length() + (20 * ec.size()));
      +  247  17
               sb.append(' ').append(txt).append(' ');
      +  248  17
               for (Evidence e : ec.iterator(confidenceFilter)) {
      +  249  36
                   String value = e.getValue();
      +  250   +
       
      +  251   +
                   //hack to get around the fact that lucene does a really good job of recognizing domains and not
      +  252   +
                   // splitting them. TODO - put together a better lucene analyzer specific to the domain.
      +  253  36
                   if (value.startsWith("http://")) {
      +  254  2
                       value = value.substring(7).replaceAll("\\.", " ");
      +  255   +
                   }
      +  256  36
                   if (value.startsWith("https://")) {
      +  257  1
                       value = value.substring(8).replaceAll("\\.", " ");
      +  258   +
                   }
      +  259  36
                   if (sb.indexOf(" " + value + " ") < 0) {
      +  260  36
                       sb.append(value).append(' ');
      +  261   +
                   }
      +  262  36
               }
      +  263  17
               return sb.toString().trim();
      +  264   +
           }
      +  265   +
       
      +  266   +
           /**
      +  267   +
            * <p>
      +  268   +
            * Searches the Lucene CPE index to identify possible CPE entries associated
      +  269   +
            * with the supplied vendor, product, and version.</p>
      +  270   +
            *
      +  271   +
            * <p>
      +  272   +
            * If either the vendorWeightings or productWeightings lists have been
      +  273   +
            * populated this data is used to add weighting factors to the search.</p>
      +  274   +
            *
      +  275   +
            * @param vendor the text used to search the vendor field
      +  276   +
            * @param product the text used to search the product field
      +  277   +
            * @param vendorWeightings a list of strings to use to add weighting factors
      +  278   +
            * to the vendor field
      +  279   +
            * @param productWeightings Adds a list of strings that will be used to add
      +  280   +
            * weighting factors to the product search
      +  281   +
            * @return a list of possible CPE values
      +  282   +
            */
      +  283   +
           protected List<IndexEntry> searchCPE(String vendor, String product,
      +  284   +
                   Set<String> vendorWeightings, Set<String> productWeightings) {
      +  285   +
       
      +  286  11
               final List<IndexEntry> ret = new ArrayList<IndexEntry>(MAX_QUERY_RESULTS);
      +  287   +
       
      +  288  11
               final String searchString = buildSearch(vendor, product, vendorWeightings, productWeightings);
      +  289  11
               if (searchString == null) {
      +  290  0
                   return ret;
      +  291   +
               }
      +  292   +
               try {
      +  293  11
                   final TopDocs docs = cpe.search(searchString, MAX_QUERY_RESULTS);
      +  294  186
                   for (ScoreDoc d : docs.scoreDocs) {
      +  295  175
                       if (d.score >= 0.08) {
      +  296  46
                           final Document doc = cpe.getDocument(d.doc);
      +  297  46
                           final IndexEntry entry = new IndexEntry();
      +  298  46
                           entry.setVendor(doc.get(Fields.VENDOR));
      +  299  46
                           entry.setProduct(doc.get(Fields.PRODUCT));
      +  300  46
                           entry.setSearchScore(d.score);
      +  301  46
                           if (!ret.contains(entry)) {
      +  302  46
                               ret.add(entry);
      +  303   +
                           }
      +  304   +
                       }
      +  305   +
                   }
      +  306  11
                   return ret;
      +  307  0
               } catch (ParseException ex) {
      +  308  0
                   LOGGER.warn("An error occurred querying the CPE data. See the log for more details.");
      +  309  0
                   LOGGER.info("Unable to parse: {}", searchString, ex);
      +  310  0
               } catch (IOException ex) {
      +  311  0
                   LOGGER.warn("An error occurred reading CPE data. See the log for more details.");
      +  312  0
                   LOGGER.info("IO Error with search string: {}", searchString, ex);
      +  313  0
               }
      +  314  0
               return null;
      +  315   +
           }
      +  316   +
       
      +  317   +
           /**
      +  318   +
            * <p>
      +  319   +
            * Builds a Lucene search string by properly escaping data and constructing
      +  320   +
            * a valid search query.</p>
      +  321   +
            *
      +  322   +
            * <p>
      +  323   +
            * If either the possibleVendor or possibleProducts lists have been
      +  324   +
            * populated this data is used to add weighting factors to the search string
      +  325   +
            * generated.</p>
      +  326   +
            *
      +  327   +
            * @param vendor text to search the vendor field
      +  328   +
            * @param product text to search the product field
      +  329   +
            * @param vendorWeighting a list of strings to apply to the vendor to boost
      +  330   +
            * the terms weight
      +  331   +
            * @param productWeightings a list of strings to apply to the product to
      +  332   +
            * boost the terms weight
      +  333   +
            * @return the Lucene query
      +  334   +
            */
      +  335   +
           protected String buildSearch(String vendor, String product,
      +  336   +
                   Set<String> vendorWeighting, Set<String> productWeightings) {
      +  337  11
               final String v = vendor; //.replaceAll("[^\\w\\d]", " ");
      +  338  11
               final String p = product; //.replaceAll("[^\\w\\d]", " ");
      +  339  11
               final StringBuilder sb = new StringBuilder(v.length() + p.length()
      +  340  11
                       + Fields.PRODUCT.length() + Fields.VENDOR.length() + STRING_BUILDER_BUFFER);
       341  
       
      -  342   -
           /**
      -  343   -
            * This method constructs a Lucene query for a given field. The searchText
      +  342  11
               if (!appendWeightedSearch(sb, Fields.PRODUCT, p, productWeightings)) {
      +  343  0
                   return null;
       344   -
            * is split into separate words and if the word is within the list of
      -  345   -
            * weighted words then an additional weighting is applied to the term as it
      -  346   -
            * is appended into the query.
      -  347   -
            *
      +
               }
      +  345  11
               sb.append(" AND ");
      +  346  11
               if (!appendWeightedSearch(sb, Fields.VENDOR, v, vendorWeighting)) {
      +  347  0
                   return null;
       348   -
            * @param sb a StringBuilder that the query text will be appended to.
      -  349   -
            * @param field the field within the Lucene index that the query is
      +
               }
      +  349  11
               return sb.toString();
       350   -
            * searching.
      +
           }
       351   -
            * @param searchText text used to construct the query.
      +
       
       352   -
            * @param weightedText a list of terms that will be considered higher
      +
           /**
       353   -
            * importance when searching.
      +
            * This method constructs a Lucene query for a given field. The searchText
       354   -
            * @return if the append was successful.
      +
            * is split into separate words and if the word is within the list of
       355   -
            */
      +
            * weighted words then an additional weighting is applied to the term as it
       356   -
           private boolean appendWeightedSearch(StringBuilder sb, String field, String searchText, Set<String> weightedText) {
      -  357  44
               sb.append(' ').append(field).append(":( ");
      +
            * is appended into the query.
      +  357   +
            *
       358   -
       
      -  359  44
               final String cleanText = cleanseText(searchText);
      +
            * @param sb a StringBuilder that the query text will be appended to.
      +  359   +
            * @param field the field within the Lucene index that the query is
       360   -
       
      -  361  44
               if (cleanText.isEmpty()) {
      -  362  0
                   return false;
      +
            * searching.
      +  361   +
            * @param searchText text used to construct the query.
      +  362   +
            * @param weightedText a list of terms that will be considered higher
       363   -
               }
      +
            * importance when searching.
       364   +
            * @return if the append was successful.
      +  365   +
            */
      +  366   +
           private boolean appendWeightedSearch(StringBuilder sb, String field, String searchText, Set<String> weightedText) {
      +  367  22
               sb.append(' ').append(field).append(":( ");
      +  368  
       
      -  365  44
               if (weightedText == null || weightedText.isEmpty()) {
      -  366  28
                   LuceneUtils.appendEscapedLuceneQuery(sb, cleanText);
      -  367   +  369  22
               final String cleanText = cleanseText(searchText);
      +  370   +
       
      +  371  22
               if (cleanText.isEmpty()) {
      +  372  0
                   return false;
      +  373   +
               }
      +  374   +
       
      +  375  22
               if (weightedText == null || weightedText.isEmpty()) {
      +  376  14
                   LuceneUtils.appendEscapedLuceneQuery(sb, cleanText);
      +  377  
               } else {
      -  368  16
                   final StringTokenizer tokens = new StringTokenizer(cleanText);
      -  369  214
                   while (tokens.hasMoreElements()) {
      -  370  198
                       final String word = tokens.nextToken();
      -  371  198
                       StringBuilder temp = null;
      -  372  198
                       for (String weighted : weightedText) {
      -  373  460
                           final String weightedStr = cleanseText(weighted);
      -  374  460
                           if (equalsIgnoreCaseAndNonAlpha(word, weightedStr)) {
      -  375  14
                               temp = new StringBuilder(word.length() + 2);
      -  376  14
                               LuceneUtils.appendEscapedLuceneQuery(temp, word);
      -  377  14
                               temp.append(WEIGHTING_BOOST);
      -  378  14
                               if (!word.equalsIgnoreCase(weightedStr)) {
      -  379  0
                                   temp.append(' ');
      -  380  0
                                   LuceneUtils.appendEscapedLuceneQuery(temp, weightedStr);
      -  381  0
                                   temp.append(WEIGHTING_BOOST);
      -  382   +  378  8
                   final StringTokenizer tokens = new StringTokenizer(cleanText);
      +  379  104
                   while (tokens.hasMoreElements()) {
      +  380  96
                       final String word = tokens.nextToken();
      +  381  96
                       StringBuilder temp = null;
      +  382  96
                       for (String weighted : weightedText) {
      +  383  227
                           final String weightedStr = cleanseText(weighted);
      +  384  227
                           if (equalsIgnoreCaseAndNonAlpha(word, weightedStr)) {
      +  385  7
                               temp = new StringBuilder(word.length() + 2);
      +  386  7
                               LuceneUtils.appendEscapedLuceneQuery(temp, word);
      +  387  7
                               temp.append(WEIGHTING_BOOST);
      +  388  7
                               if (!word.equalsIgnoreCase(weightedStr)) {
      +  389  0
                                   temp.append(' ');
      +  390  0
                                   LuceneUtils.appendEscapedLuceneQuery(temp, weightedStr);
      +  391  0
                                   temp.append(WEIGHTING_BOOST);
      +  392  
                               }
      -  383   -
                               break;
      -  384   -
                           }
      -  385  446
                       }
      -  386  198
                       sb.append(' ');
      -  387  198
                       if (temp == null) {
      -  388  184
                           LuceneUtils.appendEscapedLuceneQuery(sb, word);
      -  389   -
                       } else {
      -  390  14
                           sb.append(temp);
      -  391   -
                       }
      -  392  198
                   }
       393   -
               }
      -  394  44
               sb.append(" ) ");
      -  395  44
               return true;
      -  396   -
           }
      -  397   -
       
      -  398   -
           /**
      +
                               break;
      +  394   +
                           }
      +  395  220
                       }
      +  396  96
                       sb.append(' ');
      +  397  96
                       if (temp == null) {
      +  398  89
                           LuceneUtils.appendEscapedLuceneQuery(sb, word);
       399   -
            * Removes characters from the input text that are not used within the CPE
      -  400   -
            * index.
      +
                       } else {
      +  400  7
                           sb.append(temp);
       401   -
            *
      -  402   -
            * @param text is the text to remove the characters from.
      +
                       }
      +  402  96
                   }
       403   -
            * @return the text having removed some characters.
      -  404   -
            */
      -  405   -
           private String cleanseText(String text) {
      -  406  504
               return text.replaceAll(CLEANSE_CHARACTER_RX, " ");
      +
               }
      +  404  22
               sb.append(" ) ");
      +  405  22
               return true;
      +  406   +
           }
       407   -
           }
      +
       
       408   -
       
      +
           /**
       409   -
           /**
      +
            * Removes characters from the input text that are not used within the CPE
       410   -
            * Compares two strings after lower casing them and removing the non-alpha
      +
            * index.
       411   -
            * characters.
      +
            *
       412   -
            *
      +
            * @param text is the text to remove the characters from.
       413   -
            * @param l string one to compare.
      +
            * @return the text having removed some characters.
       414   -
            * @param r string two to compare.
      +
            */
       415   -
            * @return whether or not the two strings are similar.
      -  416   -
            */
      +
           private String cleanseText(String text) {
      +  416  249
               return text.replaceAll(CLEANSE_CHARACTER_RX, " ");
       417   -
           private boolean equalsIgnoreCaseAndNonAlpha(String l, String r) {
      -  418  460
               if (l == null || r == null) {
      -  419  0
                   return false;
      -  420   -
               }
      -  421   -
       
      -  422  460
               final String left = l.replaceAll(CLEANSE_NONALPHA_RX, "");
      -  423  460
               final String right = r.replaceAll(CLEANSE_NONALPHA_RX, "");
      -  424  460
               return left.equalsIgnoreCase(right);
      -  425  
           }
      -  426   +  418  
       
      -  427   +  419  
           /**
      -  428   -
            * Ensures that the CPE Identified matches the dependency. This validates
      -  429   -
            * that the product, vendor, and version information for the CPE are
      -  430   -
            * contained within the dependencies evidence.
      -  431   +  420   +
            * Compares two strings after lower casing them and removing the non-alpha
      +  421   +
            * characters.
      +  422  
            *
      -  432   -
            * @param entry a CPE entry.
      -  433   -
            * @param dependency the dependency that the CPE entries could be for.
      -  434   -
            * @return whether or not the entry is valid.
      -  435   +  423   +
            * @param l string one to compare.
      +  424   +
            * @param r string two to compare.
      +  425   +
            * @return whether or not the two strings are similar.
      +  426  
            */
      -  436   -
           private boolean verifyEntry(final IndexEntry entry, final Dependency dependency) {
      -  437  90
               boolean isValid = false;
      -  438   -
       
      -  439   -
               //TODO - does this nullify some of the fuzzy matching that happens in the lucene search?
      -  440   -
               // for instance CPE some-component and in the evidence we have SomeComponent.
      -  441  90
               if (collectionContainsString(dependency.getProductEvidence(), entry.getProduct())
      -  442  8
                       && collectionContainsString(dependency.getVendorEvidence(), entry.getVendor())) {
      -  443   -
                   //&& collectionContainsVersion(dependency.getVersionEvidence(), entry.getVersion())
      -  444  6
                   isValid = true;
      -  445   +  427   +
           private boolean equalsIgnoreCaseAndNonAlpha(String l, String r) {
      +  428  227
               if (l == null || r == null) {
      +  429  0
                   return false;
      +  430  
               }
      -  446  90
               return isValid;
      -  447   +  431   +
       
      +  432  227
               final String left = l.replaceAll(CLEANSE_NONALPHA_RX, "");
      +  433  227
               final String right = r.replaceAll(CLEANSE_NONALPHA_RX, "");
      +  434  227
               return left.equalsIgnoreCase(right);
      +  435  
           }
      +  436   +
       
      +  437   +
           /**
      +  438   +
            * Ensures that the CPE Identified matches the dependency. This validates
      +  439   +
            * that the product, vendor, and version information for the CPE are
      +  440   +
            * contained within the dependencies evidence.
      +  441   +
            *
      +  442   +
            * @param entry a CPE entry.
      +  443   +
            * @param dependency the dependency that the CPE entries could be for.
      +  444   +
            * @return whether or not the entry is valid.
      +  445   +
            */
      +  446   +
           private boolean verifyEntry(final IndexEntry entry, final Dependency dependency) {
      +  447  46
               boolean isValid = false;
       448  
       
       449   -
           /**
      +
               //TODO - does this nullify some of the fuzzy matching that happens in the lucene search?
       450   -
            * Used to determine if the EvidenceCollection contains a specific string.
      -  451   -
            *
      -  452   -
            * @param ec an EvidenceCollection
      +
               // for instance CPE some-component and in the evidence we have SomeComponent.
      +  451  46
               if (collectionContainsString(dependency.getProductEvidence(), entry.getProduct())
      +  452  4
                       && collectionContainsString(dependency.getVendorEvidence(), entry.getVendor())) {
       453   -
            * @param text the text to search for
      -  454   -
            * @return whether or not the EvidenceCollection contains the string
      +
                   //&& collectionContainsVersion(dependency.getVersionEvidence(), entry.getVersion())
      +  454  3
                   isValid = true;
       455   -
            */
      -  456   -
           private boolean collectionContainsString(EvidenceCollection ec, String text) {
      +
               }
      +  456  46
               return isValid;
       457   -
               //TODO - likely need to change the split... not sure if this will work for CPE with special chars
      -  458  98
               if (text == null) {
      -  459  0
                   return false;
      +
           }
      +  458   +
       
      +  459   +
           /**
       460   -
               }
      -  461  98
               final String[] words = text.split("[\\s_-]");
      -  462  98
               final List<String> list = new ArrayList<String>();
      -  463  98
               String tempWord = null;
      -  464  286
               for (String word : words) {
      +
            * Used to determine if the EvidenceCollection contains a specific string.
      +  461   +
            *
      +  462   +
            * @param ec an EvidenceCollection
      +  463   +
            * @param text the text to search for
      +  464   +
            * @return whether or not the EvidenceCollection contains the string
       465   -
                   /*
      +
            */
       466   -
                    single letter words should be concatenated with the next word.
      +
           private boolean collectionContainsString(EvidenceCollection ec, String text) {
       467   -
                    so { "m", "core", "sample" } -> { "mcore", "sample" }
      -  468   -
                    */
      -  469  188
                   if (tempWord != null) {
      -  470  6
                       list.add(tempWord + word);
      -  471  6
                       tempWord = null;
      -  472  182
                   } else if (word.length() <= 2) {
      -  473  8
                       tempWord = word;
      -  474   -
                   } else {
      -  475  174
                       list.add(word);
      +
               //TODO - likely need to change the split... not sure if this will work for CPE with special chars
      +  468  50
               if (text == null) {
      +  469  0
                   return false;
      +  470   +
               }
      +  471  50
               final String[] words = text.split("[\\s_-]");
      +  472  50
               final List<String> list = new ArrayList<String>();
      +  473  50
               String tempWord = null;
      +  474  142
               for (String word : words) {
      +  475   +
                   /*
       476   -
                   }
      +
                    single letter words should be concatenated with the next word.
       477   -
               }
      -  478  98
               if (tempWord != null) {
      -  479  2
                   if (!list.isEmpty()) {
      -  480  2
                       final String tmp = list.get(list.size() - 1) + tempWord;
      -  481  2
                       list.add(tmp);
      -  482  2
                   } else {
      -  483  0
                       list.add(tempWord);
      +
                    so { "m", "core", "sample" } -> { "mcore", "sample" }
      +  478   +
                    */
      +  479  92
                   if (tempWord != null) {
      +  480  3
                       list.add(tempWord + word);
      +  481  3
                       tempWord = null;
      +  482  89
                   } else if (word.length() <= 2) {
      +  483  4
                       tempWord = word;
       484   +
                   } else {
      +  485  85
                       list.add(word);
      +  486  
                   }
      -  485   +  487  
               }
      -  486  98
               if (list.isEmpty()) {
      -  487  0
                   return false;
      -  488   -
               }
      -  489  98
               boolean contains = true;
      -  490  98
               for (String word : list) {
      -  491  182
                   contains &= ec.containsUsedString(word);
      -  492  182
               }
      -  493  98
               return contains;
      +  488  50
               if (tempWord != null) {
      +  489  1
                   if (!list.isEmpty()) {
      +  490  1
                       final String tmp = list.get(list.size() - 1) + tempWord;
      +  491  1
                       list.add(tmp);
      +  492  1
                   } else {
      +  493  0
                       list.add(tempWord);
       494   -
           }
      -  495   -
       
      -  496   -
           /**
      -  497   -
            * Analyzes a dependency and attempts to determine if there are any CPE
      -  498   -
            * identifiers for this dependency.
      -  499   -
            *
      -  500   -
            * @param dependency The Dependency to analyze.
      -  501   -
            * @param engine The analysis engine
      -  502   -
            * @throws AnalysisException is thrown if there is an issue analyzing the
      -  503   -
            * dependency.
      -  504   -
            */
      -  505   -
           @Override
      -  506   -
           public synchronized void analyze(Dependency dependency, Engine engine) throws AnalysisException {
      -  507   -
               try {
      -  508  8
                   determineCPE(dependency);
      -  509  0
               } catch (CorruptIndexException ex) {
      -  510  0
                   throw new AnalysisException("CPE Index is corrupt.", ex);
      -  511  0
               } catch (IOException ex) {
      -  512  0
                   throw new AnalysisException("Failure opening the CPE Index.", ex);
      -  513  0
               } catch (ParseException ex) {
      -  514  0
                   throw new AnalysisException("Unable to parse the generated Lucene query for this dependency.", ex);
      -  515  8
               }
      -  516  8
           }
      -  517   -
       
      -  518   -
           /**
      -  519   -
            * Retrieves a list of CPE values from the CveDB based on the vendor and
      -  520   -
            * product passed in. The list is then validated to find only CPEs that are
      -  521   -
            * valid for the given dependency. It is possible that the CPE identified is
      -  522   -
            * a best effort "guess" based on the vendor, product, and version
      -  523   -
            * information.
      -  524   -
            *
      -  525   -
            * @param dependency the Dependency being analyzed
      -  526   -
            * @param vendor the vendor for the CPE being analyzed
      -  527   -
            * @param product the product for the CPE being analyzed
      -  528   -
            * @param currentConfidence the current confidence being used during
      -  529   -
            * analysis
      -  530   -
            * @return <code>true</code> if an identifier was added to the dependency;
      -  531   -
            * otherwise <code>false</code>
      -  532   -
            * @throws UnsupportedEncodingException is thrown if UTF-8 is not supported
      -  533   -
            */
      -  534   -
           protected boolean determineIdentifiers(Dependency dependency, String vendor, String product,
      -  535   -
                   Confidence currentConfidence) throws UnsupportedEncodingException {
      -  536  6
               final Set<VulnerableSoftware> cpes = cve.getCPEs(vendor, product);
      -  537  6
               DependencyVersion bestGuess = new DependencyVersion("-");
      -  538  6
               Confidence bestGuessConf = null;
      -  539  6
               boolean hasBroadMatch = false;
      -  540  6
               final List<IdentifierMatch> collected = new ArrayList<IdentifierMatch>();
      -  541   -
       
      -  542   -
               //TODO the following algorithm incorrectly identifies things as a lower version
      -  543   -
               // if there lower confidence evidence when the current (highest) version number 
      -  544   -
               // is newer then anything in the NVD.
      -  545  30
               for (Confidence conf : Confidence.values()) {
      -  546  24
                   for (Evidence evidence : dependency.getVersionEvidence().iterator(conf)) {
      -  547  24
                       final DependencyVersion evVer = DependencyVersionUtil.parseVersion(evidence.getValue());
      -  548  24
                       if (evVer == null) {
      -  549  0
                           continue;
      -  550   -
                       }
      -  551  24
                       for (VulnerableSoftware vs : cpes) {
      -  552   -
                           DependencyVersion dbVer;
      -  553  872
                           if (vs.getUpdate() != null && !vs.getUpdate().isEmpty()) {
      -  554  256
                               dbVer = DependencyVersionUtil.parseVersion(vs.getVersion() + '.' + vs.getUpdate());
      -  555   -
                           } else {
      -  556  616
                               dbVer = DependencyVersionUtil.parseVersion(vs.getVersion());
      -  557   -
                           }
      -  558  872
                           if (dbVer == null) { //special case, no version specified - everything is vulnerable
      -  559  0
                               hasBroadMatch = true;
      -  560  0
                               final String url = String.format(NVD_SEARCH_URL, URLEncoder.encode(vs.getName(), "UTF-8"));
      -  561  0
                               final IdentifierMatch match = new IdentifierMatch("cpe", vs.getName(), url, IdentifierConfidence.BROAD_MATCH, conf);
      -  562  0
                               collected.add(match);
      -  563  0
                           } else if (evVer.equals(dbVer)) { //yeah! exact match
      -  564  16
                               final String url = String.format(NVD_SEARCH_URL, URLEncoder.encode(vs.getName(), "UTF-8"));
      -  565  16
                               final IdentifierMatch match = new IdentifierMatch("cpe", vs.getName(), url, IdentifierConfidence.EXACT_MATCH, conf);
      -  566  16
                               collected.add(match);
      -  567  16
                           } else //TODO the following isn't quite right is it? need to think about this guessing game a bit more.
      -  568  856
                           if (evVer.getVersionParts().size() <= dbVer.getVersionParts().size()
      -  569  840
                                   && evVer.matchesAtLeastThreeLevels(dbVer)) {
      -  570  128
                               if (bestGuessConf == null || bestGuessConf.compareTo(conf) > 0) {
      -  571  4
                                   if (bestGuess.getVersionParts().size() < dbVer.getVersionParts().size()) {
      -  572  4
                                       bestGuess = dbVer;
      -  573  4
                                       bestGuessConf = conf;
      -  574   -
                                   }
      -  575   -
                               }
      -  576   -
                           }
      -  577  872
                       }
      -  578  24
                       if (bestGuessConf == null || bestGuessConf.compareTo(conf) > 0) {
      -  579  2
                           if (bestGuess.getVersionParts().size() < evVer.getVersionParts().size()) {
      -  580  2
                               bestGuess = evVer;
      -  581  2
                               bestGuessConf = conf;
      -  582   -
                           }
      -  583   -
                       }
      -  584  24
                   }
      -  585   -
               }
      -  586  6
               final String cpeName = String.format("cpe:/a:%s:%s:%s", vendor, product, bestGuess.toString());
      -  587  6
               String url = null;
      -  588  6
               if (hasBroadMatch) { //if we have a broad match we can add the URL to the best guess.
      -  589  0
                   final String cpeUrlName = String.format("cpe:/a:%s:%s", vendor, product);
      -  590  0
                   url = String.format(NVD_SEARCH_URL, URLEncoder.encode(cpeUrlName, "UTF-8"));
      -  591   -
               }
      -  592  6
               if (bestGuessConf == null) {
      -  593  0
                   bestGuessConf = Confidence.LOW;
      -  594   -
               }
      -  595  6
               final IdentifierMatch match = new IdentifierMatch("cpe", cpeName, url, IdentifierConfidence.BEST_GUESS, bestGuessConf);
      -  596  6
               collected.add(match);
      -  597   -
       
      -  598  6
               Collections.sort(collected);
      -  599  6
               final IdentifierConfidence bestIdentifierQuality = collected.get(0).getConfidence();
      -  600  6
               final Confidence bestEvidenceQuality = collected.get(0).getEvidenceConfidence();
      -  601  6
               boolean identifierAdded = false;
      -  602  6
               for (IdentifierMatch m : collected) {
      -  603  22
                   if (bestIdentifierQuality.equals(m.getConfidence())
      -  604  18
                           && bestEvidenceQuality.equals(m.getEvidenceConfidence())) {
      -  605  6
                       final Identifier i = m.getIdentifier();
      -  606  6
                       if (bestIdentifierQuality == IdentifierConfidence.BEST_GUESS) {
      -  607  2
                           i.setConfidence(Confidence.LOW);
      -  608   -
                       } else {
      -  609  4
                           i.setConfidence(bestEvidenceQuality);
      -  610   -
                       }
      -  611  6
                       dependency.addIdentifier(i);
      -  612  6
                       identifierAdded = true;
      -  613  
                   }
      -  614  22
               }
      -  615  6
               return identifierAdded;
      -  616   +  495   +
               }
      +  496  50
               if (list.isEmpty()) {
      +  497  0
                   return false;
      +  498   +
               }
      +  499  50
               boolean contains = true;
      +  500  50
               for (String word : list) {
      +  501  89
                   contains &= ec.containsUsedString(word);
      +  502  89
               }
      +  503  50
               return contains;
      +  504  
           }
      -  617   +  505  
       
      -  618   +  506  
           /**
      +  507   +
            * Analyzes a dependency and attempts to determine if there are any CPE
      +  508   +
            * identifiers for this dependency.
      +  509   +
            *
      +  510   +
            * @param dependency The Dependency to analyze.
      +  511   +
            * @param engine The analysis engine
      +  512   +
            * @throws AnalysisException is thrown if there is an issue analyzing the
      +  513   +
            * dependency.
      +  514   +
            */
      +  515   +
           @Override
      +  516   +
           public synchronized void analyze(Dependency dependency, Engine engine) throws AnalysisException {
      +  517   +
               try {
      +  518  4
                   determineCPE(dependency);
      +  519  0
               } catch (CorruptIndexException ex) {
      +  520  0
                   throw new AnalysisException("CPE Index is corrupt.", ex);
      +  521  0
               } catch (IOException ex) {
      +  522  0
                   throw new AnalysisException("Failure opening the CPE Index.", ex);
      +  523  0
               } catch (ParseException ex) {
      +  524  0
                   throw new AnalysisException("Unable to parse the generated Lucene query for this dependency.", ex);
      +  525  4
               }
      +  526  4
           }
      +  527   +
       
      +  528   +
           /**
      +  529   +
            * Retrieves a list of CPE values from the CveDB based on the vendor and
      +  530   +
            * product passed in. The list is then validated to find only CPEs that are
      +  531   +
            * valid for the given dependency. It is possible that the CPE identified is
      +  532   +
            * a best effort "guess" based on the vendor, product, and version
      +  533   +
            * information.
      +  534   +
            *
      +  535   +
            * @param dependency the Dependency being analyzed
      +  536   +
            * @param vendor the vendor for the CPE being analyzed
      +  537   +
            * @param product the product for the CPE being analyzed
      +  538   +
            * @param currentConfidence the current confidence being used during
      +  539   +
            * analysis
      +  540   +
            * @return <code>true</code> if an identifier was added to the dependency;
      +  541   +
            * otherwise <code>false</code>
      +  542   +
            * @throws UnsupportedEncodingException is thrown if UTF-8 is not supported
      +  543   +
            */
      +  544   +
           protected boolean determineIdentifiers(Dependency dependency, String vendor, String product,
      +  545   +
                   Confidence currentConfidence) throws UnsupportedEncodingException {
      +  546  3
               final Set<VulnerableSoftware> cpes = cve.getCPEs(vendor, product);
      +  547  3
               DependencyVersion bestGuess = new DependencyVersion("-");
      +  548  3
               Confidence bestGuessConf = null;
      +  549  3
               boolean hasBroadMatch = false;
      +  550  3
               final List<IdentifierMatch> collected = new ArrayList<IdentifierMatch>();
      +  551   +
       
      +  552   +
               //TODO the following algorithm incorrectly identifies things as a lower version
      +  553   +
               // if there lower confidence evidence when the current (highest) version number 
      +  554   +
               // is newer then anything in the NVD.
      +  555  15
               for (Confidence conf : Confidence.values()) {
      +  556  12
                   for (Evidence evidence : dependency.getVersionEvidence().iterator(conf)) {
      +  557  12
                       final DependencyVersion evVer = DependencyVersionUtil.parseVersion(evidence.getValue());
      +  558  12
                       if (evVer == null) {
      +  559  0
                           continue;
      +  560   +
                       }
      +  561  12
                       for (VulnerableSoftware vs : cpes) {
      +  562   +
                           DependencyVersion dbVer;
      +  563  436
                           if (vs.getUpdate() != null && !vs.getUpdate().isEmpty()) {
      +  564  128
                               dbVer = DependencyVersionUtil.parseVersion(vs.getVersion() + '.' + vs.getUpdate());
      +  565   +
                           } else {
      +  566  308
                               dbVer = DependencyVersionUtil.parseVersion(vs.getVersion());
      +  567   +
                           }
      +  568  436
                           if (dbVer == null) { //special case, no version specified - everything is vulnerable
      +  569  0
                               hasBroadMatch = true;
      +  570  0
                               final String url = String.format(NVD_SEARCH_URL, URLEncoder.encode(vs.getName(), "UTF-8"));
      +  571  0
                               final IdentifierMatch match = new IdentifierMatch("cpe", vs.getName(), url, IdentifierConfidence.BROAD_MATCH, conf);
      +  572  0
                               collected.add(match);
      +  573  0
                           } else if (evVer.equals(dbVer)) { //yeah! exact match
      +  574  8
                               final String url = String.format(NVD_SEARCH_URL, URLEncoder.encode(vs.getName(), "UTF-8"));
      +  575  8
                               final IdentifierMatch match = new IdentifierMatch("cpe", vs.getName(), url, IdentifierConfidence.EXACT_MATCH, conf);
      +  576  8
                               collected.add(match);
      +  577   +
       
      +  578   +
                               //TODO the following isn't quite right is it? need to think about this guessing game a bit more.
      +  579  8
                           } else if (evVer.getVersionParts().size() <= dbVer.getVersionParts().size()
      +  580  420
                                   && evVer.matchesAtLeastThreeLevels(dbVer)) {
      +  581  64
                               if (bestGuessConf == null || bestGuessConf.compareTo(conf) > 0) {
      +  582  2
                                   if (bestGuess.getVersionParts().size() < dbVer.getVersionParts().size()) {
      +  583  2
                                       bestGuess = dbVer;
      +  584  2
                                       bestGuessConf = conf;
      +  585   +
                                   }
      +  586   +
                               }
      +  587   +
                           }
      +  588  436
                       }
      +  589  12
                       if (bestGuessConf == null || bestGuessConf.compareTo(conf) > 0) {
      +  590  1
                           if (bestGuess.getVersionParts().size() < evVer.getVersionParts().size()) {
      +  591  1
                               bestGuess = evVer;
      +  592  1
                               bestGuessConf = conf;
      +  593   +
                           }
      +  594   +
                       }
      +  595  12
                   }
      +  596   +
               }
      +  597  3
               final String cpeName = String.format("cpe:/a:%s:%s:%s", vendor, product, bestGuess.toString());
      +  598  3
               String url = null;
      +  599  3
               if (hasBroadMatch) { //if we have a broad match we can add the URL to the best guess.
      +  600  0
                   final String cpeUrlName = String.format("cpe:/a:%s:%s", vendor, product);
      +  601  0
                   url = String.format(NVD_SEARCH_URL, URLEncoder.encode(cpeUrlName, "UTF-8"));
      +  602   +
               }
      +  603  3
               if (bestGuessConf == null) {
      +  604  0
                   bestGuessConf = Confidence.LOW;
      +  605   +
               }
      +  606  3
               final IdentifierMatch match = new IdentifierMatch("cpe", cpeName, url, IdentifierConfidence.BEST_GUESS, bestGuessConf);
      +  607  3
               collected.add(match);
      +  608   +
       
      +  609  3
               Collections.sort(collected);
      +  610  3
               final IdentifierConfidence bestIdentifierQuality = collected.get(0).getConfidence();
      +  611  3
               final Confidence bestEvidenceQuality = collected.get(0).getEvidenceConfidence();
      +  612  3
               boolean identifierAdded = false;
      +  613  3
               for (IdentifierMatch m : collected) {
      +  614  11
                   if (bestIdentifierQuality.equals(m.getConfidence())
      +  615  9
                           && bestEvidenceQuality.equals(m.getEvidenceConfidence())) {
      +  616  3
                       final Identifier i = m.getIdentifier();
      +  617  3
                       if (bestIdentifierQuality == IdentifierConfidence.BEST_GUESS) {
      +  618  1
                           i.setConfidence(Confidence.LOW);
       619   -
            * The confidence whether the identifier is an exact match, or a best guess.
      -  620   -
            */
      -  621  8
           private enum IdentifierConfidence {
      -  622   -
       
      -  623   -
               /**
      +
                       } else {
      +  620  2
                           i.setConfidence(bestEvidenceQuality);
      +  621   +
                       }
      +  622  3
                       dependency.addIdentifier(i);
      +  623  3
                       identifierAdded = true;
       624   -
                * An exact match for the CPE.
      -  625   -
                */
      -  626  2
               EXACT_MATCH,
      +
                   }
      +  625  11
               }
      +  626  3
               return identifierAdded;
       627   -
               /**
      -  628   -
                * A best guess for the CPE.
      -  629   -
                */
      -  630  2
               BEST_GUESS,
      -  631   -
               /**
      -  632   -
                * The entire vendor/product group must be added (without a guess at
      -  633   -
                * version) because there is a CVE with a VS that only specifies
      -  634   -
                * vendor/product.
      -  635   -
                */
      -  636  2
               BROAD_MATCH
      -  637  
           }
      -  638   +  628  
       
      -  639   +  629  
           /**
      -  640   -
            * A simple object to hold an identifier and carry information about the
      -  641   -
            * confidence in the identifier.
      -  642   +  630   +
            * The confidence whether the identifier is an exact match, or a best guess.
      +  631  
            */
      -  643  16
           private static class IdentifierMatch implements Comparable<IdentifierMatch> {
      +  632  4
           private enum IdentifierConfidence {
      +  633   +
       
      +  634   +
               /**
      +  635   +
                * An exact match for the CPE.
      +  636   +
                */
      +  637  1
               EXACT_MATCH,
      +  638   +
               /**
      +  639   +
                * A best guess for the CPE.
      +  640   +
                */
      +  641  1
               BEST_GUESS,
      +  642   +
               /**
      +  643   +
                * The entire vendor/product group must be added (without a guess at
       644   -
       
      +
                * version) because there is a CVE with a VS that only specifies
       645   -
               /**
      +
                * vendor/product.
       646   -
                * Constructs an IdentifierMatch.
      -  647   -
                *
      +
                */
      +  647  1
               BROAD_MATCH
       648   -
                * @param type the type of identifier (such as CPE)
      +
           }
       649   -
                * @param value the value of the identifier
      +
       
       650   -
                * @param url the URL of the identifier
      +
           /**
       651   -
                * @param identifierConfidence the confidence in the identifier: best
      +
            * A simple object to hold an identifier and carry information about the
       652   -
                * guess or exact match
      +
            * confidence in the identifier.
       653   -
                * @param evidenceConfidence the confidence of the evidence used to find
      -  654   -
                * the identifier
      +
            */
      +  654  8
           private static class IdentifierMatch implements Comparable<IdentifierMatch> {
       655   -
                */
      -  656  22
               IdentifierMatch(String type, String value, String url, IdentifierConfidence identifierConfidence, Confidence evidenceConfidence) {
      -  657  22
                   this.identifier = new Identifier(type, value, url);
      -  658  22
                   this.confidence = identifierConfidence;
      -  659  22
                   this.evidenceConfidence = evidenceConfidence;
      -  660  22
               }
      +
       
      +  656   +
               /**
      +  657   +
                * Constructs an IdentifierMatch.
      +  658   +
                *
      +  659   +
                * @param type the type of identifier (such as CPE)
      +  660   +
                * @param value the value of the identifier
       661   -
               //<editor-fold defaultstate="collapsed" desc="Property implementations: evidenceConfidence, confidence, identifier">
      +
                * @param url the URL of the identifier
       662   -
               /**
      +
                * @param identifierConfidence the confidence in the identifier: best
       663   -
                * The confidence in the evidence used to identify this match.
      +
                * guess or exact match
       664   -
                */
      +
                * @param evidenceConfidence the confidence of the evidence used to find
       665   -
               private Confidence evidenceConfidence;
      +
                * the identifier
       666   -
       
      -  667   -
               /**
      -  668   -
                * Get the value of evidenceConfidence
      -  669   -
                *
      -  670   -
                * @return the value of evidenceConfidence
      -  671  
                */
      +  667  11
               IdentifierMatch(String type, String value, String url, IdentifierConfidence identifierConfidence, Confidence evidenceConfidence) {
      +  668  11
                   this.identifier = new Identifier(type, value, url);
      +  669  11
                   this.confidence = identifierConfidence;
      +  670  11
                   this.evidenceConfidence = evidenceConfidence;
      +  671  11
               }
       672   -
               public Confidence getEvidenceConfidence() {
      -  673  24
                   return evidenceConfidence;
      +
               //<editor-fold defaultstate="collapsed" desc="Property implementations: evidenceConfidence, confidence, identifier">
      +  673   +
               /**
       674   -
               }
      +
                * The confidence in the evidence used to identify this match.
       675   -
       
      +
                */
       676   -
               /**
      +
               private Confidence evidenceConfidence;
       677   -
                * Set the value of evidenceConfidence
      +
       
       678   -
                *
      +
               /**
       679   -
                * @param evidenceConfidence new value of evidenceConfidence
      +
                * Get the value of evidenceConfidence
       680   -
                */
      +
                *
       681   -
               public void setEvidenceConfidence(Confidence evidenceConfidence) {
      -  682  0
                   this.evidenceConfidence = evidenceConfidence;
      -  683  0
               }
      -  684   -
               /**
      +
                * @return the value of evidenceConfidence
      +  682   +
                */
      +  683   +
               public Confidence getEvidenceConfidence() {
      +  684  12
                   return evidenceConfidence;
       685   -
                * The confidence whether this is an exact match, or a best guess.
      +
               }
       686   -
                */
      +
       
       687   -
               private IdentifierConfidence confidence;
      +
               /**
       688   -
       
      +
                * Set the value of evidenceConfidence
       689   -
               /**
      +
                *
       690   -
                * Get the value of confidence.
      +
                * @param evidenceConfidence new value of evidenceConfidence
       691   -
                *
      +
                */
       692   -
                * @return the value of confidence
      -  693   -
                */
      -  694   -
               public IdentifierConfidence getConfidence() {
      -  695  28
                   return confidence;
      +
               public void setEvidenceConfidence(Confidence evidenceConfidence) {
      +  693  0
                   this.evidenceConfidence = evidenceConfidence;
      +  694  0
               }
      +  695   +
               /**
       696   -
               }
      +
                * The confidence whether this is an exact match, or a best guess.
       697   -
       
      +
                */
       698   -
               /**
      +
               private IdentifierConfidence confidence;
       699   -
                * Set the value of confidence.
      +
       
       700   -
                *
      +
               /**
       701   -
                * @param confidence new value of confidence
      +
                * Get the value of confidence.
       702   -
                */
      +
                *
       703   -
               public void setConfidence(IdentifierConfidence confidence) {
      -  704  0
                   this.confidence = confidence;
      -  705  0
               }
      -  706   -
               /**
      +
                * @return the value of confidence
      +  704   +
                */
      +  705   +
               public IdentifierConfidence getConfidence() {
      +  706  14
                   return confidence;
       707   -
                * The CPE identifier.
      -  708   -
                */
      -  709   -
               private Identifier identifier;
      -  710   -
       
      -  711   -
               /**
      -  712   -
                * Get the value of identifier.
      -  713   -
                *
      -  714   -
                * @return the value of identifier
      -  715   -
                */
      -  716   -
               public Identifier getIdentifier() {
      -  717  6
                   return identifier;
      -  718  
               }
      -  719   +  708  
       
      -  720   +  709  
               /**
      -  721   -
                * Set the value of identifier.
      -  722   +  710   +
                * Set the value of confidence.
      +  711  
                *
      -  723   -
                * @param identifier new value of identifier
      -  724   +  712   +
                * @param confidence new value of confidence
      +  713  
                */
      +  714   +
               public void setConfidence(IdentifierConfidence confidence) {
      +  715  0
                   this.confidence = confidence;
      +  716  0
               }
      +  717   +
               /**
      +  718   +
                * The CPE identifier.
      +  719   +
                */
      +  720   +
               private Identifier identifier;
      +  721   +
       
      +  722   +
               /**
      +  723   +
                * Get the value of identifier.
      +  724   +
                *
       725   -
               public void setIdentifier(Identifier identifier) {
      -  726  0
                   this.identifier = identifier;
      -  727  0
               }
      -  728   -
               //</editor-fold>
      +
                * @return the value of identifier
      +  726   +
                */
      +  727   +
               public Identifier getIdentifier() {
      +  728  3
                   return identifier;
       729   -
               //<editor-fold defaultstate="collapsed" desc="Standard implementations of toString, hashCode, and equals">
      +
               }
       730  
       
       731  
               /**
       732   -
                * Standard toString() implementation.
      +
                * Set the value of identifier.
       733  
                *
       734   -
                * @return the string representation of the object
      +
                * @param identifier new value of identifier
       735  
                */
       736   -
               @Override
      -  737   -
               public String toString() {
      -  738  0
                   return "IdentifierMatch{" + "evidenceConfidence=" + evidenceConfidence
      +
               public void setIdentifier(Identifier identifier) {
      +  737  0
                   this.identifier = identifier;
      +  738  0
               }
       739   -
                           + ", confidence=" + confidence + ", identifier=" + identifier + '}';
      +
               //</editor-fold>
       740   -
               }
      +
               //<editor-fold defaultstate="collapsed" desc="Standard implementations of toString, hashCode, and equals">
       741  
       
       742  
               /**
       743   -
                * Standard hashCode() implementation.
      +
                * Standard toString() implementation.
       744  
                *
       745   -
                * @return the hashCode
      +
                * @return the string representation of the object
       746  
                */
       747  
               @Override
       748   -
               public int hashCode() {
      -  749  0
                   int hash = 5;
      -  750  0
                   hash = 97 * hash + (this.evidenceConfidence != null ? this.evidenceConfidence.hashCode() : 0);
      -  751  0
                   hash = 97 * hash + (this.confidence != null ? this.confidence.hashCode() : 0);
      -  752  0
                   hash = 97 * hash + (this.identifier != null ? this.identifier.hashCode() : 0);
      -  753  0
                   return hash;
      +
               public String toString() {
      +  749  0
                   return "IdentifierMatch{" + "evidenceConfidence=" + evidenceConfidence
      +  750   +
                           + ", confidence=" + confidence + ", identifier=" + identifier + '}';
      +  751   +
               }
      +  752   +
       
      +  753   +
               /**
       754   -
               }
      +
                * Standard hashCode() implementation.
       755   -
       
      +
                *
       756   -
               /**
      +
                * @return the hashCode
       757   -
                * Standard equals implementation.
      +
                */
       758   -
                *
      +
               @Override
       759   -
                * @param obj the object to compare
      -  760   -
                * @return true if the objects are equal, otherwise false
      -  761   -
                */
      -  762   -
               @Override
      -  763   -
               public boolean equals(Object obj) {
      -  764  0
                   if (obj == null) {
      -  765  0
                       return false;
      +
               public int hashCode() {
      +  760  0
                   int hash = 5;
      +  761  0
                   hash = 97 * hash + (this.evidenceConfidence != null ? this.evidenceConfidence.hashCode() : 0);
      +  762  0
                   hash = 97 * hash + (this.confidence != null ? this.confidence.hashCode() : 0);
      +  763  0
                   hash = 97 * hash + (this.identifier != null ? this.identifier.hashCode() : 0);
      +  764  0
                   return hash;
      +  765   +
               }
       766   -
                   }
      -  767  0
                   if (getClass() != obj.getClass()) {
      -  768  0
                       return false;
      -  769   -
                   }
      -  770  0
                   final IdentifierMatch other = (IdentifierMatch) obj;
      -  771  0
                   if (this.evidenceConfidence != other.evidenceConfidence) {
      -  772  0
                       return false;
      -  773   -
                   }
      -  774  0
                   if (this.confidence != other.confidence) {
      -  775  0
                       return false;
      -  776   -
                   }
      -  777  0
                   if (this.identifier != other.identifier && (this.identifier == null || !this.identifier.equals(other.identifier))) {
      -  778  0
                       return false;
      -  779   -
                   }
      -  780  0
                   return true;
      -  781   -
               }
      -  782   -
               //</editor-fold>
      -  783  
       
      -  784   +  767  
               /**
      -  785   -
                * Standard implementation of compareTo that compares identifier
      -  786   -
                * confidence, evidence confidence, and then the identifier.
      -  787   +  768   +
                * Standard equals implementation.
      +  769  
                *
      -  788   -
                * @param o the IdentifierMatch to compare to
      -  789   -
                * @return the natural ordering of IdentifierMatch
      -  790   +  770   +
                * @param obj the object to compare
      +  771   +
                * @return true if the objects are equal, otherwise false
      +  772  
                */
      -  791   +  773  
               @Override
      -  792   -
               public int compareTo(IdentifierMatch o) {
      -  793  16
                   int conf = this.confidence.compareTo(o.confidence);
      -  794  16
                   if (conf == 0) {
      -  795  12
                       conf = this.evidenceConfidence.compareTo(o.evidenceConfidence);
      -  796  12
                       if (conf == 0) {
      -  797  4
                           conf = identifier.compareTo(o.identifier);
      -  798   -
                       }
      -  799   +  774   +
               public boolean equals(Object obj) {
      +  775  0
                   if (obj == null) {
      +  776  0
                       return false;
      +  777  
                   }
      -  800  16
                   return conf;
      -  801   +  778  0
                   if (getClass() != obj.getClass()) {
      +  779  0
                       return false;
      +  780   +
                   }
      +  781  0
                   final IdentifierMatch other = (IdentifierMatch) obj;
      +  782  0
                   if (this.evidenceConfidence != other.evidenceConfidence) {
      +  783  0
                       return false;
      +  784   +
                   }
      +  785  0
                   if (this.confidence != other.confidence) {
      +  786  0
                       return false;
      +  787   +
                   }
      +  788  0
                   if (this.identifier != other.identifier && (this.identifier == null || !this.identifier.equals(other.identifier))) {
      +  789  0
                       return false;
      +  790   +
                   }
      +  791  0
                   return true;
      +  792  
               }
      +  793   +
               //</editor-fold>
      +  794   +
       
      +  795   +
               /**
      +  796   +
                * Standard implementation of compareTo that compares identifier
      +  797   +
                * confidence, evidence confidence, and then the identifier.
      +  798   +
                *
      +  799   +
                * @param o the IdentifierMatch to compare to
      +  800   +
                * @return the natural ordering of IdentifierMatch
      +  801   +
                */
       802   -
           }
      +
               @Override
       803   +
               public int compareTo(IdentifierMatch o) {
      +  804  8
                   int conf = this.confidence.compareTo(o.confidence);
      +  805  8
                   if (conf == 0) {
      +  806  6
                       conf = this.evidenceConfidence.compareTo(o.evidenceConfidence);
      +  807  6
                       if (conf == 0) {
      +  808  2
                           conf = identifier.compareTo(o.identifier);
      +  809   +
                       }
      +  810   +
                   }
      +  811  8
                   return conf;
      +  812   +
               }
      +  813   +
           }
      +  814  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.CentralAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.CentralAnalyzer.html index 9133028c9..b82a68125 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.CentralAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.CentralAnalyzer.html @@ -12,7 +12,7 @@
       
      - +
      Classes in this File Line Coverage Branch Coverage Complexity
      CentralAnalyzer
      26%
      18/69
      10%
      3/30
      3.625
      CentralAnalyzer
      24%
      18/73
      10%
      3/30
      3.875
       
      @@ -88,237 +88,234 @@  35  
       import java.io.IOException;
       36   -
       import java.net.URL;
      +
       import java.net.MalformedURLException;
       37   -
       import java.util.List;
      +
       import java.net.URL;
       38   -
       import org.owasp.dependencycheck.utils.DownloadFailedException;
      +
       import java.util.List;
       39   -
       import org.owasp.dependencycheck.utils.Downloader;
      +
       import org.owasp.dependencycheck.exception.InitializationException;
       40   -
       import org.owasp.dependencycheck.utils.FileFilterBuilder;
      +
       import org.owasp.dependencycheck.utils.DownloadFailedException;
       41   -
       import org.owasp.dependencycheck.utils.InvalidSettingException;
      +
       import org.owasp.dependencycheck.utils.Downloader;
       42   -
       import org.owasp.dependencycheck.utils.Settings;
      +
       import org.owasp.dependencycheck.utils.FileFilterBuilder;
       43   -
       
      +
       import org.owasp.dependencycheck.utils.InvalidSettingException;
       44   -
       /**
      +
       import org.owasp.dependencycheck.utils.Settings;
       45   -
        * Analyzer which will attempt to locate a dependency, and the GAV information, by querying Central for the dependency's SHA-1
      +
       
       46   -
        * digest.
      +
       /**
       47   -
        *
      +
        * Analyzer which will attempt to locate a dependency, and the GAV information,
       48   -
        * @author colezlaw
      +
        * by querying Central for the dependency's SHA-1 digest.
       49   -
        */
      -  50  12
       public class CentralAnalyzer extends AbstractFileTypeAnalyzer {
      +
        *
      +  50   +
        * @author colezlaw
       51   -
       
      -  52   -
           /**
      +
        */
      +  52  6
       public class CentralAnalyzer extends AbstractFileTypeAnalyzer {
       53   -
            * The logger.
      +
       
       54   -
            */
      -  55  2
           private static final Logger LOGGER = LoggerFactory.getLogger(CentralAnalyzer.class);
      +
           /**
      +  55   +
            * The logger.
       56   -
       
      -  57   -
           /**
      +
            */
      +  57  1
           private static final Logger LOGGER = LoggerFactory.getLogger(CentralAnalyzer.class);
       58   -
            * The name of the analyzer.
      +
       
       59   -
            */
      +
           /**
       60   -
           private static final String ANALYZER_NAME = "Central Analyzer";
      +
            * The name of the analyzer.
       61   -
       
      +
            */
       62   -
           /**
      +
           private static final String ANALYZER_NAME = "Central Analyzer";
       63   -
            * The phase in which this analyzer runs.
      +
       
       64   -
            */
      -  65  2
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
      +
           /**
      +  65   +
            * The phase in which this analyzer runs.
       66   -
       
      -  67   -
           /**
      +
            */
      +  67  1
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
       68   -
            * The types of files on which this will work.
      +
       
       69   -
            */
      +
           /**
       70   -
           private static final String SUPPORTED_EXTENSIONS = "jar";
      +
            * The types of files on which this will work.
       71   -
       
      +
            */
       72   -
           /**
      +
           private static final String SUPPORTED_EXTENSIONS = "jar";
       73   -
            * The analyzer should be disabled if there are errors, so this is a flag to determine if such an error has occurred.
      +
       
       74   -
            */
      -  75  12
           private boolean errorFlag = false;
      +
           /**
      +  75   +
            * The analyzer should be disabled if there are errors, so this is a flag to
       76   -
       
      +
            * determine if such an error has occurred.
       77   -
           /**
      -  78   -
            * The searcher itself.
      +
            */
      +  78  6
           private boolean errorFlag = false;
       79   -
            */
      +
       
       80   -
           private CentralSearch searcher;
      +
           /**
       81   -
           /**
      +
            * The searcher itself.
       82   -
            * Field indicating if the analyzer is enabled.
      +
            */
       83   -
            */
      -  84  12
           private final boolean enabled = checkEnabled();
      +
           private CentralSearch searcher;
      +  84   +
           /**
       85   -
       
      +
            * Field indicating if the analyzer is enabled.
       86   -
           /**
      -  87   -
            * Determine whether to enable this analyzer or not.
      +
            */
      +  87  6
           private final boolean enabled = checkEnabled();
       88   -
            *
      +
       
       89   -
            * @return whether the analyzer should be enabled
      +
           /**
       90   -
            */
      +
            * Determine whether to enable this analyzer or not.
       91   -
           @Override
      +
            *
       92   -
           public boolean isEnabled() {
      -  93  0
               return enabled;
      +
            * @return whether the analyzer should be enabled
      +  93   +
            */
       94   -
           }
      +
           @Override
       95   -
       
      -  96   -
           /**
      +
           public boolean isEnabled() {
      +  96  0
               return enabled;
       97   -
            * Determines if this analyzer is enabled.
      +
           }
       98   -
            *
      +
       
       99   -
            * @return <code>true</code> if the analyzer is enabled; otherwise <code>false</code>
      +
           /**
       100   -
            */
      +
            * Determines if this analyzer is enabled.
       101   -
           private boolean checkEnabled() {
      -  102  12
               boolean retval = false;
      +
            *
      +  102   +
            * @return <code>true</code> if the analyzer is enabled; otherwise
       103   -
       
      +
            * <code>false</code>
       104   +
            */
      +  105   +
           private boolean checkEnabled() {
      +  106  6
               boolean retval = false;
      +  107   +
       
      +  108  
               try {
      -  105  12
                   if (Settings.getBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED)) {
      -  106  8
                       if (!Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED)
      -  107  0
                               || NexusAnalyzer.DEFAULT_URL.equals(Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL))) {
      -  108  8
                           LOGGER.debug("Enabling the Central analyzer");
      -  109  8
                           retval = true;
      -  110   +  109  6
                   if (Settings.getBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED)) {
      +  110  4
                       if (!Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED)
      +  111  0
                               || NexusAnalyzer.DEFAULT_URL.equals(Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL))) {
      +  112  4
                           LOGGER.debug("Enabling the Central analyzer");
      +  113  4
                           retval = true;
      +  114  
                       } else {
      -  111  0
                           LOGGER.info("Nexus analyzer is enabled, disabling the Central Analyzer");
      -  112   +  115  0
                           LOGGER.info("Nexus analyzer is enabled, disabling the Central Analyzer");
      +  116  
                       }
      -  113   +  117  
                   } else {
      -  114  4
                       LOGGER.info("Central analyzer disabled");
      -  115   +  118  2
                       LOGGER.info("Central analyzer disabled");
      +  119  
                   }
      -  116  0
               } catch (InvalidSettingException ise) {
      -  117  0
                   LOGGER.warn("Invalid setting. Disabling the Central analyzer");
      -  118  12
               }
      -  119  12
               return retval;
      -  120   -
           }
      -  121   -
       
      -  122   -
           /**
      -  123   -
            * Initializes the analyzer once before any analysis is performed.
      +  120  0
               } catch (InvalidSettingException ise) {
      +  121  0
                   LOGGER.warn("Invalid setting. Disabling the Central analyzer");
      +  122  6
               }
      +  123  6
               return retval;
       124   -
            *
      +
           }
       125   -
            * @throws Exception if there's an error during initialization
      +
       
       126   -
            */
      +
           /**
       127   -
           @Override
      +
            * Initializes the analyzer once before any analysis is performed.
       128   -
           public void initializeFileTypeAnalyzer() throws Exception {
      -  129  0
               LOGGER.debug("Initializing Central analyzer");
      -  130  0
               LOGGER.debug("Central analyzer enabled: {}", isEnabled());
      -  131  0
               if (isEnabled()) {
      -  132  0
                   final String searchUrl = Settings.getString(Settings.KEYS.ANALYZER_CENTRAL_URL);
      -  133  0
                   LOGGER.debug("Central Analyzer URL: {}", searchUrl);
      -  134  0
                   searcher = new CentralSearch(new URL(searchUrl));
      -  135   -
               }
      -  136  0
           }
      -  137   -
       
      +
            *
      +  129   +
            * @throws InitializationException if there's an error during initialization
      +  130   +
            */
      +  131   +
           @Override
      +  132   +
           public void initializeFileTypeAnalyzer() throws InitializationException {
      +  133  0
               LOGGER.debug("Initializing Central analyzer");
      +  134  0
               LOGGER.debug("Central analyzer enabled: {}", isEnabled());
      +  135  0
               if (isEnabled()) {
      +  136  0
                   final String searchUrl = Settings.getString(Settings.KEYS.ANALYZER_CENTRAL_URL);
      +  137  0
                   LOGGER.debug("Central Analyzer URL: {}", searchUrl);
       138   -
           /**
      -  139   -
            * Returns the analyzer's name.
      -  140   -
            *
      -  141   -
            * @return the name of the analyzer
      -  142   -
            */
      -  143   -
           @Override
      +
                   try {
      +  139  0
                       searcher = new CentralSearch(new URL(searchUrl));
      +  140  0
                   } catch (MalformedURLException ex) {
      +  141  0
                       setEnabled(false);
      +  142  0
                       throw new InitializationException("The configured URL to Maven Central is malformed: " + searchUrl, ex);
      +  143  0
                   }
       144   -
           public String getName() {
      -  145  32
               return ANALYZER_NAME;
      +
               }
      +  145  0
           }
       146   -
           }
      +
       
       147   -
       
      +
           /**
       148   -
           /**
      +
            * Returns the analyzer's name.
       149   -
            * Returns the key used in the properties file to to reference the analyzer's enabled property.
      -  150  
            *
      +  150   +
            * @return the name of the analyzer
       151   -
            * @return the analyzer's enabled property setting key.
      -  152  
            */
      -  153   +  152  
           @Override
      -  154   -
           protected String getAnalyzerEnabledSettingKey() {
      -  155  12
               return Settings.KEYS.ANALYZER_CENTRAL_ENABLED;
      -  156   +  153   +
           public String getName() {
      +  154  16
               return ANALYZER_NAME;
      +  155  
           }
      -  157   +  156  
       
      -  158   +  157  
           /**
      +  158   +
            * Returns the key used in the properties file to to reference the
       159   -
            * Returns the analysis phase under which the analyzer runs.
      +
            * analyzer's enabled property.
       160  
            *
       161   -
            * @return the phase under which the analyzer runs
      +
            * @return the analyzer's enabled property setting key.
       162  
            */
       163  
           @Override
       164   -
           public AnalysisPhase getAnalysisPhase() {
      -  165  8
               return ANALYSIS_PHASE;
      +
           protected String getAnalyzerEnabledSettingKey() {
      +  165  6
               return Settings.KEYS.ANALYZER_CENTRAL_ENABLED;
       166  
           }
       167   @@ -326,17 +323,18 @@  168  
           /**
       169   -
            * The file filter used to determine which files this analyzer supports.
      +
            * Returns the analysis phase under which the analyzer runs.
       170   -
            */
      -  171  2
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(SUPPORTED_EXTENSIONS).build();
      +
            *
      +  171   +
            * @return the phase under which the analyzer runs
       172   -
       
      +
            */
       173  
           @Override
       174   -
           protected FileFilter getFileFilter() {
      -  175  1718
               return FILTER;
      +
           public AnalysisPhase getAnalysisPhase() {
      +  175  4
               return ANALYSIS_PHASE;
       176  
           }
       177   @@ -344,88 +342,106 @@  178  
           /**
       179   -
            * Performs the analysis.
      +
            * The file filter used to determine which files this analyzer supports.
       180   -
            *
      -  181   -
            * @param dependency the dependency to analyze
      -  182   -
            * @param engine the engine
      -  183   -
            * @throws AnalysisException when there's an exception during analysis
      -  184  
            */
      -  185   +  181  1
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(SUPPORTED_EXTENSIONS).build();
      +  182   +
       
      +  183  
           @Override
      +  184   +
           protected FileFilter getFileFilter() {
      +  185  10
               return FILTER;
       186   -
           public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException {
      -  187  0
               if (errorFlag || !isEnabled()) {
      -  188  0
                   return;
      +
           }
      +  187   +
       
      +  188   +
           /**
       189   -
               }
      +
            * Performs the analysis.
       190   -
       
      +
            *
       191   -
               try {
      -  192  0
                   final List<MavenArtifact> mas = searcher.searchSha1(dependency.getSha1sum());
      -  193  0
                   final Confidence confidence = mas.size() > 1 ? Confidence.HIGH : Confidence.HIGHEST;
      -  194  0
                   for (MavenArtifact ma : mas) {
      -  195  0
                       LOGGER.debug("Central analyzer found artifact ({}) for dependency ({})", ma, dependency.getFileName());
      -  196  0
                       dependency.addAsEvidence("central", ma, confidence);
      -  197  0
                       boolean pomAnalyzed = false;
      -  198  0
                       for (Evidence e : dependency.getVendorEvidence()) {
      -  199  0
                           if ("pom".equals(e.getSource())) {
      -  200  0
                               pomAnalyzed = true;
      -  201  0
                               break;
      -  202   -
                           }
      -  203  0
                       }
      -  204  0
                       if (!pomAnalyzed && ma.getPomUrl() != null) {
      -  205  0
                           File pomFile = null;
      -  206   -
                           try {
      -  207  0
                               final File baseDir = Settings.getTempDirectory();
      -  208  0
                               pomFile = File.createTempFile("pom", ".xml", baseDir);
      -  209  0
                               if (!pomFile.delete()) {
      -  210  0
                                   LOGGER.warn("Unable to fetch pom.xml for {} from Central; "
      -  211  0
                                           + "this could result in undetected CPE/CVEs.", dependency.getFileName());
      -  212  0
                                   LOGGER.debug("Unable to delete temp file");
      -  213   -
                               }
      -  214  0
                               LOGGER.debug("Downloading {}", ma.getPomUrl());
      -  215  0
                               Downloader.fetchFile(new URL(ma.getPomUrl()), pomFile);
      -  216  0
                               PomUtils.analyzePOM(dependency, pomFile);
      -  217   +
            * @param dependency the dependency to analyze
      +  192   +
            * @param engine the engine
      +  193   +
            * @throws AnalysisException when there's an exception during analysis
      +  194   +
            */
      +  195   +
           @Override
      +  196   +
           public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException {
      +  197  0
               if (errorFlag || !isEnabled()) {
      +  198  0
                   return;
      +  199   +
               }
      +  200  
       
      -  218  0
                           } catch (DownloadFailedException ex) {
      -  219  0
                               LOGGER.warn("Unable to download pom.xml for {} from Central; "
      -  220  0
                                       + "this could result in undetected CPE/CVEs.", dependency.getFileName());
      -  221   -
                           } finally {
      -  222  0
                               if (pomFile != null && !FileUtils.deleteQuietly(pomFile)) {
      -  223  0
                                   pomFile.deleteOnExit();
      -  224   -
                               }
      -  225   +  201   +
               try {
      +  202  0
                   final List<MavenArtifact> mas = searcher.searchSha1(dependency.getSha1sum());
      +  203  0
                   final Confidence confidence = mas.size() > 1 ? Confidence.HIGH : Confidence.HIGHEST;
      +  204  0
                   for (MavenArtifact ma : mas) {
      +  205  0
                       LOGGER.debug("Central analyzer found artifact ({}) for dependency ({})", ma, dependency.getFileName());
      +  206  0
                       dependency.addAsEvidence("central", ma, confidence);
      +  207  0
                       boolean pomAnalyzed = false;
      +  208  0
                       for (Evidence e : dependency.getVendorEvidence()) {
      +  209  0
                           if ("pom".equals(e.getSource())) {
      +  210  0
                               pomAnalyzed = true;
      +  211  0
                               break;
      +  212  
                           }
      -  226   -
                       }
      +  213  0
                       }
      +  214  0
                       if (!pomAnalyzed && ma.getPomUrl() != null) {
      +  215  0
                           File pomFile = null;
      +  216   +
                           try {
      +  217  0
                               final File baseDir = Settings.getTempDirectory();
      +  218  0
                               pomFile = File.createTempFile("pom", ".xml", baseDir);
      +  219  0
                               if (!pomFile.delete()) {
      +  220  0
                                   LOGGER.warn("Unable to fetch pom.xml for {} from Central; "
      +  221  0
                                           + "this could result in undetected CPE/CVEs.", dependency.getFileName());
      +  222  0
                                   LOGGER.debug("Unable to delete temp file");
      +  223   +
                               }
      +  224  0
                               LOGGER.debug("Downloading {}", ma.getPomUrl());
      +  225  0
                               Downloader.fetchFile(new URL(ma.getPomUrl()), pomFile);
      +  226  0
                               PomUtils.analyzePOM(dependency, pomFile);
       227  
       
      -  228  0
                   }
      -  229  0
               } catch (IllegalArgumentException iae) {
      -  230  0
                   LOGGER.info("invalid sha1-hash on {}", dependency.getFileName());
      -  231  0
               } catch (FileNotFoundException fnfe) {
      -  232  0
                   LOGGER.debug("Artifact not found in repository: '{}", dependency.getFileName());
      -  233  0
               } catch (IOException ioe) {
      -  234  0
                   LOGGER.debug("Could not connect to Central search", ioe);
      -  235  0
                   errorFlag = true;
      -  236  0
               }
      -  237  0
           }
      -  238   +  228  0
                           } catch (DownloadFailedException ex) {
      +  229  0
                               LOGGER.warn("Unable to download pom.xml for {} from Central; "
      +  230  0
                                       + "this could result in undetected CPE/CVEs.", dependency.getFileName());
      +  231   +
                           } finally {
      +  232  0
                               if (pomFile != null && !FileUtils.deleteQuietly(pomFile)) {
      +  233  0
                                   pomFile.deleteOnExit();
      +  234   +
                               }
      +  235   +
                           }
      +  236   +
                       }
      +  237   +
       
      +  238  0
                   }
      +  239  0
               } catch (IllegalArgumentException iae) {
      +  240  0
                   LOGGER.info("invalid sha1-hash on {}", dependency.getFileName());
      +  241  0
               } catch (FileNotFoundException fnfe) {
      +  242  0
                   LOGGER.debug("Artifact not found in repository: '{}", dependency.getFileName());
      +  243  0
               } catch (IOException ioe) {
      +  244  0
                   LOGGER.debug("Could not connect to Central search", ioe);
      +  245  0
                   errorFlag = true;
      +  246  0
               }
      +  247  0
           }
      +  248  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.ComposerLockAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.ComposerLockAnalyzer.html index 3f5108ad8..7b79e3fda 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.ComposerLockAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.ComposerLockAnalyzer.html @@ -12,7 +12,7 @@
       
      - +
      Classes in this File Line Coverage Branch Coverage Complexity
      ComposerLockAnalyzer
      83%
      31/37
      75%
      3/4
      1.833
      ComposerLockAnalyzer
      78%
      32/41
      75%
      3/4
      2.167
       
      @@ -92,222 +92,236 @@  37  
       import java.security.MessageDigest;
       38   -
       
      +
       import java.security.NoSuchAlgorithmException;
       39   -
       /**
      +
       import org.owasp.dependencycheck.exception.InitializationException;
       40   -
        * Used to analyze a composer.lock file for a composer PHP app.
      +
       
       41   -
        *
      +
       /**
       42   -
        * @author colezlaw
      +
        * Used to analyze a composer.lock file for a composer PHP app.
       43   -
        */
      +
        *
       44   -
       @Experimental
      -  45  18
       public class ComposerLockAnalyzer extends AbstractFileTypeAnalyzer {
      +
        * @author colezlaw
      +  45   +
        */
       46   -
       
      -  47   -
           /**
      +
       @Experimental
      +  47  9
       public class ComposerLockAnalyzer extends AbstractFileTypeAnalyzer {
       48   -
            * The logger.
      +
       
       49   -
            */
      -  50  2
           private static final Logger LOGGER = LoggerFactory.getLogger(ComposerLockAnalyzer.class);
      +
           /**
      +  50   +
            * The logger.
       51   -
       
      -  52   -
           /**
      +
            */
      +  52  1
           private static final Logger LOGGER = LoggerFactory.getLogger(ComposerLockAnalyzer.class);
       53   -
            * The analyzer name.
      +
       
       54   -
            */
      +
           /**
       55   -
           private static final String ANALYZER_NAME = "Composer.lock analyzer";
      +
            * The analyzer name.
       56   -
       
      +
            */
       57   -
           /**
      +
           private static final String ANALYZER_NAME = "Composer.lock analyzer";
       58   -
            * composer.json.
      +
       
       59   -
            */
      +
           /**
       60   -
           private static final String COMPOSER_LOCK = "composer.lock";
      +
            * composer.json.
       61   -
       
      +
            */
       62   -
           /**
      +
           private static final String COMPOSER_LOCK = "composer.lock";
       63   -
            * The FileFilter.
      +
       
       64   -
            */
      -  65  2
           private static final FileFilter FILE_FILTER = FileFilterBuilder.newInstance().addFilenames(COMPOSER_LOCK).build();
      +
           /**
      +  65   +
            * The FileFilter.
       66   -
       
      -  67   -
           /**
      +
            */
      +  67  1
           private static final FileFilter FILE_FILTER = FileFilterBuilder.newInstance().addFilenames(COMPOSER_LOCK).build();
       68   -
            * Returns the FileFilter.
      +
       
       69   -
            *
      +
           /**
       70   -
            * @return the FileFilter
      +
            * Returns the FileFilter.
       71   -
            */
      +
            *
       72   -
           @Override
      +
            * @return the FileFilter
       73   -
           protected FileFilter getFileFilter() {
      -  74  1720
               return FILE_FILTER;
      -  75   -
           }
      -  76   -
       
      -  77   -
           /**
      -  78   -
            * Initializes the analyzer.
      -  79   -
            *
      -  80   -
            * @throws Exception thrown if an exception occurs getting an instance of SHA1
      -  81  
            */
      -  82   +  74  
           @Override
      -  83   -
           protected void initializeFileTypeAnalyzer() throws Exception {
      -  84  6
               sha1 = MessageDigest.getInstance("SHA1");
      -  85  6
           }
      -  86   +  75   +
           protected FileFilter getFileFilter() {
      +  76  11
               return FILE_FILTER;
      +  77   +
           }
      +  78  
       
      -  87   +  79  
           /**
      -  88   -
            * The MessageDigest for calculating a new digest for the new dependencies added.
      -  89   -
            */
      -  90  18
           private MessageDigest sha1 = null;
      -  91   -
       
      -  92   -
           /**
      -  93   -
            * Entry point for the analyzer.
      -  94   +  80   +
            * Initializes the analyzer.
      +  81  
            *
      +  82   +
            * @throws InitializationException thrown if an exception occurs getting an
      +  83   +
            * instance of SHA1
      +  84   +
            */
      +  85   +
           @Override
      +  86   +
           protected void initializeFileTypeAnalyzer() throws InitializationException {
      +  87   +
               try {
      +  88  3
                   sha1 = MessageDigest.getInstance("SHA1");
      +  89  0
               } catch (NoSuchAlgorithmException ex) {
      +  90  0
                   setEnabled(false);
      +  91  0
                   throw new InitializationException("Unable to create SHA1 MmessageDigest", ex);
      +  92  3
               }
      +  93  3
           }
      +  94   +
       
       95   -
            * @param dependency the dependency to analyze
      +
           /**
       96   -
            * @param engine the engine scanning
      +
            * The MessageDigest for calculating a new digest for the new dependencies
       97   -
            * @throws AnalysisException if there's a failure during analysis
      +
            * added.
       98  
            */
      -  99   -
           @Override
      +  99  9
           private MessageDigest sha1 = null;
       100   -
           protected void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException {
      -  101  2
               FileInputStream fis = null;
      +
       
      +  101   +
           /**
       102   +
            * Entry point for the analyzer.
      +  103   +
            *
      +  104   +
            * @param dependency the dependency to analyze
      +  105   +
            * @param engine the engine scanning
      +  106   +
            * @throws AnalysisException if there's a failure during analysis
      +  107   +
            */
      +  108   +
           @Override
      +  109   +
           protected void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException {
      +  110  1
               FileInputStream fis = null;
      +  111  
               try {
      -  103  2
                   fis = new FileInputStream(dependency.getActualFile());
      -  104  2
                   final ComposerLockParser clp = new ComposerLockParser(fis);
      -  105  2
                   LOGGER.info("Checking composer.lock file {}", dependency.getActualFilePath());
      -  106  2
                   clp.process();
      -  107  2
                   for (ComposerDependency dep : clp.getDependencies()) {
      -  108  60
                       final Dependency d = new Dependency(dependency.getActualFile());
      -  109  60
                       d.setDisplayFileName(String.format("%s:%s/%s", dependency.getDisplayFileName(), dep.getGroup(), dep.getProject()));
      -  110  60
                       final String filePath = String.format("%s:%s/%s", dependency.getFilePath(), dep.getGroup(), dep.getProject());
      -  111  60
                       d.setFilePath(filePath);
      -  112  60
                       d.setSha1sum(Checksum.getHex(sha1.digest(filePath.getBytes(Charset.defaultCharset()))));
      -  113  60
                       d.getVendorEvidence().addEvidence(COMPOSER_LOCK, "vendor", dep.getGroup(), Confidence.HIGHEST);
      -  114  60
                       d.getProductEvidence().addEvidence(COMPOSER_LOCK, "product", dep.getProject(), Confidence.HIGHEST);
      -  115  60
                       d.getVersionEvidence().addEvidence(COMPOSER_LOCK, "version", dep.getVersion(), Confidence.HIGHEST);
      -  116  60
                       LOGGER.info("Adding dependency {}", d);
      -  117  60
                       engine.getDependencies().add(d);
      -  118  60
                   }
      -  119  0
               } catch (FileNotFoundException fnfe) {
      -  120  0
                   LOGGER.warn("Error opening dependency {}", dependency.getActualFilePath());
      -  121  0
               } catch (ComposerException ce) {
      -  122  0
                   LOGGER.warn("Error parsing composer.json {}", dependency.getActualFilePath(), ce);
      -  123   +  112  1
                   fis = new FileInputStream(dependency.getActualFile());
      +  113  1
                   final ComposerLockParser clp = new ComposerLockParser(fis);
      +  114  1
                   LOGGER.info("Checking composer.lock file {}", dependency.getActualFilePath());
      +  115  1
                   clp.process();
      +  116  1
                   for (ComposerDependency dep : clp.getDependencies()) {
      +  117  30
                       final Dependency d = new Dependency(dependency.getActualFile());
      +  118  30
                       d.setDisplayFileName(String.format("%s:%s/%s", dependency.getDisplayFileName(), dep.getGroup(), dep.getProject()));
      +  119  30
                       final String filePath = String.format("%s:%s/%s", dependency.getFilePath(), dep.getGroup(), dep.getProject());
      +  120  30
                       d.setFilePath(filePath);
      +  121  30
                       d.setSha1sum(Checksum.getHex(sha1.digest(filePath.getBytes(Charset.defaultCharset()))));
      +  122  30
                       d.getVendorEvidence().addEvidence(COMPOSER_LOCK, "vendor", dep.getGroup(), Confidence.HIGHEST);
      +  123  30
                       d.getProductEvidence().addEvidence(COMPOSER_LOCK, "product", dep.getProject(), Confidence.HIGHEST);
      +  124  30
                       d.getVersionEvidence().addEvidence(COMPOSER_LOCK, "version", dep.getVersion(), Confidence.HIGHEST);
      +  125  30
                       LOGGER.info("Adding dependency {}", d);
      +  126  30
                       engine.getDependencies().add(d);
      +  127  30
                   }
      +  128  0
               } catch (FileNotFoundException fnfe) {
      +  129  0
                   LOGGER.warn("Error opening dependency {}", dependency.getActualFilePath());
      +  130  0
               } catch (ComposerException ce) {
      +  131  0
                   LOGGER.warn("Error parsing composer.json {}", dependency.getActualFilePath(), ce);
      +  132  
               } finally {
      -  124  2
                   if (fis != null) {
      -  125   -
                       try {
      -  126  2
                           fis.close();
      -  127  0
                       } catch (Exception e) {
      -  128  0
                           LOGGER.debug("Unable to close file", e);
      -  129  2
                       }
      -  130   -
                   }
      -  131   -
               }
      -  132  2
           }
      -  133   -
       
      +  133  1
                   if (fis != null) {
       134   -
           /**
      -  135   -
            * Gets the key to determine whether the analyzer is enabled.
      -  136   -
            *
      -  137   -
            * @return the key specifying whether the analyzer is enabled
      -  138   -
            */
      +
                       try {
      +  135  1
                           fis.close();
      +  136  0
                       } catch (Exception e) {
      +  137  0
                           LOGGER.debug("Unable to close file", e);
      +  138  1
                       }
       139   -
           @Override
      +
                   }
       140   -
           protected String getAnalyzerEnabledSettingKey() {
      -  141  18
               return Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED;
      +
               }
      +  141  1
           }
       142   -
           }
      +
       
       143   -
       
      +
           /**
       144   -
           /**
      +
            * Gets the key to determine whether the analyzer is enabled.
       145   -
            * Returns the analyzer's name.
      +
            *
       146   -
            *
      +
            * @return the key specifying whether the analyzer is enabled
       147   -
            * @return the analyzer's name
      +
            */
       148   -
            */
      +
           @Override
       149   -
           @Override
      -  150   -
           public String getName() {
      -  151  30
               return ANALYZER_NAME;
      +
           protected String getAnalyzerEnabledSettingKey() {
      +  150  9
               return Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED;
      +  151   +
           }
       152   -
           }
      -  153  
       
      -  154   +  153  
           /**
      +  154   +
            * Returns the analyzer's name.
       155   -
            * Returns the phase this analyzer should run under.
      -  156  
            *
      +  156   +
            * @return the analyzer's name
       157   -
            * @return the analysis phase
      -  158  
            */
      -  159   +  158  
           @Override
      -  160   -
           public AnalysisPhase getAnalysisPhase() {
      -  161  8
               return AnalysisPhase.INFORMATION_COLLECTION;
      -  162   +  159   +
           public String getName() {
      +  160  15
               return ANALYZER_NAME;
      +  161  
           }
      +  162   +
       
       163   +
           /**
      +  164   +
            * Returns the phase this analyzer should run under.
      +  165   +
            *
      +  166   +
            * @return the analysis phase
      +  167   +
            */
      +  168   +
           @Override
      +  169   +
           public AnalysisPhase getAnalysisPhase() {
      +  170  4
               return AnalysisPhase.INFORMATION_COLLECTION;
      +  171   +
           }
      +  172  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.CpeSuppressionAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.CpeSuppressionAnalyzer.html index bee0838f0..bab0ed12e 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.CpeSuppressionAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.CpeSuppressionAnalyzer.html @@ -62,7 +62,7 @@  22  
       import org.owasp.dependencycheck.dependency.Dependency;
       23   -
       import org.owasp.dependencycheck.suppression.SuppressionRule;
      +
       import org.owasp.dependencycheck.xml.suppression.SuppressionRule;
       24  
       
       25   @@ -77,7 +77,7 @@
        * @author Jeremy Long
       30  
        */
      -  31  12
       public class CpeSuppressionAnalyzer extends AbstractSuppressionAnalyzer {
      +  31  6
       public class CpeSuppressionAnalyzer extends AbstractSuppressionAnalyzer {
       32  
       
       33   @@ -96,7 +96,7 @@
            * The phase that this analyzer is intended to run in.
       40  
            */
      -  41  2
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.POST_IDENTIFIER_ANALYSIS;
      +  41  1
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.POST_IDENTIFIER_ANALYSIS;
       42  
       
       43   @@ -113,7 +113,7 @@
           @Override
       49  
           public String getName() {
      -  50  32
               return ANALYZER_NAME;
      +  50  16
               return ANALYZER_NAME;
       51  
           }
       52   @@ -132,7 +132,7 @@
           @Override
       59  
           public AnalysisPhase getAnalysisPhase() {
      -  60  8
               return ANALYSIS_PHASE;
      +  60  4
               return ANALYSIS_PHASE;
       61  
           }
       62   @@ -145,20 +145,20 @@
           public void analyze(final Dependency dependency, final Engine engine) throws AnalysisException {
       66  
       
      -  67  8
               if (getRules() == null || getRules().size() <= 0) {
      +  67  4
               if (getRules() == null || getRules().size() <= 0) {
       68  0
                   return;
       69  
               }
       70  
       
      -  71  8
               for (final SuppressionRule rule : getRules()) {
      -  72  440
                   rule.process(dependency);
      -  73  440
               }
      -  74  8
           }
      +  71  4
               for (final SuppressionRule rule : getRules()) {
      +  72  224
                   rule.process(dependency);
      +  73  224
               }
      +  74  4
           }
       75  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.DependencyBundlingAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.DependencyBundlingAnalyzer.html index ac30c27e3..f74c05d1f 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.DependencyBundlingAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.DependencyBundlingAnalyzer.html @@ -113,7 +113,7 @@
        * @author Jeremy Long
       48  
        */
      -  49  20
       public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Analyzer {
      +  49  10
       public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Analyzer {
       50  
       
       51   @@ -122,7 +122,7 @@
            * The Logger.
       53  
            */
      -  54  2
           private static final Logger LOGGER = LoggerFactory.getLogger(DependencyBundlingAnalyzer.class);
      +  54  1
           private static final Logger LOGGER = LoggerFactory.getLogger(DependencyBundlingAnalyzer.class);
       55  
       
       56   @@ -133,14 +133,14 @@
            * A pattern for obtaining the first part of a filename.
       59  
            */
      -  60  2
           private static final Pattern STARTING_TEXT_PATTERN = Pattern.compile("^[a-zA-Z0-9]*");
      +  60  1
           private static final Pattern STARTING_TEXT_PATTERN = Pattern.compile("^[a-zA-Z0-9]*");
       61  
           /**
       62  
            * a flag indicating if this analyzer has run. This analyzer only runs once.
       63  
            */
      -  64  20
           private boolean analyzed = false;
      +  64  10
           private boolean analyzed = false;
       65  
           //</editor-fold>
       66   @@ -159,7 +159,7 @@
            * The phase that this analyzer is intended to run in.
       73  
            */
      -  74  2
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_FINDING_ANALYSIS;
      +  74  1
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_FINDING_ANALYSIS;
       75  
       
       76   @@ -176,7 +176,7 @@
           @Override
       82  
           public String getName() {
      -  83  34
               return ANALYZER_NAME;
      +  83  17
               return ANALYZER_NAME;
       84  
           }
       85   @@ -195,7 +195,7 @@
           @Override
       92  
           public AnalysisPhase getAnalysisPhase() {
      -  93  10
               return ANALYSIS_PHASE;
      +  93  5
               return ANALYSIS_PHASE;
       94  
           }
       95   @@ -226,19 +226,19 @@
           @Override
       108  
           public void analyze(Dependency ignore, Engine engine) throws AnalysisException {
      -  109  8
               if (!analyzed) {
      -  110  4
                   analyzed = true;
      -  111  4
                   final Set<Dependency> dependenciesToRemove = new HashSet<Dependency>();
      -  112  4
                   final ListIterator<Dependency> mainIterator = engine.getDependencies().listIterator();
      +  109  4
               if (!analyzed) {
      +  110  2
                   analyzed = true;
      +  111  2
                   final Set<Dependency> dependenciesToRemove = new HashSet<Dependency>();
      +  112  2
                   final ListIterator<Dependency> mainIterator = engine.getDependencies().listIterator();
       113  
                   //for (Dependency nextDependency : engine.getDependencies()) {
      -  114  12
                   while (mainIterator.hasNext()) {
      -  115  8
                       final Dependency dependency = mainIterator.next();
      -  116  8
                       if (mainIterator.hasNext() && !dependenciesToRemove.contains(dependency)) {
      -  117  4
                           final ListIterator<Dependency> subIterator = engine.getDependencies().listIterator(mainIterator.nextIndex());
      -  118  8
                           while (subIterator.hasNext()) {
      -  119  4
                               final Dependency nextDependency = subIterator.next();
      -  120  4
                               if (hashesMatch(dependency, nextDependency) && !containedInWar(dependency.getFilePath())
      +  114  6
                   while (mainIterator.hasNext()) {
      +  115  4
                       final Dependency dependency = mainIterator.next();
      +  116  4
                       if (mainIterator.hasNext() && !dependenciesToRemove.contains(dependency)) {
      +  117  2
                           final ListIterator<Dependency> subIterator = engine.getDependencies().listIterator(mainIterator.nextIndex());
      +  118  4
                           while (subIterator.hasNext()) {
      +  119  2
                               final Dependency nextDependency = subIterator.next();
      +  120  2
                               if (hashesMatch(dependency, nextDependency) && !containedInWar(dependency.getFilePath())
       121  0
                                       && !containedInWar(nextDependency.getFilePath())) {
       122  0
                                   if (firstPathIsShortest(dependency.getFilePath(), nextDependency.getFilePath())) {
       123  0
                                       mergeDependencies(dependency, nextDependency, dependenciesToRemove);
      @@ -248,7 +248,7 @@  126  0
                                       break; //since we merged into the next dependency - skip forward to the next in mainIterator
       127  
                                   }
      -  128  4
                               } else if (isShadedJar(dependency, nextDependency)) {
      +  128  2
                               } else if (isShadedJar(dependency, nextDependency)) {
       129  0
                                   if (dependency.getFileName().toLowerCase().endsWith("pom.xml")) {
       130  0
                                       mergeDependencies(nextDependency, dependency, dependenciesToRemove);
       131  0
                                       nextDependency.getRelatedDependencies().remove(dependency);
      @@ -259,7 +259,7 @@  135  0
                                       dependency.getRelatedDependencies().remove(nextDependency);
       136  
                                   }
      -  137  4
                               } else if (cpeIdentifiersMatch(dependency, nextDependency)
      +  137  2
                               } else if (cpeIdentifiersMatch(dependency, nextDependency)
       138  0
                                       && hasSameBasePath(dependency, nextDependency)
       139  0
                                       && fileNameMatch(dependency, nextDependency)) {
       140  0
                                   if (isCore(dependency, nextDependency)) {
      @@ -270,7 +270,7 @@  144  0
                                       break; //since we merged into the next dependency - skip forward to the next in mainIterator
       145  
                                   }
      -  146  4
                               } else if (isSameRubyGem(dependency, nextDependency)) {
      +  146  2
                               } else if (isSameRubyGem(dependency, nextDependency)) {
       147  0
                                   final Dependency main = getMainGemspecDependency(dependency, nextDependency);
       148  0
                                   if (main == dependency) {
       149  0
                                       mergeDependencies(dependency, nextDependency, dependenciesToRemove);
      @@ -282,18 +282,18 @@
                                   }
       154  
                               }
      -  155  4
                           }
      +  155  2
                           }
       156  
                       }
      -  157  8
                   }
      +  157  4
                   }
       158  
                   //removing dependencies here as ensuring correctness and avoiding ConcurrentUpdateExceptions
       159  
                   // was difficult because of the inner iterator.
      -  160  4
                   engine.getDependencies().removeAll(dependenciesToRemove);
      +  160  2
                   engine.getDependencies().removeAll(dependenciesToRemove);
       161  
               }
      -  162  8
           }
      +  162  4
           }
       163  
       
       164   @@ -447,27 +447,27 @@
            */
       256  
           private boolean cpeIdentifiersMatch(Dependency dependency1, Dependency dependency2) {
      -  257  4
               if (dependency1 == null || dependency1.getIdentifiers() == null
      -  258  4
                       || dependency2 == null || dependency2.getIdentifiers() == null) {
      +  257  2
               if (dependency1 == null || dependency1.getIdentifiers() == null
      +  258  2
                       || dependency2 == null || dependency2.getIdentifiers() == null) {
       259  0
                   return false;
       260  
               }
      -  261  4
               boolean matches = false;
      -  262  4
               int cpeCount1 = 0;
      -  263  4
               int cpeCount2 = 0;
      -  264  4
               for (Identifier i : dependency1.getIdentifiers()) {
      +  261  2
               boolean matches = false;
      +  262  2
               int cpeCount1 = 0;
      +  263  2
               int cpeCount2 = 0;
      +  264  2
               for (Identifier i : dependency1.getIdentifiers()) {
       265  0
                   if ("cpe".equals(i.getType())) {
       266  0
                       cpeCount1 += 1;
       267  
                   }
       268  0
               }
      -  269  4
               for (Identifier i : dependency2.getIdentifiers()) {
      -  270  6
                   if ("cpe".equals(i.getType())) {
      -  271  6
                       cpeCount2 += 1;
      +  269  2
               for (Identifier i : dependency2.getIdentifiers()) {
      +  270  3
                   if ("cpe".equals(i.getType())) {
      +  271  3
                       cpeCount2 += 1;
       272  
                   }
      -  273  6
               }
      -  274  4
               if (cpeCount1 > 0 && cpeCount1 == cpeCount2) {
      +  273  3
               }
      +  274  2
               if (cpeCount1 > 0 && cpeCount1 == cpeCount2) {
       275  0
                   for (Identifier i : dependency1.getIdentifiers()) {
       276  0
                       if ("cpe".equals(i.getType())) {
       277  0
                           matches |= dependency2.getIdentifiers().contains(i);
      @@ -480,8 +480,8 @@  282  0
                   }
       283  
               }
      -  284  4
               LOGGER.debug("IdentifiersMatch={} ({}, {})", matches, dependency1.getFileName(), dependency2.getFileName());
      -  285  4
               return matches;
      +  284  2
               LOGGER.debug("IdentifiersMatch={} ({}, {})", matches, dependency1.getFileName(), dependency2.getFileName());
      +  285  2
               return matches;
       286  
           }
       287   @@ -562,12 +562,12 @@
            */
       335  
           private boolean isSameRubyGem(Dependency dependency1, Dependency dependency2) {
      -  336  4
               if (dependency1 == null || dependency2 == null
      -  337  4
                       || !dependency1.getFileName().endsWith(".gemspec")
      +  336  2
               if (dependency1 == null || dependency2 == null
      +  337  2
                       || !dependency1.getFileName().endsWith(".gemspec")
       338  0
                       || !dependency2.getFileName().endsWith(".gemspec")
       339  0
                       || dependency1.getPackagePath() == null
       340  0
                       || dependency2.getPackagePath() == null) {
      -  341  4
                   return false;
      +  341  2
                   return false;
       342  
               }
       343  0
               if (dependency1.getPackagePath().equalsIgnoreCase(dependency2.getPackagePath())) {
      @@ -652,20 +652,20 @@
            */
       388  
           boolean isCore(Dependency left, Dependency right) {
      -  389  4
               final String leftName = left.getFileName().toLowerCase();
      -  390  4
               final String rightName = right.getFileName().toLowerCase();
      +  389  2
               final String leftName = left.getFileName().toLowerCase();
      +  390  2
               final String rightName = right.getFileName().toLowerCase();
       391  
       
       392  
               final boolean returnVal;
      -  393  4
               if (!rightName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+") && leftName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+")
      -  394  4
                       || rightName.contains("core") && !leftName.contains("core")
      -  395  4
                       || rightName.contains("kernel") && !leftName.contains("kernel")) {
      +  393  2
               if (!rightName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+") && leftName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+")
      +  394  2
                       || rightName.contains("core") && !leftName.contains("core")
      +  395  2
                       || rightName.contains("kernel") && !leftName.contains("kernel")) {
       396  0
                   returnVal = false;
      -  397  4
               } else if (rightName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+") && !leftName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+")
      -  398  2
                       || !rightName.contains("core") && leftName.contains("core")
      -  399  2
                       || !rightName.contains("kernel") && leftName.contains("kernel")) {
      -  400  4
                   returnVal = true;
      +  397  2
               } else if (rightName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+") && !leftName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+")
      +  398  1
                       || !rightName.contains("core") && leftName.contains("core")
      +  399  1
                       || !rightName.contains("kernel") && leftName.contains("kernel")) {
      +  400  2
                   returnVal = true;
       401  
       //        } else if (leftName.matches(".*struts2\\-core.*") && rightName.matches(".*xwork\\-core.*")) {
       402   @@ -697,8 +697,8 @@  415  0
                   returnVal = leftName.length() <= rightName.length();
       416  
               }
      -  417  4
               LOGGER.debug("IsCore={} ({}, {})", returnVal, left.getFileName(), right.getFileName());
      -  418  4
               return returnVal;
      +  417  2
               LOGGER.debug("IsCore={} ({}, {})", returnVal, left.getFileName(), right.getFileName());
      +  418  2
               return returnVal;
       419  
           }
       420   @@ -723,11 +723,11 @@
            */
       430  
           private boolean hashesMatch(Dependency dependency1, Dependency dependency2) {
      -  431  4
               if (dependency1 == null || dependency2 == null || dependency1.getSha1sum() == null || dependency2.getSha1sum() == null) {
      +  431  2
               if (dependency1 == null || dependency2 == null || dependency1.getSha1sum() == null || dependency2.getSha1sum() == null) {
       432  0
                   return false;
       433  
               }
      -  434  4
               return dependency1.getSha1sum().equals(dependency2.getSha1sum());
      +  434  2
               return dependency1.getSha1sum().equals(dependency2.getSha1sum());
       435  
           }
       436   @@ -752,15 +752,15 @@
            */
       446  
           private boolean isShadedJar(Dependency dependency, Dependency nextDependency) {
      -  447  4
               final String mainName = dependency.getFileName().toLowerCase();
      -  448  4
               final String nextName = nextDependency.getFileName().toLowerCase();
      -  449  4
               if (mainName.endsWith(".jar") && nextName.endsWith("pom.xml")) {
      +  447  2
               final String mainName = dependency.getFileName().toLowerCase();
      +  448  2
               final String nextName = nextDependency.getFileName().toLowerCase();
      +  449  2
               if (mainName.endsWith(".jar") && nextName.endsWith("pom.xml")) {
       450  0
                   return dependency.getIdentifiers().containsAll(nextDependency.getIdentifiers());
      -  451  4
               } else if (nextName.endsWith(".jar") && mainName.endsWith("pom.xml")) {
      +  451  2
               } else if (nextName.endsWith(".jar") && mainName.endsWith("pom.xml")) {
       452  0
                   return nextDependency.getIdentifiers().containsAll(dependency.getIdentifiers());
       453  
               }
      -  454  4
               return false;
      +  454  2
               return false;
       455  
           }
       456   @@ -785,17 +785,17 @@
            */
       466  
           protected boolean firstPathIsShortest(String left, String right) {
      -  467  10
               final String leftPath = left.replace('\\', '/');
      -  468  10
               final String rightPath = right.replace('\\', '/');
      +  467  5
               final String leftPath = left.replace('\\', '/');
      +  468  5
               final String rightPath = right.replace('\\', '/');
       469  
       
      -  470  10
               final int leftCount = countChar(leftPath, '/');
      -  471  10
               final int rightCount = countChar(rightPath, '/');
      -  472  10
               if (leftCount == rightCount) {
      -  473  6
                   return leftPath.compareTo(rightPath) <= 0;
      +  470  5
               final int leftCount = countChar(leftPath, '/');
      +  471  5
               final int rightCount = countChar(rightPath, '/');
      +  472  5
               if (leftCount == rightCount) {
      +  473  3
                   return leftPath.compareTo(rightPath) <= 0;
       474  
               } else {
      -  475  4
                   return leftCount < rightCount;
      +  475  2
                   return leftCount < rightCount;
       476  
               }
       477   @@ -818,16 +818,16 @@
            */
       486  
           private int countChar(String string, char c) {
      -  487  20
               int count = 0;
      -  488  20
               final int max = string.length();
      -  489  232
               for (int i = 0; i < max; i++) {
      -  490  212
                   if (c == string.charAt(i)) {
      -  491  56
                       count++;
      +  487  10
               int count = 0;
      +  488  10
               final int max = string.length();
      +  489  116
               for (int i = 0; i < max; i++) {
      +  490  106
                   if (c == string.charAt(i)) {
      +  491  28
                       count++;
       492  
                   }
       493  
               }
      -  494  20
               return count;
      +  494  10
               return count;
       495  
           }
       496   @@ -853,6 +853,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.Experimental.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.Experimental.html index 9ec7c871f..7ec00def3 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.Experimental.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.Experimental.html @@ -87,6 +87,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.FalsePositiveAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.FalsePositiveAnalyzer.html index 61c37d06d..9c009e3f7 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.FalsePositiveAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.FalsePositiveAnalyzer.html @@ -105,7 +105,7 @@
        * @author Jeremy Long
       44  
        */
      -  45  18
       public class FalsePositiveAnalyzer extends AbstractAnalyzer {
      +  45  9
       public class FalsePositiveAnalyzer extends AbstractAnalyzer {
       46  
       
       47   @@ -114,7 +114,7 @@
            * The Logger.
       49  
            */
      -  50  2
           private static final Logger LOGGER = LoggerFactory.getLogger(FalsePositiveAnalyzer.class);
      +  50  1
           private static final Logger LOGGER = LoggerFactory.getLogger(FalsePositiveAnalyzer.class);
       51  
       
       52   @@ -123,7 +123,7 @@
            * The file filter used to find DLL and EXE.
       54  
            */
      -  55  2
           private static final FileFilter DLL_EXE_FILTER = FileFilterBuilder.newInstance().addExtensions("dll", "exe").build();
      +  55  1
           private static final FileFilter DLL_EXE_FILTER = FileFilterBuilder.newInstance().addExtensions("dll", "exe").build();
       56  
       
       57   @@ -142,7 +142,7 @@
            * The phase that this analyzer is intended to run in.
       64  
            */
      -  65  2
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.POST_IDENTIFIER_ANALYSIS;
      +  65  1
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.POST_IDENTIFIER_ANALYSIS;
       66  
       
       67   @@ -159,7 +159,7 @@
           @Override
       73  
           public String getName() {
      -  74  34
               return ANALYZER_NAME;
      +  74  17
               return ANALYZER_NAME;
       75  
           }
       76   @@ -178,7 +178,7 @@
           @Override
       83  
           public AnalysisPhase getAnalysisPhase() {
      -  84  10
               return ANALYSIS_PHASE;
      +  84  5
               return ANALYSIS_PHASE;
       85  
           }
       86   @@ -203,14 +203,14 @@
           @Override
       96  
           public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
      -  97  10
               removeJreEntries(dependency);
      -  98  10
               removeBadMatches(dependency);
      -  99  10
               removeBadSpringMatches(dependency);
      -  100  10
               removeWrongVersionMatches(dependency);
      -  101  10
               removeSpuriousCPE(dependency);
      -  102  10
               removeDuplicativeEntriesFromJar(dependency, engine);
      -  103  10
               addFalseNegativeCPEs(dependency);
      -  104  10
           }
      +  97  5
               removeJreEntries(dependency);
      +  98  5
               removeBadMatches(dependency);
      +  99  5
               removeBadSpringMatches(dependency);
      +  100  5
               removeWrongVersionMatches(dependency);
      +  101  5
               removeSpuriousCPE(dependency);
      +  102  5
               removeDuplicativeEntriesFromJar(dependency, engine);
      +  103  5
               addFalseNegativeCPEs(dependency);
      +  104  5
           }
       105  
       
       106   @@ -225,9 +225,9 @@
            */
       111  
           private void removeBadSpringMatches(Dependency dependency) {
      -  112  10
               String mustContain = null;
      -  113  10
               for (Identifier i : dependency.getIdentifiers()) {
      -  114  6
                   if ("maven".contains(i.getType())) {
      +  112  5
               String mustContain = null;
      +  113  5
               for (Identifier i : dependency.getIdentifiers()) {
      +  114  3
                   if ("maven".contains(i.getType())) {
       115  0
                       if (i.getValue() != null && i.getValue().startsWith("org.springframework.")) {
       116  0
                           final int endPoint = i.getValue().indexOf(':', 19);
       117  0
                           if (endPoint >= 0) {
      @@ -239,8 +239,8 @@
                       }
       122  
                   }
      -  123  6
               }
      -  124  10
               if (mustContain != null) {
      +  123  3
               }
      +  124  5
               if (mustContain != null) {
       125  0
                   final Iterator<Identifier> itr = dependency.getIdentifiers().iterator();
       126  0
                   while (itr.hasNext()) {
       127  0
                       final Identifier i = itr.next();
      @@ -256,7 +256,7 @@  135  0
                   }
       136  
               }
      -  137  10
           }
      +  137  5
           }
       138  
       
       139   @@ -299,27 +299,27 @@
           @SuppressWarnings("null")
       158  
           private void removeSpuriousCPE(Dependency dependency) {
      -  159  10
               final List<Identifier> ids = new ArrayList<Identifier>(dependency.getIdentifiers());
      -  160  10
               Collections.sort(ids);
      -  161  10
               final ListIterator<Identifier> mainItr = ids.listIterator();
      -  162  16
               while (mainItr.hasNext()) {
      -  163  6
                   final Identifier currentId = mainItr.next();
      -  164  6
                   final VulnerableSoftware currentCpe = parseCpe(currentId.getType(), currentId.getValue());
      -  165  6
                   if (currentCpe == null) {
      +  159  5
               final List<Identifier> ids = new ArrayList<Identifier>(dependency.getIdentifiers());
      +  160  5
               Collections.sort(ids);
      +  161  5
               final ListIterator<Identifier> mainItr = ids.listIterator();
      +  162  8
               while (mainItr.hasNext()) {
      +  163  3
                   final Identifier currentId = mainItr.next();
      +  164  3
                   final VulnerableSoftware currentCpe = parseCpe(currentId.getType(), currentId.getValue());
      +  165  3
                   if (currentCpe == null) {
       166  0
                       continue;
       167  
                   }
      -  168  6
                   final ListIterator<Identifier> subItr = ids.listIterator(mainItr.nextIndex());
      -  169  12
                   while (subItr.hasNext()) {
      -  170  6
                       final Identifier nextId = subItr.next();
      -  171  6
                       final VulnerableSoftware nextCpe = parseCpe(nextId.getType(), nextId.getValue());
      -  172  6
                       if (nextCpe == null) {
      +  168  3
                   final ListIterator<Identifier> subItr = ids.listIterator(mainItr.nextIndex());
      +  169  6
                   while (subItr.hasNext()) {
      +  170  3
                       final Identifier nextId = subItr.next();
      +  171  3
                       final VulnerableSoftware nextCpe = parseCpe(nextId.getType(), nextId.getValue());
      +  172  3
                       if (nextCpe == null) {
       173  0
                           continue;
       174  
                       }
       175  
                       //TODO fix the version problem below
      -  176  6
                       if (currentCpe.getVendor().equals(nextCpe.getVendor())) {
      +  176  3
                       if (currentCpe.getVendor().equals(nextCpe.getVendor())) {
       177  0
                           if (currentCpe.getProduct().equals(nextCpe.getProduct())) {
       178  
                               // see if one is contained in the other.. remove the contained one from dependency.getIdentifier
      @@ -350,16 +350,16 @@
                           }
       198  
                       }
      -  199  6
                   }
      -  200  6
               }
      -  201  10
           }
      +  199  3
                   }
      +  200  3
               }
      +  201  5
           }
       202  
           /**
       203  
            * Regex to identify core java libraries and a few other commonly misidentified ones.
       204  
            */
      -  205  2
           public static final Pattern CORE_JAVA = Pattern.compile("^cpe:/a:(sun|oracle|ibm):(j2[ems]e|"
      +  205  1
           public static final Pattern CORE_JAVA = Pattern.compile("^cpe:/a:(sun|oracle|ibm):(j2[ems]e|"
       206  
                   + "java(_platform_micro_edition|_runtime_environment|_se|virtual_machine|se_development_kit|fx)?|"
       207   @@ -372,21 +372,21 @@
            * Regex to identify core jsf libraries.
       211  
            */
      -  212  2
           public static final Pattern CORE_JAVA_JSF = Pattern.compile("^cpe:/a:(sun|oracle|ibm):jsf($|:.*)");
      +  212  1
           public static final Pattern CORE_JAVA_JSF = Pattern.compile("^cpe:/a:(sun|oracle|ibm):jsf($|:.*)");
       213  
           /**
       214  
            * Regex to identify core java library files. This is currently incomplete.
       215  
            */
      -  216  2
           public static final Pattern CORE_FILES = Pattern.compile("(^|/)((alt[-])?rt|jsse|jfxrt|jfr|jce|javaws|deploy|charsets)\\.jar$");
      +  216  1
           public static final Pattern CORE_FILES = Pattern.compile("(^|/)((alt[-])?rt|jsse|jfxrt|jfr|jce|javaws|deploy|charsets)\\.jar$");
       217  
           /**
       218  
            * Regex to identify core jsf java library files. This is currently incomplete.
       219  
            */
      -  220  2
           public static final Pattern CORE_JSF_FILES = Pattern.compile("(^|/)jsf[-][^/]*\\.jar$");
      +  220  1
           public static final Pattern CORE_JSF_FILES = Pattern.compile("(^|/)jsf[-][^/]*\\.jar$");
       221  
       
       222   @@ -401,24 +401,24 @@
            */
       227  
           private void removeJreEntries(Dependency dependency) {
      -  228  10
               final Set<Identifier> identifiers = dependency.getIdentifiers();
      -  229  10
               final Iterator<Identifier> itr = identifiers.iterator();
      -  230  18
               while (itr.hasNext()) {
      -  231  8
                   final Identifier i = itr.next();
      -  232  8
                   final Matcher coreCPE = CORE_JAVA.matcher(i.getValue());
      -  233  8
                   final Matcher coreFiles = CORE_FILES.matcher(dependency.getFileName());
      -  234  8
                   if (coreCPE.matches() && !coreFiles.matches()) {
      +  228  5
               final Set<Identifier> identifiers = dependency.getIdentifiers();
      +  229  5
               final Iterator<Identifier> itr = identifiers.iterator();
      +  230  9
               while (itr.hasNext()) {
      +  231  4
                   final Identifier i = itr.next();
      +  232  4
                   final Matcher coreCPE = CORE_JAVA.matcher(i.getValue());
      +  233  4
                   final Matcher coreFiles = CORE_FILES.matcher(dependency.getFileName());
      +  234  4
                   if (coreCPE.matches() && !coreFiles.matches()) {
       235  0
                       itr.remove();
       236  
                   }
      -  237  8
                   final Matcher coreJsfCPE = CORE_JAVA_JSF.matcher(i.getValue());
      -  238  8
                   final Matcher coreJsfFiles = CORE_JSF_FILES.matcher(dependency.getFileName());
      -  239  8
                   if (coreJsfCPE.matches() && !coreJsfFiles.matches()) {
      +  237  4
                   final Matcher coreJsfCPE = CORE_JAVA_JSF.matcher(i.getValue());
      +  238  4
                   final Matcher coreJsfFiles = CORE_JSF_FILES.matcher(dependency.getFileName());
      +  239  4
                   if (coreJsfCPE.matches() && !coreJsfFiles.matches()) {
       240  0
                       itr.remove();
       241  
                   }
      -  242  8
               }
      -  243  10
           }
      +  242  4
               }
      +  243  5
           }
       244  
       
       245   @@ -437,19 +437,19 @@
            */
       252  
           private VulnerableSoftware parseCpe(String type, String value) {
      -  253  12
               if (!"cpe".equals(type)) {
      +  253  6
               if (!"cpe".equals(type)) {
       254  0
                   return null;
       255  
               }
      -  256  12
               final VulnerableSoftware cpe = new VulnerableSoftware();
      +  256  6
               final VulnerableSoftware cpe = new VulnerableSoftware();
       257  
               try {
      -  258  12
                   cpe.parseName(value);
      +  258  6
                   cpe.parseName(value);
       259  0
               } catch (UnsupportedEncodingException ex) {
       260  0
                   LOGGER.trace("", ex);
       261  0
                   return null;
      -  262  12
               }
      -  263  12
               return cpe;
      +  262  6
               }
      +  263  6
               return cpe;
       264  
           }
       265   @@ -468,8 +468,8 @@
            */
       272  
           private void removeBadMatches(Dependency dependency) {
      -  273  10
               final Set<Identifier> identifiers = dependency.getIdentifiers();
      -  274  10
               final Iterator<Identifier> itr = identifiers.iterator();
      +  273  5
               final Set<Identifier> identifiers = dependency.getIdentifiers();
      +  274  5
               final Iterator<Identifier> itr = identifiers.iterator();
       275  
       
       276   @@ -486,21 +486,21 @@
               //Set<Evidence> groupId = dependency.getVendorEvidence().getEvidence("pom", "groupid");
       282  
               //Set<Evidence> artifactId = dependency.getVendorEvidence().getEvidence("pom", "artifactid");
      -  283  18
               while (itr.hasNext()) {
      -  284  8
                   final Identifier i = itr.next();
      +  283  9
               while (itr.hasNext()) {
      +  284  4
                   final Identifier i = itr.next();
       285  
                   //TODO move this startsWith expression to the base suppression file
      -  286  8
                   if ("cpe".equals(i.getType())) {
      -  287  8
                       if ((i.getValue().matches(".*c\\+\\+.*")
      -  288  8
                               || i.getValue().startsWith("cpe:/a:file:file")
      -  289  6
                               || i.getValue().startsWith("cpe:/a:mozilla:mozilla")
      -  290  6
                               || i.getValue().startsWith("cpe:/a:cvs:cvs")
      -  291  6
                               || i.getValue().startsWith("cpe:/a:ftp:ftp")
      -  292  6
                               || i.getValue().startsWith("cpe:/a:tcp:tcp")
      -  293  6
                               || i.getValue().startsWith("cpe:/a:ssh:ssh")
      -  294  6
                               || i.getValue().startsWith("cpe:/a:lookup:lookup"))
      -  295  2
                               && (dependency.getFileName().toLowerCase().endsWith(".jar")
      -  296  2
                               || dependency.getFileName().toLowerCase().endsWith("pom.xml")
      +  286  4
                   if ("cpe".equals(i.getType())) {
      +  287  4
                       if ((i.getValue().matches(".*c\\+\\+.*")
      +  288  4
                               || i.getValue().startsWith("cpe:/a:file:file")
      +  289  3
                               || i.getValue().startsWith("cpe:/a:mozilla:mozilla")
      +  290  3
                               || i.getValue().startsWith("cpe:/a:cvs:cvs")
      +  291  3
                               || i.getValue().startsWith("cpe:/a:ftp:ftp")
      +  292  3
                               || i.getValue().startsWith("cpe:/a:tcp:tcp")
      +  293  3
                               || i.getValue().startsWith("cpe:/a:ssh:ssh")
      +  294  3
                               || i.getValue().startsWith("cpe:/a:lookup:lookup"))
      +  295  1
                               && (dependency.getFileName().toLowerCase().endsWith(".jar")
      +  296  1
                               || dependency.getFileName().toLowerCase().endsWith("pom.xml")
       297  0
                               || dependency.getFileName().toLowerCase().endsWith(".dll")
       298  0
                               || dependency.getFileName().toLowerCase().endsWith(".exe")
       299  0
                               || dependency.getFileName().toLowerCase().endsWith(".nuspec")
      @@ -512,41 +512,41 @@  305  0
                               || dependency.getFileName().toLowerCase().endsWith(".tgz")
       306  0
                               || dependency.getFileName().toLowerCase().endsWith(".ear")
       307  0
                               || dependency.getFileName().toLowerCase().endsWith(".war"))) {
      -  308  2
                           itr.remove();
      -  309  6
                       } else if ((i.getValue().startsWith("cpe:/a:jquery:jquery")
      -  310  6
                               || i.getValue().startsWith("cpe:/a:prototypejs:prototype")
      -  311  6
                               || i.getValue().startsWith("cpe:/a:yahoo:yui"))
      +  308  1
                           itr.remove();
      +  309  3
                       } else if ((i.getValue().startsWith("cpe:/a:jquery:jquery")
      +  310  3
                               || i.getValue().startsWith("cpe:/a:prototypejs:prototype")
      +  311  3
                               || i.getValue().startsWith("cpe:/a:yahoo:yui"))
       312  0
                               && (dependency.getFileName().toLowerCase().endsWith(".jar")
       313  0
                               || dependency.getFileName().toLowerCase().endsWith("pom.xml")
       314  0
                               || dependency.getFileName().toLowerCase().endsWith(".dll")
       315  0
                               || dependency.getFileName().toLowerCase().endsWith(".exe"))) {
       316  0
                           itr.remove();
      -  317  6
                       } else if ((i.getValue().startsWith("cpe:/a:microsoft:excel")
      -  318  6
                               || i.getValue().startsWith("cpe:/a:microsoft:word")
      -  319  6
                               || i.getValue().startsWith("cpe:/a:microsoft:visio")
      -  320  6
                               || i.getValue().startsWith("cpe:/a:microsoft:powerpoint")
      -  321  6
                               || i.getValue().startsWith("cpe:/a:microsoft:office")
      -  322  6
                               || i.getValue().startsWith("cpe:/a:core_ftp:core_ftp"))
      +  317  3
                       } else if ((i.getValue().startsWith("cpe:/a:microsoft:excel")
      +  318  3
                               || i.getValue().startsWith("cpe:/a:microsoft:word")
      +  319  3
                               || i.getValue().startsWith("cpe:/a:microsoft:visio")
      +  320  3
                               || i.getValue().startsWith("cpe:/a:microsoft:powerpoint")
      +  321  3
                               || i.getValue().startsWith("cpe:/a:microsoft:office")
      +  322  3
                               || i.getValue().startsWith("cpe:/a:core_ftp:core_ftp"))
       323  0
                               && (dependency.getFileName().toLowerCase().endsWith(".jar")
       324  0
                               || dependency.getFileName().toLowerCase().endsWith(".ear")
       325  0
                               || dependency.getFileName().toLowerCase().endsWith(".war")
       326  0
                               || dependency.getFileName().toLowerCase().endsWith("pom.xml"))) {
       327  0
                           itr.remove();
      -  328  6
                       } else if (i.getValue().startsWith("cpe:/a:apache:maven")
      +  328  3
                       } else if (i.getValue().startsWith("cpe:/a:apache:maven")
       329  0
                               && !dependency.getFileName().toLowerCase().matches("maven-core-[\\d\\.]+\\.jar")) {
       330  0
                           itr.remove();
      -  331  6
                       } else if (i.getValue().startsWith("cpe:/a:m-core:m-core")
      +  331  3
                       } else if (i.getValue().startsWith("cpe:/a:m-core:m-core")
       332  0
                               && !dependency.getEvidenceUsed().containsUsedString("m-core")) {
       333  0
                           itr.remove();
      -  334  6
                       } else if (i.getValue().startsWith("cpe:/a:jboss:jboss")
      +  334  3
                       } else if (i.getValue().startsWith("cpe:/a:jboss:jboss")
       335  0
                               && !dependency.getFileName().toLowerCase().matches("jboss-?[\\d\\.-]+(GA)?\\.jar")) {
       336  0
                           itr.remove();
       337  
                       }
       338  
                   }
      -  339  8
               }
      -  340  10
           }
      +  339  4
               }
      +  340  5
           }
       341  
       
       342   @@ -561,12 +561,12 @@
            */
       347  
           private void removeWrongVersionMatches(Dependency dependency) {
      -  348  10
               final Set<Identifier> identifiers = dependency.getIdentifiers();
      -  349  10
               final Iterator<Identifier> itr = identifiers.iterator();
      +  348  5
               final Set<Identifier> identifiers = dependency.getIdentifiers();
      +  349  5
               final Iterator<Identifier> itr = identifiers.iterator();
       350  
       
      -  351  10
               final String fileName = dependency.getFileName();
      -  352  10
               if (fileName != null && fileName.contains("axis2")) {
      +  351  5
               final String fileName = dependency.getFileName();
      +  352  5
               if (fileName != null && fileName.contains("axis2")) {
       353  0
                   while (itr.hasNext()) {
       354  0
                       final Identifier i = itr.next();
       355  0
                       if ("cpe".equals(i.getType())) {
      @@ -578,7 +578,7 @@  360  
                       }
       361  0
                   }
      -  362  10
               } else if (fileName != null && fileName.contains("axis")) {
      +  362  5
               } else if (fileName != null && fileName.contains("axis")) {
       363  0
                   while (itr.hasNext()) {
       364  0
                       final Identifier i = itr.next();
       365  0
                       if ("cpe".equals(i.getType())) {
      @@ -592,7 +592,7 @@  371  0
                   }
       372  
               }
      -  373  10
           }
      +  373  5
           }
       374  
       
       375   @@ -611,12 +611,12 @@
           private void addFalseNegativeCPEs(Dependency dependency) {
       382  
               //TODO move this to the hint analyzer
      -  383  10
               for (final Identifier identifier : dependency.getIdentifiers()) {
      -  384  6
                   if ("cpe".equals(identifier.getType()) && identifier.getValue() != null
      -  385  6
                           && (identifier.getValue().startsWith("cpe:/a:oracle:opensso:")
      -  386  6
                           || identifier.getValue().startsWith("cpe:/a:oracle:opensso_enterprise:")
      -  387  6
                           || identifier.getValue().startsWith("cpe:/a:sun:opensso_enterprise:")
      -  388  6
                           || identifier.getValue().startsWith("cpe:/a:sun:opensso:"))) {
      +  383  5
               for (final Identifier identifier : dependency.getIdentifiers()) {
      +  384  3
                   if ("cpe".equals(identifier.getType()) && identifier.getValue() != null
      +  385  3
                           && (identifier.getValue().startsWith("cpe:/a:oracle:opensso:")
      +  386  3
                           || identifier.getValue().startsWith("cpe:/a:oracle:opensso_enterprise:")
      +  387  3
                           || identifier.getValue().startsWith("cpe:/a:sun:opensso_enterprise:")
      +  388  3
                           || identifier.getValue().startsWith("cpe:/a:sun:opensso:"))) {
       389  0
                       final String newCpe = String.format("cpe:/a:sun:opensso_enterprise:%s", identifier.getValue().substring(22));
       390  0
                       final String newCpe2 = String.format("cpe:/a:oracle:opensso_enterprise:%s", identifier.getValue().substring(22));
       391  0
                       final String newCpe3 = String.format("cpe:/a:sun:opensso:%s", identifier.getValue().substring(22));
      @@ -644,8 +644,8 @@  408  0
                       }
       409  
                   }
      -  410  6
               }
      -  411  10
           }
      +  410  3
               }
      +  411  5
           }
       412  
       
       413   @@ -664,10 +664,10 @@
            */
       420  
           private void removeDuplicativeEntriesFromJar(Dependency dependency, Engine engine) {
      -  421  10
               if (dependency.getFileName().toLowerCase().endsWith("pom.xml")
      -  422  8
                       || DLL_EXE_FILTER.accept(dependency.getActualFile())) {
      -  423  2
                   String parentPath = dependency.getFilePath().toLowerCase();
      -  424  2
                   if (parentPath.contains(".jar")) {
      +  421  5
               if (dependency.getFileName().toLowerCase().endsWith("pom.xml")
      +  422  4
                       || DLL_EXE_FILTER.accept(dependency.getActualFile())) {
      +  423  1
                   String parentPath = dependency.getFilePath().toLowerCase();
      +  424  1
                   if (parentPath.contains(".jar")) {
       425  0
                       parentPath = parentPath.substring(0, parentPath.indexOf(".jar") + 4);
       426  0
                       final Dependency parent = findDependency(parentPath, engine.getDependencies());
       427  0
                       if (parent != null) {
      @@ -700,7 +700,7 @@
       
       448  
               }
      -  449  10
           }
      +  449  5
           }
       450  
       
       451   @@ -761,6 +761,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.FileNameAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.FileNameAnalyzer.html index 12f39ea55..a7844f398 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.FileNameAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.FileNameAnalyzer.html @@ -89,7 +89,7 @@
        * @author Jeremy Long
       36  
        */
      -  37  22
       public class FileNameAnalyzer extends AbstractAnalyzer implements Analyzer {
      +  37  11
       public class FileNameAnalyzer extends AbstractAnalyzer implements Analyzer {
       38  
       
       39   @@ -108,7 +108,7 @@
            * The phase that this analyzer is intended to run in.
       46  
            */
      -  47  2
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
      +  47  1
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
       48  
       
       49   @@ -125,7 +125,7 @@
           @Override
       55  
           public String getName() {
      -  56  34
               return ANALYZER_NAME;
      +  56  17
               return ANALYZER_NAME;
       57  
           }
       58   @@ -144,7 +144,7 @@
           @Override
       65  
           public AnalysisPhase getAnalysisPhase() {
      -  66  10
               return ANALYSIS_PHASE;
      +  66  5
               return ANALYSIS_PHASE;
       67  
           }
       68   @@ -157,7 +157,7 @@
            * Python init files
       72  
            */
      -  73  2
           private static final NameFileFilter IGNORED_FILES = new NameFileFilter(new String[]{
      +  73  1
           private static final NameFileFilter IGNORED_FILES = new NameFileFilter(new String[]{
       74  
               "__init__.py",
       75   @@ -192,50 +192,50 @@
       
       90  
               //strip any path information that may get added by ArchiveAnalyzer, etc.
      -  91  12
               final File f = dependency.getActualFile();
      -  92  12
               final String fileName = FilenameUtils.removeExtension(f.getName());
      +  91  6
               final File f = dependency.getActualFile();
      +  92  6
               final String fileName = FilenameUtils.removeExtension(f.getName());
       93  
       
       94  
               //add version evidence
      -  95  12
               final DependencyVersion version = DependencyVersionUtil.parseVersion(fileName);
      -  96  12
               if (version != null) {
      +  95  6
               final DependencyVersion version = DependencyVersionUtil.parseVersion(fileName);
      +  96  6
               if (version != null) {
       97  
                   // If the version number is just a number like 2 or 23, reduce the confidence
       98  
                   // a shade. This should hopefully correct for cases like log4j.jar or
       99  
                   // struts2-core.jar
      -  100  10
                   if (version.getVersionParts() == null || version.getVersionParts().size() < 2) {
      +  100  5
                   if (version.getVersionParts() == null || version.getVersionParts().size() < 2) {
       101  0
                       dependency.getVersionEvidence().addEvidence("file", "name",
       102  0
                               version.toString(), Confidence.MEDIUM);
       103  
                   } else {
      -  104  20
                       dependency.getVersionEvidence().addEvidence("file", "version",
      -  105  10
                               version.toString(), Confidence.HIGHEST);
      +  104  10
                       dependency.getVersionEvidence().addEvidence("file", "version",
      +  105  5
                               version.toString(), Confidence.HIGHEST);
       106  
                   }
      -  107  10
                   dependency.getVersionEvidence().addEvidence("file", "name",
      +  107  5
                   dependency.getVersionEvidence().addEvidence("file", "name",
       108  
                           fileName, Confidence.MEDIUM);
       109  
               }
       110  
       
      -  111  12
               if (!IGNORED_FILES.accept(f)) {
      -  112  12
                   dependency.getProductEvidence().addEvidence("file", "name",
      +  111  6
               if (!IGNORED_FILES.accept(f)) {
      +  112  6
                   dependency.getProductEvidence().addEvidence("file", "name",
       113  
                           fileName, Confidence.HIGH);
      -  114  12
                   dependency.getVendorEvidence().addEvidence("file", "name",
      +  114  6
                   dependency.getVendorEvidence().addEvidence("file", "name",
       115  
                           fileName, Confidence.HIGH);
       116  
               }
      -  117  12
           }
      +  117  6
           }
       118  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.FileTypeAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.FileTypeAnalyzer.html index 10de905fc..dbdcde749 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.FileTypeAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.FileTypeAnalyzer.html @@ -85,6 +85,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.HintAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.HintAnalyzer.html index 092a2589f..345de6d05 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.HintAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.HintAnalyzer.html @@ -12,7 +12,7 @@
       
      - +
      Classes in this File Line Coverage Branch Coverage Complexity
      HintAnalyzer
      74%
      37/50
      56%
      17/30
      6
      HintAnalyzer
      45%
      49/107
      60%
      28/46
      8.8
       
      @@ -56,271 +56,568 @@  19  
       
       20   -
       import java.util.ArrayList;
      +
       import java.io.File;
       21   -
       import java.util.Iterator;
      +
       import java.io.IOException;
       22   -
       import java.util.List;
      +
       import java.io.InputStream;
       23   -
       import java.util.Set;
      +
       import java.net.MalformedURLException;
       24   -
       import org.owasp.dependencycheck.Engine;
      +
       import java.net.URL;
       25   -
       import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
      +
       import java.util.ArrayList;
       26   -
       import org.owasp.dependencycheck.dependency.Confidence;
      +
       import java.util.Iterator;
       27   -
       import org.owasp.dependencycheck.dependency.Dependency;
      +
       import java.util.List;
       28   -
       import org.owasp.dependencycheck.dependency.Evidence;
      +
       import java.util.regex.Pattern;
       29   -
       
      +
       import org.owasp.dependencycheck.Engine;
       30   -
       /**
      +
       import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
       31   -
        *
      +
       import org.owasp.dependencycheck.dependency.Dependency;
       32   -
        * @author Jeremy Long
      +
       import org.owasp.dependencycheck.dependency.Evidence;
       33   -
        */
      -  34  18
       public class HintAnalyzer extends AbstractAnalyzer implements Analyzer {
      +
       import org.owasp.dependencycheck.exception.InitializationException;
      +  34   +
       import org.owasp.dependencycheck.xml.suppression.PropertyType;
       35   -
       
      +
       import org.owasp.dependencycheck.utils.DownloadFailedException;
       36   -
           //<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer">
      +
       import org.owasp.dependencycheck.utils.Downloader;
       37   -
           /**
      +
       import org.owasp.dependencycheck.utils.FileUtils;
       38   -
            * The name of the analyzer.
      +
       import org.owasp.dependencycheck.utils.Settings;
       39   -
            */
      +
       import org.owasp.dependencycheck.xml.hints.VendorDuplicatingHintRule;
       40   -
           private static final String ANALYZER_NAME = "Hint Analyzer";
      +
       import org.owasp.dependencycheck.xml.hints.HintParseException;
       41   -
           /**
      +
       import org.owasp.dependencycheck.xml.hints.HintParser;
       42   -
            * The phase that this analyzer is intended to run in.
      +
       import org.owasp.dependencycheck.xml.hints.HintRule;
       43   -
            */
      -  44  2
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_IDENTIFIER_ANALYSIS;
      +
       import org.owasp.dependencycheck.xml.hints.Hints;
      +  44   +
       import org.slf4j.Logger;
       45   -
       
      +
       import org.slf4j.LoggerFactory;
       46   -
           /**
      +
       import org.xml.sax.SAXException;
       47   -
            * Returns the name of the analyzer.
      +
       
       48   -
            *
      +
       /**
       49   -
            * @return the name of the analyzer.
      +
        * This analyzer adds evidence to dependencies to enhance the accuracy of
       50   -
            */
      +
        * library identification.
       51   -
           @Override
      +
        *
       52   -
           public String getName() {
      -  53  34
               return ANALYZER_NAME;
      -  54   -
           }
      +
        * @author Jeremy Long
      +  53   +
        */
      +  54  9
       public class HintAnalyzer extends AbstractAnalyzer implements Analyzer {
       55  
       
       56   -
           /**
      +
           //<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer">
       57   -
            * Returns the phase that the analyzer is intended to run in.
      -  58   -
            *
      -  59   -
            * @return the phase that the analyzer is intended to run in.
      -  60   -
            */
      -  61   -
           @Override
      -  62   -
           public AnalysisPhase getAnalysisPhase() {
      -  63  10
               return ANALYSIS_PHASE;
      -  64   -
           }
      -  65   -
           //</editor-fold>
      -  66   -
       
      -  67  
           /**
      -  68   -
            * The HintAnalyzer uses knowledge about a dependency to add additional information to help in identification of identifiers
      -  69   -
            * or vulnerabilities.
      -  70   -
            *
      -  71   -
            * @param dependency The dependency being analyzed
      -  72   -
            * @param engine The scanning engine
      -  73   -
            * @throws AnalysisException is thrown if there is an exception analyzing the dependency.
      -  74   +  58   +
            * The name of the analyzer.
      +  59  
            */
      -  75   +  60   +
           private static final String ANALYZER_NAME = "Hint Analyzer";
      +  61   +
           /**
      +  62   +
            * The phase that this analyzer is intended to run in.
      +  63   +
            */
      +  64  1
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_IDENTIFIER_ANALYSIS;
      +  65   +
       
      +  66   +
           /**
      +  67   +
            * Returns the name of the analyzer.
      +  68   +
            *
      +  69   +
            * @return the name of the analyzer.
      +  70   +
            */
      +  71  
           @Override
      +  72   +
           public String getName() {
      +  73  17
               return ANALYZER_NAME;
      +  74   +
           }
      +  75   +
       
       76   -
           public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
      -  77  8
               final Evidence springTest1 = new Evidence("Manifest",
      +
           /**
      +  77   +
            * Returns the phase that the analyzer is intended to run in.
       78   -
                       "Implementation-Title",
      +
            *
       79   -
                       "Spring Framework",
      +
            * @return the phase that the analyzer is intended to run in.
       80   -
                       Confidence.HIGH);
      +
            */
       81   -
       
      -  82  8
               final Evidence springTest2 = new Evidence("Manifest",
      -  83   -
                       "Implementation-Title",
      +
           @Override
      +  82   +
           public AnalysisPhase getAnalysisPhase() {
      +  83  5
               return ANALYSIS_PHASE;
       84   -
                       "org.springframework.core",
      +
           }
       85   -
                       Confidence.HIGH);
      +
       
       86   -
       
      -  87  8
               final Evidence springTest3 = new Evidence("Manifest",
      +
           /**
      +  87   +
            * The initialize method does nothing for this Analyzer.
       88   -
                       "Implementation-Title",
      +
            *
       89   -
                       "spring-core",
      +
            * @throws InitializationException thrown if there is an exception
       90   -
                       Confidence.HIGH);
      +
            */
       91   -
       
      -  92  8
               final Evidence springTest4 = new Evidence("jar",
      +
           @Override
      +  92   +
           public void initialize() throws InitializationException {
       93   -
                       "package name",
      -  94   -
                       "springframework",
      -  95   -
                       Confidence.LOW);
      -  96   -
       
      -  97  8
               final Evidence springSecurityTest1 = new Evidence("Manifest",
      -  98   -
                       "Bundle-Name",
      -  99   -
                       "Spring Security Core",
      -  100   -
                       Confidence.MEDIUM);
      +
               try {
      +  94  2
                   super.initialize();
      +  95  2
                   loadHintRules();
      +  96  0
               } catch (HintParseException ex) {
      +  97  0
                   LOGGER.debug("Unable to parse hint file", ex);
      +  98  0
                   throw new InitializationException("Unable to parse the hint file", ex);
      +  99  2
               }
      +  100  2
           }
       101   +
           //</editor-fold>
      +  102  
       
      -  102  8
               final Evidence springSecurityTest2 = new Evidence("pom",
       103   -
                       "artifactid",
      +
           /**
       104   -
                       "spring-security-core",
      +
            * The Logger for use throughout the class
       105   -
                       Confidence.HIGH);
      -  106   -
       
      -  107  8
               final Evidence symfony = new Evidence("composer.lock",
      +
            */
      +  106  1
           private static final Logger LOGGER = LoggerFactory.getLogger(HintAnalyzer.class);
      +  107   +
           /**
       108   -
                   "vendor",
      +
            * The name of the hint rule file
       109   -
                   "symfony",
      +
            */
       110   -
                   Confidence.HIGHEST);
      +
           private static final String HINT_RULE_FILE_NAME = "dependencycheck-base-hint.xml";
       111   -
       
      -  112  8
               final Evidence zendframeworkVendor = new Evidence("composer.lock",
      +
           /**
      +  112   +
            * The collection of hints.
       113   -
                   "vendor",
      +
            */
       114   -
                   "zendframework",
      +
           private Hints hints;
       115   -
                   Confidence.HIGHEST);
      +
       
       116   -
       
      -  117  8
               final Evidence zendframeworkProduct = new Evidence("composer.lock",
      +
           /**
      +  117   +
            * The HintAnalyzer uses knowledge about a dependency to add additional
       118   -
                   "product",
      +
            * information to help in identification of identifiers or vulnerabilities.
       119   -
                   "zendframework",
      +
            *
       120   -
                   Confidence.HIGHEST);
      +
            * @param dependency The dependency being analyzed
       121   -
       
      +
            * @param engine The scanning engine
       122   -
               //springsource/vware problem
      -  123  8
               final Set<Evidence> product = dependency.getProductEvidence().getEvidence();
      -  124  8
               final Set<Evidence> vendor = dependency.getVendorEvidence().getEvidence();
      +
            * @throws AnalysisException is thrown if there is an exception analyzing
      +  123   +
            * the dependency.
      +  124   +
            */
       125   -
       
      -  126  8
               if (product.contains(springTest1) || product.contains(springTest2) || product.contains(springTest3)
      -  127  6
                       || (dependency.getFileName().contains("spring") && product.contains(springTest4))) {
      -  128  2
                   dependency.getProductEvidence().addEvidence("hint analyzer", "product", "springsource spring framework", Confidence.HIGH);
      -  129  2
                   dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "SpringSource", Confidence.HIGH);
      -  130  2
                   dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "vmware", Confidence.HIGH);
      -  131  2
                   dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "pivotal", Confidence.HIGH);
      -  132   -
               }
      +
           @Override
      +  126   +
           public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
      +  127  4
               for (HintRule hint : hints.getHintRules()) {
      +  128  28
                   boolean shouldAdd = false;
      +  129  28
                   for (Evidence given : hint.getGivenVendor()) {
      +  130  8
                       if (dependency.getVendorEvidence().getEvidence().contains(given)) {
      +  131  0
                           shouldAdd = true;
      +  132  0
                           break;
       133   -
       
      -  134  8
               if (vendor.contains(springTest4)) {
      -  135  2
                   dependency.getProductEvidence().addEvidence("hint analyzer", "product", "springsource_spring_framework", Confidence.HIGH);
      -  136  2
                   dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "vmware", Confidence.HIGH);
      -  137  2
                   dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "pivotal", Confidence.HIGH);
      -  138   -
               }
      -  139   -
       
      -  140  8
               if (product.contains(springSecurityTest1) || product.contains(springSecurityTest2)) {
      -  141  0
                   dependency.getProductEvidence().addEvidence("hint analyzer", "product", "springsource_spring_security", Confidence.HIGH);
      -  142  0
                   dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "SpringSource", Confidence.HIGH);
      -  143  0
                   dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "vmware", Confidence.HIGH);
      -  144   -
               }
      -  145   -
       
      -  146  8
               if (vendor.contains(symfony)) {
      -  147  0
                   dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "sensiolabs", Confidence.HIGHEST);
      -  148   -
               }
      -  149   -
       
      -  150  8
               if (vendor.contains(zendframeworkVendor)) {
      -  151  0
                   dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "zend", Confidence.HIGHEST);
      -  152   -
               }
      -  153   -
       
      -  154  8
               if (product.contains(zendframeworkProduct)) {
      -  155  0
                   dependency.getProductEvidence().addEvidence("hint analyzer", "vendor", "zend_framework", Confidence.HIGHEST);
      -  156   -
               }
      -  157   -
       
      -  158   -
               //sun/oracle problem
      -  159  8
               final Iterator<Evidence> itr = dependency.getVendorEvidence().iterator();
      -  160  8
               final List<Evidence> newEntries = new ArrayList<Evidence>();
      -  161  58
               while (itr.hasNext()) {
      -  162  50
                   final Evidence e = itr.next();
      -  163  50
                   if ("sun".equalsIgnoreCase(e.getValue(false))) {
      -  164  0
                       final Evidence newEvidence = new Evidence(e.getSource() + " (hint)", e.getName(), "oracle", e.getConfidence());
      -  165  0
                       newEntries.add(newEvidence);
      -  166  0
                   } else if ("oracle".equalsIgnoreCase(e.getValue(false))) {
      -  167  0
                       final Evidence newEvidence = new Evidence(e.getSource() + " (hint)", e.getName(), "sun", e.getConfidence());
      -  168  0
                       newEntries.add(newEvidence);
      -  169   +
                       }
      +  134  8
                   }
      +  135  28
                   if (!shouldAdd) {
      +  136  28
                       for (Evidence given : hint.getGivenProduct()) {
      +  137  31
                           if (dependency.getProductEvidence().getEvidence().contains(given)) {
      +  138  1
                               shouldAdd = true;
      +  139  1
                               break;
      +  140   +
                           }
      +  141  30
                       }
      +  142  
                   }
      -  170  50
               }
      -  171  8
               for (Evidence e : newEntries) {
      +  143  28
                   if (!shouldAdd) {
      +  144  27
                       for (PropertyType pt : hint.getFilenames()) {
      +  145  4
                           if (pt.matches(dependency.getFileName())) {
      +  146  0
                               shouldAdd = true;
      +  147   +
                           }
      +  148  4
                       }
      +  149   +
                   }
      +  150  28
                   if (shouldAdd) {
      +  151  1
                       for (Evidence e : hint.getAddVendor()) {
      +  152  3
                           dependency.getVendorEvidence().addEvidence(e);
      +  153  3
                       }
      +  154  1
                       for (Evidence e : hint.getAddProduct()) {
      +  155  1
                           dependency.getProductEvidence().addEvidence(e);
      +  156  1
                       }
      +  157   +
                   }
      +  158  28
               }
      +  159   +
       
      +  160  4
               final Iterator<Evidence> itr = dependency.getVendorEvidence().iterator();
      +  161  4
               final List<Evidence> newEntries = new ArrayList<Evidence>();
      +  162  29
               while (itr.hasNext()) {
      +  163  25
                   final Evidence e = itr.next();
      +  164  25
                   for (VendorDuplicatingHintRule dhr : hints.getVendorDuplicatingHintRules()) {
      +  165  50
                       if (dhr.getValue().equalsIgnoreCase(e.getValue(false))) {
      +  166  0
                           newEntries.add(new Evidence(e.getSource() + " (hint)",
      +  167  0
                                   e.getName(), dhr.getDuplicate(), e.getConfidence()));
      +  168   +
                       }
      +  169  50
                   }
      +  170  25
               }
      +  171  4
               for (Evidence e : newEntries) {
       172  0
                   dependency.getVendorEvidence().addEvidence(e);
       173  0
               }
       174  
       
      -  175  8
           }
      +  175   +
               //<editor-fold defaultstate="collapsed" desc="Old implementation">
       176   +
               /*
      +  177   +
               final Evidence springTest1 = new Evidence("Manifest",
      +  178   +
                       "Implementation-Title",
      +  179   +
                       "Spring Framework",
      +  180   +
                       Confidence.HIGH);
      +  181   +
       
      +  182   +
               final Evidence springTest2 = new Evidence("Manifest",
      +  183   +
                       "Implementation-Title",
      +  184   +
                       "org.springframework.core",
      +  185   +
                       Confidence.HIGH);
      +  186   +
       
      +  187   +
               final Evidence springTest3 = new Evidence("Manifest",
      +  188   +
                       "Implementation-Title",
      +  189   +
                       "spring-core",
      +  190   +
                       Confidence.HIGH);
      +  191   +
       
      +  192   +
               final Evidence springTest4 = new Evidence("jar",
      +  193   +
                       "package name",
      +  194   +
                       "springframework",
      +  195   +
                       Confidence.LOW);
      +  196   +
       
      +  197   +
               final Evidence springSecurityTest1 = new Evidence("Manifest",
      +  198   +
                       "Bundle-Name",
      +  199   +
                       "Spring Security Core",
      +  200   +
                       Confidence.MEDIUM);
      +  201   +
       
      +  202   +
               final Evidence springSecurityTest2 = new Evidence("pom",
      +  203   +
                       "artifactid",
      +  204   +
                       "spring-security-core",
      +  205   +
                       Confidence.HIGH);
      +  206   +
       
      +  207   +
               final Evidence symfony = new Evidence("composer.lock",
      +  208   +
                   "vendor",
      +  209   +
                   "symfony",
      +  210   +
                   Confidence.HIGHEST);
      +  211   +
       
      +  212   +
               final Evidence zendframeworkVendor = new Evidence("composer.lock",
      +  213   +
                   "vendor",
      +  214   +
                   "zendframework",
      +  215   +
                   Confidence.HIGHEST);
      +  216   +
       
      +  217   +
               final Evidence zendframeworkProduct = new Evidence("composer.lock",
      +  218   +
                   "product",
      +  219   +
                   "zendframework",
      +  220   +
                   Confidence.HIGHEST);
      +  221   +
       
      +  222   +
               //springsource/vware problem
      +  223   +
               final Set<Evidence> product = dependency.getProductEvidence().getEvidence();
      +  224   +
               final Set<Evidence> vendor = dependency.getVendorEvidence().getEvidence();
      +  225   +
       
      +  226   +
               if (product.contains(springTest1) || product.contains(springTest2) || product.contains(springTest3)
      +  227   +
                       || (dependency.getFileName().contains("spring") && product.contains(springTest4))) {
      +  228   +
                   dependency.getProductEvidence().addEvidence("hint analyzer", "product", "springsource spring framework", Confidence.HIGH);
      +  229   +
                   dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "SpringSource", Confidence.HIGH);
      +  230   +
                   dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "vmware", Confidence.HIGH);
      +  231   +
                   dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "pivotal", Confidence.HIGH);
      +  232   +
               }
      +  233   +
       
      +  234   +
               if (vendor.contains(springTest4)) {
      +  235   +
                   dependency.getProductEvidence().addEvidence("hint analyzer", "product", "springsource_spring_framework", Confidence.HIGH);
      +  236   +
                   dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "vmware", Confidence.HIGH);
      +  237   +
                   dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "pivotal", Confidence.HIGH);
      +  238   +
               }
      +  239   +
       
      +  240   +
               if (product.contains(springSecurityTest1) || product.contains(springSecurityTest2)) {
      +  241   +
                   dependency.getProductEvidence().addEvidence("hint analyzer", "product", "springsource_spring_security", Confidence.HIGH);
      +  242   +
                   dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "SpringSource", Confidence.HIGH);
      +  243   +
                   dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "vmware", Confidence.HIGH);
      +  244   +
               }
      +  245   +
       
      +  246   +
               if (vendor.contains(symfony)) {
      +  247   +
                   dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "sensiolabs", Confidence.HIGHEST);
      +  248   +
               }
      +  249   +
       
      +  250   +
               if (vendor.contains(zendframeworkVendor)) {
      +  251   +
                   dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "zend", Confidence.HIGHEST);
      +  252   +
               }
      +  253   +
       
      +  254   +
               if (product.contains(zendframeworkProduct)) {
      +  255   +
                   dependency.getProductEvidence().addEvidence("hint analyzer", "vendor", "zend_framework", Confidence.HIGHEST);
      +  256   +
               }
      +  257   +
       
      +  258   +
               //sun/oracle problem
      +  259   +
               final Iterator<Evidence> itr = dependency.getVendorEvidence().iterator();
      +  260   +
               final List<Evidence> newEntries = new ArrayList<Evidence>();
      +  261   +
               while (itr.hasNext()) {
      +  262   +
                   final Evidence e = itr.next();
      +  263   +
                   if ("sun".equalsIgnoreCase(e.getValue(false))) {
      +  264   +
                       final Evidence newEvidence = new Evidence(e.getSource() + " (hint)", e.getName(), "oracle", e.getConfidence());
      +  265   +
                       newEntries.add(newEvidence);
      +  266   +
                   } else if ("oracle".equalsIgnoreCase(e.getValue(false))) {
      +  267   +
                       final Evidence newEvidence = new Evidence(e.getSource() + " (hint)", e.getName(), "sun", e.getConfidence());
      +  268   +
                       newEntries.add(newEvidence);
      +  269   +
                   }
      +  270   +
               }
      +  271   +
               for (Evidence e : newEntries) {
      +  272   +
                   dependency.getVendorEvidence().addEvidence(e);
      +  273   +
               }
      +  274   +
                */
      +  275   +
               //</editor-fold>
      +  276  4
           }
      +  277   +
       
      +  278   +
           /**
      +  279   +
            * Loads the hint rules file.
      +  280   +
            *
      +  281   +
            * @throws HintParseException thrown if the XML cannot be parsed.
      +  282   +
            */
      +  283   +
           private void loadHintRules() throws HintParseException {
      +  284  2
               final HintParser parser = new HintParser();
      +  285  2
               File file = null;
      +  286   +
               try {
      +  287  2
                   hints = parser.parseHints(this.getClass().getClassLoader().getResourceAsStream(HINT_RULE_FILE_NAME));
      +  288  0
               } catch (HintParseException ex) {
      +  289  0
                   LOGGER.error("Unable to parse the base hint data file");
      +  290  0
                   LOGGER.debug("Unable to parse the base hint data file", ex);
      +  291  0
               } catch (SAXException ex) {
      +  292  0
                   LOGGER.error("Unable to parse the base hint data file");
      +  293  0
                   LOGGER.debug("Unable to parse the base hint data file", ex);
      +  294  2
               }
      +  295  2
               final String filePath = Settings.getString(Settings.KEYS.HINTS_FILE);
      +  296  2
               if (filePath == null) {
      +  297  2
                   return;
      +  298   +
               }
      +  299  0
               boolean deleteTempFile = false;
      +  300   +
               try {
      +  301  0
                   final Pattern uriRx = Pattern.compile("^(https?|file)\\:.*", Pattern.CASE_INSENSITIVE);
      +  302  0
                   if (uriRx.matcher(filePath).matches()) {
      +  303  0
                       deleteTempFile = true;
      +  304  0
                       file = FileUtils.getTempFile("hint", "xml");
      +  305  0
                       final URL url = new URL(filePath);
      +  306   +
                       try {
      +  307  0
                           Downloader.fetchFile(url, file, false);
      +  308  0
                       } catch (DownloadFailedException ex) {
      +  309  0
                           Downloader.fetchFile(url, file, true);
      +  310  0
                       }
      +  311  0
                   } else {
      +  312  0
                       file = new File(filePath);
      +  313  0
                       if (!file.exists()) {
      +  314  0
                           final InputStream fromClasspath = this.getClass().getClassLoader().getResourceAsStream(filePath);
      +  315  0
                           if (fromClasspath != null) {
      +  316  0
                               deleteTempFile = true;
      +  317  0
                               file = FileUtils.getTempFile("hint", "xml");
      +  318   +
                               try {
      +  319  0
                                   org.apache.commons.io.FileUtils.copyInputStreamToFile(fromClasspath, file);
      +  320  0
                               } catch (IOException ex) {
      +  321  0
                                   throw new HintParseException("Unable to locate suppressions file in classpath", ex);
      +  322  0
                               }
      +  323   +
                           }
      +  324   +
                       }
      +  325   +
                   }
      +  326   +
       
      +  327  0
                   if (file != null) {
      +  328   +
                       try {
      +  329  0
                           final Hints newHints = parser.parseHints(file);
      +  330  0
                           hints.getHintRules().addAll(newHints.getHintRules());
      +  331  0
                           hints.getVendorDuplicatingHintRules().addAll(newHints.getVendorDuplicatingHintRules());
      +  332  0
                           LOGGER.debug("{} hint rules were loaded.", hints.getHintRules().size());
      +  333  0
                           LOGGER.debug("{} duplicating hint rules were loaded.", hints.getVendorDuplicatingHintRules().size());
      +  334  0
                       } catch (HintParseException ex) {
      +  335  0
                           LOGGER.warn("Unable to parse hint rule xml file '{}'", file.getPath());
      +  336  0
                           LOGGER.warn(ex.getMessage());
      +  337  0
                           LOGGER.debug("", ex);
      +  338  0
                           throw ex;
      +  339  0
                       }
      +  340   +
                   }
      +  341  0
               } catch (DownloadFailedException ex) {
      +  342  0
                   throw new HintParseException("Unable to fetch the configured hint file", ex);
      +  343  0
               } catch (MalformedURLException ex) {
      +  344  0
                   throw new HintParseException("Configured hint file has an invalid URL", ex);
      +  345  0
               } catch (IOException ex) {
      +  346  0
                   throw new HintParseException("Unable to create temp file for hints", ex);
      +  347   +
               } finally {
      +  348  0
                   if (deleteTempFile && file != null) {
      +  349  0
                       FileUtils.delete(file);
      +  350   +
                   }
      +  351   +
               }
      +  352  0
           }
      +  353  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.JarAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.JarAnalyzer.html index 6dd5491d9..5dc2c68f1 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.JarAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.JarAnalyzer.html @@ -12,8 +12,8 @@
       
      - - + +
      Classes in this File Line Coverage Branch Coverage Complexity
      JarAnalyzer
      66%
      349/522
      56%
      195/346
      7.355
      JarAnalyzer$ClassNameInformation
      80%
      17/21
      80%
      8/10
      7.355
      JarAnalyzer
      66%
      350/528
      56%
      195/346
      7.419
      JarAnalyzer$ClassNameInformation
      80%
      17/21
      80%
      8/10
      7.419
       
      @@ -121,1820 +121,1822 @@  51  
       import org.owasp.dependencycheck.dependency.EvidenceCollection;
       52   -
       import org.owasp.dependencycheck.utils.FileFilterBuilder;
      +
       import org.owasp.dependencycheck.exception.InitializationException;
       53   -
       import org.owasp.dependencycheck.xml.pom.License;
      +
       import org.owasp.dependencycheck.utils.FileFilterBuilder;
       54   -
       import org.owasp.dependencycheck.xml.pom.PomUtils;
      +
       import org.owasp.dependencycheck.xml.pom.License;
       55   -
       import org.owasp.dependencycheck.xml.pom.Model;
      +
       import org.owasp.dependencycheck.xml.pom.PomUtils;
       56   -
       import org.owasp.dependencycheck.utils.FileUtils;
      +
       import org.owasp.dependencycheck.xml.pom.Model;
       57   -
       import org.owasp.dependencycheck.utils.Settings;
      +
       import org.owasp.dependencycheck.utils.FileUtils;
       58   -
       import org.slf4j.Logger;
      +
       import org.owasp.dependencycheck.utils.Settings;
       59   -
       import org.slf4j.LoggerFactory;
      +
       import org.slf4j.Logger;
       60   -
       
      +
       import org.slf4j.LoggerFactory;
       61   -
       /**
      +
       
       62   -
        * Used to load a JAR file and collect information that can be used to determine
      +
       /**
       63   -
        * the associated CPE.
      +
        * Used to load a JAR file and collect information that can be used to determine
       64   -
        *
      +
        * the associated CPE.
       65   -
        * @author Jeremy Long
      +
        *
       66   -
        */
      +
        * @author Jeremy Long
       67   -
       public class JarAnalyzer extends AbstractFileTypeAnalyzer {
      +
        */
       68   -
       
      +
       public class JarAnalyzer extends AbstractFileTypeAnalyzer {
       69   -
           //<editor-fold defaultstate="collapsed" desc="Constants and Member Variables">
      +
       
       70   -
           /**
      +
           //<editor-fold defaultstate="collapsed" desc="Constants and Member Variables">
       71   -
            * The logger.
      +
           /**
       72   +
            * The logger.
      +  73  
            */
      -  73  2
           private static final Logger LOGGER = LoggerFactory.getLogger(JarAnalyzer.class);
      -  74   -
           /**
      +  74  1
           private static final Logger LOGGER = LoggerFactory.getLogger(JarAnalyzer.class);
       75   -
            * The count of directories created during analysis. This is used for
      +
           /**
       76   -
            * creating temporary directories.
      +
            * The count of directories created during analysis. This is used for
       77   +
            * creating temporary directories.
      +  78  
            */
      -  78  2
           private static int dirCount = 0;
      -  79   -
           /**
      +  79  1
           private static int dirCount = 0;
       80   -
            * The system independent newline character.
      +
           /**
       81   +
            * The system independent newline character.
      +  82  
            */
      -  82  2
           private static final String NEWLINE = System.getProperty("line.separator");
      -  83   -
           /**
      +  83  1
           private static final String NEWLINE = System.getProperty("line.separator");
       84   -
            * A list of values in the manifest to ignore as they only result in false
      +
           /**
       85   -
            * positives.
      +
            * A list of values in the manifest to ignore as they only result in false
       86   +
            * positives.
      +  87  
            */
      -  87  2
           private static final Set<String> IGNORE_VALUES = newHashSet(
      -  88   -
                   "Sun Java System Application Server");
      +  88  1
           private static final Set<String> IGNORE_VALUES = newHashSet(
       89   -
           /**
      +
                   "Sun Java System Application Server");
       90   -
            * A list of elements in the manifest to ignore.
      +
           /**
       91   +
            * A list of elements in the manifest to ignore.
      +  92  
            */
      -  92  2
           private static final Set<String> IGNORE_KEYS = newHashSet(
      -  93   -
                   "built-by",
      +  93  1
           private static final Set<String> IGNORE_KEYS = newHashSet(
       94   -
                   "created-by",
      +
                   "built-by",
       95   -
                   "builtby",
      +
                   "created-by",
       96   -
                   "createdby",
      +
                   "builtby",
       97   -
                   "build-jdk",
      +
                   "createdby",
       98   -
                   "buildjdk",
      +
                   "build-jdk",
       99   -
                   "ant-version",
      +
                   "buildjdk",
       100   -
                   "antversion",
      +
                   "ant-version",
       101   -
                   "dynamicimportpackage",
      +
                   "antversion",
       102   -
                   "dynamicimport-package",
      +
                   "dynamicimportpackage",
       103   -
                   "dynamic-importpackage",
      +
                   "dynamicimport-package",
       104   -
                   "dynamic-import-package",
      +
                   "dynamic-importpackage",
       105   -
                   "import-package",
      +
                   "dynamic-import-package",
       106   -
                   "ignore-package",
      +
                   "import-package",
       107   -
                   "export-package",
      +
                   "ignore-package",
       108   -
                   "importpackage",
      +
                   "export-package",
       109   -
                   "ignorepackage",
      +
                   "importpackage",
       110   -
                   "exportpackage",
      +
                   "ignorepackage",
       111   -
                   "sealed",
      +
                   "exportpackage",
       112   -
                   "manifest-version",
      +
                   "sealed",
       113   -
                   "archiver-version",
      +
                   "manifest-version",
       114   -
                   "manifestversion",
      +
                   "archiver-version",
       115   -
                   "archiverversion",
      +
                   "manifestversion",
       116   -
                   "classpath",
      +
                   "archiverversion",
       117   -
                   "class-path",
      +
                   "classpath",
       118   -
                   "tool",
      +
                   "class-path",
       119   -
                   "bundle-manifestversion",
      +
                   "tool",
       120   -
                   "bundlemanifestversion",
      +
                   "bundle-manifestversion",
       121   -
                   "bundle-vendor",
      +
                   "bundlemanifestversion",
       122   -
                   "include-resource",
      +
                   "bundle-vendor",
       123   -
                   "embed-dependency",
      +
                   "include-resource",
       124   -
                   "ipojo-components",
      +
                   "embed-dependency",
       125   -
                   "ipojo-extension",
      +
                   "ipojo-components",
       126   -
                   "eclipse-sourcereferences");
      +
                   "ipojo-extension",
       127   -
           /**
      +
                   "eclipse-sourcereferences");
       128   -
            * Deprecated Jar manifest attribute, that is, nonetheless, useful for
      +
           /**
       129   -
            * analysis.
      +
            * Deprecated Jar manifest attribute, that is, nonetheless, useful for
       130   -
            */
      +
            * analysis.
       131   +
            */
      +  132  
           @SuppressWarnings("deprecation")
      -  132  2
           private static final String IMPLEMENTATION_VENDOR_ID = Attributes.Name.IMPLEMENTATION_VENDOR_ID
      -  133  2
                   .toString();
      -  134   -
           /**
      +  133  1
           private static final String IMPLEMENTATION_VENDOR_ID = Attributes.Name.IMPLEMENTATION_VENDOR_ID
      +  134  1
                   .toString();
       135   -
            * item in some manifest, should be considered medium confidence.
      +
           /**
       136   -
            */
      +
            * item in some manifest, should be considered medium confidence.
       137   -
           private static final String BUNDLE_VERSION = "Bundle-Version"; //: 2.1.2
      +
            */
       138   -
           /**
      +
           private static final String BUNDLE_VERSION = "Bundle-Version"; //: 2.1.2
       139   -
            * item in some manifest, should be considered medium confidence.
      +
           /**
       140   -
            */
      -  141   -
           private static final String BUNDLE_DESCRIPTION = "Bundle-Description"; //: Apache Struts 2
      -  142   -
           /**
      -  143  
            * item in some manifest, should be considered medium confidence.
      +  141   +
            */
      +  142   +
           private static final String BUNDLE_DESCRIPTION = "Bundle-Description"; //: Apache Struts 2
      +  143   +
           /**
       144   -
            */
      +
            * item in some manifest, should be considered medium confidence.
       145   -
           private static final String BUNDLE_NAME = "Bundle-Name"; //: Struts 2 Core
      +
            */
       146   -
           /**
      +
           private static final String BUNDLE_NAME = "Bundle-Name"; //: Struts 2 Core
       147   -
            * A pattern to detect HTML within text.
      +
           /**
       148   +
            * A pattern to detect HTML within text.
      +  149  
            */
      -  149  2
           private static final Pattern HTML_DETECTION_PATTERN = Pattern.compile("\\<[a-z]+.*/?\\>", Pattern.CASE_INSENSITIVE);
      -  150   -
       
      +  150  1
           private static final Pattern HTML_DETECTION_PATTERN = Pattern.compile("\\<[a-z]+.*/?\\>", Pattern.CASE_INSENSITIVE);
       151   -
           //</editor-fold>
      +
       
       152   -
           /**
      -  153   -
            * Constructs a new JarAnalyzer.
      -  154   -
            */
      -  155  20
           public JarAnalyzer() {
      -  156  20
           }
      -  157   -
       
      -  158   -
           //<editor-fold defaultstate="collapsed" desc="All standard implmentation details of Analyzer">
      -  159   -
           /**
      -  160   -
            * The name of the analyzer.
      -  161   -
            */
      -  162   -
           private static final String ANALYZER_NAME = "Jar Analyzer";
      -  163   -
           /**
      -  164   -
            * The phase that this analyzer is intended to run in.
      -  165   -
            */
      -  166  2
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
      -  167   -
           /**
      -  168   -
            * The set of file extensions supported by this analyzer.
      -  169   -
            */
      -  170  2
           private static final String[] EXTENSIONS = {"jar", "war"};
      -  171   -
       
      -  172   -
           /**
      -  173   -
            * The file filter used to determine which files this analyzer supports.
      -  174   -
            */
      -  175  2
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(EXTENSIONS).build();
      -  176   -
       
      -  177   -
           /**
      -  178   -
            * Returns the FileFilter.
      -  179   -
            *
      -  180   -
            * @return the FileFilter
      -  181   -
            */
      -  182   -
           @Override
      -  183   -
           protected FileFilter getFileFilter() {
      -  184  1722
               return FILTER;
      -  185   -
           }
      -  186   -
       
      -  187   -
           /**
      -  188   -
            * Returns the name of the analyzer.
      -  189   -
            *
      -  190   -
            * @return the name of the analyzer.
      -  191   -
            */
      -  192   -
           @Override
      -  193   -
           public String getName() {
      -  194  34
               return ANALYZER_NAME;
      -  195   -
           }
      -  196   -
       
      -  197   -
           /**
      -  198   -
            * Returns the phase that the analyzer is intended to run in.
      -  199   -
            *
      -  200   -
            * @return the phase that the analyzer is intended to run in.
      -  201   -
            */
      -  202   -
           @Override
      -  203   -
           public AnalysisPhase getAnalysisPhase() {
      -  204  8
               return ANALYSIS_PHASE;
      -  205   -
           }
      -  206  
           //</editor-fold>
      +  153   +
           /**
      +  154   +
            * Constructs a new JarAnalyzer.
      +  155   +
            */
      +  156  10
           public JarAnalyzer() {
      +  157  10
           }
      +  158   +
       
      +  159   +
           //<editor-fold defaultstate="collapsed" desc="All standard implmentation details of Analyzer">
      +  160   +
           /**
      +  161   +
            * The name of the analyzer.
      +  162   +
            */
      +  163   +
           private static final String ANALYZER_NAME = "Jar Analyzer";
      +  164   +
           /**
      +  165   +
            * The phase that this analyzer is intended to run in.
      +  166   +
            */
      +  167  1
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
      +  168   +
           /**
      +  169   +
            * The set of file extensions supported by this analyzer.
      +  170   +
            */
      +  171  1
           private static final String[] EXTENSIONS = {"jar", "war"};
      +  172   +
       
      +  173   +
           /**
      +  174   +
            * The file filter used to determine which files this analyzer supports.
      +  175   +
            */
      +  176  1
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(EXTENSIONS).build();
      +  177   +
       
      +  178   +
           /**
      +  179   +
            * Returns the FileFilter.
      +  180   +
            *
      +  181   +
            * @return the FileFilter
      +  182   +
            */
      +  183   +
           @Override
      +  184   +
           protected FileFilter getFileFilter() {
      +  185  12
               return FILTER;
      +  186   +
           }
      +  187   +
       
      +  188   +
           /**
      +  189   +
            * Returns the name of the analyzer.
      +  190   +
            *
      +  191   +
            * @return the name of the analyzer.
      +  192   +
            */
      +  193   +
           @Override
      +  194   +
           public String getName() {
      +  195  17
               return ANALYZER_NAME;
      +  196   +
           }
      +  197   +
       
      +  198   +
           /**
      +  199   +
            * Returns the phase that the analyzer is intended to run in.
      +  200   +
            *
      +  201   +
            * @return the phase that the analyzer is intended to run in.
      +  202   +
            */
      +  203   +
           @Override
      +  204   +
           public AnalysisPhase getAnalysisPhase() {
      +  205  4
               return ANALYSIS_PHASE;
      +  206   +
           }
       207   -
       
      +
           //</editor-fold>
       208   -
           /**
      +
       
       209   -
            * Returns the key used in the properties file to reference the analyzer's
      +
           /**
       210   -
            * enabled property.
      +
            * Returns the key used in the properties file to reference the analyzer's
       211   -
            *
      +
            * enabled property.
       212   -
            * @return the analyzer's enabled property setting key
      +
            *
       213   -
            */
      +
            * @return the analyzer's enabled property setting key
       214   -
           @Override
      +
            */
       215   +
           @Override
      +  216  
           protected String getAnalyzerEnabledSettingKey() {
      -  216  20
               return Settings.KEYS.ANALYZER_JAR_ENABLED;
      -  217   -
           }
      +  217  10
               return Settings.KEYS.ANALYZER_JAR_ENABLED;
       218   -
       
      +
           }
       219   -
           /**
      +
       
       220   -
            * Loads a specified JAR file and collects information from the manifest and
      +
           /**
       221   -
            * checksums to identify the correct CPE information.
      +
            * Loads a specified JAR file and collects information from the manifest and
       222   -
            *
      +
            * checksums to identify the correct CPE information.
       223   -
            * @param dependency the dependency to analyze.
      +
            *
       224   -
            * @param engine the engine that is scanning the dependencies
      +
            * @param dependency the dependency to analyze.
       225   -
            * @throws AnalysisException is thrown if there is an error reading the JAR
      +
            * @param engine the engine that is scanning the dependencies
       226   -
            * file.
      +
            * @throws AnalysisException is thrown if there is an error reading the JAR
       227   -
            */
      +
            * file.
       228   -
           @Override
      +
            */
       229   -
           public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException {
      +
           @Override
       230   +
           public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException {
      +  231  
               try {
      -  231  12
                   final List<ClassNameInformation> classNames = collectClassNames(dependency);
      -  232  12
                   final String fileName = dependency.getFileName().toLowerCase();
      -  233  12
                   if (classNames.isEmpty()
      -  234  2
                           && (fileName.endsWith("-sources.jar")
      -  235  2
                           || fileName.endsWith("-javadoc.jar")
      -  236  2
                           || fileName.endsWith("-src.jar")
      -  237  2
                           || fileName.endsWith("-doc.jar"))) {
      -  238  0
                       engine.getDependencies().remove(dependency);
      -  239   +  232  6
                   final List<ClassNameInformation> classNames = collectClassNames(dependency);
      +  233  6
                   final String fileName = dependency.getFileName().toLowerCase();
      +  234  6
                   if (classNames.isEmpty()
      +  235  1
                           && (fileName.endsWith("-sources.jar")
      +  236  1
                           || fileName.endsWith("-javadoc.jar")
      +  237  1
                           || fileName.endsWith("-src.jar")
      +  238  1
                           || fileName.endsWith("-doc.jar"))) {
      +  239  0
                       engine.getDependencies().remove(dependency);
      +  240  
                   }
      -  240  12
                   final boolean hasManifest = parseManifest(dependency, classNames);
      -  241  12
                   final boolean hasPOM = analyzePOM(dependency, classNames, engine);
      -  242  12
                   final boolean addPackagesAsEvidence = !(hasManifest && hasPOM);
      -  243  12
                   analyzePackageNames(classNames, dependency, addPackagesAsEvidence);
      -  244  0
               } catch (IOException ex) {
      -  245  0
                   throw new AnalysisException("Exception occurred reading the JAR file.", ex);
      -  246  12
               }
      -  247  12
           }
      -  248   -
       
      +  241  6
                   final boolean hasManifest = parseManifest(dependency, classNames);
      +  242  6
                   final boolean hasPOM = analyzePOM(dependency, classNames, engine);
      +  243  6
                   final boolean addPackagesAsEvidence = !(hasManifest && hasPOM);
      +  244  6
                   analyzePackageNames(classNames, dependency, addPackagesAsEvidence);
      +  245  0
               } catch (IOException ex) {
      +  246  0
                   throw new AnalysisException("Exception occurred reading the JAR file.", ex);
      +  247  6
               }
      +  248  6
           }
       249   -
           /**
      +
       
       250   -
            * Attempts to find a pom.xml within the JAR file. If found it extracts
      +
           /**
       251   -
            * information and adds it to the evidence. This will attempt to interpolate
      +
            * Attempts to find a pom.xml within the JAR file. If found it extracts
       252   -
            * the strings contained within the pom.properties if one exists.
      +
            * information and adds it to the evidence. This will attempt to interpolate
       253   -
            *
      +
            * the strings contained within the pom.properties if one exists.
       254   -
            * @param dependency the dependency being analyzed
      +
            *
       255   -
            * @param classes a collection of class name information
      +
            * @param dependency the dependency being analyzed
       256   -
            * @param engine the analysis engine, used to add additional dependencies
      -  257   -
            * @throws AnalysisException is thrown if there is an exception parsing the
      -  258   -
            * pom
      -  259   -
            * @return whether or not evidence was added to the dependency
      -  260   -
            */
      -  261   -
           protected boolean analyzePOM(Dependency dependency, List<ClassNameInformation> classes, Engine engine) throws AnalysisException {
      -  262  12
               boolean foundSomething = false;
      -  263   -
               final JarFile jar;
      -  264   -
               try {
      -  265  12
                   jar = new JarFile(dependency.getActualFilePath());
      -  266  0
               } catch (IOException ex) {
      -  267  0
                   LOGGER.warn("Unable to read JarFile '{}'.", dependency.getActualFilePath());
      -  268  0
                   LOGGER.trace("", ex);
      -  269  0
                   return false;
      -  270  12
               }
      -  271   -
               List<String> pomEntries;
      -  272   -
               try {
      -  273  12
                   pomEntries = retrievePomListing(jar);
      -  274  0
               } catch (IOException ex) {
      -  275  0
                   LOGGER.warn("Unable to read Jar file entries in '{}'.", dependency.getActualFilePath());
      -  276  0
                   LOGGER.trace("", ex);
      -  277  0
                   return false;
      -  278  12
               }
      -  279  12
               File externalPom = null;
      -  280  12
               if (pomEntries.isEmpty()) {
      -  281  8
                   final String pomPath = FilenameUtils.removeExtension(dependency.getActualFilePath()) + ".pom";
      -  282  8
                   externalPom = new File(pomPath);
      -  283  8
                   if (externalPom.isFile()) {
      -  284  0
                       pomEntries.add(pomPath);
      -  285   -
                   } else {
      -  286  8
                       return false;
      -  287   -
                   }
      -  288   -
               }
      -  289  4
               for (String path : pomEntries) {
      -  290  4
                   LOGGER.debug("Reading pom entry: {}", path);
      -  291  4
                   Properties pomProperties = null;
      -  292   -
                   try {
      -  293  4
                       if (externalPom == null) {
      -  294  4
                           pomProperties = retrievePomProperties(path, jar);
      -  295   -
                       }
      -  296  0
                   } catch (IOException ex) {
      -  297  0
                       LOGGER.trace("ignore this, failed reading a non-existent pom.properties", ex);
      -  298  4
                   }
      -  299  4
                   Model pom = null;
      -  300   -
                   try {
      -  301  4
                       if (pomEntries.size() > 1) {
      -  302   -
                           //extract POM to its own directory and add it as its own dependency
      -  303  0
                           final Dependency newDependency = new Dependency();
      -  304  0
                           pom = extractPom(path, jar, newDependency);
      -  305   -
       
      -  306  0
                           final String displayPath = String.format("%s%s%s",
      -  307  0
                                   dependency.getFilePath(),
      -  308   -
                                   File.separator,
      -  309   -
                                   path);
      -  310  0
                           final String displayName = String.format("%s%s%s",
      -  311  0
                                   dependency.getFileName(),
      -  312   -
                                   File.separator,
      -  313   -
                                   path);
      -  314   -
       
      -  315  0
                           newDependency.setFileName(displayName);
      -  316  0
                           newDependency.setFilePath(displayPath);
      -  317  0
                           pom.processProperties(pomProperties);
      -  318  0
                           setPomEvidence(newDependency, pom, null);
      -  319  0
                           engine.getDependencies().add(newDependency);
      -  320  0
                           Collections.sort(engine.getDependencies());
      -  321  0
                       } else {
      -  322  4
                           if (externalPom == null) {
      -  323  4
                               pom = PomUtils.readPom(path, jar);
      -  324   -
                           } else {
      -  325  0
                               pom = PomUtils.readPom(externalPom);
      -  326   -
                           }
      -  327  4
                           pom.processProperties(pomProperties);
      -  328  4
                           foundSomething |= setPomEvidence(dependency, pom, classes);
      -  329   -
                       }
      -  330  0
                   } catch (AnalysisException ex) {
      -  331  0
                       LOGGER.warn("An error occurred while analyzing '{}'.", dependency.getActualFilePath());
      -  332  0
                       LOGGER.trace("", ex);
      -  333  4
                   }
      -  334  4
               }
      -  335  4
               return foundSomething;
      -  336   -
           }
      -  337   -
       
      -  338   -
           /**
      -  339   -
            * Given a path to a pom.xml within a JarFile, this method attempts to load
      -  340   -
            * a sibling pom.properties if one exists.
      -  341   -
            *
      -  342   -
            * @param path the path to the pom.xml within the JarFile
      -  343   -
            * @param jar the JarFile to load the pom.properties from
      -  344   -
            * @return a Properties object or null if no pom.properties was found
      -  345   -
            * @throws IOException thrown if there is an exception reading the
      -  346   -
            * pom.properties
      -  347   -
            */
      -  348   -
           private Properties retrievePomProperties(String path, final JarFile jar) throws IOException {
      -  349  4
               Properties pomProperties = null;
      -  350  4
               final String propPath = path.substring(0, path.length() - 7) + "pom.properies";
      -  351  4
               final ZipEntry propEntry = jar.getEntry(propPath);
      -  352  4
               if (propEntry != null) {
      -  353  0
                   Reader reader = null;
      -  354   -
                   try {
      -  355  0
                       reader = new InputStreamReader(jar.getInputStream(propEntry), "UTF-8");
      -  356  0
                       pomProperties = new Properties();
      -  357  0
                       pomProperties.load(reader);
      -  358  0
                       LOGGER.debug("Read pom.properties: {}", propPath);
      -  359   -
                   } finally {
      -  360  0
                       if (reader != null) {
      -  361   -
                           try {
      -  362  0
                               reader.close();
      -  363  0
                           } catch (IOException ex) {
      -  364  0
                               LOGGER.trace("close error", ex);
      -  365  0
                           }
      -  366   -
                       }
      -  367   -
                   }
      -  368   -
               }
      -  369  4
               return pomProperties;
      -  370   -
           }
      -  371   -
       
      -  372   -
           /**
      -  373   -
            * Searches a JarFile for pom.xml entries and returns a listing of these
      -  374   -
            * entries.
      -  375   -
            *
      -  376   -
            * @param jar the JarFile to search
      -  377   -
            * @return a list of pom.xml entries
      -  378   -
            * @throws IOException thrown if there is an exception reading a JarEntry
      -  379   -
            */
      -  380   -
           private List<String> retrievePomListing(final JarFile jar) throws IOException {
      -  381  12
               final List<String> pomEntries = new ArrayList<String>();
      -  382  12
               final Enumeration<JarEntry> entries = jar.entries();
      -  383  3704
               while (entries.hasMoreElements()) {
      -  384  3692
                   final JarEntry entry = entries.nextElement();
      -  385  3692
                   final String entryName = (new File(entry.getName())).getName().toLowerCase();
      -  386  3692
                   if (!entry.isDirectory() && "pom.xml".equals(entryName)) {
      -  387  4
                       LOGGER.trace("POM Entry found: {}", entry.getName());
      -  388  4
                       pomEntries.add(entry.getName());
      -  389   -
                   }
      -  390  3692
               }
      -  391  12
               return pomEntries;
      -  392   -
           }
      -  393   -
       
      -  394   -
           /**
      -  395   -
            * Retrieves the specified POM from a jar file and converts it to a Model.
      -  396   -
            *
      -  397   -
            * @param path the path to the pom.xml file within the jar file
      -  398   -
            * @param jar the jar file to extract the pom from
      -  399   -
            * @param dependency the dependency being analyzed
      -  400   -
            * @return returns the POM object
      -  401   -
            * @throws AnalysisException is thrown if there is an exception extracting
      -  402   -
            * or parsing the POM {@link org.owasp.dependencycheck.xml.pom.Model} object
      -  403   -
            */
      -  404   -
           private Model extractPom(String path, JarFile jar, Dependency dependency) throws AnalysisException {
      -  405  0
               InputStream input = null;
      -  406  0
               FileOutputStream fos = null;
      -  407  0
               final File tmpDir = getNextTempDirectory();
      -  408  0
               final File file = new File(tmpDir, "pom.xml");
      -  409   -
               try {
      -  410  0
                   final ZipEntry entry = jar.getEntry(path);
      -  411  0
                   input = jar.getInputStream(entry);
      -  412  0
                   fos = new FileOutputStream(file);
      -  413  0
                   IOUtils.copy(input, fos);
      -  414  0
                   dependency.setActualFilePath(file.getAbsolutePath());
      -  415  0
               } catch (IOException ex) {
      -  416  0
                   LOGGER.warn("An error occurred reading '{}' from '{}'.", path, dependency.getFilePath());
      -  417  0
                   LOGGER.error("", ex);
      -  418   -
               } finally {
      -  419  0
                   closeStream(fos);
      -  420  0
                   closeStream(input);
      -  421  0
               }
      -  422  0
               return PomUtils.readPom(file);
      -  423   -
           }
      -  424   -
       
      -  425   -
           /**
      -  426   -
            * Silently closes an input stream ignoring errors.
      -  427   -
            *
      -  428   -
            * @param stream an input stream to close
      -  429   -
            */
      -  430   -
           private void closeStream(InputStream stream) {
      -  431  0
               if (stream != null) {
      -  432   -
                   try {
      -  433  0
                       stream.close();
      -  434  0
                   } catch (IOException ex) {
      -  435  0
                       LOGGER.trace("", ex);
      -  436  0
                   }
      -  437   -
               }
      -  438  0
           }
      -  439   -
       
      -  440   -
           /**
      -  441   -
            * Silently closes an output stream ignoring errors.
      -  442   -
            *
      -  443   -
            * @param stream an output stream to close
      -  444   -
            */
      -  445   -
           private void closeStream(OutputStream stream) {
      -  446  0
               if (stream != null) {
      -  447   -
                   try {
      -  448  0
                       stream.close();
      -  449  0
                   } catch (IOException ex) {
      -  450  0
                       LOGGER.trace("", ex);
      -  451  0
                   }
      -  452   -
               }
      -  453  0
           }
      -  454   -
       
      -  455   -
           /**
      -  456   -
            * Sets evidence from the pom on the supplied dependency.
      -  457   -
            *
      -  458   -
            * @param dependency the dependency to set data on
      -  459   -
            * @param pom the information from the pom
      -  460   -
            * @param classes a collection of ClassNameInformation - containing data
      -  461   -
            * about the fully qualified class names within the JAR file being analyzed
      -  462   -
            * @return true if there was evidence within the pom that we could use;
      -  463   -
            * otherwise false
      -  464   -
            */
      -  465   -
           public static boolean setPomEvidence(Dependency dependency, Model pom, List<ClassNameInformation> classes) {
      -  466  4
               boolean foundSomething = false;
      -  467  4
               boolean addAsIdentifier = true;
      -  468  4
               if (pom == null) {
      -  469  0
                   return foundSomething;
      -  470   -
               }
      -  471  4
               String groupid = pom.getGroupId();
      -  472  4
               String parentGroupId = pom.getParentGroupId();
      -  473  4
               String artifactid = pom.getArtifactId();
      -  474  4
               String parentArtifactId = pom.getParentArtifactId();
      -  475  4
               String version = pom.getVersion();
      -  476  4
               String parentVersion = pom.getParentVersion();
      -  477   -
       
      -  478  4
               if ("org.sonatype.oss".equals(parentGroupId) && "oss-parent".equals(parentArtifactId)) {
      -  479  0
                   parentGroupId = null;
      -  480  0
                   parentArtifactId = null;
      -  481  0
                   parentVersion = null;
      -  482   -
               }
      -  483   -
       
      -  484  4
               if ((groupid == null || groupid.isEmpty()) && parentGroupId != null && !parentGroupId.isEmpty()) {
      -  485  0
                   groupid = parentGroupId;
      -  486   -
               }
      -  487   -
       
      -  488  4
               final String originalGroupID = groupid;
      -  489  4
               if (groupid.startsWith("org.") || groupid.startsWith("com.")) {
      -  490  2
                   groupid = groupid.substring(4);
      -  491   -
               }
      -  492   -
       
      -  493  4
               if ((artifactid == null || artifactid.isEmpty()) && parentArtifactId != null && !parentArtifactId.isEmpty()) {
      -  494  0
                   artifactid = parentArtifactId;
      -  495   -
               }
      -  496   -
       
      -  497  4
               final String originalArtifactID = artifactid;
      -  498  4
               if (artifactid.startsWith("org.") || artifactid.startsWith("com.")) {
      -  499  0
                   artifactid = artifactid.substring(4);
      -  500   -
               }
      -  501   -
       
      -  502  4
               if ((version == null || version.isEmpty()) && parentVersion != null && !parentVersion.isEmpty()) {
      -  503  2
                   version = parentVersion;
      -  504   -
               }
      -  505   -
       
      -  506  4
               if (groupid != null && !groupid.isEmpty()) {
      -  507  4
                   foundSomething = true;
      -  508  4
                   dependency.getVendorEvidence().addEvidence("pom", "groupid", groupid, Confidence.HIGHEST);
      -  509  4
                   dependency.getProductEvidence().addEvidence("pom", "groupid", groupid, Confidence.LOW);
      -  510  4
                   addMatchingValues(classes, groupid, dependency.getVendorEvidence());
      -  511  4
                   addMatchingValues(classes, groupid, dependency.getProductEvidence());
      -  512  4
                   if (parentGroupId != null && !parentGroupId.isEmpty() && !parentGroupId.equals(groupid)) {
      -  513  2
                       dependency.getVendorEvidence().addEvidence("pom", "parent-groupid", parentGroupId, Confidence.MEDIUM);
      -  514  2
                       dependency.getProductEvidence().addEvidence("pom", "parent-groupid", parentGroupId, Confidence.LOW);
      -  515  2
                       addMatchingValues(classes, parentGroupId, dependency.getVendorEvidence());
      -  516  2
                       addMatchingValues(classes, parentGroupId, dependency.getProductEvidence());
      -  517   -
                   }
      -  518   -
               } else {
      -  519  0
                   addAsIdentifier = false;
      -  520   -
               }
      -  521   -
       
      -  522  4
               if (artifactid != null && !artifactid.isEmpty()) {
      -  523  4
                   foundSomething = true;
      -  524  4
                   dependency.getProductEvidence().addEvidence("pom", "artifactid", artifactid, Confidence.HIGHEST);
      -  525  4
                   dependency.getVendorEvidence().addEvidence("pom", "artifactid", artifactid, Confidence.LOW);
      -  526  4
                   addMatchingValues(classes, artifactid, dependency.getVendorEvidence());
      -  527  4
                   addMatchingValues(classes, artifactid, dependency.getProductEvidence());
      -  528  4
                   if (parentArtifactId != null && !parentArtifactId.isEmpty() && !parentArtifactId.equals(artifactid)) {
      -  529  2
                       dependency.getProductEvidence().addEvidence("pom", "parent-artifactid", parentArtifactId, Confidence.MEDIUM);
      -  530  2
                       dependency.getVendorEvidence().addEvidence("pom", "parent-artifactid", parentArtifactId, Confidence.LOW);
      -  531  2
                       addMatchingValues(classes, parentArtifactId, dependency.getVendorEvidence());
      -  532  2
                       addMatchingValues(classes, parentArtifactId, dependency.getProductEvidence());
      -  533   -
                   }
      -  534   -
               } else {
      -  535  0
                   addAsIdentifier = false;
      -  536   -
               }
      -  537   -
       
      -  538  4
               if (version != null && !version.isEmpty()) {
      -  539  4
                   foundSomething = true;
      -  540  4
                   dependency.getVersionEvidence().addEvidence("pom", "version", version, Confidence.HIGHEST);
      -  541  4
                   if (parentVersion != null && !parentVersion.isEmpty() && !parentVersion.equals(version)) {
      -  542  0
                       dependency.getVersionEvidence().addEvidence("pom", "parent-version", version, Confidence.LOW);
      -  543   -
                   }
      -  544   -
               } else {
      -  545  0
                   addAsIdentifier = false;
      -  546   -
               }
      -  547   -
       
      -  548  4
               if (addAsIdentifier) {
      -  549  4
                   dependency.addIdentifier("maven", String.format("%s:%s:%s", originalGroupID, originalArtifactID, version), null, Confidence.HIGH);
      -  550   -
               }
      -  551   -
       
      -  552   -
               // org name
      -  553  4
               final String org = pom.getOrganization();
      -  554  4
               if (org != null && !org.isEmpty()) {
      -  555  0
                   dependency.getVendorEvidence().addEvidence("pom", "organization name", org, Confidence.HIGH);
      -  556  0
                   dependency.getProductEvidence().addEvidence("pom", "organization name", org, Confidence.LOW);
      -  557  0
                   addMatchingValues(classes, org, dependency.getVendorEvidence());
      -  558  0
                   addMatchingValues(classes, org, dependency.getProductEvidence());
      -  559   -
               }
      -  560   -
               //pom name
      -  561  4
               final String pomName = pom.getName();
      -  562  4
               if (pomName
      -  563  4
                       != null && !pomName.isEmpty()) {
      -  564  4
                   foundSomething = true;
      -  565  4
                   dependency.getProductEvidence().addEvidence("pom", "name", pomName, Confidence.HIGH);
      -  566  4
                   dependency.getVendorEvidence().addEvidence("pom", "name", pomName, Confidence.HIGH);
      -  567  4
                   addMatchingValues(classes, pomName, dependency.getVendorEvidence());
      -  568  4
                   addMatchingValues(classes, pomName, dependency.getProductEvidence());
      -  569   -
               }
      -  570   -
       
      -  571   -
               //Description
      -  572  4
               final String description = pom.getDescription();
      -  573  4
               if (description != null && !description.isEmpty() && !description.startsWith("POM was created by")) {
      -  574  2
                   foundSomething = true;
      -  575  2
                   final String trimmedDescription = addDescription(dependency, description, "pom", "description");
      -  576  2
                   addMatchingValues(classes, trimmedDescription, dependency.getVendorEvidence());
      -  577  2
                   addMatchingValues(classes, trimmedDescription, dependency.getProductEvidence());
      -  578   -
               }
      -  579   -
       
      -  580  4
               final String projectURL = pom.getProjectURL();
      -  581  4
               if (projectURL != null && !projectURL.trim().isEmpty()) {
      -  582  2
                   dependency.getVendorEvidence().addEvidence("pom", "url", projectURL, Confidence.HIGHEST);
      -  583   -
               }
      -  584   -
       
      -  585  4
               extractLicense(pom, dependency);
      -  586  4
               return foundSomething;
      -  587   -
           }
      -  588   -
       
      -  589   -
           /**
      -  590   -
            * Analyzes the path information of the classes contained within the
      -  591   -
            * JarAnalyzer to try and determine possible vendor or product names. If any
      -  592   -
            * are found they are stored in the packageVendor and packageProduct
      -  593   -
            * hashSets.
      -  594   -
            *
      -  595   -
            * @param classNames a list of class names
      -  596   -
            * @param dependency a dependency to analyze
      -  597   -
            * @param addPackagesAsEvidence a flag indicating whether or not package
      -  598   -
            * names should be added as evidence.
      -  599   -
            */
      -  600   -
           protected void analyzePackageNames(List<ClassNameInformation> classNames,
      -  601   -
                   Dependency dependency, boolean addPackagesAsEvidence) {
      -  602  12
               final Map<String, Integer> vendorIdentifiers = new HashMap<String, Integer>();
      -  603  12
               final Map<String, Integer> productIdentifiers = new HashMap<String, Integer>();
      -  604  12
               analyzeFullyQualifiedClassNames(classNames, vendorIdentifiers, productIdentifiers);
      -  605   -
       
      -  606  12
               final int classCount = classNames.size();
      -  607  12
               final EvidenceCollection vendor = dependency.getVendorEvidence();
      -  608  12
               final EvidenceCollection product = dependency.getProductEvidence();
      -  609   -
       
      -  610  12
               for (Map.Entry<String, Integer> entry : vendorIdentifiers.entrySet()) {
      -  611  96
                   final float ratio = entry.getValue() / (float) classCount;
      -  612  96
                   if (ratio > 0.5) {
      -  613   -
                       //TODO remove weighting
      -  614  20
                       vendor.addWeighting(entry.getKey());
      -  615  20
                       if (addPackagesAsEvidence && entry.getKey().length() > 1) {
      -  616  16
                           vendor.addEvidence("jar", "package name", entry.getKey(), Confidence.LOW);
      -  617   -
                       }
      -  618   -
                   }
      -  619  96
               }
      -  620  12
               for (Map.Entry<String, Integer> entry : productIdentifiers.entrySet()) {
      -  621  1970
                   final float ratio = entry.getValue() / (float) classCount;
      -  622  1970
                   if (ratio > 0.5) {
      -  623  10
                       product.addWeighting(entry.getKey());
      -  624  10
                       if (addPackagesAsEvidence && entry.getKey().length() > 1) {
      -  625  8
                           product.addEvidence("jar", "package name", entry.getKey(), Confidence.LOW);
      -  626   -
                       }
      -  627   -
                   }
      -  628  1970
               }
      -  629  12
           }
      -  630   -
       
      -  631   -
           /**
      -  632   -
            * <p>
      -  633   -
            * Reads the manifest from the JAR file and collects the entries. Some
      -  634   -
            * vendorKey entries are:</p>
      -  635   -
            * <ul><li>Implementation Title</li>
      -  636   -
            * <li>Implementation Version</li> <li>Implementation Vendor</li>
      -  637   -
            * <li>Implementation VendorId</li> <li>Bundle Name</li> <li>Bundle
      -  638   -
            * Version</li> <li>Bundle Vendor</li> <li>Bundle Description</li> <li>Main
      -  639   -
            * Class</li> </ul>
      -  640   -
            * However, all but a handful of specific entries are read in.
      -  641   -
            *
      -  642   -
            * @param dependency A reference to the dependency
      -  643   -
            * @param classInformation a collection of class information
      -  644   -
            * @return whether evidence was identified parsing the manifest
      -  645   -
            * @throws IOException if there is an issue reading the JAR file
      -  646   -
            */
      -  647   -
           protected boolean parseManifest(Dependency dependency,
      -  648   -
                   List<ClassNameInformation> classInformation)
      -  649   -
                   throws IOException {
      -  650  14
               boolean foundSomething = false;
      -  651  14
               JarFile jar = null;
      -  652   -
               try {
      -  653  14
                   jar = new JarFile(dependency.getActualFilePath());
      -  654  14
                   final Manifest manifest = jar.getManifest();
      -  655  14
                   if (manifest == null) {
      -  656  0
                       if (!dependency.getFileName().toLowerCase().endsWith("-sources.jar")
      -  657  0
                               && !dependency.getFileName().toLowerCase().endsWith("-javadoc.jar")
      -  658  0
                               && !dependency.getFileName().toLowerCase().endsWith("-src.jar")
      -  659  0
                               && !dependency.getFileName().toLowerCase().endsWith("-doc.jar")) {
      -  660  0
                           LOGGER.debug("Jar file '{}' does not contain a manifest.",
      -  661  0
                                   dependency.getFileName());
      -  662   -
                       }
      -  663  0
                       return false;
      -  664   -
                   }
      -  665  14
                   final EvidenceCollection vendorEvidence = dependency.getVendorEvidence();
      -  666  14
                   final EvidenceCollection productEvidence = dependency.getProductEvidence();
      -  667  14
                   final EvidenceCollection versionEvidence = dependency.getVersionEvidence();
      -  668   -
       
      -  669  14
                   String source = "Manifest";
      -  670  14
                   String specificationVersion = null;
      -  671  14
                   boolean hasImplementationVersion = false;
      -  672  14
                   Attributes atts = manifest.getMainAttributes();
      -  673  14
                   for (Entry<Object, Object> entry : atts.entrySet()) {
      -  674  144
                       String key = entry.getKey().toString();
      -  675  144
                       String value = atts.getValue(key);
      -  676  144
                       if (HTML_DETECTION_PATTERN.matcher(value).find()) {
      -  677  0
                           value = Jsoup.parse(value).text();
      -  678   -
                       }
      -  679  144
                       if (IGNORE_VALUES.contains(value)) {
      -  680  0
                           continue;
      -  681  144
                       } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_TITLE.toString())) {
      -  682  2
                           foundSomething = true;
      -  683  2
                           productEvidence.addEvidence(source, key, value, Confidence.HIGH);
      -  684  2
                           addMatchingValues(classInformation, value, productEvidence);
      -  685  142
                       } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VERSION.toString())) {
      -  686  4
                           hasImplementationVersion = true;
      -  687  4
                           foundSomething = true;
      -  688  4
                           versionEvidence.addEvidence(source, key, value, Confidence.HIGH);
      -  689  138
                       } else if ("specification-version".equalsIgnoreCase(key)) {
      -  690  2
                           specificationVersion = key;
      -  691  136
                       } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VENDOR.toString())) {
      -  692  2
                           foundSomething = true;
      -  693  2
                           vendorEvidence.addEvidence(source, key, value, Confidence.HIGH);
      -  694  2
                           addMatchingValues(classInformation, value, vendorEvidence);
      -  695  134
                       } else if (key.equalsIgnoreCase(IMPLEMENTATION_VENDOR_ID)) {
      -  696  0
                           foundSomething = true;
      -  697  0
                           vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      -  698  0
                           addMatchingValues(classInformation, value, vendorEvidence);
      -  699  134
                       } else if (key.equalsIgnoreCase(BUNDLE_DESCRIPTION)) {
      -  700  4
                           foundSomething = true;
      -  701  4
                           addDescription(dependency, value, "manifest", key);
      -  702  4
                           addMatchingValues(classInformation, value, productEvidence);
      -  703  130
                       } else if (key.equalsIgnoreCase(BUNDLE_NAME)) {
      -  704  6
                           foundSomething = true;
      -  705  6
                           productEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      -  706  6
                           addMatchingValues(classInformation, value, productEvidence);
      -  707   -
       //                //the following caused false positives.
      -  708   -
       //                } else if (key.equalsIgnoreCase(BUNDLE_VENDOR)) {
      -  709   -
       //                    foundSomething = true;
      -  710   -
       //                    vendorEvidence.addEvidence(source, key, value, Confidence.HIGH);
      -  711   -
       //                    addMatchingValues(classInformation, value, vendorEvidence);
      -  712  124
                       } else if (key.equalsIgnoreCase(BUNDLE_VERSION)) {
      -  713  6
                           foundSomething = true;
      -  714  6
                           versionEvidence.addEvidence(source, key, value, Confidence.HIGH);
      -  715  118
                       } else if (key.equalsIgnoreCase(Attributes.Name.MAIN_CLASS.toString())) {
      -  716  6
                           continue;
      -  717   -
                           //skipping main class as if this has important information to add
      -  718   -
                           // it will be added during class name analysis...  if other fields
      -  719   -
                           // have the information from the class name then they will get added...
      -  720   -
                       } else {
      -  721  112
                           key = key.toLowerCase();
      -  722  112
                           if (!IGNORE_KEYS.contains(key)
      -  723  30
                                   && !key.endsWith("jdk")
      -  724  30
                                   && !key.contains("lastmodified")
      -  725  28
                                   && !key.endsWith("package")
      -  726  28
                                   && !key.endsWith("classpath")
      -  727  28
                                   && !key.endsWith("class-path")
      -  728  28
                                   && !key.endsWith("-scm") //todo change this to a regex?
      -  729  28
                                   && !key.startsWith("scm-")
      -  730  28
                                   && !value.trim().startsWith("scm:")
      -  731  28
                                   && !isImportPackage(key, value)
      -  732  28
                                   && !isPackage(key, value)) {
      -  733  26
                               foundSomething = true;
      -  734  26
                               if (key.contains("version")) {
      -  735  0
                                   if (!key.contains("specification")) {
      -  736  0
                                       versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      -  737   -
                                   }
      -  738  26
                               } else if ("build-id".equals(key)) {
      -  739  0
                                   int pos = value.indexOf('(');
      -  740  0
                                   if (pos >= 0) {
      -  741  0
                                       value = value.substring(0, pos - 1);
      -  742   -
                                   }
      -  743  0
                                   pos = value.indexOf('[');
      -  744  0
                                   if (pos >= 0) {
      -  745  0
                                       value = value.substring(0, pos - 1);
      -  746   -
                                   }
      -  747  0
                                   versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      -  748  0
                               } else if (key.contains("title")) {
      -  749  2
                                   productEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      -  750  2
                                   addMatchingValues(classInformation, value, productEvidence);
      -  751  24
                               } else if (key.contains("vendor")) {
      -  752  0
                                   if (key.contains("specification")) {
      -  753  0
                                       vendorEvidence.addEvidence(source, key, value, Confidence.LOW);
      -  754   -
                                   } else {
      -  755  0
                                       vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      -  756  0
                                       addMatchingValues(classInformation, value, vendorEvidence);
      -  757   -
                                   }
      -  758  24
                               } else if (key.contains("name")) {
      -  759  6
                                   productEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      -  760  6
                                   vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      -  761  6
                                   addMatchingValues(classInformation, value, vendorEvidence);
      -  762  6
                                   addMatchingValues(classInformation, value, productEvidence);
      -  763  18
                               } else if (key.contains("license")) {
      -  764  4
                                   addLicense(dependency, value);
      -  765  14
                               } else if (key.contains("description")) {
      -  766  0
                                   addDescription(dependency, value, "manifest", key);
      -  767   -
                               } else {
      -  768  14
                                   productEvidence.addEvidence(source, key, value, Confidence.LOW);
      -  769  14
                                   vendorEvidence.addEvidence(source, key, value, Confidence.LOW);
      -  770  14
                                   addMatchingValues(classInformation, value, vendorEvidence);
      -  771  14
                                   addMatchingValues(classInformation, value, productEvidence);
      -  772  14
                                   if (value.matches(".*\\d.*")) {
      -  773  6
                                       final StringTokenizer tokenizer = new StringTokenizer(value, " ");
      -  774  30
                                       while (tokenizer.hasMoreElements()) {
      -  775  24
                                           final String s = tokenizer.nextToken();
      -  776  24
                                           if (s.matches("^[0-9.]+$")) {
      -  777  2
                                               versionEvidence.addEvidence(source, key, s, Confidence.LOW);
      -  778   -
                                           }
      -  779  24
                                       }
      -  780   -
                                   }
      -  781   -
                               }
      -  782   -
                           }
      -  783   -
                       }
      -  784  138
                   }
      -  785   -
       
      -  786  14
                   for (Map.Entry<String, Attributes> item : manifest.getEntries().entrySet()) {
      -  787  16
                       final String name = item.getKey();
      -  788  16
                       source = "manifest: " + name;
      -  789  16
                       atts = item.getValue();
      -  790  16
                       for (Entry<Object, Object> entry : atts.entrySet()) {
      -  791  76
                           final String key = entry.getKey().toString();
      -  792  76
                           final String value = atts.getValue(key);
      -  793  76
                           if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_TITLE.toString())) {
      -  794  16
                               foundSomething = true;
      -  795  16
                               productEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      -  796  16
                               addMatchingValues(classInformation, value, productEvidence);
      -  797  60
                           } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VERSION.toString())) {
      -  798  10
                               foundSomething = true;
      -  799  10
                               versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      -  800  50
                           } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VENDOR.toString())) {
      -  801  10
                               foundSomething = true;
      -  802  10
                               vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      -  803  10
                               addMatchingValues(classInformation, value, vendorEvidence);
      -  804  40
                           } else if (key.equalsIgnoreCase(Attributes.Name.SPECIFICATION_TITLE.toString())) {
      -  805  8
                               foundSomething = true;
      -  806  8
                               productEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      -  807  8
                               addMatchingValues(classInformation, value, productEvidence);
      -  808   -
                           }
      -  809  76
                       }
      -  810  16
                   }
      -  811  14
                   if (specificationVersion != null && !hasImplementationVersion) {
      -  812  0
                       foundSomething = true;
      -  813  0
                       versionEvidence.addEvidence(source, "specification-version", specificationVersion, Confidence.HIGH);
      -  814   -
                   }
      -  815   -
               } finally {
      -  816  14
                   if (jar != null) {
      -  817  14
                       jar.close();
      -  818   -
                   }
      -  819   -
               }
      -  820  14
               return foundSomething;
      -  821   -
           }
      -  822   -
       
      -  823   -
           /**
      -  824   -
            * Adds a description to the given dependency. If the description contains
      -  825   -
            * one of the following strings beyond 100 characters, then the description
      -  826   -
            * used will be trimmed to that position:
      -  827   -
            * <ul><li>"such as"</li><li>"like "</li><li>"will use "</li><li>"* uses
      -  828   -
            * "</li></ul>
      -  829   -
            *
      -  830   -
            * @param dependency a dependency
      -  831   -
            * @param description the description
      -  832   -
            * @param source the source of the evidence
      -  833   -
            * @param key the "name" of the evidence
      -  834   -
            * @return if the description is trimmed, the trimmed version is returned;
      -  835   -
            * otherwise the original description is returned
      -  836   -
            */
      -  837   -
           public static String addDescription(Dependency dependency, String description, String source, String key) {
      -  838  20
               if (dependency.getDescription() == null) {
      -  839  20
                   dependency.setDescription(description);
      -  840   -
               }
      -  841   -
               String desc;
      -  842  20
               if (HTML_DETECTION_PATTERN.matcher(description).find()) {
      -  843  0
                   desc = Jsoup.parse(description).text();
      -  844   -
               } else {
      -  845  20
                   desc = description;
      -  846   -
               }
      -  847  20
               dependency.setDescription(desc);
      -  848  20
               if (desc.length() > 100) {
      -  849  0
                   desc = desc.replaceAll("\\s\\s+", " ");
      -  850  0
                   final int posSuchAs = desc.toLowerCase().indexOf("such as ", 100);
      -  851  0
                   final int posLike = desc.toLowerCase().indexOf("like ", 100);
      -  852  0
                   final int posWillUse = desc.toLowerCase().indexOf("will use ", 100);
      -  853  0
                   final int posUses = desc.toLowerCase().indexOf(" uses ", 100);
      -  854  0
                   int pos = -1;
      -  855  0
                   pos = Math.max(pos, posSuchAs);
      -  856  0
                   if (pos >= 0 && posLike >= 0) {
      -  857  0
                       pos = Math.min(pos, posLike);
      -  858   -
                   } else {
      -  859  0
                       pos = Math.max(pos, posLike);
      -  860   -
                   }
      -  861  0
                   if (pos >= 0 && posWillUse >= 0) {
      -  862  0
                       pos = Math.min(pos, posWillUse);
      -  863   -
                   } else {
      -  864  0
                       pos = Math.max(pos, posWillUse);
      -  865   -
                   }
      -  866  0
                   if (pos >= 0 && posUses >= 0) {
      -  867  0
                       pos = Math.min(pos, posUses);
      -  868   -
                   } else {
      -  869  0
                       pos = Math.max(pos, posUses);
      -  870   -
                   }
      -  871   -
       
      -  872  0
                   if (pos > 0) {
      -  873  0
                       desc = desc.substring(0, pos) + "...";
      -  874   -
                   }
      -  875  0
                   dependency.getProductEvidence().addEvidence(source, key, desc, Confidence.LOW);
      -  876  0
                   dependency.getVendorEvidence().addEvidence(source, key, desc, Confidence.LOW);
      -  877  0
               } else {
      -  878  20
                   dependency.getProductEvidence().addEvidence(source, key, desc, Confidence.MEDIUM);
      -  879  20
                   dependency.getVendorEvidence().addEvidence(source, key, desc, Confidence.MEDIUM);
      -  880   -
               }
      -  881  20
               return desc;
      -  882   -
           }
      -  883   -
       
      -  884   -
           /**
      -  885   -
            * Adds a license to the given dependency.
      -  886   -
            *
      -  887   -
            * @param d a dependency
      -  888   -
            * @param license the license
      -  889   -
            */
      -  890   -
           private void addLicense(Dependency d, String license) {
      -  891  4
               if (d.getLicense() == null) {
      -  892  4
                   d.setLicense(license);
      -  893  0
               } else if (!d.getLicense().contains(license)) {
      -  894  0
                   d.setLicense(d.getLicense() + NEWLINE + license);
      -  895   -
               }
      -  896  4
           }
      -  897   -
       
      -  898   -
           /**
      -  899   -
            * The parent directory for the individual directories per archive.
      -  900   -
            */
      -  901  20
           private File tempFileLocation = null;
      -  902   -
       
      -  903   -
           /**
      -  904   -
            * Initializes the JarAnalyzer.
      -  905   -
            *
      -  906   -
            * @throws Exception is thrown if there is an exception creating a temporary
      -  907   -
            * directory
      -  908   -
            */
      -  909   -
           @Override
      -  910   -
           public void initializeFileTypeAnalyzer() throws Exception {
      -  911  2
               final File baseDir = Settings.getTempDirectory();
      -  912  2
               tempFileLocation = File.createTempFile("check", "tmp", baseDir);
      -  913  2
               if (!tempFileLocation.delete()) {
      -  914  0
                   final String msg = String.format("Unable to delete temporary file '%s'.", tempFileLocation.getAbsolutePath());
      -  915  0
                   throw new AnalysisException(msg);
      -  916   -
               }
      -  917  2
               if (!tempFileLocation.mkdirs()) {
      -  918  0
                   final String msg = String.format("Unable to create directory '%s'.", tempFileLocation.getAbsolutePath());
      -  919  0
                   throw new AnalysisException(msg);
      -  920   -
               }
      -  921  2
           }
      -  922   -
       
      -  923   -
           /**
      -  924   -
            * Deletes any files extracted from the JAR during analysis.
      -  925   -
            */
      -  926   -
           @Override
      -  927   -
           public void close() {
      -  928  4
               if (tempFileLocation != null && tempFileLocation.exists()) {
      -  929  2
                   LOGGER.debug("Attempting to delete temporary files");
      -  930  2
                   final boolean success = FileUtils.delete(tempFileLocation);
      -  931  2
                   if (!success) {
      -  932  0
                       LOGGER.warn("Failed to delete some temporary files, see the log for more details");
      -  933   -
                   }
      -  934   -
               }
      -  935  4
           }
      -  936   -
       
      -  937   -
           /**
      -  938   -
            * Determines if the key value pair from the manifest is for an "import"
      -  939   -
            * type entry for package names.
      -  940   -
            *
      -  941   -
            * @param key the key from the manifest
      -  942   -
            * @param value the value from the manifest
      -  943   -
            * @return true or false depending on if it is believed the entry is an
      -  944   -
            * "import" entry
      -  945   -
            */
      -  946   -
           private boolean isImportPackage(String key, String value) {
      -  947  28
               final Pattern packageRx = Pattern.compile("^([a-zA-Z0-9_#\\$\\*\\.]+\\s*[,;]\\s*)+([a-zA-Z0-9_#\\$\\*\\.]+\\s*)?$");
      -  948  28
               final boolean matches = packageRx.matcher(value).matches();
      -  949  28
               return matches && (key.contains("import") || key.contains("include") || value.length() > 10);
      -  950   -
           }
      -  951   -
       
      -  952   -
           /**
      -  953   -
            * Cycles through an enumeration of JarEntries, contained within the
      -  954   -
            * dependency, and returns a list of the class names. This does not include
      -  955   -
            * core Java package names (i.e. java.* or javax.*).
      -  956   -
            *
      -  957   -
            * @param dependency the dependency being analyzed
      -  958   -
            * @return an list of fully qualified class names
      -  959   -
            */
      -  960   -
           private List<ClassNameInformation> collectClassNames(Dependency dependency) {
      -  961  12
               final List<ClassNameInformation> classNames = new ArrayList<ClassNameInformation>();
      -  962  12
               JarFile jar = null;
      -  963   -
               try {
      -  964  12
                   jar = new JarFile(dependency.getActualFilePath());
      -  965  12
                   final Enumeration<JarEntry> entries = jar.entries();
      -  966  3704
                   while (entries.hasMoreElements()) {
      -  967  3692
                       final JarEntry entry = entries.nextElement();
      -  968  3692
                       final String name = entry.getName().toLowerCase();
      -  969   -
                       //no longer stripping "|com\\.sun" - there are some com.sun jar files with CVEs.
      -  970  3692
                       if (name.endsWith(".class") && !name.matches("^javax?\\..*$")) {
      -  971  3070
                           final ClassNameInformation className = new ClassNameInformation(name.substring(0, name.length() - 6));
      -  972  3070
                           classNames.add(className);
      -  973   -
                       }
      -  974  3692
                   }
      -  975  0
               } catch (IOException ex) {
      -  976  0
                   LOGGER.warn("Unable to open jar file '{}'.", dependency.getFileName());
      -  977  0
                   LOGGER.debug("", ex);
      -  978   -
               } finally {
      -  979  12
                   if (jar != null) {
      -  980   -
                       try {
      -  981  12
                           jar.close();
      -  982  0
                       } catch (IOException ex) {
      -  983  0
                           LOGGER.trace("", ex);
      -  984  12
                       }
      -  985   -
                   }
      -  986   -
               }
      -  987  12
               return classNames;
      -  988   -
           }
      -  989   -
       
      -  990   -
           /**
      -  991   -
            * Cycles through the list of class names and places the package levels 0-3
      -  992   -
            * into the provided maps for vendor and product. This is helpful when
      -  993   -
            * analyzing vendor/product as many times this is included in the package
      -  994   -
            * name.
      -  995   -
            *
      -  996   -
            * @param classNames a list of class names
      -  997   -
            * @param vendor HashMap of possible vendor names from package names (e.g.
      -  998   -
            * owasp)
      -  999   -
            * @param product HashMap of possible product names from package names (e.g.
      -  1000   -
            * dependencycheck)
      -  1001   -
            */
      -  1002   -
           private void analyzeFullyQualifiedClassNames(List<ClassNameInformation> classNames,
      -  1003   -
                   Map<String, Integer> vendor, Map<String, Integer> product) {
      -  1004  12
               for (ClassNameInformation entry : classNames) {
      -  1005  3070
                   final List<String> list = entry.getPackageStructure();
      -  1006  3070
                   addEntry(vendor, list.get(0));
      -  1007   -
       
      -  1008  3070
                   if (list.size() == 2) {
      -  1009  0
                       addEntry(product, list.get(1));
      -  1010   -
                   }
      -  1011  3070
                   if (list.size() == 3) {
      -  1012  690
                       addEntry(vendor, list.get(1));
      -  1013  690
                       addEntry(product, list.get(1));
      -  1014  690
                       addEntry(product, list.get(2));
      -  1015   -
                   }
      -  1016  3070
                   if (list.size() >= 4) {
      -  1017  2380
                       addEntry(vendor, list.get(1));
      -  1018  2380
                       addEntry(vendor, list.get(2));
      -  1019  2380
                       addEntry(product, list.get(1));
      -  1020  2380
                       addEntry(product, list.get(2));
      -  1021  2380
                       addEntry(product, list.get(3));
      -  1022   -
                   }
      -  1023  3070
               }
      -  1024  12
           }
      -  1025   -
       
      -  1026   -
           /**
      -  1027   -
            * Adds an entry to the specified collection and sets the Integer (e.g. the
      -  1028   -
            * count) to 1. If the entry already exists in the collection then the
      -  1029   -
            * Integer is incremented by 1.
      -  1030   -
            *
      -  1031   -
            * @param collection a collection of strings and their occurrence count
      -  1032   -
            * @param key the key to add to the collection
      -  1033   -
            */
      -  1034   -
           private void addEntry(Map<String, Integer> collection, String key) {
      -  1035  17040
               if (collection.containsKey(key)) {
      -  1036  14974
                   collection.put(key, collection.get(key) + 1);
      -  1037   -
               } else {
      -  1038  2066
                   collection.put(key, 1);
      -  1039   -
               }
      -  1040  17040
           }
      -  1041   -
       
      -  1042   -
           /**
      -  1043   -
            * Cycles through the collection of class name information to see if parts
      -  1044   -
            * of the package names are contained in the provided value. If found, it
      -  1045   -
            * will be added as the HIGHEST confidence evidence because we have more
      -  1046   -
            * then one source corroborating the value.
      -  1047   -
            *
      -  1048  
            * @param classes a collection of class name information
      -  1049   -
            * @param value the value to check to see if it contains a package name
      -  1050   -
            * @param evidence the evidence collection to add new entries too
      -  1051   +  257   +
            * @param engine the analysis engine, used to add additional dependencies
      +  258   +
            * @throws AnalysisException is thrown if there is an exception parsing the
      +  259   +
            * pom
      +  260   +
            * @return whether or not evidence was added to the dependency
      +  261  
            */
      -  1052   -
           private static void addMatchingValues(List<ClassNameInformation> classes, String value, EvidenceCollection evidence) {
      -  1053  126
               if (value == null || value.isEmpty() || classes == null || classes.isEmpty()) {
      -  1054  42
                   return;
      -  1055   -
               }
      -  1056  84
               final String text = value.toLowerCase();
      -  1057  84
               for (ClassNameInformation cni : classes) {
      -  1058  32644
                   for (String key : cni.getPackageStructure()) {
      -  1059  124836
                       final Pattern p = Pattern.compile("\b" + key + "\b");
      -  1060  124836
                       if (p.matcher(text).find()) {
      -  1061   -
                           //if (text.contains(key)) { //note, package structure elements are already lowercase.
      -  1062  0
                           evidence.addEvidence("jar", "package name", key, Confidence.HIGHEST);
      -  1063   -
                       }
      -  1064  124836
                   }
      -  1065  32644
               }
      -  1066  84
           }
      -  1067   -
       
      -  1068   -
           /**
      -  1069   -
            * Simple check to see if the attribute from a manifest is just a package
      -  1070   -
            * name.
      -  1071   -
            *
      -  1072   -
            * @param key the key of the value to check
      -  1073   -
            * @param value the value to check
      -  1074   -
            * @return true if the value looks like a java package name, otherwise false
      -  1075   -
            */
      -  1076   -
           private boolean isPackage(String key, String value) {
      -  1077   -
       
      -  1078  56
               return !key.matches(".*(version|title|vendor|name|license|description).*")
      -  1079  16
                       && value.matches("^([a-zA-Z_][a-zA-Z0-9_\\$]*(\\.[a-zA-Z_][a-zA-Z0-9_\\$]*)*)?$");
      -  1080   -
       
      -  1081   -
           }
      -  1082   -
       
      -  1083   -
           /**
      -  1084   -
            * Extracts the license information from the pom and adds it to the
      -  1085   -
            * dependency.
      -  1086   -
            *
      -  1087   -
            * @param pom the pom object
      -  1088   -
            * @param dependency the dependency to add license information too
      -  1089   -
            */
      -  1090   -
           public static void extractLicense(Model pom, Dependency dependency) {
      -  1091   -
               //license
      -  1092  4
               if (pom.getLicenses() != null) {
      -  1093  4
                   String license = null;
      -  1094  4
                   for (License lic : pom.getLicenses()) {
      -  1095  0
                       String tmp = null;
      -  1096  0
                       if (lic.getName() != null) {
      -  1097  0
                           tmp = lic.getName();
      -  1098   -
                       }
      -  1099  0
                       if (lic.getUrl() != null) {
      -  1100  0
                           if (tmp == null) {
      -  1101  0
                               tmp = lic.getUrl();
      -  1102   -
                           } else {
      -  1103  0
                               tmp += ": " + lic.getUrl();
      -  1104   -
                           }
      -  1105   -
                       }
      -  1106  0
                       if (tmp == null) {
      -  1107  0
                           continue;
      -  1108   -
                       }
      -  1109  0
                       if (HTML_DETECTION_PATTERN.matcher(tmp).find()) {
      -  1110  0
                           tmp = Jsoup.parse(tmp).text();
      -  1111   -
                       }
      -  1112  0
                       if (license == null) {
      -  1113  0
                           license = tmp;
      -  1114   -
                       } else {
      -  1115  0
                           license += "\n" + tmp;
      -  1116   -
                       }
      -  1117  0
                   }
      -  1118  4
                   if (license != null) {
      -  1119  0
                       dependency.setLicense(license);
      -  1120   -
       
      -  1121   +  262   +
           protected boolean analyzePOM(Dependency dependency, List<ClassNameInformation> classes, Engine engine) throws AnalysisException {
      +  263  6
               boolean foundSomething = false;
      +  264   +
               final JarFile jar;
      +  265   +
               try {
      +  266  6
                   jar = new JarFile(dependency.getActualFilePath());
      +  267  0
               } catch (IOException ex) {
      +  268  0
                   LOGGER.warn("Unable to read JarFile '{}'.", dependency.getActualFilePath());
      +  269  0
                   LOGGER.trace("", ex);
      +  270  0
                   return false;
      +  271  6
               }
      +  272   +
               List<String> pomEntries;
      +  273   +
               try {
      +  274  6
                   pomEntries = retrievePomListing(jar);
      +  275  0
               } catch (IOException ex) {
      +  276  0
                   LOGGER.warn("Unable to read Jar file entries in '{}'.", dependency.getActualFilePath());
      +  277  0
                   LOGGER.trace("", ex);
      +  278  0
                   return false;
      +  279  6
               }
      +  280  6
               File externalPom = null;
      +  281  6
               if (pomEntries.isEmpty()) {
      +  282  4
                   final String pomPath = FilenameUtils.removeExtension(dependency.getActualFilePath()) + ".pom";
      +  283  4
                   externalPom = new File(pomPath);
      +  284  4
                   if (externalPom.isFile()) {
      +  285  0
                       pomEntries.add(pomPath);
      +  286   +
                   } else {
      +  287  4
                       return false;
      +  288  
                   }
      -  1122   +  289  
               }
      -  1123  4
           }
      +  290  2
               for (String path : pomEntries) {
      +  291  2
                   LOGGER.debug("Reading pom entry: {}", path);
      +  292  2
                   Properties pomProperties = null;
      +  293   +
                   try {
      +  294  2
                       if (externalPom == null) {
      +  295  2
                           pomProperties = retrievePomProperties(path, jar);
      +  296   +
                       }
      +  297  0
                   } catch (IOException ex) {
      +  298  0
                       LOGGER.trace("ignore this, failed reading a non-existent pom.properties", ex);
      +  299  2
                   }
      +  300  2
                   Model pom = null;
      +  301   +
                   try {
      +  302  2
                       if (pomEntries.size() > 1) {
      +  303   +
                           //extract POM to its own directory and add it as its own dependency
      +  304  0
                           final Dependency newDependency = new Dependency();
      +  305  0
                           pom = extractPom(path, jar, newDependency);
      +  306   +
       
      +  307  0
                           final String displayPath = String.format("%s%s%s",
      +  308  0
                                   dependency.getFilePath(),
      +  309   +
                                   File.separator,
      +  310   +
                                   path);
      +  311  0
                           final String displayName = String.format("%s%s%s",
      +  312  0
                                   dependency.getFileName(),
      +  313   +
                                   File.separator,
      +  314   +
                                   path);
      +  315   +
       
      +  316  0
                           newDependency.setFileName(displayName);
      +  317  0
                           newDependency.setFilePath(displayPath);
      +  318  0
                           pom.processProperties(pomProperties);
      +  319  0
                           setPomEvidence(newDependency, pom, null);
      +  320  0
                           engine.getDependencies().add(newDependency);
      +  321  0
                           Collections.sort(engine.getDependencies());
      +  322  0
                       } else {
      +  323  2
                           if (externalPom == null) {
      +  324  2
                               pom = PomUtils.readPom(path, jar);
      +  325   +
                           } else {
      +  326  0
                               pom = PomUtils.readPom(externalPom);
      +  327   +
                           }
      +  328  2
                           pom.processProperties(pomProperties);
      +  329  2
                           foundSomething |= setPomEvidence(dependency, pom, classes);
      +  330   +
                       }
      +  331  0
                   } catch (AnalysisException ex) {
      +  332  0
                       LOGGER.warn("An error occurred while analyzing '{}'.", dependency.getActualFilePath());
      +  333  0
                       LOGGER.trace("", ex);
      +  334  2
                   }
      +  335  2
               }
      +  336  2
               return foundSomething;
      +  337   +
           }
      +  338   +
       
      +  339   +
           /**
      +  340   +
            * Given a path to a pom.xml within a JarFile, this method attempts to load
      +  341   +
            * a sibling pom.properties if one exists.
      +  342   +
            *
      +  343   +
            * @param path the path to the pom.xml within the JarFile
      +  344   +
            * @param jar the JarFile to load the pom.properties from
      +  345   +
            * @return a Properties object or null if no pom.properties was found
      +  346   +
            * @throws IOException thrown if there is an exception reading the
      +  347   +
            * pom.properties
      +  348   +
            */
      +  349   +
           private Properties retrievePomProperties(String path, final JarFile jar) throws IOException {
      +  350  2
               Properties pomProperties = null;
      +  351  2
               final String propPath = path.substring(0, path.length() - 7) + "pom.properies";
      +  352  2
               final ZipEntry propEntry = jar.getEntry(propPath);
      +  353  2
               if (propEntry != null) {
      +  354  0
                   Reader reader = null;
      +  355   +
                   try {
      +  356  0
                       reader = new InputStreamReader(jar.getInputStream(propEntry), "UTF-8");
      +  357  0
                       pomProperties = new Properties();
      +  358  0
                       pomProperties.load(reader);
      +  359  0
                       LOGGER.debug("Read pom.properties: {}", propPath);
      +  360   +
                   } finally {
      +  361  0
                       if (reader != null) {
      +  362   +
                           try {
      +  363  0
                               reader.close();
      +  364  0
                           } catch (IOException ex) {
      +  365  0
                               LOGGER.trace("close error", ex);
      +  366  0
                           }
      +  367   +
                       }
      +  368   +
                   }
      +  369   +
               }
      +  370  2
               return pomProperties;
      +  371   +
           }
      +  372   +
       
      +  373   +
           /**
      +  374   +
            * Searches a JarFile for pom.xml entries and returns a listing of these
      +  375   +
            * entries.
      +  376   +
            *
      +  377   +
            * @param jar the JarFile to search
      +  378   +
            * @return a list of pom.xml entries
      +  379   +
            * @throws IOException thrown if there is an exception reading a JarEntry
      +  380   +
            */
      +  381   +
           private List<String> retrievePomListing(final JarFile jar) throws IOException {
      +  382  6
               final List<String> pomEntries = new ArrayList<String>();
      +  383  6
               final Enumeration<JarEntry> entries = jar.entries();
      +  384  1852
               while (entries.hasMoreElements()) {
      +  385  1846
                   final JarEntry entry = entries.nextElement();
      +  386  1846
                   final String entryName = (new File(entry.getName())).getName().toLowerCase();
      +  387  1846
                   if (!entry.isDirectory() && "pom.xml".equals(entryName)) {
      +  388  2
                       LOGGER.trace("POM Entry found: {}", entry.getName());
      +  389  2
                       pomEntries.add(entry.getName());
      +  390   +
                   }
      +  391  1846
               }
      +  392  6
               return pomEntries;
      +  393   +
           }
      +  394   +
       
      +  395   +
           /**
      +  396   +
            * Retrieves the specified POM from a jar file and converts it to a Model.
      +  397   +
            *
      +  398   +
            * @param path the path to the pom.xml file within the jar file
      +  399   +
            * @param jar the jar file to extract the pom from
      +  400   +
            * @param dependency the dependency being analyzed
      +  401   +
            * @return returns the POM object
      +  402   +
            * @throws AnalysisException is thrown if there is an exception extracting
      +  403   +
            * or parsing the POM {@link org.owasp.dependencycheck.xml.pom.Model} object
      +  404   +
            */
      +  405   +
           private Model extractPom(String path, JarFile jar, Dependency dependency) throws AnalysisException {
      +  406  0
               InputStream input = null;
      +  407  0
               FileOutputStream fos = null;
      +  408  0
               final File tmpDir = getNextTempDirectory();
      +  409  0
               final File file = new File(tmpDir, "pom.xml");
      +  410   +
               try {
      +  411  0
                   final ZipEntry entry = jar.getEntry(path);
      +  412  0
                   input = jar.getInputStream(entry);
      +  413  0
                   fos = new FileOutputStream(file);
      +  414  0
                   IOUtils.copy(input, fos);
      +  415  0
                   dependency.setActualFilePath(file.getAbsolutePath());
      +  416  0
               } catch (IOException ex) {
      +  417  0
                   LOGGER.warn("An error occurred reading '{}' from '{}'.", path, dependency.getFilePath());
      +  418  0
                   LOGGER.error("", ex);
      +  419   +
               } finally {
      +  420  0
                   closeStream(fos);
      +  421  0
                   closeStream(input);
      +  422  0
               }
      +  423  0
               return PomUtils.readPom(file);
      +  424   +
           }
      +  425   +
       
      +  426   +
           /**
      +  427   +
            * Silently closes an input stream ignoring errors.
      +  428   +
            *
      +  429   +
            * @param stream an input stream to close
      +  430   +
            */
      +  431   +
           private void closeStream(InputStream stream) {
      +  432  0
               if (stream != null) {
      +  433   +
                   try {
      +  434  0
                       stream.close();
      +  435  0
                   } catch (IOException ex) {
      +  436  0
                       LOGGER.trace("", ex);
      +  437  0
                   }
      +  438   +
               }
      +  439  0
           }
      +  440   +
       
      +  441   +
           /**
      +  442   +
            * Silently closes an output stream ignoring errors.
      +  443   +
            *
      +  444   +
            * @param stream an output stream to close
      +  445   +
            */
      +  446   +
           private void closeStream(OutputStream stream) {
      +  447  0
               if (stream != null) {
      +  448   +
                   try {
      +  449  0
                       stream.close();
      +  450  0
                   } catch (IOException ex) {
      +  451  0
                       LOGGER.trace("", ex);
      +  452  0
                   }
      +  453   +
               }
      +  454  0
           }
      +  455   +
       
      +  456   +
           /**
      +  457   +
            * Sets evidence from the pom on the supplied dependency.
      +  458   +
            *
      +  459   +
            * @param dependency the dependency to set data on
      +  460   +
            * @param pom the information from the pom
      +  461   +
            * @param classes a collection of ClassNameInformation - containing data
      +  462   +
            * about the fully qualified class names within the JAR file being analyzed
      +  463   +
            * @return true if there was evidence within the pom that we could use;
      +  464   +
            * otherwise false
      +  465   +
            */
      +  466   +
           public static boolean setPomEvidence(Dependency dependency, Model pom, List<ClassNameInformation> classes) {
      +  467  2
               boolean foundSomething = false;
      +  468  2
               boolean addAsIdentifier = true;
      +  469  2
               if (pom == null) {
      +  470  0
                   return foundSomething;
      +  471   +
               }
      +  472  2
               String groupid = pom.getGroupId();
      +  473  2
               String parentGroupId = pom.getParentGroupId();
      +  474  2
               String artifactid = pom.getArtifactId();
      +  475  2
               String parentArtifactId = pom.getParentArtifactId();
      +  476  2
               String version = pom.getVersion();
      +  477  2
               String parentVersion = pom.getParentVersion();
      +  478   +
       
      +  479  2
               if ("org.sonatype.oss".equals(parentGroupId) && "oss-parent".equals(parentArtifactId)) {
      +  480  0
                   parentGroupId = null;
      +  481  0
                   parentArtifactId = null;
      +  482  0
                   parentVersion = null;
      +  483   +
               }
      +  484   +
       
      +  485  2
               if ((groupid == null || groupid.isEmpty()) && parentGroupId != null && !parentGroupId.isEmpty()) {
      +  486  0
                   groupid = parentGroupId;
      +  487   +
               }
      +  488   +
       
      +  489  2
               final String originalGroupID = groupid;
      +  490  2
               if (groupid.startsWith("org.") || groupid.startsWith("com.")) {
      +  491  1
                   groupid = groupid.substring(4);
      +  492   +
               }
      +  493   +
       
      +  494  2
               if ((artifactid == null || artifactid.isEmpty()) && parentArtifactId != null && !parentArtifactId.isEmpty()) {
      +  495  0
                   artifactid = parentArtifactId;
      +  496   +
               }
      +  497   +
       
      +  498  2
               final String originalArtifactID = artifactid;
      +  499  2
               if (artifactid.startsWith("org.") || artifactid.startsWith("com.")) {
      +  500  0
                   artifactid = artifactid.substring(4);
      +  501   +
               }
      +  502   +
       
      +  503  2
               if ((version == null || version.isEmpty()) && parentVersion != null && !parentVersion.isEmpty()) {
      +  504  1
                   version = parentVersion;
      +  505   +
               }
      +  506   +
       
      +  507  2
               if (groupid != null && !groupid.isEmpty()) {
      +  508  2
                   foundSomething = true;
      +  509  2
                   dependency.getVendorEvidence().addEvidence("pom", "groupid", groupid, Confidence.HIGHEST);
      +  510  2
                   dependency.getProductEvidence().addEvidence("pom", "groupid", groupid, Confidence.LOW);
      +  511  2
                   addMatchingValues(classes, groupid, dependency.getVendorEvidence());
      +  512  2
                   addMatchingValues(classes, groupid, dependency.getProductEvidence());
      +  513  2
                   if (parentGroupId != null && !parentGroupId.isEmpty() && !parentGroupId.equals(groupid)) {
      +  514  1
                       dependency.getVendorEvidence().addEvidence("pom", "parent-groupid", parentGroupId, Confidence.MEDIUM);
      +  515  1
                       dependency.getProductEvidence().addEvidence("pom", "parent-groupid", parentGroupId, Confidence.LOW);
      +  516  1
                       addMatchingValues(classes, parentGroupId, dependency.getVendorEvidence());
      +  517  1
                       addMatchingValues(classes, parentGroupId, dependency.getProductEvidence());
      +  518   +
                   }
      +  519   +
               } else {
      +  520  0
                   addAsIdentifier = false;
      +  521   +
               }
      +  522   +
       
      +  523  2
               if (artifactid != null && !artifactid.isEmpty()) {
      +  524  2
                   foundSomething = true;
      +  525  2
                   dependency.getProductEvidence().addEvidence("pom", "artifactid", artifactid, Confidence.HIGHEST);
      +  526  2
                   dependency.getVendorEvidence().addEvidence("pom", "artifactid", artifactid, Confidence.LOW);
      +  527  2
                   addMatchingValues(classes, artifactid, dependency.getVendorEvidence());
      +  528  2
                   addMatchingValues(classes, artifactid, dependency.getProductEvidence());
      +  529  2
                   if (parentArtifactId != null && !parentArtifactId.isEmpty() && !parentArtifactId.equals(artifactid)) {
      +  530  1
                       dependency.getProductEvidence().addEvidence("pom", "parent-artifactid", parentArtifactId, Confidence.MEDIUM);
      +  531  1
                       dependency.getVendorEvidence().addEvidence("pom", "parent-artifactid", parentArtifactId, Confidence.LOW);
      +  532  1
                       addMatchingValues(classes, parentArtifactId, dependency.getVendorEvidence());
      +  533  1
                       addMatchingValues(classes, parentArtifactId, dependency.getProductEvidence());
      +  534   +
                   }
      +  535   +
               } else {
      +  536  0
                   addAsIdentifier = false;
      +  537   +
               }
      +  538   +
       
      +  539  2
               if (version != null && !version.isEmpty()) {
      +  540  2
                   foundSomething = true;
      +  541  2
                   dependency.getVersionEvidence().addEvidence("pom", "version", version, Confidence.HIGHEST);
      +  542  2
                   if (parentVersion != null && !parentVersion.isEmpty() && !parentVersion.equals(version)) {
      +  543  0
                       dependency.getVersionEvidence().addEvidence("pom", "parent-version", version, Confidence.LOW);
      +  544   +
                   }
      +  545   +
               } else {
      +  546  0
                   addAsIdentifier = false;
      +  547   +
               }
      +  548   +
       
      +  549  2
               if (addAsIdentifier) {
      +  550  2
                   dependency.addIdentifier("maven", String.format("%s:%s:%s", originalGroupID, originalArtifactID, version), null, Confidence.HIGH);
      +  551   +
               }
      +  552   +
       
      +  553   +
               // org name
      +  554  2
               final String org = pom.getOrganization();
      +  555  2
               if (org != null && !org.isEmpty()) {
      +  556  0
                   dependency.getVendorEvidence().addEvidence("pom", "organization name", org, Confidence.HIGH);
      +  557  0
                   dependency.getProductEvidence().addEvidence("pom", "organization name", org, Confidence.LOW);
      +  558  0
                   addMatchingValues(classes, org, dependency.getVendorEvidence());
      +  559  0
                   addMatchingValues(classes, org, dependency.getProductEvidence());
      +  560   +
               }
      +  561   +
               //pom name
      +  562  2
               final String pomName = pom.getName();
      +  563  2
               if (pomName
      +  564  2
                       != null && !pomName.isEmpty()) {
      +  565  2
                   foundSomething = true;
      +  566  2
                   dependency.getProductEvidence().addEvidence("pom", "name", pomName, Confidence.HIGH);
      +  567  2
                   dependency.getVendorEvidence().addEvidence("pom", "name", pomName, Confidence.HIGH);
      +  568  2
                   addMatchingValues(classes, pomName, dependency.getVendorEvidence());
      +  569  2
                   addMatchingValues(classes, pomName, dependency.getProductEvidence());
      +  570   +
               }
      +  571   +
       
      +  572   +
               //Description
      +  573  2
               final String description = pom.getDescription();
      +  574  2
               if (description != null && !description.isEmpty() && !description.startsWith("POM was created by")) {
      +  575  1
                   foundSomething = true;
      +  576  1
                   final String trimmedDescription = addDescription(dependency, description, "pom", "description");
      +  577  1
                   addMatchingValues(classes, trimmedDescription, dependency.getVendorEvidence());
      +  578  1
                   addMatchingValues(classes, trimmedDescription, dependency.getProductEvidence());
      +  579   +
               }
      +  580   +
       
      +  581  2
               final String projectURL = pom.getProjectURL();
      +  582  2
               if (projectURL != null && !projectURL.trim().isEmpty()) {
      +  583  1
                   dependency.getVendorEvidence().addEvidence("pom", "url", projectURL, Confidence.HIGHEST);
      +  584   +
               }
      +  585   +
       
      +  586  2
               extractLicense(pom, dependency);
      +  587  2
               return foundSomething;
      +  588   +
           }
      +  589   +
       
      +  590   +
           /**
      +  591   +
            * Analyzes the path information of the classes contained within the
      +  592   +
            * JarAnalyzer to try and determine possible vendor or product names. If any
      +  593   +
            * are found they are stored in the packageVendor and packageProduct
      +  594   +
            * hashSets.
      +  595   +
            *
      +  596   +
            * @param classNames a list of class names
      +  597   +
            * @param dependency a dependency to analyze
      +  598   +
            * @param addPackagesAsEvidence a flag indicating whether or not package
      +  599   +
            * names should be added as evidence.
      +  600   +
            */
      +  601   +
           protected void analyzePackageNames(List<ClassNameInformation> classNames,
      +  602   +
                   Dependency dependency, boolean addPackagesAsEvidence) {
      +  603  6
               final Map<String, Integer> vendorIdentifiers = new HashMap<String, Integer>();
      +  604  6
               final Map<String, Integer> productIdentifiers = new HashMap<String, Integer>();
      +  605  6
               analyzeFullyQualifiedClassNames(classNames, vendorIdentifiers, productIdentifiers);
      +  606   +
       
      +  607  6
               final int classCount = classNames.size();
      +  608  6
               final EvidenceCollection vendor = dependency.getVendorEvidence();
      +  609  6
               final EvidenceCollection product = dependency.getProductEvidence();
      +  610   +
       
      +  611  6
               for (Map.Entry<String, Integer> entry : vendorIdentifiers.entrySet()) {
      +  612  48
                   final float ratio = entry.getValue() / (float) classCount;
      +  613  48
                   if (ratio > 0.5) {
      +  614   +
                       //TODO remove weighting
      +  615  10
                       vendor.addWeighting(entry.getKey());
      +  616  10
                       if (addPackagesAsEvidence && entry.getKey().length() > 1) {
      +  617  8
                           vendor.addEvidence("jar", "package name", entry.getKey(), Confidence.LOW);
      +  618   +
                       }
      +  619   +
                   }
      +  620  48
               }
      +  621  6
               for (Map.Entry<String, Integer> entry : productIdentifiers.entrySet()) {
      +  622  985
                   final float ratio = entry.getValue() / (float) classCount;
      +  623  985
                   if (ratio > 0.5) {
      +  624  5
                       product.addWeighting(entry.getKey());
      +  625  5
                       if (addPackagesAsEvidence && entry.getKey().length() > 1) {
      +  626  4
                           product.addEvidence("jar", "package name", entry.getKey(), Confidence.LOW);
      +  627   +
                       }
      +  628   +
                   }
      +  629  985
               }
      +  630  6
           }
      +  631   +
       
      +  632   +
           /**
      +  633   +
            * <p>
      +  634   +
            * Reads the manifest from the JAR file and collects the entries. Some
      +  635   +
            * vendorKey entries are:</p>
      +  636   +
            * <ul><li>Implementation Title</li>
      +  637   +
            * <li>Implementation Version</li> <li>Implementation Vendor</li>
      +  638   +
            * <li>Implementation VendorId</li> <li>Bundle Name</li> <li>Bundle
      +  639   +
            * Version</li> <li>Bundle Vendor</li> <li>Bundle Description</li> <li>Main
      +  640   +
            * Class</li> </ul>
      +  641   +
            * However, all but a handful of specific entries are read in.
      +  642   +
            *
      +  643   +
            * @param dependency A reference to the dependency
      +  644   +
            * @param classInformation a collection of class information
      +  645   +
            * @return whether evidence was identified parsing the manifest
      +  646   +
            * @throws IOException if there is an issue reading the JAR file
      +  647   +
            */
      +  648   +
           protected boolean parseManifest(Dependency dependency, List<ClassNameInformation> classInformation) throws IOException {
      +  649  7
               boolean foundSomething = false;
      +  650  7
               JarFile jar = null;
      +  651   +
               try {
      +  652  7
                   jar = new JarFile(dependency.getActualFilePath());
      +  653  7
                   final Manifest manifest = jar.getManifest();
      +  654  7
                   if (manifest == null) {
      +  655  0
                       if (!dependency.getFileName().toLowerCase().endsWith("-sources.jar")
      +  656  0
                               && !dependency.getFileName().toLowerCase().endsWith("-javadoc.jar")
      +  657  0
                               && !dependency.getFileName().toLowerCase().endsWith("-src.jar")
      +  658  0
                               && !dependency.getFileName().toLowerCase().endsWith("-doc.jar")) {
      +  659  0
                           LOGGER.debug("Jar file '{}' does not contain a manifest.",
      +  660  0
                                   dependency.getFileName());
      +  661   +
                       }
      +  662  0
                       return false;
      +  663   +
                   }
      +  664  7
                   final EvidenceCollection vendorEvidence = dependency.getVendorEvidence();
      +  665  7
                   final EvidenceCollection productEvidence = dependency.getProductEvidence();
      +  666  7
                   final EvidenceCollection versionEvidence = dependency.getVersionEvidence();
      +  667  7
                   String source = "Manifest";
      +  668  7
                   String specificationVersion = null;
      +  669  7
                   boolean hasImplementationVersion = false;
      +  670  7
                   Attributes atts = manifest.getMainAttributes();
      +  671  7
                   for (Entry<Object, Object> entry : atts.entrySet()) {
      +  672  72
                       String key = entry.getKey().toString();
      +  673  72
                       String value = atts.getValue(key);
      +  674  72
                       if (HTML_DETECTION_PATTERN.matcher(value).find()) {
      +  675  0
                           value = Jsoup.parse(value).text();
      +  676   +
                       }
      +  677  72
                       if (IGNORE_VALUES.contains(value)) {
      +  678  0
                           continue;
      +  679  72
                       } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_TITLE.toString())) {
      +  680  1
                           foundSomething = true;
      +  681  1
                           productEvidence.addEvidence(source, key, value, Confidence.HIGH);
      +  682  1
                           addMatchingValues(classInformation, value, productEvidence);
      +  683  71
                       } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VERSION.toString())) {
      +  684  2
                           hasImplementationVersion = true;
      +  685  2
                           foundSomething = true;
      +  686  2
                           versionEvidence.addEvidence(source, key, value, Confidence.HIGH);
      +  687  69
                       } else if ("specification-version".equalsIgnoreCase(key)) {
      +  688  1
                           specificationVersion = key;
      +  689  68
                       } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VENDOR.toString())) {
      +  690  1
                           foundSomething = true;
      +  691  1
                           vendorEvidence.addEvidence(source, key, value, Confidence.HIGH);
      +  692  1
                           addMatchingValues(classInformation, value, vendorEvidence);
      +  693  67
                       } else if (key.equalsIgnoreCase(IMPLEMENTATION_VENDOR_ID)) {
      +  694  0
                           foundSomething = true;
      +  695  0
                           vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      +  696  0
                           addMatchingValues(classInformation, value, vendorEvidence);
      +  697  67
                       } else if (key.equalsIgnoreCase(BUNDLE_DESCRIPTION)) {
      +  698  2
                           foundSomething = true;
      +  699  2
                           addDescription(dependency, value, "manifest", key);
      +  700  2
                           addMatchingValues(classInformation, value, productEvidence);
      +  701  65
                       } else if (key.equalsIgnoreCase(BUNDLE_NAME)) {
      +  702  3
                           foundSomething = true;
      +  703  3
                           productEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      +  704  3
                           addMatchingValues(classInformation, value, productEvidence);
      +  705   +
       //                //the following caused false positives.
      +  706   +
       //                } else if (key.equalsIgnoreCase(BUNDLE_VENDOR)) {
      +  707   +
       //                    foundSomething = true;
      +  708   +
       //                    vendorEvidence.addEvidence(source, key, value, Confidence.HIGH);
      +  709   +
       //                    addMatchingValues(classInformation, value, vendorEvidence);
      +  710  62
                       } else if (key.equalsIgnoreCase(BUNDLE_VERSION)) {
      +  711  3
                           foundSomething = true;
      +  712  3
                           versionEvidence.addEvidence(source, key, value, Confidence.HIGH);
      +  713  59
                       } else if (key.equalsIgnoreCase(Attributes.Name.MAIN_CLASS.toString())) {
      +  714  3
                           continue;
      +  715   +
                           //skipping main class as if this has important information to add
      +  716   +
                           // it will be added during class name analysis...  if other fields
      +  717   +
                           // have the information from the class name then they will get added...
      +  718   +
                       } else {
      +  719  56
                           key = key.toLowerCase();
      +  720  56
                           if (!IGNORE_KEYS.contains(key)
      +  721  15
                                   && !key.endsWith("jdk")
      +  722  15
                                   && !key.contains("lastmodified")
      +  723  14
                                   && !key.endsWith("package")
      +  724  14
                                   && !key.endsWith("classpath")
      +  725  14
                                   && !key.endsWith("class-path")
      +  726  14
                                   && !key.endsWith("-scm") //todo change this to a regex?
      +  727  14
                                   && !key.startsWith("scm-")
      +  728  14
                                   && !value.trim().startsWith("scm:")
      +  729  14
                                   && !isImportPackage(key, value)
      +  730  14
                                   && !isPackage(key, value)) {
      +  731  13
                               foundSomething = true;
      +  732  13
                               if (key.contains("version")) {
      +  733  0
                                   if (!key.contains("specification")) {
      +  734  0
                                       versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      +  735   +
                                   }
      +  736  13
                               } else if ("build-id".equals(key)) {
      +  737  0
                                   int pos = value.indexOf('(');
      +  738  0
                                   if (pos >= 0) {
      +  739  0
                                       value = value.substring(0, pos - 1);
      +  740   +
                                   }
      +  741  0
                                   pos = value.indexOf('[');
      +  742  0
                                   if (pos >= 0) {
      +  743  0
                                       value = value.substring(0, pos - 1);
      +  744   +
                                   }
      +  745  0
                                   versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      +  746  0
                               } else if (key.contains("title")) {
      +  747  1
                                   productEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      +  748  1
                                   addMatchingValues(classInformation, value, productEvidence);
      +  749  12
                               } else if (key.contains("vendor")) {
      +  750  0
                                   if (key.contains("specification")) {
      +  751  0
                                       vendorEvidence.addEvidence(source, key, value, Confidence.LOW);
      +  752   +
                                   } else {
      +  753  0
                                       vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      +  754  0
                                       addMatchingValues(classInformation, value, vendorEvidence);
      +  755   +
                                   }
      +  756  12
                               } else if (key.contains("name")) {
      +  757  3
                                   productEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      +  758  3
                                   vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      +  759  3
                                   addMatchingValues(classInformation, value, vendorEvidence);
      +  760  3
                                   addMatchingValues(classInformation, value, productEvidence);
      +  761  9
                               } else if (key.contains("license")) {
      +  762  2
                                   addLicense(dependency, value);
      +  763  7
                               } else if (key.contains("description")) {
      +  764  0
                                   addDescription(dependency, value, "manifest", key);
      +  765   +
                               } else {
      +  766  7
                                   productEvidence.addEvidence(source, key, value, Confidence.LOW);
      +  767  7
                                   vendorEvidence.addEvidence(source, key, value, Confidence.LOW);
      +  768  7
                                   addMatchingValues(classInformation, value, vendorEvidence);
      +  769  7
                                   addMatchingValues(classInformation, value, productEvidence);
      +  770  7
                                   if (value.matches(".*\\d.*")) {
      +  771  3
                                       final StringTokenizer tokenizer = new StringTokenizer(value, " ");
      +  772  15
                                       while (tokenizer.hasMoreElements()) {
      +  773  12
                                           final String s = tokenizer.nextToken();
      +  774  12
                                           if (s.matches("^[0-9.]+$")) {
      +  775  1
                                               versionEvidence.addEvidence(source, key, s, Confidence.LOW);
      +  776   +
                                           }
      +  777  12
                                       }
      +  778   +
                                   }
      +  779   +
                               }
      +  780   +
                           }
      +  781   +
                       }
      +  782  69
                   }
      +  783  7
                   for (Map.Entry<String, Attributes> item : manifest.getEntries().entrySet()) {
      +  784  8
                       final String name = item.getKey();
      +  785  8
                       source = "manifest: " + name;
      +  786  8
                       atts = item.getValue();
      +  787  8
                       for (Entry<Object, Object> entry : atts.entrySet()) {
      +  788  38
                           final String key = entry.getKey().toString();
      +  789  38
                           final String value = atts.getValue(key);
      +  790  38
                           if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_TITLE.toString())) {
      +  791  8
                               foundSomething = true;
      +  792  8
                               productEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      +  793  8
                               addMatchingValues(classInformation, value, productEvidence);
      +  794  30
                           } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VERSION.toString())) {
      +  795  5
                               foundSomething = true;
      +  796  5
                               versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      +  797  25
                           } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VENDOR.toString())) {
      +  798  5
                               foundSomething = true;
      +  799  5
                               vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      +  800  5
                               addMatchingValues(classInformation, value, vendorEvidence);
      +  801  20
                           } else if (key.equalsIgnoreCase(Attributes.Name.SPECIFICATION_TITLE.toString())) {
      +  802  4
                               foundSomething = true;
      +  803  4
                               productEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
      +  804  4
                               addMatchingValues(classInformation, value, productEvidence);
      +  805   +
                           }
      +  806  38
                       }
      +  807  8
                   }
      +  808  7
                   if (specificationVersion != null && !hasImplementationVersion) {
      +  809  0
                       foundSomething = true;
      +  810  0
                       versionEvidence.addEvidence(source, "specification-version", specificationVersion, Confidence.HIGH);
      +  811   +
                   }
      +  812   +
               } finally {
      +  813  7
                   if (jar != null) {
      +  814  7
                       jar.close();
      +  815   +
                   }
      +  816   +
               }
      +  817  7
               return foundSomething;
      +  818   +
           }
      +  819   +
       
      +  820   +
           /**
      +  821   +
            * Adds a description to the given dependency. If the description contains
      +  822   +
            * one of the following strings beyond 100 characters, then the description
      +  823   +
            * used will be trimmed to that position:
      +  824   +
            * <ul><li>"such as"</li><li>"like "</li><li>"will use "</li><li>"* uses
      +  825   +
            * "</li></ul>
      +  826   +
            *
      +  827   +
            * @param dependency a dependency
      +  828   +
            * @param description the description
      +  829   +
            * @param source the source of the evidence
      +  830   +
            * @param key the "name" of the evidence
      +  831   +
            * @return if the description is trimmed, the trimmed version is returned;
      +  832   +
            * otherwise the original description is returned
      +  833   +
            */
      +  834   +
           public static String addDescription(Dependency dependency, String description, String source, String key) {
      +  835  10
               if (dependency.getDescription() == null) {
      +  836  10
                   dependency.setDescription(description);
      +  837   +
               }
      +  838   +
               String desc;
      +  839  10
               if (HTML_DETECTION_PATTERN.matcher(description).find()) {
      +  840  0
                   desc = Jsoup.parse(description).text();
      +  841   +
               } else {
      +  842  10
                   desc = description;
      +  843   +
               }
      +  844  10
               dependency.setDescription(desc);
      +  845  10
               if (desc.length() > 100) {
      +  846  0
                   desc = desc.replaceAll("\\s\\s+", " ");
      +  847  0
                   final int posSuchAs = desc.toLowerCase().indexOf("such as ", 100);
      +  848  0
                   final int posLike = desc.toLowerCase().indexOf("like ", 100);
      +  849  0
                   final int posWillUse = desc.toLowerCase().indexOf("will use ", 100);
      +  850  0
                   final int posUses = desc.toLowerCase().indexOf(" uses ", 100);
      +  851  0
                   int pos = -1;
      +  852  0
                   pos = Math.max(pos, posSuchAs);
      +  853  0
                   if (pos >= 0 && posLike >= 0) {
      +  854  0
                       pos = Math.min(pos, posLike);
      +  855   +
                   } else {
      +  856  0
                       pos = Math.max(pos, posLike);
      +  857   +
                   }
      +  858  0
                   if (pos >= 0 && posWillUse >= 0) {
      +  859  0
                       pos = Math.min(pos, posWillUse);
      +  860   +
                   } else {
      +  861  0
                       pos = Math.max(pos, posWillUse);
      +  862   +
                   }
      +  863  0
                   if (pos >= 0 && posUses >= 0) {
      +  864  0
                       pos = Math.min(pos, posUses);
      +  865   +
                   } else {
      +  866  0
                       pos = Math.max(pos, posUses);
      +  867   +
                   }
      +  868   +
       
      +  869  0
                   if (pos > 0) {
      +  870  0
                       desc = desc.substring(0, pos) + "...";
      +  871   +
                   }
      +  872  0
                   dependency.getProductEvidence().addEvidence(source, key, desc, Confidence.LOW);
      +  873  0
                   dependency.getVendorEvidence().addEvidence(source, key, desc, Confidence.LOW);
      +  874  0
               } else {
      +  875  10
                   dependency.getProductEvidence().addEvidence(source, key, desc, Confidence.MEDIUM);
      +  876  10
                   dependency.getVendorEvidence().addEvidence(source, key, desc, Confidence.MEDIUM);
      +  877   +
               }
      +  878  10
               return desc;
      +  879   +
           }
      +  880   +
       
      +  881   +
           /**
      +  882   +
            * Adds a license to the given dependency.
      +  883   +
            *
      +  884   +
            * @param d a dependency
      +  885   +
            * @param license the license
      +  886   +
            */
      +  887   +
           private void addLicense(Dependency d, String license) {
      +  888  2
               if (d.getLicense() == null) {
      +  889  2
                   d.setLicense(license);
      +  890  0
               } else if (!d.getLicense().contains(license)) {
      +  891  0
                   d.setLicense(d.getLicense() + NEWLINE + license);
      +  892   +
               }
      +  893  2
           }
      +  894   +
       
      +  895   +
           /**
      +  896   +
            * The parent directory for the individual directories per archive.
      +  897   +
            */
      +  898  10
           private File tempFileLocation = null;
      +  899   +
       
      +  900   +
           /**
      +  901   +
            * Initializes the JarAnalyzer.
      +  902   +
            *
      +  903   +
            * @throws InitializationException is thrown if there is an exception
      +  904   +
            * creating a temporary directory
      +  905   +
            */
      +  906   +
           @Override
      +  907   +
           public void initializeFileTypeAnalyzer() throws InitializationException {
      +  908   +
               try {
      +  909  1
                   final File baseDir = Settings.getTempDirectory();
      +  910  1
                   tempFileLocation = File.createTempFile("check", "tmp", baseDir);
      +  911  1
                   if (!tempFileLocation.delete()) {
      +  912  0
                       final String msg = String.format("Unable to delete temporary file '%s'.", tempFileLocation.getAbsolutePath());
      +  913  0
                       setEnabled(false);
      +  914  0
                       throw new InitializationException(msg);
      +  915   +
                   }
      +  916  1
                   if (!tempFileLocation.mkdirs()) {
      +  917  0
                       final String msg = String.format("Unable to create directory '%s'.", tempFileLocation.getAbsolutePath());
      +  918  0
                       setEnabled(false);
      +  919  0
                       throw new InitializationException(msg);
      +  920   +
                   }
      +  921  0
               } catch (IOException ex) {
      +  922  0
                   setEnabled(false);
      +  923  0
                   throw new InitializationException("Unable to create a temporary file", ex);
      +  924  1
               }
      +  925  1
           }
      +  926   +
       
      +  927   +
           /**
      +  928   +
            * Deletes any files extracted from the JAR during analysis.
      +  929   +
            */
      +  930   +
           @Override
      +  931   +
           public void close() {
      +  932  2
               if (tempFileLocation != null && tempFileLocation.exists()) {
      +  933  1
                   LOGGER.debug("Attempting to delete temporary files");
      +  934  1
                   final boolean success = FileUtils.delete(tempFileLocation);
      +  935  1
                   if (!success) {
      +  936  0
                       LOGGER.warn("Failed to delete some temporary files, see the log for more details");
      +  937   +
                   }
      +  938   +
               }
      +  939  2
           }
      +  940   +
       
      +  941   +
           /**
      +  942   +
            * Determines if the key value pair from the manifest is for an "import"
      +  943   +
            * type entry for package names.
      +  944   +
            *
      +  945   +
            * @param key the key from the manifest
      +  946   +
            * @param value the value from the manifest
      +  947   +
            * @return true or false depending on if it is believed the entry is an
      +  948   +
            * "import" entry
      +  949   +
            */
      +  950   +
           private boolean isImportPackage(String key, String value) {
      +  951  14
               final Pattern packageRx = Pattern.compile("^([a-zA-Z0-9_#\\$\\*\\.]+\\s*[,;]\\s*)+([a-zA-Z0-9_#\\$\\*\\.]+\\s*)?$");
      +  952  14
               final boolean matches = packageRx.matcher(value).matches();
      +  953  14
               return matches && (key.contains("import") || key.contains("include") || value.length() > 10);
      +  954   +
           }
      +  955   +
       
      +  956   +
           /**
      +  957   +
            * Cycles through an enumeration of JarEntries, contained within the
      +  958   +
            * dependency, and returns a list of the class names. This does not include
      +  959   +
            * core Java package names (i.e. java.* or javax.*).
      +  960   +
            *
      +  961   +
            * @param dependency the dependency being analyzed
      +  962   +
            * @return an list of fully qualified class names
      +  963   +
            */
      +  964   +
           private List<ClassNameInformation> collectClassNames(Dependency dependency) {
      +  965  6
               final List<ClassNameInformation> classNames = new ArrayList<ClassNameInformation>();
      +  966  6
               JarFile jar = null;
      +  967   +
               try {
      +  968  6
                   jar = new JarFile(dependency.getActualFilePath());
      +  969  6
                   final Enumeration<JarEntry> entries = jar.entries();
      +  970  1852
                   while (entries.hasMoreElements()) {
      +  971  1846
                       final JarEntry entry = entries.nextElement();
      +  972  1846
                       final String name = entry.getName().toLowerCase();
      +  973   +
                       //no longer stripping "|com\\.sun" - there are some com.sun jar files with CVEs.
      +  974  1846
                       if (name.endsWith(".class") && !name.matches("^javax?\\..*$")) {
      +  975  1535
                           final ClassNameInformation className = new ClassNameInformation(name.substring(0, name.length() - 6));
      +  976  1535
                           classNames.add(className);
      +  977   +
                       }
      +  978  1846
                   }
      +  979  0
               } catch (IOException ex) {
      +  980  0
                   LOGGER.warn("Unable to open jar file '{}'.", dependency.getFileName());
      +  981  0
                   LOGGER.debug("", ex);
      +  982   +
               } finally {
      +  983  6
                   if (jar != null) {
      +  984   +
                       try {
      +  985  6
                           jar.close();
      +  986  0
                       } catch (IOException ex) {
      +  987  0
                           LOGGER.trace("", ex);
      +  988  6
                       }
      +  989   +
                   }
      +  990   +
               }
      +  991  6
               return classNames;
      +  992   +
           }
      +  993   +
       
      +  994   +
           /**
      +  995   +
            * Cycles through the list of class names and places the package levels 0-3
      +  996   +
            * into the provided maps for vendor and product. This is helpful when
      +  997   +
            * analyzing vendor/product as many times this is included in the package
      +  998   +
            * name.
      +  999   +
            *
      +  1000   +
            * @param classNames a list of class names
      +  1001   +
            * @param vendor HashMap of possible vendor names from package names (e.g.
      +  1002   +
            * owasp)
      +  1003   +
            * @param product HashMap of possible product names from package names (e.g.
      +  1004   +
            * dependencycheck)
      +  1005   +
            */
      +  1006   +
           private void analyzeFullyQualifiedClassNames(List<ClassNameInformation> classNames,
      +  1007   +
                   Map<String, Integer> vendor, Map<String, Integer> product) {
      +  1008  6
               for (ClassNameInformation entry : classNames) {
      +  1009  1535
                   final List<String> list = entry.getPackageStructure();
      +  1010  1535
                   addEntry(vendor, list.get(0));
      +  1011   +
       
      +  1012  1535
                   if (list.size() == 2) {
      +  1013  0
                       addEntry(product, list.get(1));
      +  1014   +
                   }
      +  1015  1535
                   if (list.size() == 3) {
      +  1016  345
                       addEntry(vendor, list.get(1));
      +  1017  345
                       addEntry(product, list.get(1));
      +  1018  345
                       addEntry(product, list.get(2));
      +  1019   +
                   }
      +  1020  1535
                   if (list.size() >= 4) {
      +  1021  1190
                       addEntry(vendor, list.get(1));
      +  1022  1190
                       addEntry(vendor, list.get(2));
      +  1023  1190
                       addEntry(product, list.get(1));
      +  1024  1190
                       addEntry(product, list.get(2));
      +  1025  1190
                       addEntry(product, list.get(3));
      +  1026   +
                   }
      +  1027  1535
               }
      +  1028  6
           }
      +  1029   +
       
      +  1030   +
           /**
      +  1031   +
            * Adds an entry to the specified collection and sets the Integer (e.g. the
      +  1032   +
            * count) to 1. If the entry already exists in the collection then the
      +  1033   +
            * Integer is incremented by 1.
      +  1034   +
            *
      +  1035   +
            * @param collection a collection of strings and their occurrence count
      +  1036   +
            * @param key the key to add to the collection
      +  1037   +
            */
      +  1038   +
           private void addEntry(Map<String, Integer> collection, String key) {
      +  1039  8520
               if (collection.containsKey(key)) {
      +  1040  7487
                   collection.put(key, collection.get(key) + 1);
      +  1041   +
               } else {
      +  1042  1033
                   collection.put(key, 1);
      +  1043   +
               }
      +  1044  8520
           }
      +  1045   +
       
      +  1046   +
           /**
      +  1047   +
            * Cycles through the collection of class name information to see if parts
      +  1048   +
            * of the package names are contained in the provided value. If found, it
      +  1049   +
            * will be added as the HIGHEST confidence evidence because we have more
      +  1050   +
            * then one source corroborating the value.
      +  1051   +
            *
      +  1052   +
            * @param classes a collection of class name information
      +  1053   +
            * @param value the value to check to see if it contains a package name
      +  1054   +
            * @param evidence the evidence collection to add new entries too
      +  1055   +
            */
      +  1056   +
           private static void addMatchingValues(List<ClassNameInformation> classes, String value, EvidenceCollection evidence) {
      +  1057  63
               if (value == null || value.isEmpty() || classes == null || classes.isEmpty()) {
      +  1058  21
                   return;
      +  1059   +
               }
      +  1060  42
               final String text = value.toLowerCase();
      +  1061  42
               for (ClassNameInformation cni : classes) {
      +  1062  16322
                   for (String key : cni.getPackageStructure()) {
      +  1063  62418
                       final Pattern p = Pattern.compile("\b" + key + "\b");
      +  1064  62418
                       if (p.matcher(text).find()) {
      +  1065   +
                           //if (text.contains(key)) { //note, package structure elements are already lowercase.
      +  1066  0
                           evidence.addEvidence("jar", "package name", key, Confidence.HIGHEST);
      +  1067   +
                       }
      +  1068  62418
                   }
      +  1069  16322
               }
      +  1070  42
           }
      +  1071   +
       
      +  1072   +
           /**
      +  1073   +
            * Simple check to see if the attribute from a manifest is just a package
      +  1074   +
            * name.
      +  1075   +
            *
      +  1076   +
            * @param key the key of the value to check
      +  1077   +
            * @param value the value to check
      +  1078   +
            * @return true if the value looks like a java package name, otherwise false
      +  1079   +
            */
      +  1080   +
           private boolean isPackage(String key, String value) {
      +  1081   +
       
      +  1082  28
               return !key.matches(".*(version|title|vendor|name|license|description).*")
      +  1083  8
                       && value.matches("^([a-zA-Z_][a-zA-Z0-9_\\$]*(\\.[a-zA-Z_][a-zA-Z0-9_\\$]*)*)?$");
      +  1084   +
       
      +  1085   +
           }
      +  1086   +
       
      +  1087   +
           /**
      +  1088   +
            * Extracts the license information from the pom and adds it to the
      +  1089   +
            * dependency.
      +  1090   +
            *
      +  1091   +
            * @param pom the pom object
      +  1092   +
            * @param dependency the dependency to add license information too
      +  1093   +
            */
      +  1094   +
           public static void extractLicense(Model pom, Dependency dependency) {
      +  1095   +
               //license
      +  1096  2
               if (pom.getLicenses() != null) {
      +  1097  2
                   String license = null;
      +  1098  2
                   for (License lic : pom.getLicenses()) {
      +  1099  0
                       String tmp = null;
      +  1100  0
                       if (lic.getName() != null) {
      +  1101  0
                           tmp = lic.getName();
      +  1102   +
                       }
      +  1103  0
                       if (lic.getUrl() != null) {
      +  1104  0
                           if (tmp == null) {
      +  1105  0
                               tmp = lic.getUrl();
      +  1106   +
                           } else {
      +  1107  0
                               tmp += ": " + lic.getUrl();
      +  1108   +
                           }
      +  1109   +
                       }
      +  1110  0
                       if (tmp == null) {
      +  1111  0
                           continue;
      +  1112   +
                       }
      +  1113  0
                       if (HTML_DETECTION_PATTERN.matcher(tmp).find()) {
      +  1114  0
                           tmp = Jsoup.parse(tmp).text();
      +  1115   +
                       }
      +  1116  0
                       if (license == null) {
      +  1117  0
                           license = tmp;
      +  1118   +
                       } else {
      +  1119  0
                           license += "\n" + tmp;
      +  1120   +
                       }
      +  1121  0
                   }
      +  1122  2
                   if (license != null) {
      +  1123  0
                       dependency.setLicense(license);
       1124  
       
       1125   -
           /**
      -  1126   -
            * Stores information about a class name.
      -  1127   -
            */
      -  1128   -
           protected static class ClassNameInformation {
      -  1129   -
       
      -  1130   -
               /**
      -  1131   -
                * <p>
      -  1132   -
                * Stores information about a given class name. This class will keep the
      -  1133   -
                * fully qualified class name and a list of the important parts of the
      -  1134   -
                * package structure. Up to the first four levels of the package
      -  1135   -
                * structure are stored, excluding a leading "org" or "com".
      -  1136   -
                * Example:</p>
      -  1137   -
                * <code>ClassNameInformation obj = new ClassNameInformation("org.owasp.dependencycheck.analyzer.JarAnalyzer");
      -  1138   -
                * System.out.println(obj.getName());
      -  1139   -
                * for (String p : obj.getPackageStructure())
      -  1140   -
                *     System.out.println(p);
      -  1141   -
                * </code>
      -  1142   -
                * <p>
      -  1143   -
                * Would result in:</p>
      -  1144   -
                * <code>org.owasp.dependencycheck.analyzer.JarAnalyzer
      -  1145   -
                * owasp
      -  1146   -
                * dependencycheck
      -  1147   -
                * analyzer
      -  1148   -
                * jaranalyzer</code>
      -  1149   -
                *
      -  1150   -
                * @param className a fully qualified class name
      -  1151   -
                */
      -  1152  3070
               ClassNameInformation(String className) {
      -  1153  3070
                   name = className;
      -  1154  3070
                   if (name.contains("/")) {
      -  1155  3070
                       final String[] tmp = className.toLowerCase().split("/");
      -  1156  3070
                       int start = 0;
      -  1157  3070
                       int end = 3;
      -  1158  3070
                       if ("com".equals(tmp[0]) || "org".equals(tmp[0])) {
      -  1159  3070
                           start = 1;
      -  1160  3070
                           end = 4;
      -  1161   -
                       }
      -  1162  3070
                       if (tmp.length <= end) {
      -  1163  690
                           end = tmp.length - 1;
      -  1164   -
                       }
      -  1165  14660
                       for (int i = start; i <= end; i++) {
      -  1166  11590
                           packageStructure.add(tmp[i]);
      -  1167   -
                       }
      -  1168  3070
                   } else {
      -  1169  0
                       packageStructure.add(name);
      -  1170  
                   }
      -  1171  3070
               }
      -  1172   -
               /**
      -  1173   -
                * The fully qualified class name.
      -  1174   -
                */
      -  1175   -
               private String name;
      -  1176   -
       
      -  1177   -
               /**
      -  1178   -
                * Get the value of name
      -  1179   -
                *
      -  1180   -
                * @return the value of name
      -  1181   -
                */
      -  1182   -
               public String getName() {
      -  1183  0
                   return name;
      -  1184   +  1126  
               }
      -  1185   +  1127  2
           }
      +  1128  
       
      -  1186   -
               /**
      -  1187   -
                * Set the value of name
      -  1188   -
                *
      -  1189   -
                * @param name new value of name
      -  1190   -
                */
      -  1191   -
               public void setName(String name) {
      -  1192  0
                   this.name = name;
      -  1193  0
               }
      -  1194   -
               /**
      -  1195   -
                * Up to the first four levels of the package structure, excluding a
      -  1196   -
                * leading "org" or "com".
      -  1197   -
                */
      -  1198  3070
               private final ArrayList<String> packageStructure = new ArrayList<String>();
      -  1199   -
       
      -  1200   -
               /**
      -  1201   -
                * Get the value of packageStructure
      -  1202   -
                *
      -  1203   -
                * @return the value of packageStructure
      -  1204   -
                */
      -  1205   -
               public ArrayList<String> getPackageStructure() {
      -  1206  35714
                   return packageStructure;
      -  1207   -
               }
      -  1208   -
           }
      -  1209   -
       
      -  1210   +  1129  
           /**
      -  1211   -
            * Retrieves the next temporary directory to extract an archive too.
      -  1212   -
            *
      -  1213   -
            * @return a directory
      -  1214   -
            * @throws AnalysisException thrown if unable to create temporary directory
      -  1215   +  1130   +
            * Stores information about a class name.
      +  1131  
            */
      -  1216   -
           private File getNextTempDirectory() throws AnalysisException {
      -  1217  0
               dirCount += 1;
      -  1218  0
               final File directory = new File(tempFileLocation, String.valueOf(dirCount));
      -  1219   -
               //getting an exception for some directories not being able to be created; might be because the directory already exists?
      -  1220  0
               if (directory.exists()) {
      -  1221  0
                   return getNextTempDirectory();
      -  1222   +  1132   +
           protected static class ClassNameInformation {
      +  1133   +
       
      +  1134   +
               /**
      +  1135   +
                * <p>
      +  1136   +
                * Stores information about a given class name. This class will keep the
      +  1137   +
                * fully qualified class name and a list of the important parts of the
      +  1138   +
                * package structure. Up to the first four levels of the package
      +  1139   +
                * structure are stored, excluding a leading "org" or "com".
      +  1140   +
                * Example:</p>
      +  1141   +
                * <code>ClassNameInformation obj = new ClassNameInformation("org.owasp.dependencycheck.analyzer.JarAnalyzer");
      +  1142   +
                * System.out.println(obj.getName());
      +  1143   +
                * for (String p : obj.getPackageStructure())
      +  1144   +
                *     System.out.println(p);
      +  1145   +
                * </code>
      +  1146   +
                * <p>
      +  1147   +
                * Would result in:</p>
      +  1148   +
                * <code>org.owasp.dependencycheck.analyzer.JarAnalyzer
      +  1149   +
                * owasp
      +  1150   +
                * dependencycheck
      +  1151   +
                * analyzer
      +  1152   +
                * jaranalyzer</code>
      +  1153   +
                *
      +  1154   +
                * @param className a fully qualified class name
      +  1155   +
                */
      +  1156  1535
               ClassNameInformation(String className) {
      +  1157  1535
                   name = className;
      +  1158  1535
                   if (name.contains("/")) {
      +  1159  1535
                       final String[] tmp = className.toLowerCase().split("/");
      +  1160  1535
                       int start = 0;
      +  1161  1535
                       int end = 3;
      +  1162  1535
                       if ("com".equals(tmp[0]) || "org".equals(tmp[0])) {
      +  1163  1535
                           start = 1;
      +  1164  1535
                           end = 4;
      +  1165   +
                       }
      +  1166  1535
                       if (tmp.length <= end) {
      +  1167  345
                           end = tmp.length - 1;
      +  1168   +
                       }
      +  1169  7330
                       for (int i = start; i <= end; i++) {
      +  1170  5795
                           packageStructure.add(tmp[i]);
      +  1171   +
                       }
      +  1172  1535
                   } else {
      +  1173  0
                       packageStructure.add(name);
      +  1174   +
                   }
      +  1175  1535
               }
      +  1176   +
               /**
      +  1177   +
                * The fully qualified class name.
      +  1178   +
                */
      +  1179   +
               private String name;
      +  1180   +
       
      +  1181   +
               /**
      +  1182   +
                * Get the value of name
      +  1183   +
                *
      +  1184   +
                * @return the value of name
      +  1185   +
                */
      +  1186   +
               public String getName() {
      +  1187  0
                   return name;
      +  1188  
               }
      -  1223  0
               if (!directory.mkdirs()) {
      -  1224  0
                   final String msg = String.format("Unable to create temp directory '%s'.", directory.getAbsolutePath());
      -  1225  0
                   throw new AnalysisException(msg);
      +  1189   +
       
      +  1190   +
               /**
      +  1191   +
                * Set the value of name
      +  1192   +
                *
      +  1193   +
                * @param name new value of name
      +  1194   +
                */
      +  1195   +
               public void setName(String name) {
      +  1196  0
                   this.name = name;
      +  1197  0
               }
      +  1198   +
               /**
      +  1199   +
                * Up to the first four levels of the package structure, excluding a
      +  1200   +
                * leading "org" or "com".
      +  1201   +
                */
      +  1202  1535
               private final ArrayList<String> packageStructure = new ArrayList<String>();
      +  1203   +
       
      +  1204   +
               /**
      +  1205   +
                * Get the value of packageStructure
      +  1206   +
                *
      +  1207   +
                * @return the value of packageStructure
      +  1208   +
                */
      +  1209   +
               public ArrayList<String> getPackageStructure() {
      +  1210  17857
                   return packageStructure;
      +  1211   +
               }
      +  1212   +
           }
      +  1213   +
       
      +  1214   +
           /**
      +  1215   +
            * Retrieves the next temporary directory to extract an archive too.
      +  1216   +
            *
      +  1217   +
            * @return a directory
      +  1218   +
            * @throws AnalysisException thrown if unable to create temporary directory
      +  1219   +
            */
      +  1220   +
           private File getNextTempDirectory() throws AnalysisException {
      +  1221  0
               dirCount += 1;
      +  1222  0
               final File directory = new File(tempFileLocation, String.valueOf(dirCount));
      +  1223   +
               //getting an exception for some directories not being able to be created; might be because the directory already exists?
      +  1224  0
               if (directory.exists()) {
      +  1225  0
                   return getNextTempDirectory();
       1226  
               }
      -  1227  0
               return directory;
      -  1228   +  1227  0
               if (!directory.mkdirs()) {
      +  1228  0
                   final String msg = String.format("Unable to create temp directory '%s'.", directory.getAbsolutePath());
      +  1229  0
                   throw new AnalysisException(msg);
      +  1230   +
               }
      +  1231  0
               return directory;
      +  1232  
           }
      -  1229   +  1233  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.NexusAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.NexusAnalyzer.html index a17bba47e..ce683db9c 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.NexusAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.NexusAnalyzer.html @@ -12,7 +12,7 @@
       
      - +
      Classes in this File Line Coverage Branch Coverage Complexity
      NexusAnalyzer
      20%
      14/70
      4%
      1/24
      3.375
      NexusAnalyzer
      20%
      14/70
      4%
      1/24
      3.625
       
      @@ -92,383 +92,393 @@  37  
       import java.net.URL;
       38   -
       import org.owasp.dependencycheck.utils.DownloadFailedException;
      +
       import org.owasp.dependencycheck.exception.InitializationException;
       39   -
       import org.owasp.dependencycheck.utils.Downloader;
      +
       import org.owasp.dependencycheck.utils.DownloadFailedException;
       40   -
       import org.owasp.dependencycheck.utils.FileFilterBuilder;
      +
       import org.owasp.dependencycheck.utils.Downloader;
       41   -
       import org.owasp.dependencycheck.utils.InvalidSettingException;
      +
       import org.owasp.dependencycheck.utils.FileFilterBuilder;
       42   -
       import org.owasp.dependencycheck.utils.Settings;
      +
       import org.owasp.dependencycheck.utils.InvalidSettingException;
       43   -
       
      +
       import org.owasp.dependencycheck.utils.Settings;
       44   -
       /**
      +
       
       45   -
        * Analyzer which will attempt to locate a dependency on a Nexus service by SHA-1 digest of the dependency.
      +
       /**
       46   -
        *
      +
        * Analyzer which will attempt to locate a dependency on a Nexus service by
       47   -
        * There are two settings which govern this behavior:
      +
        * SHA-1 digest of the dependency.
       48  
        *
       49   -
        * <ul>
      +
        * There are two settings which govern this behavior:
       50   -
        * <li>{@link org.owasp.dependencycheck.utils.Settings.KEYS#ANALYZER_NEXUS_ENABLED} determines whether this analyzer is even
      -  51   -
        * enabled. This can be overridden by setting the system property.</li>
      -  52   -
        * <li>{@link org.owasp.dependencycheck.utils.Settings.KEYS#ANALYZER_NEXUS_URL} the URL to a Nexus service to search by SHA-1.
      -  53   -
        * There is an expected <code>%s</code> in this where the SHA-1 will get entered.</li>
      -  54   -
        * </ul>
      -  55  
        *
      +  51   +
        * <ul>
      +  52   +
        * <li>{@link org.owasp.dependencycheck.utils.Settings.KEYS#ANALYZER_NEXUS_ENABLED}
      +  53   +
        * determines whether this analyzer is even enabled. This can be overridden by
      +  54   +
        * setting the system property.</li>
      +  55   +
        * <li>{@link org.owasp.dependencycheck.utils.Settings.KEYS#ANALYZER_NEXUS_URL}
       56   -
        * @author colezlaw
      +
        * the URL to a Nexus service to search by SHA-1. There is an expected
       57   -
        */
      -  58  12
       public class NexusAnalyzer extends AbstractFileTypeAnalyzer {
      +
        * <code>%s</code> in this where the SHA-1 will get entered.</li>
      +  58   +
        * </ul>
       59   -
       
      +
        *
       60   -
           /**
      +
        * @author colezlaw
       61   -
            * The default URL - this will be used by the CentralAnalyzer to determine whether to enable this.
      -  62   -
            */
      +
        */
      +  62  6
       public class NexusAnalyzer extends AbstractFileTypeAnalyzer {
       63   -
           public static final String DEFAULT_URL = "https://repository.sonatype.org/service/local/";
      -  64  
       
      -  65   +  64  
           /**
      +  65   +
            * The default URL - this will be used by the CentralAnalyzer to determine
       66   -
            * The logger.
      +
            * whether to enable this.
       67  
            */
      -  68  2
           private static final Logger LOGGER = LoggerFactory.getLogger(NexusAnalyzer.class);
      +  68   +
           public static final String DEFAULT_URL = "https://repository.sonatype.org/service/local/";
       69  
       
       70  
           /**
       71   -
            * The name of the analyzer.
      +
            * The logger.
       72  
            */
      -  73   -
           private static final String ANALYZER_NAME = "Nexus Analyzer";
      +  73  1
           private static final Logger LOGGER = LoggerFactory.getLogger(NexusAnalyzer.class);
       74  
       
       75  
           /**
       76   -
            * The phase in which the analyzer runs.
      +
            * The name of the analyzer.
       77  
            */
      -  78  2
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
      +  78   +
           private static final String ANALYZER_NAME = "Nexus Analyzer";
       79  
       
       80  
           /**
       81   -
            * The types of files on which this will work.
      +
            * The phase in which the analyzer runs.
       82  
            */
      -  83   -
           private static final String SUPPORTED_EXTENSIONS = "jar";
      +  83  1
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
       84  
       
       85  
           /**
       86   -
            * The Nexus Search to be set up for this analyzer.
      +
            * The types of files on which this will work.
       87  
            */
       88   -
           private NexusSearch searcher;
      +
           private static final String SUPPORTED_EXTENSIONS = "jar";
       89  
       
       90  
           /**
       91   -
            * Field indicating if the analyzer is enabled.
      +
            * The Nexus Search to be set up for this analyzer.
       92  
            */
      -  93  12
           private final boolean enabled = checkEnabled();
      +  93   +
           private NexusSearch searcher;
       94  
       
       95  
           /**
       96   -
            * Determines if this analyzer is enabled
      +
            * Field indicating if the analyzer is enabled.
       97   -
            *
      -  98   -
            * @return <code>true</code> if the analyzer is enabled; otherwise <code>false</code>
      +
            */
      +  98  6
           private final boolean enabled = checkEnabled();
       99   -
            */
      +
       
       100   -
           private boolean checkEnabled() {
      +
           /**
       101   -
               /* Enable this analyzer ONLY if the Nexus URL has been set to something
      +
            * Determines if this analyzer is enabled
       102   -
                other than the default one (if it's the default one, we'll use the
      +
            *
       103   -
                central one) and it's enabled by the user.
      +
            * @return <code>true</code> if the analyzer is enabled; otherwise
       104   -
                */
      -  105  12
               boolean retval = false;
      +
            * <code>false</code>
      +  105   +
            */
       106   +
           private boolean checkEnabled() {
      +  107   +
               /* Enable this analyzer ONLY if the Nexus URL has been set to something
      +  108   +
                other than the default one (if it's the default one, we'll use the
      +  109   +
                central one) and it's enabled by the user.
      +  110   +
                */
      +  111  6
               boolean retval = false;
      +  112  
               try {
      -  107  12
                   if (!DEFAULT_URL.equals(Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL))
      -  108  0
                           && Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED)) {
      -  109  0
                       LOGGER.info("Enabling Nexus analyzer");
      -  110  0
                       retval = true;
      -  111   -
                   } else {
      -  112  12
                       LOGGER.debug("Nexus analyzer disabled, using Central instead");
      -  113   -
                   }
      -  114  0
               } catch (InvalidSettingException ise) {
      -  115  0
                   LOGGER.warn("Invalid setting. Disabling Nexus analyzer");
      -  116  12
               }
      +  113  6
                   if (!DEFAULT_URL.equals(Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL))
      +  114  0
                           && Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED)) {
      +  115  0
                       LOGGER.info("Enabling Nexus analyzer");
      +  116  0
                       retval = true;
       117   -
       
      -  118  12
               return retval;
      +
                   } else {
      +  118  6
                       LOGGER.debug("Nexus analyzer disabled, using Central instead");
       119   -
           }
      -  120   -
       
      -  121   -
           /**
      -  122   -
            * Determine whether to enable this analyzer or not.
      +
                   }
      +  120  0
               } catch (InvalidSettingException ise) {
      +  121  0
                   LOGGER.warn("Invalid setting. Disabling Nexus analyzer");
      +  122  6
               }
       123   -
            *
      -  124   -
            * @return whether the analyzer should be enabled
      +
       
      +  124  6
               return retval;
       125   -
            */
      +
           }
       126   -
           @Override
      +
       
       127   -
           public boolean isEnabled() {
      -  128  0
               return enabled;
      +
           /**
      +  128   +
            * Determine whether to enable this analyzer or not.
       129   -
           }
      +
            *
       130   -
       
      +
            * @return whether the analyzer should be enabled
       131   -
           /**
      +
            */
       132   -
            * Initializes the analyzer once before any analysis is performed.
      +
           @Override
       133   -
            *
      -  134   -
            * @throws Exception if there's an error during initialization
      +
           public boolean isEnabled() {
      +  134  0
               return enabled;
       135   -
            */
      +
           }
       136   -
           @Override
      +
       
       137   -
           public void initializeFileTypeAnalyzer() throws Exception {
      -  138  0
               LOGGER.debug("Initializing Nexus Analyzer");
      -  139  0
               LOGGER.debug("Nexus Analyzer enabled: {}", isEnabled());
      -  140  0
               if (isEnabled()) {
      -  141  0
                   final String searchUrl = Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL);
      -  142  0
                   LOGGER.debug("Nexus Analyzer URL: {}", searchUrl);
      +
           /**
      +  138   +
            * Initializes the analyzer once before any analysis is performed.
      +  139   +
            *
      +  140   +
            * @throws InitializationException if there's an error during initialization
      +  141   +
            */
      +  142   +
           @Override
       143   +
           public void initializeFileTypeAnalyzer() throws InitializationException {
      +  144  0
               LOGGER.debug("Initializing Nexus Analyzer");
      +  145  0
               LOGGER.debug("Nexus Analyzer enabled: {}", isEnabled());
      +  146  0
               if (isEnabled()) {
      +  147  0
                   final String searchUrl = Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL);
      +  148  0
                   LOGGER.debug("Nexus Analyzer URL: {}", searchUrl);
      +  149  
                   try {
      -  144  0
                       searcher = new NexusSearch(new URL(searchUrl));
      -  145  0
                       if (!searcher.preflightRequest()) {
      -  146  0
                           LOGGER.warn("There was an issue getting Nexus status. Disabling analyzer.");
      -  147  0
                           setEnabled(false);
      -  148   +  150  0
                       searcher = new NexusSearch(new URL(searchUrl));
      +  151  0
                       if (!searcher.preflightRequest()) {
      +  152  0
                           setEnabled(false);
      +  153  0
                           throw new InitializationException("There was an issue getting Nexus status. Disabling analyzer.");
      +  154  
                       }
      -  149  0
                   } catch (MalformedURLException mue) {
      -  150   -
                       // I know that initialize can throw an exception, but we'll
      -  151   -
                       // just disable the analyzer if the URL isn't valid
      -  152  0
                       LOGGER.warn("Property {} not a valid URL. Nexus Analyzer disabled", searchUrl);
      -  153  0
                       setEnabled(false);
      -  154  0
                   }
      -  155   -
               }
      -  156  0
           }
      -  157   -
       
      -  158   -
           /**
      +  155  0
                   } catch (MalformedURLException mue) {
      +  156  0
                       setEnabled(false);
      +  157  0
                       throw new InitializationException("Malformed URL to Nexus: " + searchUrl, mue);
      +  158  0
                   }
       159   -
            * Returns the analyzer's name.
      -  160   -
            *
      +
               }
      +  160  0
           }
       161   -
            * @return the name of the analyzer
      +
       
       162   -
            */
      +
           /**
       163   -
           @Override
      +
            * Returns the analyzer's name.
       164   -
           public String getName() {
      -  165  32
               return ANALYZER_NAME;
      +
            *
      +  165   +
            * @return the name of the analyzer
       166   -
           }
      +
            */
       167   -
       
      +
           @Override
       168   -
           /**
      -  169   -
            * Returns the key used in the properties file to reference the analyzer's enabled property.
      +
           public String getName() {
      +  169  16
               return ANALYZER_NAME;
       170   -
            *
      +
           }
       171   -
            * @return the analyzer's enabled property setting key
      +
       
       172   -
            */
      +
           /**
       173   -
           @Override
      +
            * Returns the key used in the properties file to reference the analyzer's
       174   -
           protected String getAnalyzerEnabledSettingKey() {
      -  175  12
               return Settings.KEYS.ANALYZER_NEXUS_ENABLED;
      -  176   -
           }
      -  177   -
       
      -  178   -
           /**
      -  179   -
            * Returns the analysis phase under which the analyzer runs.
      -  180   +
            * enabled property.
      +  175  
            *
      -  181   -
            * @return the phase under which this analyzer runs
      -  182   +  176   +
            * @return the analyzer's enabled property setting key
      +  177  
            */
      -  183   +  178  
           @Override
      -  184   -
           public AnalysisPhase getAnalysisPhase() {
      -  185  8
               return ANALYSIS_PHASE;
      -  186   +  179   +
           protected String getAnalyzerEnabledSettingKey() {
      +  180  6
               return Settings.KEYS.ANALYZER_NEXUS_ENABLED;
      +  181  
           }
      -  187   +  182  
       
      -  188   +  183  
           /**
      -  189   -
            * The file filter used to determine which files this analyzer supports.
      -  190   +  184   +
            * Returns the analysis phase under which the analyzer runs.
      +  185   +
            *
      +  186   +
            * @return the phase under which this analyzer runs
      +  187  
            */
      -  191  2
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(SUPPORTED_EXTENSIONS).build();
      +  188   +
           @Override
      +  189   +
           public AnalysisPhase getAnalysisPhase() {
      +  190  4
               return ANALYSIS_PHASE;
      +  191   +
           }
       192  
       
       193  
           /**
       194   -
            * Returns the FileFilter
      +
            * The file filter used to determine which files this analyzer supports.
       195   -
            *
      -  196   -
            * @return the FileFilter
      +
            */
      +  196  1
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(SUPPORTED_EXTENSIONS).build();
       197   -
            */
      -  198   -
           @Override
      -  199   -
           protected FileFilter getFileFilter() {
      -  200  1718
               return FILTER;
      -  201   -
           }
      -  202  
       
      -  203   +  198  
           /**
      -  204   -
            * Performs the analysis.
      -  205   +  199   +
            * Returns the FileFilter
      +  200  
            *
      -  206   -
            * @param dependency the dependency to analyze
      -  207   -
            * @param engine the engine
      -  208   -
            * @throws AnalysisException when there's an exception during analysis
      -  209   +  201   +
            * @return the FileFilter
      +  202  
            */
      -  210   +  203  
           @Override
      +  204   +
           protected FileFilter getFileFilter() {
      +  205  10
               return FILTER;
      +  206   +
           }
      +  207   +
       
      +  208   +
           /**
      +  209   +
            * Performs the analysis.
      +  210   +
            *
       211   -
           public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException {
      -  212  0
               if (!isEnabled()) {
      -  213  0
                   return;
      +
            * @param dependency the dependency to analyze
      +  212   +
            * @param engine the engine
      +  213   +
            * @throws AnalysisException when there's an exception during analysis
       214   -
               }
      +
            */
       215   +
           @Override
      +  216   +
           public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException {
      +  217  0
               if (!isEnabled()) {
      +  218  0
                   return;
      +  219   +
               }
      +  220  
               try {
      -  216  0
                   final MavenArtifact ma = searcher.searchSha1(dependency.getSha1sum());
      -  217  0
                   dependency.addAsEvidence("nexus", ma, Confidence.HIGH);
      -  218  0
                   boolean pomAnalyzed = false;
      -  219  0
                   LOGGER.debug("POM URL {}", ma.getPomUrl());
      -  220  0
                   for (Evidence e : dependency.getVendorEvidence()) {
      -  221  0
                       if ("pom".equals(e.getSource())) {
      -  222  0
                           pomAnalyzed = true;
      -  223  0
                           break;
      -  224   +  221  0
                   final MavenArtifact ma = searcher.searchSha1(dependency.getSha1sum());
      +  222  0
                   dependency.addAsEvidence("nexus", ma, Confidence.HIGH);
      +  223  0
                   boolean pomAnalyzed = false;
      +  224  0
                   LOGGER.debug("POM URL {}", ma.getPomUrl());
      +  225  0
                   for (Evidence e : dependency.getVendorEvidence()) {
      +  226  0
                       if ("pom".equals(e.getSource())) {
      +  227  0
                           pomAnalyzed = true;
      +  228  0
                           break;
      +  229  
                       }
      -  225  0
                   }
      -  226  0
                   if (!pomAnalyzed && ma.getPomUrl() != null) {
      -  227  0
                       File pomFile = null;
      -  228   +  230  0
                   }
      +  231  0
                   if (!pomAnalyzed && ma.getPomUrl() != null) {
      +  232  0
                       File pomFile = null;
      +  233  
                       try {
      -  229  0
                           final File baseDir = Settings.getTempDirectory();
      -  230  0
                           pomFile = File.createTempFile("pom", ".xml", baseDir);
      -  231  0
                           if (!pomFile.delete()) {
      -  232  0
                               LOGGER.warn("Unable to fetch pom.xml for {} from Nexus repository; "
      -  233  0
                                       + "this could result in undetected CPE/CVEs.", dependency.getFileName());
      -  234  0
                               LOGGER.debug("Unable to delete temp file");
      -  235   +  234  0
                           final File baseDir = Settings.getTempDirectory();
      +  235  0
                           pomFile = File.createTempFile("pom", ".xml", baseDir);
      +  236  0
                           if (!pomFile.delete()) {
      +  237  0
                               LOGGER.warn("Unable to fetch pom.xml for {} from Nexus repository; "
      +  238  0
                                       + "this could result in undetected CPE/CVEs.", dependency.getFileName());
      +  239  0
                               LOGGER.debug("Unable to delete temp file");
      +  240  
                           }
      -  236  0
                           LOGGER.debug("Downloading {}", ma.getPomUrl());
      -  237  0
                           Downloader.fetchFile(new URL(ma.getPomUrl()), pomFile);
      -  238  0
                           PomUtils.analyzePOM(dependency, pomFile);
      -  239  0
                       } catch (DownloadFailedException ex) {
      -  240  0
                           LOGGER.warn("Unable to download pom.xml for {} from Nexus repository; "
      -  241  0
                                   + "this could result in undetected CPE/CVEs.", dependency.getFileName());
      -  242   -
                       } finally {
      -  243  0
                           if (pomFile != null && !FileUtils.deleteQuietly(pomFile)) {
      -  244  0
                               pomFile.deleteOnExit();
      -  245   -
                           }
      -  246   -
                       }
      +  241  0
                           LOGGER.debug("Downloading {}", ma.getPomUrl());
      +  242  0
                           Downloader.fetchFile(new URL(ma.getPomUrl()), pomFile);
      +  243  0
                           PomUtils.analyzePOM(dependency, pomFile);
      +  244  0
                       } catch (DownloadFailedException ex) {
      +  245  0
                           LOGGER.warn("Unable to download pom.xml for {} from Nexus repository; "
      +  246  0
                                   + "this could result in undetected CPE/CVEs.", dependency.getFileName());
       247   -
                   }
      -  248  0
               } catch (IllegalArgumentException iae) {
      -  249   -
                   //dependency.addAnalysisException(new AnalysisException("Invalid SHA-1"));
      -  250  0
                   LOGGER.info("invalid sha-1 hash on {}", dependency.getFileName());
      -  251  0
               } catch (FileNotFoundException fnfe) {
      +
                       } finally {
      +  248  0
                           if (pomFile != null && !FileUtils.deleteQuietly(pomFile)) {
      +  249  0
                               pomFile.deleteOnExit();
      +  250   +
                           }
      +  251   +
                       }
       252   +
                   }
      +  253  0
               } catch (IllegalArgumentException iae) {
      +  254   +
                   //dependency.addAnalysisException(new AnalysisException("Invalid SHA-1"));
      +  255  0
                   LOGGER.info("invalid sha-1 hash on {}", dependency.getFileName());
      +  256  0
               } catch (FileNotFoundException fnfe) {
      +  257  
                   //dependency.addAnalysisException(new AnalysisException("Artifact not found on repository"));
      -  253  0
                   LOGGER.debug("Artifact not found in repository '{}'", dependency.getFileName());
      -  254  0
                   LOGGER.debug(fnfe.getMessage(), fnfe);
      -  255  0
               } catch (IOException ioe) {
      -  256   +  258  0
                   LOGGER.debug("Artifact not found in repository '{}'", dependency.getFileName());
      +  259  0
                   LOGGER.debug(fnfe.getMessage(), fnfe);
      +  260  0
               } catch (IOException ioe) {
      +  261  
                   //dependency.addAnalysisException(new AnalysisException("Could not connect to repository", ioe));
      -  257  0
                   LOGGER.debug("Could not connect to nexus repository", ioe);
      -  258  0
               }
      -  259  0
           }
      -  260   +  262  0
                   LOGGER.debug("Could not connect to nexus repository", ioe);
      +  263  0
               }
      +  264  0
           }
      +  265  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.NodePackageAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.NodePackageAnalyzer.html index 7c9c26792..1e7afcc43 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.NodePackageAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.NodePackageAnalyzer.html @@ -98,250 +98,256 @@  40  
       import javax.json.JsonValue;
       41   -
       
      +
       import org.owasp.dependencycheck.exception.InitializationException;
       42   -
       /**
      +
       
       43   -
        * Used to analyze Node Package Manager (npm) package.json files, and collect information that can be used to determine the
      +
       /**
       44   -
        * associated CPE.
      +
        * Used to analyze Node Package Manager (npm) package.json files, and collect
       45   -
        *
      +
        * information that can be used to determine the associated CPE.
       46   -
        * @author Dale Visser
      +
        *
       47   -
        */
      +
        * @author Dale Visser
       48   +
        */
      +  49  
       @Experimental
      -  49  18
       public class NodePackageAnalyzer extends AbstractFileTypeAnalyzer {
      -  50   -
       
      +  50  9
       public class NodePackageAnalyzer extends AbstractFileTypeAnalyzer {
       51   -
           /**
      +
       
       52   -
            * The logger.
      +
           /**
       53   +
            * The logger.
      +  54  
            */
      -  54  2
           private static final Logger LOGGER = LoggerFactory.getLogger(NodePackageAnalyzer.class);
      -  55   -
       
      +  55  1
           private static final Logger LOGGER = LoggerFactory.getLogger(NodePackageAnalyzer.class);
       56   -
           /**
      +
       
       57   -
            * The name of the analyzer.
      +
           /**
       58   -
            */
      +
            * The name of the analyzer.
       59   -
           private static final String ANALYZER_NAME = "Node.js Package Analyzer";
      +
            */
       60   -
       
      +
           private static final String ANALYZER_NAME = "Node.js Package Analyzer";
       61   -
           /**
      +
       
       62   -
            * The phase that this analyzer is intended to run in.
      +
           /**
       63   +
            * The phase that this analyzer is intended to run in.
      +  64  
            */
      -  64  2
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
      -  65   -
       
      +  65  1
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
       66   -
           /**
      +
       
       67   -
            * The file name to scan.
      +
           /**
       68   -
            */
      +
            * The file name to scan.
       69   -
           public static final String PACKAGE_JSON = "package.json";
      +
            */
       70   -
           /**
      +
           public static final String PACKAGE_JSON = "package.json";
       71   -
            * Filter that detects files named "package.json".
      +
           /**
       72   +
            * Filter that detects files named "package.json".
      +  73  
            */
      -  73  4
           private static final FileFilter PACKAGE_JSON_FILTER = FileFilterBuilder.newInstance()
      -  74  2
                   .addFilenames(PACKAGE_JSON).build();
      -  75   -
       
      +  74  2
           private static final FileFilter PACKAGE_JSON_FILTER = FileFilterBuilder.newInstance()
      +  75  1
                   .addFilenames(PACKAGE_JSON).build();
       76   -
           /**
      +
       
       77   -
            * Returns the FileFilter
      +
           /**
       78   -
            *
      +
            * Returns the FileFilter
       79   -
            * @return the FileFilter
      +
            *
       80   -
            */
      +
            * @return the FileFilter
       81   -
           @Override
      +
            */
       82   +
           @Override
      +  83  
           protected FileFilter getFileFilter() {
      -  83  1720
               return PACKAGE_JSON_FILTER;
      -  84   -
           }
      +  84  11
               return PACKAGE_JSON_FILTER;
       85   -
       
      +
           }
       86   -
           @Override
      +
       
       87   -
           protected void initializeFileTypeAnalyzer() throws Exception {
      +
           @Override
       88   +
           protected void initializeFileTypeAnalyzer() throws InitializationException {
      +  89  
               // NO-OP
      -  89  6
           }
      -  90   -
       
      +  90  3
           }
       91   -
           /**
      +
       
       92   -
            * Returns the name of the analyzer.
      +
           /**
       93   -
            *
      +
            * Returns the name of the analyzer.
       94   -
            * @return the name of the analyzer.
      +
            *
       95   -
            */
      +
            * @return the name of the analyzer.
       96   -
           @Override
      +
            */
       97   +
           @Override
      +  98  
           public String getName() {
      -  98  30
               return ANALYZER_NAME;
      -  99   -
           }
      +  99  15
               return ANALYZER_NAME;
       100   -
       
      +
           }
       101   -
           /**
      +
       
       102   -
            * Returns the phase that the analyzer is intended to run in.
      +
           /**
       103   -
            *
      +
            * Returns the phase that the analyzer is intended to run in.
       104   -
            * @return the phase that the analyzer is intended to run in.
      +
            *
       105   -
            */
      +
            * @return the phase that the analyzer is intended to run in.
       106   -
           @Override
      +
            */
       107   +
           @Override
      +  108  
           public AnalysisPhase getAnalysisPhase() {
      -  108  8
               return ANALYSIS_PHASE;
      -  109   -
           }
      +  109  4
               return ANALYSIS_PHASE;
       110   -
       
      -  111   -
           /**
      -  112   -
            * Returns the key used in the properties file to reference the analyzer's enabled property.
      -  113   -
            *
      -  114   -
            * @return the analyzer's enabled property setting key
      -  115   -
            */
      -  116   -
           @Override
      -  117   -
           protected String getAnalyzerEnabledSettingKey() {
      -  118  18
               return Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED;
      -  119  
           }
      -  120   +  111  
       
      -  121   -
           @Override
      -  122   -
           protected void analyzeFileType(Dependency dependency, Engine engine)
      -  123   -
                   throws AnalysisException {
      -  124  2
               final File file = dependency.getActualFile();
      -  125   -
               JsonReader jsonReader;
      -  126   -
               try {
      -  127  2
                   jsonReader = Json.createReader(FileUtils.openInputStream(file));
      -  128  0
               } catch (IOException e) {
      -  129  0
                   throw new AnalysisException(
      -  130   -
                           "Problem occurred while reading dependency file.", e);
      -  131  2
               }
      -  132   -
               try {
      -  133  2
                   final JsonObject json = jsonReader.readObject();
      -  134  2
                   final EvidenceCollection productEvidence = dependency.getProductEvidence();
      -  135  2
                   final EvidenceCollection vendorEvidence = dependency.getVendorEvidence();
      -  136  2
                   if (json.containsKey("name")) {
      -  137  2
                       final Object value = json.get("name");
      -  138  2
                       if (value instanceof JsonString) {
      -  139  2
                           final String valueString = ((JsonString) value).getString();
      -  140  2
                           productEvidence.addEvidence(PACKAGE_JSON, "name", valueString, Confidence.HIGHEST);
      -  141  2
                           vendorEvidence.addEvidence(PACKAGE_JSON, "name_project", String.format("%s_project", valueString), Confidence.LOW);
      -  142  2
                       } else {
      -  143  0
                           LOGGER.warn("JSON value not string as expected: {}", value);
      -  144   -
                       }
      -  145   -
                   }
      -  146  2
                   addToEvidence(json, productEvidence, "description");
      -  147  2
                   addToEvidence(json, vendorEvidence, "author");
      -  148  2
                   addToEvidence(json, dependency.getVersionEvidence(), "version");
      -  149  2
                   dependency.setDisplayFileName(String.format("%s/%s", file.getParentFile().getName(), file.getName()));
      -  150  0
               } catch (JsonException e) {
      -  151  0
                   LOGGER.warn("Failed to parse package.json file.", e);
      -  152   -
               } finally {
      -  153  2
                   jsonReader.close();
      -  154  2
               }
      -  155  2
           }
      -  156   -
       
      -  157   +  112  
           /**
      -  158   -
            * Adds information to an evidence collection from the node json configuration.
      -  159   +  113   +
            * Returns the key used in the properties file to reference the analyzer's
      +  114   +
            * enabled property.
      +  115  
            *
      -  160   -
            * @param json information from node.js
      -  161   -
            * @param collection a set of evidence about a dependency
      -  162   -
            * @param key the key to obtain the data from the json information
      -  163   +  116   +
            * @return the analyzer's enabled property setting key
      +  117  
            */
      -  164   -
           private void addToEvidence(JsonObject json, EvidenceCollection collection, String key) {
      -  165  6
               if (json.containsKey(key)) {
      -  166  6
                   final JsonValue value = json.get(key);
      -  167  6
                   if (value instanceof JsonString) {
      -  168  4
                       collection.addEvidence(PACKAGE_JSON, key, ((JsonString) value).getString(), Confidence.HIGHEST);
      -  169  2
                   } else if (value instanceof JsonObject) {
      -  170  2
                       final JsonObject jsonObject = (JsonObject) value;
      -  171  2
                       for (final Map.Entry<String, JsonValue> entry : jsonObject.entrySet()) {
      -  172  2
                           final String property = entry.getKey();
      -  173  2
                           final JsonValue subValue = entry.getValue();
      -  174  2
                           if (subValue instanceof JsonString) {
      -  175  4
                               collection.addEvidence(PACKAGE_JSON,
      -  176  2
                                       String.format("%s.%s", key, property),
      -  177  2
                                       ((JsonString) subValue).getString(),
      -  178   -
                                       Confidence.HIGHEST);
      -  179   -
                           } else {
      -  180  0
                               LOGGER.warn("JSON sub-value not string as expected: {}", subValue);
      -  181   -
                           }
      -  182  2
                       }
      -  183  2
                   } else {
      -  184  0
                       LOGGER.warn("JSON value not string or JSON object as expected: {}", value);
      -  185   +  118   +
           @Override
      +  119   +
           protected String getAnalyzerEnabledSettingKey() {
      +  120  9
               return Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED;
      +  121   +
           }
      +  122   +
       
      +  123   +
           @Override
      +  124   +
           protected void analyzeFileType(Dependency dependency, Engine engine)
      +  125   +
                   throws AnalysisException {
      +  126  1
               final File file = dependency.getActualFile();
      +  127   +
               JsonReader jsonReader;
      +  128   +
               try {
      +  129  1
                   jsonReader = Json.createReader(FileUtils.openInputStream(file));
      +  130  0
               } catch (IOException e) {
      +  131  0
                   throw new AnalysisException(
      +  132   +
                           "Problem occurred while reading dependency file.", e);
      +  133  1
               }
      +  134   +
               try {
      +  135  1
                   final JsonObject json = jsonReader.readObject();
      +  136  1
                   final EvidenceCollection productEvidence = dependency.getProductEvidence();
      +  137  1
                   final EvidenceCollection vendorEvidence = dependency.getVendorEvidence();
      +  138  1
                   if (json.containsKey("name")) {
      +  139  1
                       final Object value = json.get("name");
      +  140  1
                       if (value instanceof JsonString) {
      +  141  1
                           final String valueString = ((JsonString) value).getString();
      +  142  1
                           productEvidence.addEvidence(PACKAGE_JSON, "name", valueString, Confidence.HIGHEST);
      +  143  1
                           vendorEvidence.addEvidence(PACKAGE_JSON, "name_project", String.format("%s_project", valueString), Confidence.LOW);
      +  144  1
                       } else {
      +  145  0
                           LOGGER.warn("JSON value not string as expected: {}", value);
      +  146   +
                       }
      +  147  
                   }
      -  186   -
               }
      -  187  6
           }
      +  148  1
                   addToEvidence(json, productEvidence, "description");
      +  149  1
                   addToEvidence(json, vendorEvidence, "author");
      +  150  1
                   addToEvidence(json, dependency.getVersionEvidence(), "version");
      +  151  1
                   dependency.setDisplayFileName(String.format("%s/%s", file.getParentFile().getName(), file.getName()));
      +  152  0
               } catch (JsonException e) {
      +  153  0
                   LOGGER.warn("Failed to parse package.json file.", e);
      +  154   +
               } finally {
      +  155  1
                   jsonReader.close();
      +  156  1
               }
      +  157  1
           }
      +  158   +
       
      +  159   +
           /**
      +  160   +
            * Adds information to an evidence collection from the node json
      +  161   +
            * configuration.
      +  162   +
            *
      +  163   +
            * @param json information from node.js
      +  164   +
            * @param collection a set of evidence about a dependency
      +  165   +
            * @param key the key to obtain the data from the json information
      +  166   +
            */
      +  167   +
           private void addToEvidence(JsonObject json, EvidenceCollection collection, String key) {
      +  168  3
               if (json.containsKey(key)) {
      +  169  3
                   final JsonValue value = json.get(key);
      +  170  3
                   if (value instanceof JsonString) {
      +  171  2
                       collection.addEvidence(PACKAGE_JSON, key, ((JsonString) value).getString(), Confidence.HIGHEST);
      +  172  1
                   } else if (value instanceof JsonObject) {
      +  173  1
                       final JsonObject jsonObject = (JsonObject) value;
      +  174  1
                       for (final Map.Entry<String, JsonValue> entry : jsonObject.entrySet()) {
      +  175  1
                           final String property = entry.getKey();
      +  176  1
                           final JsonValue subValue = entry.getValue();
      +  177  1
                           if (subValue instanceof JsonString) {
      +  178  2
                               collection.addEvidence(PACKAGE_JSON,
      +  179  1
                                       String.format("%s.%s", key, property),
      +  180  1
                                       ((JsonString) subValue).getString(),
      +  181   +
                                       Confidence.HIGHEST);
      +  182   +
                           } else {
      +  183  0
                               LOGGER.warn("JSON sub-value not string as expected: {}", subValue);
      +  184   +
                           }
      +  185  1
                       }
      +  186  1
                   } else {
      +  187  0
                       LOGGER.warn("JSON value not string or JSON object as expected: {}", value);
       188   +
                   }
      +  189   +
               }
      +  190  3
           }
      +  191  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.NuspecAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.NuspecAnalyzer.html index 46161c9fa..fa2a77811 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.NuspecAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.NuspecAnalyzer.html @@ -90,227 +90,231 @@  36  
       import java.io.IOException;
       37   -
       
      +
       import org.owasp.dependencycheck.exception.InitializationException;
       38   -
       /**
      +
       
       39   -
        * Analyzer which will parse a Nuspec file to gather module information.
      +
       /**
       40   -
        *
      +
        * Analyzer which will parse a Nuspec file to gather module information.
       41   -
        * @author colezlaw
      +
        *
       42   +
        * @author colezlaw
      +  43  
        */
      -  43  18
       public class NuspecAnalyzer extends AbstractFileTypeAnalyzer {
      -  44   -
       
      +  44  9
       public class NuspecAnalyzer extends AbstractFileTypeAnalyzer {
       45   -
           /**
      +
       
       46   -
            * The logger.
      +
           /**
       47   +
            * The logger.
      +  48  
            */
      -  48  2
           private static final Logger LOGGER = LoggerFactory.getLogger(NuspecAnalyzer.class);
      -  49   -
       
      +  49  1
           private static final Logger LOGGER = LoggerFactory.getLogger(NuspecAnalyzer.class);
       50   -
           /**
      +
       
       51   -
            * The name of the analyzer.
      +
           /**
       52   -
            */
      +
            * The name of the analyzer.
       53   -
           private static final String ANALYZER_NAME = "Nuspec Analyzer";
      +
            */
       54   -
       
      +
           private static final String ANALYZER_NAME = "Nuspec Analyzer";
       55   -
           /**
      +
       
       56   -
            * The phase in which the analyzer runs.
      +
           /**
       57   +
            * The phase in which the analyzer runs.
      +  58  
            */
      -  58  2
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
      -  59   -
       
      +  59  1
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
       60   -
           /**
      +
       
       61   -
            * The types of files on which this will work.
      +
           /**
       62   -
            */
      +
            * The types of files on which this will work.
       63   -
           private static final String SUPPORTED_EXTENSIONS = "nuspec";
      +
            */
       64   -
       
      +
           private static final String SUPPORTED_EXTENSIONS = "nuspec";
       65   -
           /**
      +
       
       66   -
            * Initializes the analyzer once before any analysis is performed.
      +
           /**
       67   -
            *
      +
            * Initializes the analyzer once before any analysis is performed.
       68   -
            * @throws Exception if there's an error during initialization
      +
            *
       69   -
            */
      +
            * @throws InitializationException if there's an error during initialization
       70   -
           @Override
      +
            */
       71   -
           public void initializeFileTypeAnalyzer() throws Exception {
      -  72  0
           }
      -  73   -
       
      +
           @Override
      +  72   +
           public void initializeFileTypeAnalyzer() throws InitializationException {
      +  73  0
           }
       74   -
           /**
      +
       
       75   -
            * Returns the analyzer's name.
      +
           /**
       76   -
            *
      +
            * Returns the analyzer's name.
       77   -
            * @return the name of the analyzer
      +
            *
       78   -
            */
      +
            * @return the name of the analyzer
       79   -
           @Override
      +
            */
       80   +
           @Override
      +  81  
           public String getName() {
      -  81  34
               return ANALYZER_NAME;
      -  82   -
           }
      +  82  17
               return ANALYZER_NAME;
       83   -
       
      +
           }
       84   -
           /**
      +
       
       85   -
            * Returns the key used in the properties file to reference the analyzer's enabled property.
      +
           /**
       86   -
            *
      +
            * Returns the key used in the properties file to reference the analyzer's
       87   -
            * @return the analyzer's enabled property setting key
      +
            * enabled property.
       88   -
            */
      +
            *
       89   -
           @Override
      +
            * @return the analyzer's enabled property setting key
       90   -
           protected String getAnalyzerEnabledSettingKey() {
      -  91  18
               return Settings.KEYS.ANALYZER_NUSPEC_ENABLED;
      +
            */
      +  91   +
           @Override
       92   -
           }
      -  93   -
       
      +
           protected String getAnalyzerEnabledSettingKey() {
      +  93  9
               return Settings.KEYS.ANALYZER_NUSPEC_ENABLED;
       94   -
           /**
      +
           }
       95   -
            * Returns the analysis phase under which the analyzer runs.
      +
       
       96   -
            *
      +
           /**
       97   -
            * @return the phase under which this analyzer runs
      +
            * Returns the analysis phase under which the analyzer runs.
       98   -
            */
      +
            *
       99   -
           @Override
      +
            * @return the phase under which this analyzer runs
       100   -
           public AnalysisPhase getAnalysisPhase() {
      -  101  10
               return ANALYSIS_PHASE;
      +
            */
      +  101   +
           @Override
       102   -
           }
      -  103   -
       
      +
           public AnalysisPhase getAnalysisPhase() {
      +  103  5
               return ANALYSIS_PHASE;
       104   -
           /**
      -  105   -
            * The file filter used to determine which files this analyzer supports.
      -  106   -
            */
      -  107  4
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(
      -  108  2
                   SUPPORTED_EXTENSIONS).build();
      -  109   -
       
      -  110   -
           /**
      -  111   -
            * Returns the FileFilter
      -  112   -
            *
      -  113   -
            * @return the FileFilter
      -  114   -
            */
      -  115   -
           @Override
      -  116   -
           protected FileFilter getFileFilter() {
      -  117  1722
               return FILTER;
      -  118  
           }
      -  119   +  105  
       
      -  120   +  106  
           /**
      -  121   -
            * Performs the analysis.
      -  122   -
            *
      -  123   -
            * @param dependency the dependency to analyze
      -  124   -
            * @param engine the engine
      -  125   -
            * @throws AnalysisException when there's an exception during analysis
      -  126   +  107   +
            * The file filter used to determine which files this analyzer supports.
      +  108  
            */
      -  127   -
           @Override
      -  128   -
           public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException {
      -  129  0
               LOGGER.debug("Checking Nuspec file {}", dependency);
      -  130   -
               try {
      -  131  0
                   final NuspecParser parser = new XPathNuspecParser();
      -  132  0
                   NugetPackage np = null;
      -  133  0
                   FileInputStream fis = null;
      -  134   -
                   try {
      -  135  0
                       fis = new FileInputStream(dependency.getActualFilePath());
      -  136  0
                       np = parser.parse(fis);
      -  137  0
                   } catch (NuspecParseException ex) {
      -  138  0
                       throw new AnalysisException(ex);
      -  139  0
                   } catch (FileNotFoundException ex) {
      -  140  0
                       throw new AnalysisException(ex);
      -  141   -
                   } finally {
      -  142  0
                       if (fis != null) {
      -  143   -
                           try {
      -  144  0
                               fis.close();
      -  145  0
                           } catch (IOException e) {
      -  146  0
                               LOGGER.debug("Error closing input stream");
      -  147  0
                           }
      -  148   -
                       }
      -  149   -
                   }
      -  150   +  109  2
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(
      +  110  1
                   SUPPORTED_EXTENSIONS).build();
      +  111  
       
      -  151  0
                   if (np.getOwners() != null) {
      -  152  0
                       dependency.getVendorEvidence().addEvidence("nuspec", "owners", np.getOwners(), Confidence.HIGHEST);
      -  153   +  112   +
           /**
      +  113   +
            * Returns the FileFilter
      +  114   +
            *
      +  115   +
            * @return the FileFilter
      +  116   +
            */
      +  117   +
           @Override
      +  118   +
           protected FileFilter getFileFilter() {
      +  119  12
               return FILTER;
      +  120   +
           }
      +  121   +
       
      +  122   +
           /**
      +  123   +
            * Performs the analysis.
      +  124   +
            *
      +  125   +
            * @param dependency the dependency to analyze
      +  126   +
            * @param engine the engine
      +  127   +
            * @throws AnalysisException when there's an exception during analysis
      +  128   +
            */
      +  129   +
           @Override
      +  130   +
           public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException {
      +  131  0
               LOGGER.debug("Checking Nuspec file {}", dependency);
      +  132   +
               try {
      +  133  0
                   final NuspecParser parser = new XPathNuspecParser();
      +  134  0
                   NugetPackage np = null;
      +  135  0
                   FileInputStream fis = null;
      +  136   +
                   try {
      +  137  0
                       fis = new FileInputStream(dependency.getActualFilePath());
      +  138  0
                       np = parser.parse(fis);
      +  139  0
                   } catch (NuspecParseException ex) {
      +  140  0
                       throw new AnalysisException(ex);
      +  141  0
                   } catch (FileNotFoundException ex) {
      +  142  0
                       throw new AnalysisException(ex);
      +  143   +
                   } finally {
      +  144  0
                       if (fis != null) {
      +  145   +
                           try {
      +  146  0
                               fis.close();
      +  147  0
                           } catch (IOException e) {
      +  148  0
                               LOGGER.debug("Error closing input stream");
      +  149  0
                           }
      +  150   +
                       }
      +  151  
                   }
      -  154  0
                   dependency.getVendorEvidence().addEvidence("nuspec", "authors", np.getAuthors(), Confidence.HIGH);
      -  155  0
                   dependency.getVersionEvidence().addEvidence("nuspec", "version", np.getVersion(), Confidence.HIGHEST);
      -  156  0
                   dependency.getProductEvidence().addEvidence("nuspec", "id", np.getId(), Confidence.HIGHEST);
      -  157  0
                   if (np.getTitle() != null) {
      -  158  0
                       dependency.getProductEvidence().addEvidence("nuspec", "title", np.getTitle(), Confidence.MEDIUM);
      -  159   +  152   +
       
      +  153  0
                   if (np.getOwners() != null) {
      +  154  0
                       dependency.getVendorEvidence().addEvidence("nuspec", "owners", np.getOwners(), Confidence.HIGHEST);
      +  155  
                   }
      -  160  0
               } catch (Throwable e) {
      -  161  0
                   throw new AnalysisException(e);
      -  162  0
               }
      -  163  0
           }
      -  164   +  156  0
                   dependency.getVendorEvidence().addEvidence("nuspec", "authors", np.getAuthors(), Confidence.HIGH);
      +  157  0
                   dependency.getVersionEvidence().addEvidence("nuspec", "version", np.getVersion(), Confidence.HIGHEST);
      +  158  0
                   dependency.getProductEvidence().addEvidence("nuspec", "id", np.getId(), Confidence.HIGHEST);
      +  159  0
                   if (np.getTitle() != null) {
      +  160  0
                       dependency.getProductEvidence().addEvidence("nuspec", "title", np.getTitle(), Confidence.MEDIUM);
      +  161   +
                   }
      +  162  0
               } catch (Throwable e) {
      +  163  0
                   throw new AnalysisException(e);
      +  164  0
               }
      +  165  0
           }
      +  166  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.NvdCveAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.NvdCveAnalyzer.html index 1a48141ae..c63b35707 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.NvdCveAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.NvdCveAnalyzer.html @@ -12,7 +12,7 @@
       
      - +
      Classes in this File Line Coverage Branch Coverage Complexity
      NvdCveAnalyzer
      68%
      24/35
      50%
      6/12
      2.125
      NvdCveAnalyzer
      53%
      26/49
      50%
      6/12
      3.125
       
      @@ -76,222 +76,246 @@  29  
       import org.owasp.dependencycheck.dependency.Vulnerability;
       30   -
       
      +
       import org.owasp.dependencycheck.exception.InitializationException;
       31   -
       /**
      +
       import org.slf4j.LoggerFactory;
       32   -
        * NvdCveAnalyzer is a utility class that takes a project dependency and attempts to discern if there is an associated
      +
       
       33   -
        * CVEs. It uses the the identifiers found by other analyzers to lookup the CVE data.
      +
       /**
       34   -
        *
      +
        * NvdCveAnalyzer is a utility class that takes a project dependency and attempts to discern if there is an associated
       35   -
        * @author Jeremy Long
      +
        * CVEs. It uses the the identifiers found by other analyzers to lookup the CVE data.
       36   -
        */
      -  37  12
       public class NvdCveAnalyzer implements Analyzer {
      +
        *
      +  37   +
        * @author Jeremy Long
       38   -
       
      -  39   -
           /**
      +
        */
      +  39  6
       public class NvdCveAnalyzer implements Analyzer {
       40   -
            * The maximum number of query results to return.
      -  41   -
            */
      -  42   -
           static final int MAX_QUERY_RESULTS = 100;
      -  43  
           /**
      -  44   -
            * The CVE Index.
      -  45   +  41   +
            * The Logger for use throughout the class
      +  42  
            */
      +  43  1
           private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(NvdCveAnalyzer.class);
      +  44   +
           /**
      +  45   +
            * The maximum number of query results to return.
       46   -
           private CveDB cveDB;
      +
            */
       47   -
       
      +
           static final int MAX_QUERY_RESULTS = 100;
       48  
           /**
       49   -
            * Opens the data source.
      +
            * The CVE Index.
       50   -
            *
      +
            */
       51   -
            * @throws SQLException thrown when there is a SQL Exception
      +
           private CveDB cveDB;
       52   -
            * @throws IOException thrown when there is an IO Exception
      +
       
       53   -
            * @throws DatabaseException thrown when there is a database exceptions
      +
           /**
       54   -
            * @throws ClassNotFoundException thrown if the h2 database driver cannot be loaded
      +
            * Opens the data source.
       55   -
            */
      +
            *
       56   -
           public void open() throws SQLException, IOException, DatabaseException, ClassNotFoundException {
      -  57  4
               cveDB = new CveDB();
      -  58  4
               cveDB.open();
      -  59  4
           }
      +
            * @throws SQLException thrown when there is a SQL Exception
      +  57   +
            * @throws IOException thrown when there is an IO Exception
      +  58   +
            * @throws DatabaseException thrown when there is a database exceptions
      +  59   +
            * @throws ClassNotFoundException thrown if the h2 database driver cannot be loaded
       60   -
       
      +
            */
       61   -
           /**
      -  62   -
            * Closes the data source.
      -  63   -
            */
      -  64   -
           @Override
      +
           public void open() throws SQLException, IOException, DatabaseException, ClassNotFoundException {
      +  62  2
               cveDB = new CveDB();
      +  63  2
               cveDB.open();
      +  64  2
           }
       65   -
           public void close() {
      -  66  4
               cveDB.close();
      -  67  4
               cveDB = null;
      -  68  4
           }
      +
       
      +  66   +
           /**
      +  67   +
            * Closes the data source.
      +  68   +
            */
       69   -
       
      +
           @Override
       70   -
           /**
      -  71   -
            * Returns the status of the data source - is the database open.
      -  72   -
            *
      -  73   -
            * @return true or false.
      +
           public void close() {
      +  71  2
               cveDB.close();
      +  72  2
               cveDB = null;
      +  73  2
           }
       74   -
            */
      +
       
       75   -
           public boolean isOpen() {
      -  76  12
               return cveDB != null;
      +
           /**
      +  76   +
            * Returns the status of the data source - is the database open.
       77   -
           }
      +
            *
       78   -
       
      +
            * @return true or false.
       79   -
           /**
      +
            */
       80   -
            * Ensures that the CVE Database is closed.
      -  81   -
            *
      +
           public boolean isOpen() {
      +  81  5
               return cveDB != null;
       82   -
            * @throws Throwable when a throwable is thrown.
      +
           }
       83   -
            */
      +
       
       84   -
           @Override
      +
           /**
       85   -
           protected void finalize() throws Throwable {
      -  86  12
               super.finalize();
      -  87  12
               if (isOpen()) {
      -  88  0
                   close();
      +
            * Ensures that the CVE Database is closed.
      +  86   +
            *
      +  87   +
            * @throws Throwable an exception raised by this method
      +  88   +
            */
       89   -
               }
      -  90  12
           }
      -  91   -
       
      -  92   -
           /**
      -  93   -
            * Analyzes a dependency and attempts to determine if there are any CPE identifiers for this dependency.
      +
           @Override
      +  90   +
           protected void finalize() throws Throwable {
      +  91  5
               super.finalize();
      +  92  5
               if (isOpen()) {
      +  93  0
                   close();
       94   -
            *
      -  95   -
            * @param dependency The Dependency to analyze
      +
               }
      +  95  5
           }
       96   -
            * @param engine The analysis engine
      +
       
       97   -
            * @throws AnalysisException is thrown if there is an issue analyzing the dependency
      +
           /**
       98   -
            */
      +
            * Analyzes a dependency and attempts to determine if there are any CPE identifiers for this dependency.
       99   -
           @Override
      +
            *
       100   -
           public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
      -  101  8
               for (Identifier id : dependency.getIdentifiers()) {
      -  102  6
                   if ("cpe".equals(id.getType())) {
      +
            * @param dependency The Dependency to analyze
      +  101   +
            * @param engine The analysis engine
      +  102   +
            * @throws AnalysisException thrown if there is an issue analyzing the dependency
       103   +
            */
      +  104   +
           @Override
      +  105   +
           public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
      +  106  4
               for (Identifier id : dependency.getIdentifiers()) {
      +  107  3
                   if ("cpe".equals(id.getType())) {
      +  108  
                       try {
      -  104  6
                           final String value = id.getValue();
      -  105  6
                           final List<Vulnerability> vulns = cveDB.getVulnerabilities(value);
      -  106  6
                           dependency.getVulnerabilities().addAll(vulns);
      -  107  0
                       } catch (DatabaseException ex) {
      -  108  0
                           throw new AnalysisException(ex);
      -  109  6
                       }
      -  110   +  109  3
                           final String value = id.getValue();
      +  110  3
                           final List<Vulnerability> vulns = cveDB.getVulnerabilities(value);
      +  111  3
                           dependency.getVulnerabilities().addAll(vulns);
      +  112  0
                       } catch (DatabaseException ex) {
      +  113  0
                           throw new AnalysisException(ex);
      +  114  3
                       }
      +  115  
                   }
      -  111  6
               }
      -  112  8
               for (Identifier id : dependency.getSuppressedIdentifiers()) {
      -  113  0
                   if ("cpe".equals(id.getType())) {
      -  114   +  116  3
               }
      +  117  4
               for (Identifier id : dependency.getSuppressedIdentifiers()) {
      +  118  0
                   if ("cpe".equals(id.getType())) {
      +  119  
                       try {
      -  115  0
                           final String value = id.getValue();
      -  116  0
                           final List<Vulnerability> vulns = cveDB.getVulnerabilities(value);
      -  117  0
                           dependency.getSuppressedVulnerabilities().addAll(vulns);
      -  118  0
                       } catch (DatabaseException ex) {
      -  119  0
                           throw new AnalysisException(ex);
      -  120  0
                       }
      -  121   -
                   }
      -  122  0
               }
      -  123  8
           }
      -  124   -
       
      -  125   -
           /**
      +  120  0
                           final String value = id.getValue();
      +  121  0
                           final List<Vulnerability> vulns = cveDB.getVulnerabilities(value);
      +  122  0
                           dependency.getSuppressedVulnerabilities().addAll(vulns);
      +  123  0
                       } catch (DatabaseException ex) {
      +  124  0
                           throw new AnalysisException(ex);
      +  125  0
                       }
       126   -
            * Returns the name of this analyzer.
      -  127   -
            *
      -  128   -
            * @return the name of this analyzer.
      +
                   }
      +  127  0
               }
      +  128  4
           }
       129   -
            */
      +
       
       130   -
           @Override
      +
           /**
       131   -
           public String getName() {
      -  132  32
               return "NVD CVE Analyzer";
      +
            * Returns the name of this analyzer.
      +  132   +
            *
       133   -
           }
      +
            * @return the name of this analyzer.
       134   -
       
      +
            */
       135   -
           /**
      +
           @Override
       136   -
            * Returns the analysis phase that this analyzer should run in.
      -  137   -
            *
      +
           public String getName() {
      +  137  16
               return "NVD CVE Analyzer";
       138   -
            * @return the analysis phase that this analyzer should run in.
      -  139   -
            */
      -  140   -
           @Override
      -  141   -
           public AnalysisPhase getAnalysisPhase() {
      -  142  8
               return AnalysisPhase.FINDING_ANALYSIS;
      -  143  
           }
      -  144   +  139  
       
      -  145   +  140  
           /**
      -  146   -
            * Opens the database used to gather NVD CVE data.
      -  147   +  141   +
            * Returns the analysis phase that this analyzer should run in.
      +  142  
            *
      -  148   -
            * @throws Exception is thrown if there is an issue opening the index.
      -  149   +  143   +
            * @return the analysis phase that this analyzer should run in.
      +  144  
            */
      -  150   +  145  
           @Override
      +  146   +
           public AnalysisPhase getAnalysisPhase() {
      +  147  4
               return AnalysisPhase.FINDING_ANALYSIS;
      +  148   +
           }
      +  149   +
       
      +  150   +
           /**
       151   -
           public void initialize() throws Exception {
      -  152  4
               this.open();
      -  153  4
           }
      +
            * Opens the database used to gather NVD CVE data.
      +  152   +
            *
      +  153   +
            * @throws InitializationException is thrown if there is an issue opening the index.
       154   +
            */
      +  155   +
           @Override
      +  156   +
           public void initialize() throws InitializationException {
      +  157   +
               try {
      +  158  2
                   this.open();
      +  159  0
               } catch (SQLException ex) {
      +  160  0
                   LOGGER.debug("SQL Exception initializing NvdCveAnalyzer", ex);
      +  161  0
                   throw new InitializationException(ex);
      +  162  0
               } catch (IOException ex) {
      +  163  0
                   LOGGER.debug("IO Exception initializing NvdCveAnalyzer", ex);
      +  164  0
                   throw new InitializationException(ex);
      +  165  0
               } catch (DatabaseException ex) {
      +  166  0
                   LOGGER.debug("Database Exception initializing NvdCveAnalyzer", ex);
      +  167  0
                   throw new InitializationException(ex);
      +  168  0
               } catch (ClassNotFoundException ex) {
      +  169  0
                   LOGGER.debug("Exception initializing NvdCveAnalyzer", ex);
      +  170  0
                   throw new InitializationException(ex);
      +  171  2
               }
      +  172  2
           }
      +  173  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.OpenSSLAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.OpenSSLAnalyzer.html index be27a36bd..83538ba5e 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.OpenSSLAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.OpenSSLAnalyzer.html @@ -84,332 +84,334 @@  33  
       import java.util.regex.Pattern;
       34   -
       
      +
       import org.owasp.dependencycheck.exception.InitializationException;
       35   -
       /**
      +
       
       36   -
        * Used to analyze OpenSSL source code present in the file system.
      +
       /**
       37   -
        *
      +
        * Used to analyze OpenSSL source code present in the file system.
       38   -
        * @author Dale Visser
      +
        *
       39   +
        * @author Dale Visser
      +  40  
        */
      -  40  20
       public class OpenSSLAnalyzer extends AbstractFileTypeAnalyzer {
      -  41   -
       
      +  41  10
       public class OpenSSLAnalyzer extends AbstractFileTypeAnalyzer {
       42   -
           /**
      +
       
       43   -
            * Hexadecimal.
      +
           /**
       44   -
            */
      +
            * Hexadecimal.
       45   -
           private static final int HEXADECIMAL = 16;
      +
            */
       46   -
           /**
      +
           private static final int HEXADECIMAL = 16;
       47   -
            * Filename to analyze. All other .h files get removed from consideration.
      +
           /**
       48   -
            */
      +
            * Filename to analyze. All other .h files get removed from consideration.
       49   -
           private static final String OPENSSLV_H = "opensslv.h";
      +
            */
       50   -
       
      +
           private static final String OPENSSLV_H = "opensslv.h";
       51   -
           /**
      +
       
       52   -
            * Filter that detects files named "__init__.py".
      +
           /**
       53   +
            * Filter that detects files named "__init__.py".
      +  54  
            */
      -  54  2
           private static final FileFilter OPENSSLV_FILTER = FileFilterBuilder.newInstance().addFilenames(OPENSSLV_H).build();
      -  55   -
           /**
      +  55  1
           private static final FileFilter OPENSSLV_FILTER = FileFilterBuilder.newInstance().addFilenames(OPENSSLV_H).build();
       56   -
            * Open SSL Version number pattern.
      +
           /**
       57   +
            * Open SSL Version number pattern.
      +  58  
            */
      -  58  2
           private static final Pattern VERSION_PATTERN = Pattern.compile(
      -  59   -
                   "define\\s+OPENSSL_VERSION_NUMBER\\s+0x([0-9a-zA-Z]{8})L", Pattern.DOTALL
      +  59  1
           private static final Pattern VERSION_PATTERN = Pattern.compile(
       60   -
                   | Pattern.CASE_INSENSITIVE);
      +
                   "define\\s+OPENSSL_VERSION_NUMBER\\s+0x([0-9a-zA-Z]{8})L", Pattern.DOTALL
       61   -
           /**
      +
                   | Pattern.CASE_INSENSITIVE);
       62   -
            * The offset of the major version number.
      +
           /**
       63   -
            */
      +
            * The offset of the major version number.
       64   -
           private static final int MAJOR_OFFSET = 28;
      +
            */
       65   -
           /**
      +
           private static final int MAJOR_OFFSET = 28;
       66   -
            * The mask for the minor version number.
      +
           /**
       67   -
            */
      +
            * The mask for the minor version number.
       68   -
           private static final long MINOR_MASK = 0x0ff00000L;
      +
            */
       69   -
           /**
      +
           private static final long MINOR_MASK = 0x0ff00000L;
       70   -
            * The offset of the minor version number.
      +
           /**
       71   -
            */
      +
            * The offset of the minor version number.
       72   -
           private static final int MINOR_OFFSET = 20;
      +
            */
       73   -
           /**
      +
           private static final int MINOR_OFFSET = 20;
       74   -
            * The max for the fix version.
      +
           /**
       75   -
            */
      +
            * The max for the fix version.
       76   -
           private static final long FIX_MASK = 0x000ff000L;
      +
            */
       77   -
           /**
      +
           private static final long FIX_MASK = 0x000ff000L;
       78   -
            * The offset for the fix version.
      +
           /**
       79   -
            */
      +
            * The offset for the fix version.
       80   -
           private static final int FIX_OFFSET = 12;
      +
            */
       81   -
           /**
      +
           private static final int FIX_OFFSET = 12;
       82   -
            * The mask for the patch version.
      +
           /**
       83   -
            */
      +
            * The mask for the patch version.
       84   -
           private static final long PATCH_MASK = 0x00000ff0L;
      +
            */
       85   -
           /**
      +
           private static final long PATCH_MASK = 0x00000ff0L;
       86   -
            * The offset for the patch version.
      +
           /**
       87   -
            */
      +
            * The offset for the patch version.
       88   -
           private static final int PATCH_OFFSET = 4;
      +
            */
       89   -
           /**
      +
           private static final int PATCH_OFFSET = 4;
       90   -
            * Number of letters.
      +
           /**
       91   -
            */
      +
            * Number of letters.
       92   -
           private static final int NUM_LETTERS = 26;
      +
            */
       93   -
           /**
      +
           private static final int NUM_LETTERS = 26;
       94   -
            * The status mask.
      +
           /**
       95   -
            */
      +
            * The status mask.
       96   -
           private static final int STATUS_MASK = 0x0000000f;
      +
            */
       97   -
       
      +
           private static final int STATUS_MASK = 0x0000000f;
       98   -
           /**
      +
       
       99   -
            * Returns the open SSL version as a string.
      +
           /**
       100   -
            *
      +
            * Returns the open SSL version as a string.
       101   -
            * @param openSSLVersionConstant The open SSL version
      +
            *
       102   -
            * @return the version of openssl
      +
            * @param openSSLVersionConstant The open SSL version
       103   -
            */
      +
            * @return the version of openssl
       104   +
            */
      +  105  
           static String getOpenSSLVersion(long openSSLVersionConstant) {
      -  105  18
               final long major = openSSLVersionConstant >>> MAJOR_OFFSET;
      -  106  18
               final long minor = (openSSLVersionConstant & MINOR_MASK) >>> MINOR_OFFSET;
      -  107  18
               final long fix = (openSSLVersionConstant & FIX_MASK) >>> FIX_OFFSET;
      -  108  18
               final long patchLevel = (openSSLVersionConstant & PATCH_MASK) >>> PATCH_OFFSET;
      -  109  18
               final String patch = 0 == patchLevel || patchLevel > NUM_LETTERS ? "" : String.valueOf((char) (patchLevel + 'a' - 1));
      -  110  18
               final int statusCode = (int) (openSSLVersionConstant & STATUS_MASK);
      -  111  18
               final String status = 0xf == statusCode ? "" : (0 == statusCode ? "-dev" : "-beta" + statusCode);
      -  112  18
               return String.format("%d.%d.%d%s%s", major, minor, fix, patch, status);
      -  113   -
           }
      +  106  9
               final long major = openSSLVersionConstant >>> MAJOR_OFFSET;
      +  107  9
               final long minor = (openSSLVersionConstant & MINOR_MASK) >>> MINOR_OFFSET;
      +  108  9
               final long fix = (openSSLVersionConstant & FIX_MASK) >>> FIX_OFFSET;
      +  109  9
               final long patchLevel = (openSSLVersionConstant & PATCH_MASK) >>> PATCH_OFFSET;
      +  110  9
               final String patch = 0 == patchLevel || patchLevel > NUM_LETTERS ? "" : String.valueOf((char) (patchLevel + 'a' - 1));
      +  111  9
               final int statusCode = (int) (openSSLVersionConstant & STATUS_MASK);
      +  112  9
               final String status = 0xf == statusCode ? "" : (0 == statusCode ? "-dev" : "-beta" + statusCode);
      +  113  9
               return String.format("%d.%d.%d%s%s", major, minor, fix, patch, status);
       114   -
       
      +
           }
       115   -
           /**
      +
       
       116   -
            * Returns the name of the Python Package Analyzer.
      +
           /**
       117   -
            *
      +
            * Returns the name of the Python Package Analyzer.
       118   -
            * @return the name of the analyzer
      +
            *
       119   -
            */
      +
            * @return the name of the analyzer
       120   -
           @Override
      +
            */
       121   +
           @Override
      +  122  
           public String getName() {
      -  122  34
               return "OpenSSL Source Analyzer";
      -  123   -
           }
      +  123  17
               return "OpenSSL Source Analyzer";
       124   -
       
      +
           }
       125   -
           /**
      +
       
       126   -
            * Tell that we are used for information collection.
      +
           /**
       127   -
            *
      +
            * Tell that we are used for information collection.
       128   -
            * @return INFORMATION_COLLECTION
      +
            *
       129   -
            */
      +
            * @return INFORMATION_COLLECTION
       130   -
           @Override
      +
            */
       131   +
           @Override
      +  132  
           public AnalysisPhase getAnalysisPhase() {
      -  132  8
               return AnalysisPhase.INFORMATION_COLLECTION;
      -  133   -
           }
      +  133  4
               return AnalysisPhase.INFORMATION_COLLECTION;
       134   -
       
      +
           }
       135   -
           /**
      +
       
       136   -
            * Returns the set of supported file extensions.
      +
           /**
       137   -
            *
      +
            * Returns the set of supported file extensions.
       138   -
            * @return the set of supported file extensions
      +
            *
       139   -
            */
      +
            * @return the set of supported file extensions
       140   -
           @Override
      +
            */
       141   +
           @Override
      +  142  
           protected FileFilter getFileFilter() {
      -  142  1720
               return OPENSSLV_FILTER;
      -  143   -
           }
      +  143  11
               return OPENSSLV_FILTER;
       144   -
       
      +
           }
       145   -
           /**
      +
       
       146   -
            * No-op initializer implementation.
      +
           /**
       147   -
            *
      +
            * No-op initializer implementation.
       148   -
            * @throws Exception never thrown
      +
            *
       149   -
            */
      +
            * @throws InitializationException never thrown
       150   -
           @Override
      +
            */
       151   -
           protected void initializeFileTypeAnalyzer() throws Exception {
      +
           @Override
       152   +
           protected void initializeFileTypeAnalyzer() throws InitializationException {
      +  153  
               // Nothing to do here.
      -  153  8
           }
      -  154   -
       
      +  154  4
           }
       155   -
           /**
      +
       
       156   -
            * Analyzes python packages and adds evidence to the dependency.
      +
           /**
       157   -
            *
      +
            * Analyzes python packages and adds evidence to the dependency.
       158   -
            * @param dependency the dependency being analyzed
      +
            *
       159   -
            * @param engine the engine being used to perform the scan
      +
            * @param dependency the dependency being analyzed
       160   -
            * @throws AnalysisException thrown if there is an unrecoverable error
      +
            * @param engine the engine being used to perform the scan
       161   -
            * analyzing the dependency
      +
            * @throws AnalysisException thrown if there is an unrecoverable error
       162   -
            */
      +
            * analyzing the dependency
       163   -
           @Override
      +
            */
       164   -
           protected void analyzeFileType(Dependency dependency, Engine engine)
      -  165   -
                   throws AnalysisException {
      -  166  2
               final File file = dependency.getActualFile();
      -  167  2
               final String parentName = file.getParentFile().getName();
      -  168  2
               boolean found = false;
      -  169  2
               final String contents = getFileContents(file);
      -  170  2
               if (!contents.isEmpty()) {
      -  171  2
                   final Matcher matcher = VERSION_PATTERN.matcher(contents);
      -  172  2
                   if (matcher.find()) {
      -  173  4
                       dependency.getVersionEvidence().addEvidence(OPENSSLV_H, "Version Constant",
      -  174  2
                               getOpenSSLVersion(Long.parseLong(matcher.group(1), HEXADECIMAL)), Confidence.HIGH);
      -  175  2
                       found = true;
      -  176   -
                   }
      -  177   -
               }
      -  178  2
               if (found) {
      -  179  2
                   dependency.setDisplayFileName(parentName + File.separatorChar + OPENSSLV_H);
      -  180  2
                   dependency.getVendorEvidence().addEvidence(OPENSSLV_H, "Vendor", "OpenSSL", Confidence.HIGHEST);
      -  181  2
                   dependency.getProductEvidence().addEvidence(OPENSSLV_H, "Product", "OpenSSL", Confidence.HIGHEST);
      -  182   -
               } else {
      -  183  0
                   engine.getDependencies().remove(dependency);
      -  184   -
               }
      -  185  2
           }
      -  186   -
       
      -  187   -
           /**
      -  188   -
            * Retrieves the contents of a given file.
      -  189   -
            *
      -  190   -
            * @param actualFile the file to read
      -  191   -
            * @return the contents of the file
      -  192   -
            * @throws AnalysisException thrown if there is an IO Exception
      -  193   -
            */
      -  194   -
           private String getFileContents(final File actualFile)
      -  195   -
                   throws AnalysisException {
      -  196   -
               try {
      -  197  2
                   return FileUtils.readFileToString(actualFile, Charset.defaultCharset()).trim();
      -  198  0
               } catch (IOException e) {
      -  199  0
                   throw new AnalysisException(
      -  200   -
                           "Problem occurred while reading dependency file.", e);
      -  201   -
               }
      -  202   -
           }
      -  203   -
       
      -  204   -
           /**
      -  205   -
            * Returns the setting for the analyzer enabled setting key.
      -  206   -
            *
      -  207   -
            * @return the setting for the analyzer enabled setting key
      -  208   -
            */
      -  209  
           @Override
      -  210   -
           protected String getAnalyzerEnabledSettingKey() {
      -  211  20
               return Settings.KEYS.ANALYZER_OPENSSL_ENABLED;
      -  212   +  165   +
           protected void analyzeFileType(Dependency dependency, Engine engine)
      +  166   +
                   throws AnalysisException {
      +  167  1
               final File file = dependency.getActualFile();
      +  168  1
               final String parentName = file.getParentFile().getName();
      +  169  1
               boolean found = false;
      +  170  1
               final String contents = getFileContents(file);
      +  171  1
               if (!contents.isEmpty()) {
      +  172  1
                   final Matcher matcher = VERSION_PATTERN.matcher(contents);
      +  173  1
                   if (matcher.find()) {
      +  174  2
                       dependency.getVersionEvidence().addEvidence(OPENSSLV_H, "Version Constant",
      +  175  1
                               getOpenSSLVersion(Long.parseLong(matcher.group(1), HEXADECIMAL)), Confidence.HIGH);
      +  176  1
                       found = true;
      +  177   +
                   }
      +  178   +
               }
      +  179  1
               if (found) {
      +  180  1
                   dependency.setDisplayFileName(parentName + File.separatorChar + OPENSSLV_H);
      +  181  1
                   dependency.getVendorEvidence().addEvidence(OPENSSLV_H, "Vendor", "OpenSSL", Confidence.HIGHEST);
      +  182  1
                   dependency.getProductEvidence().addEvidence(OPENSSLV_H, "Product", "OpenSSL", Confidence.HIGHEST);
      +  183   +
               } else {
      +  184  0
                   engine.getDependencies().remove(dependency);
      +  185   +
               }
      +  186  1
           }
      +  187   +
       
      +  188   +
           /**
      +  189   +
            * Retrieves the contents of a given file.
      +  190   +
            *
      +  191   +
            * @param actualFile the file to read
      +  192   +
            * @return the contents of the file
      +  193   +
            * @throws AnalysisException thrown if there is an IO Exception
      +  194   +
            */
      +  195   +
           private String getFileContents(final File actualFile)
      +  196   +
                   throws AnalysisException {
      +  197   +
               try {
      +  198  1
                   return FileUtils.readFileToString(actualFile, Charset.defaultCharset()).trim();
      +  199  0
               } catch (IOException e) {
      +  200  0
                   throw new AnalysisException(
      +  201   +
                           "Problem occurred while reading dependency file.", e);
      +  202   +
               }
      +  203  
           }
      +  204   +
       
      +  205   +
           /**
      +  206   +
            * Returns the setting for the analyzer enabled setting key.
      +  207   +
            *
      +  208   +
            * @return the setting for the analyzer enabled setting key
      +  209   +
            */
      +  210   +
           @Override
      +  211   +
           protected String getAnalyzerEnabledSettingKey() {
      +  212  10
               return Settings.KEYS.ANALYZER_OPENSSL_ENABLED;
       213   +
           }
      +  214  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.PythonDistributionAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.PythonDistributionAnalyzer.html index 6492f3d42..02e011e54 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.PythonDistributionAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.PythonDistributionAnalyzer.html @@ -12,7 +12,7 @@
       
      - +
      Classes in this File Line Coverage Branch Coverage Complexity
      PythonDistributionAnalyzer
      85%
      89/104
      65%
      30/46
      3.308
      PythonDistributionAnalyzer
      81%
      90/110
      65%
      30/46
      3.462
       
      @@ -68,603 +68,631 @@  25  
       import java.io.FilenameFilter;
       26   -
       import org.apache.commons.io.filefilter.NameFileFilter;
      +
       import java.io.IOException;
       27   -
       import org.apache.commons.io.filefilter.SuffixFileFilter;
      +
       import org.apache.commons.io.filefilter.NameFileFilter;
       28   -
       import org.apache.commons.io.input.AutoCloseInputStream;
      +
       import org.apache.commons.io.filefilter.SuffixFileFilter;
       29   -
       import org.apache.commons.lang3.StringUtils;
      +
       import org.apache.commons.io.input.AutoCloseInputStream;
       30   -
       import org.owasp.dependencycheck.Engine;
      +
       import org.apache.commons.lang3.StringUtils;
       31   -
       import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
      +
       import org.owasp.dependencycheck.Engine;
       32   -
       import org.owasp.dependencycheck.dependency.Confidence;
      +
       import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
       33   -
       import org.owasp.dependencycheck.dependency.Dependency;
      +
       import org.owasp.dependencycheck.dependency.Confidence;
       34   -
       import org.owasp.dependencycheck.dependency.EvidenceCollection;
      +
       import org.owasp.dependencycheck.dependency.Dependency;
       35   -
       import org.slf4j.Logger;
      +
       import org.owasp.dependencycheck.dependency.EvidenceCollection;
       36   -
       import org.slf4j.LoggerFactory;
      +
       import org.slf4j.Logger;
       37   -
       
      +
       import org.slf4j.LoggerFactory;
       38   -
       import javax.mail.MessagingException;
      +
       
       39   -
       import javax.mail.internet.InternetHeaders;
      +
       import javax.mail.MessagingException;
       40   -
       import org.owasp.dependencycheck.utils.ExtractionException;
      +
       import javax.mail.internet.InternetHeaders;
       41   -
       import org.owasp.dependencycheck.utils.ExtractionUtil;
      +
       import org.owasp.dependencycheck.exception.InitializationException;
       42   -
       import org.owasp.dependencycheck.utils.FileFilterBuilder;
      +
       import org.owasp.dependencycheck.utils.ExtractionException;
       43   -
       import org.owasp.dependencycheck.utils.FileUtils;
      +
       import org.owasp.dependencycheck.utils.ExtractionUtil;
       44   -
       import org.owasp.dependencycheck.utils.Settings;
      +
       import org.owasp.dependencycheck.utils.FileFilterBuilder;
       45   -
       import org.owasp.dependencycheck.utils.UrlStringUtils;
      +
       import org.owasp.dependencycheck.utils.FileUtils;
       46   -
       
      +
       import org.owasp.dependencycheck.utils.Settings;
       47   -
       /**
      +
       import org.owasp.dependencycheck.utils.UrlStringUtils;
       48   -
        * Used to analyze a Wheel or egg distribution files, or their contents in unzipped form, and collect information that can be used
      +
       
       49   -
        * to determine the associated CPE.
      +
       /**
       50   -
        *
      +
        * Used to analyze a Wheel or egg distribution files, or their contents in
       51   -
        * @author Dale Visser
      +
        * unzipped form, and collect information that can be used to determine the
       52   -
        */
      +
        * associated CPE.
       53   -
       @Experimental
      -  54  28
       public class PythonDistributionAnalyzer extends AbstractFileTypeAnalyzer {
      +
        *
      +  54   +
        * @author Dale Visser
       55   -
       
      +
        */
       56   -
           /**
      -  57   -
            * Name of egg metadata files to analyze.
      +
       @Experimental
      +  57  14
       public class PythonDistributionAnalyzer extends AbstractFileTypeAnalyzer {
       58   -
            */
      +
       
       59   -
           private static final String PKG_INFO = "PKG-INFO";
      +
           /**
       60   -
       
      +
            * Name of egg metadata files to analyze.
       61   -
           /**
      +
            */
       62   -
            * Name of wheel metadata files to analyze.
      +
           private static final String PKG_INFO = "PKG-INFO";
       63   -
            */
      +
       
       64   -
           private static final String METADATA = "METADATA";
      +
           /**
       65   -
       
      +
            * Name of wheel metadata files to analyze.
       66   -
           /**
      +
            */
       67   -
            * The logger.
      +
           private static final String METADATA = "METADATA";
       68   -
            */
      -  69  2
           private static final Logger LOGGER = LoggerFactory
      -  70  2
                   .getLogger(PythonDistributionAnalyzer.class);
      +
       
      +  69   +
           /**
      +  70   +
            * The logger.
       71   -
       
      -  72   -
           /**
      -  73   -
            * The count of directories created during analysis. This is used for creating temporary directories.
      +
            */
      +  72  1
           private static final Logger LOGGER = LoggerFactory
      +  73  1
                   .getLogger(PythonDistributionAnalyzer.class);
       74   -
            */
      -  75  2
           private static int dirCount = 0;
      -  76  
       
      -  77   +  75  
           /**
      +  76   +
            * The count of directories created during analysis. This is used for
      +  77   +
            * creating temporary directories.
       78   -
            * The name of the analyzer.
      -  79  
            */
      +  79  1
           private static int dirCount = 0;
       80   -
           private static final String ANALYZER_NAME = "Python Distribution Analyzer";
      +
       
       81  
           /**
       82   -
            * The phase that this analyzer is intended to run in.
      +
            * The name of the analyzer.
       83  
            */
      -  84  2
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
      +  84   +
           private static final String ANALYZER_NAME = "Python Distribution Analyzer";
       85   -
       
      +
           /**
       86   -
           /**
      +
            * The phase that this analyzer is intended to run in.
       87   -
            * The set of file extensions supported by this analyzer.
      -  88  
            */
      -  89  2
           private static final String[] EXTENSIONS = {"whl", "egg", "zip"};
      +  88  1
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
      +  89   +
       
       90   -
       
      +
           /**
       91   -
           /**
      +
            * The set of file extensions supported by this analyzer.
       92   -
            * Used to match on egg archive candidate extensions.
      -  93  
            */
      -  94  2
           private static final FileFilter EGG_OR_ZIP = FileFilterBuilder.newInstance().addExtensions("egg", "zip").build();
      +  93  1
           private static final String[] EXTENSIONS = {"whl", "egg", "zip"};
      +  94   +
       
       95   -
       
      +
           /**
       96   -
           /**
      +
            * Used to match on egg archive candidate extensions.
       97   -
            * Used to detect files with a .whl extension.
      -  98  
            */
      -  99  2
           private static final FileFilter WHL_FILTER = FileFilterBuilder.newInstance().addExtensions("whl").build();
      +  98  1
           private static final FileFilter EGG_OR_ZIP = FileFilterBuilder.newInstance().addExtensions("egg", "zip").build();
      +  99   +
       
       100   -
       
      +
           /**
       101   -
           /**
      +
            * Used to detect files with a .whl extension.
       102   -
            * The parent directory for the individual directories per archive.
      -  103  
            */
      +  103  1
           private static final FileFilter WHL_FILTER = FileFilterBuilder.newInstance().addExtensions("whl").build();
       104   -
           private File tempFileLocation;
      +
       
       105   -
       
      +
           /**
       106   -
           /**
      +
            * The parent directory for the individual directories per archive.
       107   -
            * Filter that detects *.dist-info files (but doesn't verify they are directories.
      +
            */
       108   -
            */
      -  109  2
           private static final FilenameFilter DIST_INFO_FILTER = new SuffixFileFilter(
      +
           private File tempFileLocation;
      +  109   +
       
       110   -
                   ".dist-info");
      +
           /**
       111   -
       
      +
            * Filter that detects *.dist-info files (but doesn't verify they are
       112   -
           /**
      +
            * directories.
       113   -
            * Filter that detects files named "METADATA".
      -  114  
            */
      -  115  2
           private static final FilenameFilter EGG_INFO_FILTER = new NameFileFilter(
      +  114  1
           private static final FilenameFilter DIST_INFO_FILTER = new SuffixFileFilter(
      +  115   +
                   ".dist-info");
       116   -
                   "EGG-INFO");
      +
       
       117   -
       
      +
           /**
       118   -
           /**
      -  119  
            * Filter that detects files named "METADATA".
      -  120   +  119  
            */
      -  121  2
           private static final NameFileFilter METADATA_FILTER = new NameFileFilter(
      +  120  1
           private static final FilenameFilter EGG_INFO_FILTER = new NameFileFilter(
      +  121   +
                   "EGG-INFO");
       122   -
                   METADATA);
      +
       
       123   -
       
      +
           /**
       124   -
           /**
      +
            * Filter that detects files named "METADATA".
       125   -
            * Filter that detects files named "PKG-INFO".
      -  126  
            */
      -  127  2
           private static final NameFileFilter PKG_INFO_FILTER = new NameFileFilter(
      +  126  1
           private static final NameFileFilter METADATA_FILTER = new NameFileFilter(
      +  127   +
                   METADATA);
       128   -
                   PKG_INFO);
      +
       
       129   -
       
      +
           /**
       130   -
           /**
      +
            * Filter that detects files named "PKG-INFO".
       131   -
            * The file filter used to determine which files this analyzer supports.
      -  132  
            */
      -  133  4
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addFileFilters(
      -  134  2
                   METADATA_FILTER, PKG_INFO_FILTER).addExtensions(EXTENSIONS).build();
      +  132  1
           private static final NameFileFilter PKG_INFO_FILTER = new NameFileFilter(
      +  133   +
                   PKG_INFO);
      +  134   +
       
       135   -
       
      +
           /**
       136   -
           /**
      +
            * The file filter used to determine which files this analyzer supports.
       137   -
            * Returns the FileFilter
      -  138   -
            *
      -  139   -
            * @return the FileFilter
      +
            */
      +  138  2
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addFileFilters(
      +  139  1
                   METADATA_FILTER, PKG_INFO_FILTER).addExtensions(EXTENSIONS).build();
       140   -
            */
      +
       
       141   -
           @Override
      +
           /**
       142   -
           protected FileFilter getFileFilter() {
      -  143  1728
               return FILTER;
      +
            * Returns the FileFilter
      +  143   +
            *
       144   -
           }
      +
            * @return the FileFilter
       145   -
       
      +
            */
       146   -
           /**
      +
           @Override
       147   -
            * Returns the name of the analyzer.
      -  148   -
            *
      +
           protected FileFilter getFileFilter() {
      +  148  15
               return FILTER;
       149   -
            * @return the name of the analyzer.
      +
           }
       150   -
            */
      +
       
       151   -
           @Override
      +
           /**
       152   -
           public String getName() {
      -  153  30
               return ANALYZER_NAME;
      +
            * Returns the name of the analyzer.
      +  153   +
            *
       154   -
           }
      +
            * @return the name of the analyzer.
       155   -
       
      +
            */
       156   -
           /**
      +
           @Override
       157   -
            * Returns the phase that the analyzer is intended to run in.
      -  158   -
            *
      +
           public String getName() {
      +  158  15
               return ANALYZER_NAME;
       159   -
            * @return the phase that the analyzer is intended to run in.
      +
           }
       160   -
            */
      +
       
       161   -
           @Override
      +
           /**
       162   -
           public AnalysisPhase getAnalysisPhase() {
      -  163  8
               return ANALYSIS_PHASE;
      +
            * Returns the phase that the analyzer is intended to run in.
      +  163   +
            *
       164   -
           }
      +
            * @return the phase that the analyzer is intended to run in.
       165   -
       
      +
            */
       166   -
           /**
      +
           @Override
       167   -
            * Returns the key used in the properties file to reference the analyzer's enabled property.
      -  168   -
            *
      +
           public AnalysisPhase getAnalysisPhase() {
      +  168  4
               return ANALYSIS_PHASE;
       169   -
            * @return the analyzer's enabled property setting key
      -  170   -
            */
      -  171   -
           @Override
      -  172   -
           protected String getAnalyzerEnabledSettingKey() {
      -  173  28
               return Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED;
      -  174  
           }
      +  170   +
       
      +  171   +
           /**
      +  172   +
            * Returns the key used in the properties file to reference the analyzer's
      +  173   +
            * enabled property.
      +  174   +
            *
       175   -
       
      +
            * @return the analyzer's enabled property setting key
       176   -
           @Override
      +
            */
       177   -
           protected void analyzeFileType(Dependency dependency, Engine engine)
      +
           @Override
       178   -
                   throws AnalysisException {
      -  179  12
               final File actualFile = dependency.getActualFile();
      -  180  12
               if (WHL_FILTER.accept(actualFile)) {
      -  181  2
                   collectMetadataFromArchiveFormat(dependency, DIST_INFO_FILTER,
      +
           protected String getAnalyzerEnabledSettingKey() {
      +  179  14
               return Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED;
      +  180   +
           }
      +  181   +
       
       182   -
                           METADATA_FILTER);
      -  183  10
               } else if (EGG_OR_ZIP.accept(actualFile)) {
      -  184  4
                   collectMetadataFromArchiveFormat(dependency, EGG_INFO_FILTER,
      -  185   -
                           PKG_INFO_FILTER);
      -  186   -
               } else {
      -  187  6
                   final String name = actualFile.getName();
      -  188  6
                   final boolean metadata = METADATA.equals(name);
      -  189  6
                   if (metadata || PKG_INFO.equals(name)) {
      -  190  6
                       final File parent = actualFile.getParentFile();
      -  191  6
                       final String parentName = parent.getName();
      -  192  6
                       dependency.setDisplayFileName(parentName + "/" + name);
      -  193  6
                       if (parent.isDirectory()
      -  194  2
                               && (metadata && parentName.endsWith(".dist-info")
      -  195  4
                               || parentName.endsWith(".egg-info") || "EGG-INFO"
      -  196  2
                               .equals(parentName))) {
      -  197  6
                           collectWheelMetadata(dependency, actualFile);
      -  198   -
                       }
      -  199   -
                   }
      -  200   -
               }
      -  201  12
           }
      -  202   -
       
      -  203   -
           /**
      -  204   -
            * Collects the meta data from an archive.
      -  205   -
            *
      -  206   -
            * @param dependency the archive being scanned
      -  207   -
            * @param folderFilter the filter to apply to the folder
      -  208   -
            * @param metadataFilter the filter to apply to the meta data
      -  209   -
            * @throws AnalysisException thrown when there is a problem analyzing the dependency
      -  210   -
            */
      -  211   -
           private void collectMetadataFromArchiveFormat(Dependency dependency,
      -  212   -
                   FilenameFilter folderFilter, FilenameFilter metadataFilter)
      -  213   +
           @Override
      +  183   +
           protected void analyzeFileType(Dependency dependency, Engine engine)
      +  184  
                   throws AnalysisException {
      -  214  6
               final File temp = getNextTempDirectory();
      -  215  6
               LOGGER.debug("{} exists? {}", temp, temp.exists());
      -  216   -
               try {
      -  217  12
                   ExtractionUtil.extractFilesUsingFilter(
      -  218  6
                           new File(dependency.getActualFilePath()), temp,
      -  219   -
                           metadataFilter);
      -  220  0
               } catch (ExtractionException ex) {
      -  221  0
                   throw new AnalysisException(ex);
      -  222  6
               }
      -  223   -
       
      -  224  12
               collectWheelMetadata(
      -  225   -
                       dependency,
      -  226  6
                       getMatchingFile(getMatchingFile(temp, folderFilter),
      -  227   -
                               metadataFilter));
      -  228  6
           }
      -  229   -
       
      -  230   -
           /**
      -  231   -
            * Makes sure a usable temporary directory is available.
      -  232   -
            *
      -  233   -
            * @throws Exception an AnalyzeException is thrown when the temp directory cannot be created
      -  234   -
            */
      -  235   -
           @Override
      -  236   -
           protected void initializeFileTypeAnalyzer() throws Exception {
      -  237  16
               final File baseDir = Settings.getTempDirectory();
      -  238  16
               tempFileLocation = File.createTempFile("check", "tmp", baseDir);
      -  239  16
               if (!tempFileLocation.delete()) {
      -  240  0
                   final String msg = String.format(
      -  241   -
                           "Unable to delete temporary file '%s'.",
      -  242  0
                           tempFileLocation.getAbsolutePath());
      -  243  0
                   throw new AnalysisException(msg);
      -  244   -
               }
      -  245  16
               if (!tempFileLocation.mkdirs()) {
      -  246  0
                   final String msg = String.format(
      -  247   -
                           "Unable to create directory '%s'.",
      -  248  0
                           tempFileLocation.getAbsolutePath());
      -  249  0
                   throw new AnalysisException(msg);
      -  250   -
               }
      -  251  16
           }
      -  252   -
       
      -  253   -
           /**
      -  254   -
            * Deletes any files extracted from the Wheel during analysis.
      -  255   -
            */
      -  256   -
           @Override
      -  257   -
           public void close() {
      -  258  20
               if (tempFileLocation != null && tempFileLocation.exists()) {
      -  259  16
                   LOGGER.debug("Attempting to delete temporary files");
      -  260  16
                   final boolean success = FileUtils.delete(tempFileLocation);
      -  261  16
                   if (!success) {
      -  262  2
                       LOGGER.warn(
      -  263   -
                               "Failed to delete some temporary files, see the log for more details");
      -  264   +  185  6
               final File actualFile = dependency.getActualFile();
      +  186  6
               if (WHL_FILTER.accept(actualFile)) {
      +  187  1
                   collectMetadataFromArchiveFormat(dependency, DIST_INFO_FILTER,
      +  188   +
                           METADATA_FILTER);
      +  189  5
               } else if (EGG_OR_ZIP.accept(actualFile)) {
      +  190  2
                   collectMetadataFromArchiveFormat(dependency, EGG_INFO_FILTER,
      +  191   +
                           PKG_INFO_FILTER);
      +  192   +
               } else {
      +  193  3
                   final String name = actualFile.getName();
      +  194  3
                   final boolean metadata = METADATA.equals(name);
      +  195  3
                   if (metadata || PKG_INFO.equals(name)) {
      +  196  3
                       final File parent = actualFile.getParentFile();
      +  197  3
                       final String parentName = parent.getName();
      +  198  3
                       dependency.setDisplayFileName(parentName + "/" + name);
      +  199  3
                       if (parent.isDirectory()
      +  200  1
                               && (metadata && parentName.endsWith(".dist-info")
      +  201  2
                               || parentName.endsWith(".egg-info") || "EGG-INFO"
      +  202  1
                               .equals(parentName))) {
      +  203  3
                           collectWheelMetadata(dependency, actualFile);
      +  204   +
                       }
      +  205  
                   }
      -  265   +  206  
               }
      -  266  20
           }
      +  207  6
           }
      +  208   +
       
      +  209   +
           /**
      +  210   +
            * Collects the meta data from an archive.
      +  211   +
            *
      +  212   +
            * @param dependency the archive being scanned
      +  213   +
            * @param folderFilter the filter to apply to the folder
      +  214   +
            * @param metadataFilter the filter to apply to the meta data
      +  215   +
            * @throws AnalysisException thrown when there is a problem analyzing the
      +  216   +
            * dependency
      +  217   +
            */
      +  218   +
           private void collectMetadataFromArchiveFormat(Dependency dependency,
      +  219   +
                   FilenameFilter folderFilter, FilenameFilter metadataFilter)
      +  220   +
                   throws AnalysisException {
      +  221  3
               final File temp = getNextTempDirectory();
      +  222  3
               LOGGER.debug("{} exists? {}", temp, temp.exists());
      +  223   +
               try {
      +  224  6
                   ExtractionUtil.extractFilesUsingFilter(
      +  225  3
                           new File(dependency.getActualFilePath()), temp,
      +  226   +
                           metadataFilter);
      +  227  0
               } catch (ExtractionException ex) {
      +  228  0
                   throw new AnalysisException(ex);
      +  229  3
               }
      +  230   +
       
      +  231  6
               collectWheelMetadata(
      +  232   +
                       dependency,
      +  233  3
                       getMatchingFile(getMatchingFile(temp, folderFilter),
      +  234   +
                               metadataFilter));
      +  235  3
           }
      +  236   +
       
      +  237   +
           /**
      +  238   +
            * Makes sure a usable temporary directory is available.
      +  239   +
            *
      +  240   +
            * @throws InitializationException an AnalyzeException is thrown when the
      +  241   +
            * temp directory cannot be created
      +  242   +
            */
      +  243   +
           @Override
      +  244   +
           protected void initializeFileTypeAnalyzer() throws InitializationException {
      +  245   +
               try {
      +  246  8
                   final File baseDir = Settings.getTempDirectory();
      +  247  8
                   tempFileLocation = File.createTempFile("check", "tmp", baseDir);
      +  248  8
                   if (!tempFileLocation.delete()) {
      +  249  0
                       setEnabled(false);
      +  250  0
                       final String msg = String.format(
      +  251   +
                               "Unable to delete temporary file '%s'.",
      +  252  0
                               tempFileLocation.getAbsolutePath());
      +  253  0
                       throw new InitializationException(msg);
      +  254   +
                   }
      +  255  8
                   if (!tempFileLocation.mkdirs()) {
      +  256  0
                       setEnabled(false);
      +  257  0
                       final String msg = String.format(
      +  258   +
                               "Unable to create directory '%s'.",
      +  259  0
                               tempFileLocation.getAbsolutePath());
      +  260  0
                       throw new InitializationException(msg);
      +  261   +
                   }
      +  262  0
               } catch (IOException ex) {
      +  263  0
                   setEnabled(false);
      +  264  0
                   throw new InitializationException("Unable to create a temporary file", ex);
      +  265  8
               }
      +  266  8
           }
       267  
       
       268  
           /**
       269   -
            * Gathers evidence from the METADATA file.
      +
            * Deletes any files extracted from the Wheel during analysis.
       270   -
            *
      +
            */
       271   -
            * @param dependency the dependency being analyzed
      +
           @Override
       272   -
            * @param file a reference to the manifest/properties file
      -  273   -
            */
      -  274   -
           private static void collectWheelMetadata(Dependency dependency, File file) {
      -  275  12
               final InternetHeaders headers = getManifestProperties(file);
      -  276  12
               addPropertyToEvidence(headers, dependency.getVersionEvidence(),
      -  277   -
                       "Version", Confidence.HIGHEST);
      -  278  12
               addPropertyToEvidence(headers, dependency.getProductEvidence(), "Name",
      +
           public void close() {
      +  273  10
               if (tempFileLocation != null && tempFileLocation.exists()) {
      +  274  8
                   LOGGER.debug("Attempting to delete temporary files");
      +  275  8
                   final boolean success = FileUtils.delete(tempFileLocation);
      +  276  8
                   if (!success) {
      +  277  1
                       LOGGER.warn(
      +  278   +
                               "Failed to delete some temporary files, see the log for more details");
       279   -
                       Confidence.HIGHEST);
      -  280  12
               final String url = headers.getHeader("Home-page", null);
      -  281  12
               final EvidenceCollection vendorEvidence = dependency
      -  282  12
                       .getVendorEvidence();
      -  283  12
               if (StringUtils.isNotBlank(url)) {
      -  284  12
                   if (UrlStringUtils.isUrl(url)) {
      -  285  12
                       vendorEvidence.addEvidence(METADATA, "vendor", url,
      -  286   -
                               Confidence.MEDIUM);
      -  287  
                   }
      +  280   +
               }
      +  281  10
           }
      +  282   +
       
      +  283   +
           /**
      +  284   +
            * Gathers evidence from the METADATA file.
      +  285   +
            *
      +  286   +
            * @param dependency the dependency being analyzed
      +  287   +
            * @param file a reference to the manifest/properties file
       288   -
               }
      -  289  12
               addPropertyToEvidence(headers, vendorEvidence, "Author", Confidence.LOW);
      -  290  12
               final String summary = headers.getHeader("Summary", null);
      -  291  12
               if (StringUtils.isNotBlank(summary)) {
      -  292  12
                   JarAnalyzer
      -  293  12
                           .addDescription(dependency, summary, METADATA, "summary");
      +
            */
      +  289   +
           private static void collectWheelMetadata(Dependency dependency, File file) {
      +  290  6
               final InternetHeaders headers = getManifestProperties(file);
      +  291  6
               addPropertyToEvidence(headers, dependency.getVersionEvidence(),
      +  292   +
                       "Version", Confidence.HIGHEST);
      +  293  6
               addPropertyToEvidence(headers, dependency.getProductEvidence(), "Name",
       294   -
               }
      -  295  12
           }
      -  296   -
       
      -  297   -
           /**
      -  298   -
            * Adds a value to the evidence collection.
      -  299   -
            *
      -  300   -
            * @param headers the properties collection
      +
                       Confidence.HIGHEST);
      +  295  6
               final String url = headers.getHeader("Home-page", null);
      +  296  6
               final EvidenceCollection vendorEvidence = dependency
      +  297  6
                       .getVendorEvidence();
      +  298  6
               if (StringUtils.isNotBlank(url)) {
      +  299  6
                   if (UrlStringUtils.isUrl(url)) {
      +  300  6
                       vendorEvidence.addEvidence(METADATA, "vendor", url,
       301   -
            * @param evidence the evidence collection to add the value
      +
                               Confidence.MEDIUM);
       302   -
            * @param property the property name
      +
                   }
       303   -
            * @param confidence the confidence of the evidence
      -  304   -
            */
      -  305   -
           private static void addPropertyToEvidence(InternetHeaders headers,
      -  306   -
                   EvidenceCollection evidence, String property, Confidence confidence) {
      -  307  36
               final String value = headers.getHeader(property, null);
      -  308  36
               LOGGER.debug("Property: {}, Value: {}", property, value);
      -  309  36
               if (StringUtils.isNotBlank(value)) {
      -  310  36
                   evidence.addEvidence(METADATA, property, value, confidence);
      -  311  
               }
      -  312  36
           }
      -  313   +  304  6
               addPropertyToEvidence(headers, vendorEvidence, "Author", Confidence.LOW);
      +  305  6
               final String summary = headers.getHeader("Summary", null);
      +  306  6
               if (StringUtils.isNotBlank(summary)) {
      +  307  6
                   JarAnalyzer
      +  308  6
                           .addDescription(dependency, summary, METADATA, "summary");
      +  309   +
               }
      +  310  6
           }
      +  311  
       
      -  314   +  312  
           /**
      -  315   -
            * Returns a list of files that match the given filter, this does not recursively scan the directory.
      -  316   +  313   +
            * Adds a value to the evidence collection.
      +  314  
            *
      +  315   +
            * @param headers the properties collection
      +  316   +
            * @param evidence the evidence collection to add the value
       317   -
            * @param folder the folder to filter
      +
            * @param property the property name
       318   -
            * @param filter the filter to apply to the files in the directory
      +
            * @param confidence the confidence of the evidence
       319   -
            * @return the list of Files in the directory that match the provided filter
      -  320  
            */
      +  320   +
           private static void addPropertyToEvidence(InternetHeaders headers,
       321   -
           private static File getMatchingFile(File folder, FilenameFilter filter) {
      -  322  12
               File result = null;
      -  323  12
               final File[] matches = folder.listFiles(filter);
      -  324  12
               if (null != matches && 1 == matches.length) {
      -  325  12
                   result = matches[0];
      +
                   EvidenceCollection evidence, String property, Confidence confidence) {
      +  322  18
               final String value = headers.getHeader(property, null);
      +  323  18
               LOGGER.debug("Property: {}, Value: {}", property, value);
      +  324  18
               if (StringUtils.isNotBlank(value)) {
      +  325  18
                   evidence.addEvidence(METADATA, property, value, confidence);
       326  
               }
      -  327  12
               return result;
      +  327  18
           }
       328   -
           }
      -  329  
       
      -  330   +  329  
           /**
      +  330   +
            * Returns a list of files that match the given filter, this does not
       331   -
            * Reads the manifest entries from the provided file.
      +
            * recursively scan the directory.
       332  
            *
       333   -
            * @param manifest the manifest
      +
            * @param folder the folder to filter
       334   -
            * @return the manifest entries
      +
            * @param filter the filter to apply to the files in the directory
       335   -
            */
      +
            * @return the list of Files in the directory that match the provided filter
       336   -
           private static InternetHeaders getManifestProperties(File manifest) {
      -  337  12
               final InternetHeaders result = new InternetHeaders();
      -  338  12
               if (null == manifest) {
      -  339  0
                   LOGGER.debug("Manifest file not found.");
      -  340   -
               } else {
      -  341   -
                   try {
      -  342  12
                       result.load(new AutoCloseInputStream(new BufferedInputStream(
      -  343   -
                               new FileInputStream(manifest))));
      -  344  0
                   } catch (MessagingException e) {
      -  345  0
                       LOGGER.warn(e.getMessage(), e);
      -  346  0
                   } catch (FileNotFoundException e) {
      -  347  0
                       LOGGER.warn(e.getMessage(), e);
      -  348  12
                   }
      -  349   -
               }
      -  350  12
               return result;
      -  351   -
           }
      -  352   -
       
      -  353   -
           /**
      -  354   -
            * Retrieves the next temporary destination directory for extracting an archive.
      -  355   -
            *
      -  356   -
            * @return a directory
      -  357   -
            * @throws AnalysisException thrown if unable to create temporary directory
      -  358  
            */
      -  359   -
           private File getNextTempDirectory() throws AnalysisException {
      -  360   -
               File directory;
      -  361   -
       
      -  362   -
               // getting an exception for some directories not being able to be
      -  363   -
               // created; might be because the directory already exists?
      -  364   -
               do {
      -  365  6
                   dirCount += 1;
      -  366  6
                   directory = new File(tempFileLocation, String.valueOf(dirCount));
      -  367  6
               } while (directory.exists());
      -  368  6
               if (!directory.mkdirs()) {
      -  369  0
                   throw new AnalysisException(String.format(
      -  370   -
                           "Unable to create temp directory '%s'.",
      -  371  0
                           directory.getAbsolutePath()));
      -  372   +  337   +
           private static File getMatchingFile(File folder, FilenameFilter filter) {
      +  338  6
               File result = null;
      +  339  6
               final File[] matches = folder.listFiles(filter);
      +  340  6
               if (null != matches && 1 == matches.length) {
      +  341  6
                   result = matches[0];
      +  342  
               }
      -  373  6
               return directory;
      -  374   +  343  6
               return result;
      +  344  
           }
      +  345   +
       
      +  346   +
           /**
      +  347   +
            * Reads the manifest entries from the provided file.
      +  348   +
            *
      +  349   +
            * @param manifest the manifest
      +  350   +
            * @return the manifest entries
      +  351   +
            */
      +  352   +
           private static InternetHeaders getManifestProperties(File manifest) {
      +  353  6
               final InternetHeaders result = new InternetHeaders();
      +  354  6
               if (null == manifest) {
      +  355  0
                   LOGGER.debug("Manifest file not found.");
      +  356   +
               } else {
      +  357   +
                   try {
      +  358  6
                       result.load(new AutoCloseInputStream(new BufferedInputStream(
      +  359   +
                               new FileInputStream(manifest))));
      +  360  0
                   } catch (MessagingException e) {
      +  361  0
                       LOGGER.warn(e.getMessage(), e);
      +  362  0
                   } catch (FileNotFoundException e) {
      +  363  0
                       LOGGER.warn(e.getMessage(), e);
      +  364  6
                   }
      +  365   +
               }
      +  366  6
               return result;
      +  367   +
           }
      +  368   +
       
      +  369   +
           /**
      +  370   +
            * Retrieves the next temporary destination directory for extracting an
      +  371   +
            * archive.
      +  372   +
            *
      +  373   +
            * @return a directory
      +  374   +
            * @throws AnalysisException thrown if unable to create temporary directory
       375   +
            */
      +  376   +
           private File getNextTempDirectory() throws AnalysisException {
      +  377   +
               File directory;
      +  378   +
       
      +  379   +
               // getting an exception for some directories not being able to be
      +  380   +
               // created; might be because the directory already exists?
      +  381   +
               do {
      +  382  3
                   dirCount += 1;
      +  383  3
                   directory = new File(tempFileLocation, String.valueOf(dirCount));
      +  384  3
               } while (directory.exists());
      +  385  3
               if (!directory.mkdirs()) {
      +  386  0
                   throw new AnalysisException(String.format(
      +  387   +
                           "Unable to create temp directory '%s'.",
      +  388  0
                           directory.getAbsolutePath()));
      +  389   +
               }
      +  390  3
               return directory;
      +  391   +
           }
      +  392  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.PythonPackageAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.PythonPackageAnalyzer.html index 5bff71a78..042991dec 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.PythonPackageAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.PythonPackageAnalyzer.html @@ -96,503 +96,505 @@  39  
       import java.util.regex.Pattern;
       40   -
       
      +
       import org.owasp.dependencycheck.exception.InitializationException;
       41   -
       /**
      +
       
       42   -
        * Used to analyze a Python package, and collect information that can be used to
      +
       /**
       43   -
        * determine the associated CPE.
      +
        * Used to analyze a Python package, and collect information that can be used to
       44   -
        *
      +
        * determine the associated CPE.
       45   -
        * @author Dale Visser
      +
        *
       46   -
        */
      +
        * @author Dale Visser
       47   +
        */
      +  48  
       @Experimental
      -  48  18
       public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer {
      -  49   -
       
      +  49  9
       public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer {
       50   -
           /**
      +
       
       51   -
            * Used when compiling file scanning regex patterns.
      +
           /**
       52   -
            */
      +
            * Used when compiling file scanning regex patterns.
       53   -
           private static final int REGEX_OPTIONS = Pattern.DOTALL
      +
            */
       54   -
                   | Pattern.CASE_INSENSITIVE;
      +
           private static final int REGEX_OPTIONS = Pattern.DOTALL
       55   -
       
      +
                   | Pattern.CASE_INSENSITIVE;
       56   -
           /**
      +
       
       57   -
            * Filename extensions for files to be analyzed.
      +
           /**
       58   -
            */
      +
            * Filename extensions for files to be analyzed.
       59   -
           private static final String EXTENSIONS = "py";
      +
            */
       60   -
       
      +
           private static final String EXTENSIONS = "py";
       61   -
           /**
      +
       
       62   -
            * Pattern for matching the module docstring in a source file.
      +
           /**
       63   +
            * Pattern for matching the module docstring in a source file.
      +  64  
            */
      -  64  2
           private static final Pattern MODULE_DOCSTRING = Pattern.compile(
      -  65   -
                   "^(['\\\"]{3})(.*?)\\1", REGEX_OPTIONS);
      +  65  1
           private static final Pattern MODULE_DOCSTRING = Pattern.compile(
       66   -
       
      +
                   "^(['\\\"]{3})(.*?)\\1", REGEX_OPTIONS);
       67   -
           /**
      +
       
       68   -
            * Matches assignments to version variables in Python source code.
      +
           /**
       69   +
            * Matches assignments to version variables in Python source code.
      +  70  
            */
      -  70  2
           private static final Pattern VERSION_PATTERN = Pattern.compile(
      -  71   -
                   "\\b(__)?version(__)? *= *(['\"]+)(\\d+\\.\\d+.*?)\\3",
      +  71  1
           private static final Pattern VERSION_PATTERN = Pattern.compile(
       72   -
                   REGEX_OPTIONS);
      +
                   "\\b(__)?version(__)? *= *(['\"]+)(\\d+\\.\\d+.*?)\\3",
       73   -
       
      +
                   REGEX_OPTIONS);
       74   -
           /**
      +
       
       75   -
            * Matches assignments to title variables in Python source code.
      +
           /**
       76   +
            * Matches assignments to title variables in Python source code.
      +  77  
            */
      -  77  2
           private static final Pattern TITLE_PATTERN = compileAssignPattern("title");
      -  78   -
       
      +  78  1
           private static final Pattern TITLE_PATTERN = compileAssignPattern("title");
       79   -
           /**
      +
       
       80   -
            * Matches assignments to summary variables in Python source code.
      +
           /**
       81   +
            * Matches assignments to summary variables in Python source code.
      +  82  
            */
      -  82  2
           private static final Pattern SUMMARY_PATTERN = compileAssignPattern("summary");
      -  83   -
       
      +  83  1
           private static final Pattern SUMMARY_PATTERN = compileAssignPattern("summary");
       84   -
           /**
      +
       
       85   -
            * Matches assignments to URL/URL variables in Python source code.
      +
           /**
       86   +
            * Matches assignments to URL/URL variables in Python source code.
      +  87  
            */
      -  87  2
           private static final Pattern URI_PATTERN = compileAssignPattern("ur[il]");
      -  88   -
       
      +  88  1
           private static final Pattern URI_PATTERN = compileAssignPattern("ur[il]");
       89   -
           /**
      +
       
       90   -
            * Matches assignments to home page variables in Python source code.
      +
           /**
       91   +
            * Matches assignments to home page variables in Python source code.
      +  92  
            */
      -  92  2
           private static final Pattern HOMEPAGE_PATTERN = compileAssignPattern("home_?page");
      -  93   -
       
      +  93  1
           private static final Pattern HOMEPAGE_PATTERN = compileAssignPattern("home_?page");
       94   -
           /**
      +
       
       95   -
            * Matches assignments to author variables in Python source code.
      +
           /**
       96   +
            * Matches assignments to author variables in Python source code.
      +  97  
            */
      -  97  2
           private static final Pattern AUTHOR_PATTERN = compileAssignPattern("author");
      -  98   -
       
      +  98  1
           private static final Pattern AUTHOR_PATTERN = compileAssignPattern("author");
       99   -
           /**
      +
       
       100   -
            * Filter that detects files named "__init__.py".
      +
           /**
       101   +
            * Filter that detects files named "__init__.py".
      +  102  
            */
      -  102  2
           private static final FileFilter INIT_PY_FILTER = new NameFileFilter("__init__.py");
      -  103   -
       
      +  103  1
           private static final FileFilter INIT_PY_FILTER = new NameFileFilter("__init__.py");
       104   -
           /**
      +
       
       105   -
            * The file filter for python files.
      +
           /**
       106   +
            * The file filter for python files.
      +  107  
            */
      -  107  2
           private static final FileFilter PY_FILTER = new SuffixFileFilter(".py");
      -  108   -
       
      +  108  1
           private static final FileFilter PY_FILTER = new SuffixFileFilter(".py");
       109   -
           /**
      +
       
       110   -
            * Returns the name of the Python Package Analyzer.
      +
           /**
       111   -
            *
      +
            * Returns the name of the Python Package Analyzer.
       112   -
            * @return the name of the analyzer
      +
            *
       113   -
            */
      +
            * @return the name of the analyzer
       114   -
           @Override
      +
            */
       115   +
           @Override
      +  116  
           public String getName() {
      -  116  30
               return "Python Package Analyzer";
      -  117   -
           }
      +  117  15
               return "Python Package Analyzer";
       118   -
       
      +
           }
       119   -
           /**
      +
       
       120   -
            * Tell that we are used for information collection.
      +
           /**
       121   -
            *
      +
            * Tell that we are used for information collection.
       122   -
            * @return INFORMATION_COLLECTION
      +
            *
       123   -
            */
      +
            * @return INFORMATION_COLLECTION
       124   -
           @Override
      +
            */
       125   +
           @Override
      +  126  
           public AnalysisPhase getAnalysisPhase() {
      -  126  8
               return AnalysisPhase.INFORMATION_COLLECTION;
      -  127   -
           }
      +  127  4
               return AnalysisPhase.INFORMATION_COLLECTION;
       128   -
       
      -  129   -
           /**
      -  130   -
            * The file filter used to determine which files this analyzer supports.
      -  131   -
            */
      -  132  2
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(EXTENSIONS).build();
      -  133   -
       
      -  134   -
           /**
      -  135   -
            * Returns the FileFilter
      -  136   -
            *
      -  137   -
            * @return the FileFilter
      -  138   -
            */
      -  139   -
           @Override
      -  140   -
           protected FileFilter getFileFilter() {
      -  141  1720
               return FILTER;
      -  142  
           }
      -  143   +  129  
       
      -  144   +  130  
           /**
      -  145   -
            * No-op initializer implementation.
      -  146   -
            *
      -  147   -
            * @throws Exception never thrown
      -  148   +  131   +
            * The file filter used to determine which files this analyzer supports.
      +  132  
            */
      -  149   +  133  1
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(EXTENSIONS).build();
      +  134   +
       
      +  135   +
           /**
      +  136   +
            * Returns the FileFilter
      +  137   +
            *
      +  138   +
            * @return the FileFilter
      +  139   +
            */
      +  140  
           @Override
      -  150   -
           protected void initializeFileTypeAnalyzer() throws Exception {
      -  151   -
               // Nothing to do here.
      -  152  6
           }
      -  153   +  141   +
           protected FileFilter getFileFilter() {
      +  142  11
               return FILTER;
      +  143   +
           }
      +  144  
       
      -  154   +  145  
           /**
      -  155   -
            * Utility function to create a regex pattern matcher.
      -  156   +  146   +
            * No-op initializer implementation.
      +  147  
            *
      -  157   -
            * @param name the value to use when constructing the assignment pattern
      -  158   -
            * @return the compiled Pattern
      -  159   +  148   +
            * @throws InitializationException never thrown
      +  149  
            */
      +  150   +
           @Override
      +  151   +
           protected void initializeFileTypeAnalyzer() throws InitializationException {
      +  152   +
               // Nothing to do here.
      +  153  3
           }
      +  154   +
       
      +  155   +
           /**
      +  156   +
            * Utility function to create a regex pattern matcher.
      +  157   +
            *
      +  158   +
            * @param name the value to use when constructing the assignment pattern
      +  159   +
            * @return the compiled Pattern
       160   +
            */
      +  161  
           private static Pattern compileAssignPattern(String name) {
      -  161  20
               return Pattern.compile(
      -  162  10
                       String.format("\\b(__)?%s(__)?\\b *= *(['\"]+)(.*?)\\3", name),
      -  163   -
                       REGEX_OPTIONS);
      +  162  10
               return Pattern.compile(
      +  163  5
                       String.format("\\b(__)?%s(__)?\\b *= *(['\"]+)(.*?)\\3", name),
       164   -
           }
      +
                       REGEX_OPTIONS);
       165   -
       
      +
           }
       166   -
           /**
      +
       
       167   -
            * Analyzes python packages and adds evidence to the dependency.
      +
           /**
       168   -
            *
      +
            * Analyzes python packages and adds evidence to the dependency.
       169   -
            * @param dependency the dependency being analyzed
      +
            *
       170   -
            * @param engine the engine being used to perform the scan
      +
            * @param dependency the dependency being analyzed
       171   -
            * @throws AnalysisException thrown if there is an unrecoverable error
      +
            * @param engine the engine being used to perform the scan
       172   -
            * analyzing the dependency
      -  173   -
            */
      -  174   -
           @Override
      -  175   -
           protected void analyzeFileType(Dependency dependency, Engine engine)
      -  176   -
                   throws AnalysisException {
      -  177  2
               final File file = dependency.getActualFile();
      -  178  2
               final File parent = file.getParentFile();
      -  179  2
               final String parentName = parent.getName();
      -  180  2
               if (INIT_PY_FILTER.accept(file)) {
      -  181   -
                   //by definition, the containing folder of __init__.py is considered the package, even the file is empty:
      -  182   -
                   //"The __init__.py files are required to make Python treat the directories as containing packages"
      -  183   -
                   //see section "6.4 Packages" from https://docs.python.org/2/tutorial/modules.html;
      -  184  2
                   dependency.setDisplayFileName(parentName + "/__init__.py");
      -  185  2
                   dependency.getProductEvidence().addEvidence(file.getName(),
      -  186   -
                           "PackageName", parentName, Confidence.HIGHEST);
      -  187   -
       
      -  188  2
                   final File[] fileList = parent.listFiles(PY_FILTER);
      -  189  2
                   if (fileList != null) {
      -  190  8
                       for (final File sourceFile : fileList) {
      -  191  6
                           analyzeFileContents(dependency, sourceFile);
      -  192   -
                       }
      -  193   -
                   }
      -  194  2
               } else {
      -  195   -
                   // copy, alter and set in case some other thread is iterating over
      -  196  0
                   final List<Dependency> dependencies = new ArrayList<Dependency>(
      -  197  0
                           engine.getDependencies());
      -  198  0
                   dependencies.remove(dependency);
      -  199  0
                   engine.setDependencies(dependencies);
      -  200   -
               }
      -  201  2
           }
      -  202   -
       
      -  203   -
           /**
      -  204   -
            * This should gather information from leading docstrings, file comments,
      -  205   -
            * and assignments to __version__, __title__, __summary__, __uri__, __url__,
      -  206   -
            * __home*page__, __author__, and their all caps equivalents.
      -  207   -
            *
      -  208   -
            * @param dependency the dependency being analyzed
      -  209   -
            * @param file the file name to analyze
      -  210   -
            * @return whether evidence was found
      -  211  
            * @throws AnalysisException thrown if there is an unrecoverable error
      -  212   +  173   +
            * analyzing the dependency
      +  174  
            */
      -  213   -
           private boolean analyzeFileContents(Dependency dependency, File file)
      -  214   -
                   throws AnalysisException {
      -  215   -
               String contents;
      -  216   -
               try {
      -  217  6
                   contents = FileUtils.readFileToString(file, Charset.defaultCharset()).trim();
      -  218  0
               } catch (IOException e) {
      -  219  0
                   throw new AnalysisException(
      -  220   -
                           "Problem occurred while reading dependency file.", e);
      -  221  6
               }
      -  222  6
               boolean found = false;
      -  223  6
               if (!contents.isEmpty()) {
      -  224  6
                   final String source = file.getName();
      -  225  12
                   found = gatherEvidence(VERSION_PATTERN, contents, source,
      -  226  6
                           dependency.getVersionEvidence(), "SourceVersion",
      -  227   -
                           Confidence.MEDIUM);
      -  228  6
                   found |= addSummaryInfo(dependency, SUMMARY_PATTERN, 4, contents,
      -  229   -
                           source, "summary");
      -  230  6
                   if (INIT_PY_FILTER.accept(file)) {
      -  231  2
                       found |= addSummaryInfo(dependency, MODULE_DOCSTRING, 2,
      -  232   -
                               contents, source, "docstring");
      -  233   -
                   }
      -  234  12
                   found |= gatherEvidence(TITLE_PATTERN, contents, source,
      -  235  6
                           dependency.getProductEvidence(), "SourceTitle",
      -  236   -
                           Confidence.LOW);
      -  237  6
                   final EvidenceCollection vendorEvidence = dependency
      -  238  6
                           .getVendorEvidence();
      -  239  6
                   found |= gatherEvidence(AUTHOR_PATTERN, contents, source,
      -  240   -
                           vendorEvidence, "SourceAuthor", Confidence.MEDIUM);
      -  241  6
                   found |= gatherHomePageEvidence(URI_PATTERN, vendorEvidence,
      -  242   -
                           source, "URL", contents);
      -  243  6
                   found |= gatherHomePageEvidence(HOMEPAGE_PATTERN,
      -  244   -
                           vendorEvidence, source, "HomePage", contents);
      -  245   -
               }
      -  246  6
               return found;
      -  247   -
           }
      -  248   -
       
      -  249   -
           /**
      -  250   -
            * Adds summary information to the dependency
      -  251   -
            *
      -  252   -
            * @param dependency the dependency being analyzed
      -  253   -
            * @param pattern the pattern used to perform analysis
      -  254   -
            * @param group the group from the pattern that indicates the data to use
      -  255   -
            * @param contents the data being analyzed
      -  256   -
            * @param source the source name to use when recording the evidence
      -  257   -
            * @param key the key name to use when recording the evidence
      -  258   -
            * @return true if evidence was collected; otherwise false
      -  259   -
            */
      -  260   -
           private boolean addSummaryInfo(Dependency dependency, Pattern pattern,
      -  261   -
                   int group, String contents, String source, String key) {
      -  262  8
               final Matcher matcher = pattern.matcher(contents);
      -  263  8
               final boolean found = matcher.find();
      -  264  8
               if (found) {
      -  265  2
                   JarAnalyzer.addDescription(dependency, matcher.group(group),
      -  266   -
                           source, key);
      -  267   -
               }
      -  268  8
               return found;
      -  269   -
           }
      -  270   -
       
      -  271   -
           /**
      -  272   -
            * Collects evidence from the home page URL.
      -  273   -
            *
      -  274   -
            * @param pattern the pattern to match
      -  275   -
            * @param evidence the evidence collection to add the evidence to
      -  276   -
            * @param source the source of the evidence
      -  277   -
            * @param name the name of the evidence
      -  278   -
            * @param contents the home page URL
      -  279   -
            * @return true if evidence was collected; otherwise false
      -  280   -
            */
      -  281   -
           private boolean gatherHomePageEvidence(Pattern pattern,
      -  282   -
                   EvidenceCollection evidence, String source, String name,
      -  283   -
                   String contents) {
      -  284  12
               final Matcher matcher = pattern.matcher(contents);
      -  285  12
               boolean found = false;
      -  286  12
               if (matcher.find()) {
      -  287  2
                   final String url = matcher.group(4);
      -  288  2
                   if (UrlStringUtils.isUrl(url)) {
      -  289  2
                       found = true;
      -  290  2
                       evidence.addEvidence(source, name, url, Confidence.MEDIUM);
      -  291   -
                   }
      -  292   -
               }
      -  293  12
               return found;
      -  294   -
           }
      -  295   -
       
      -  296   -
           /**
      -  297   -
            * Gather evidence from a Python source file using the given string
      -  298   -
            * assignment regex pattern.
      -  299   -
            *
      -  300   -
            * @param pattern to scan contents with
      -  301   -
            * @param contents of Python source file
      -  302   -
            * @param source for storing evidence
      -  303   -
            * @param evidence to store evidence in
      -  304   -
            * @param name of evidence
      -  305   -
            * @param confidence in evidence
      -  306   -
            * @return whether evidence was found
      -  307   -
            */
      -  308   -
           private boolean gatherEvidence(Pattern pattern, String contents,
      -  309   -
                   String source, EvidenceCollection evidence, String name,
      -  310   -
                   Confidence confidence) {
      -  311  18
               final Matcher matcher = pattern.matcher(contents);
      -  312  18
               final boolean found = matcher.find();
      -  313  18
               if (found) {
      -  314  6
                   evidence.addEvidence(source, name, matcher.group(4), confidence);
      -  315   -
               }
      -  316  18
               return found;
      -  317   -
           }
      -  318   -
       
      -  319   +  175  
           @Override
      -  320   -
           protected String getAnalyzerEnabledSettingKey() {
      -  321  18
               return Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED;
      -  322   +  176   +
           protected void analyzeFileType(Dependency dependency, Engine engine)
      +  177   +
                   throws AnalysisException {
      +  178  1
               final File file = dependency.getActualFile();
      +  179  1
               final File parent = file.getParentFile();
      +  180  1
               final String parentName = parent.getName();
      +  181  1
               if (INIT_PY_FILTER.accept(file)) {
      +  182   +
                   //by definition, the containing folder of __init__.py is considered the package, even the file is empty:
      +  183   +
                   //"The __init__.py files are required to make Python treat the directories as containing packages"
      +  184   +
                   //see section "6.4 Packages" from https://docs.python.org/2/tutorial/modules.html;
      +  185  1
                   dependency.setDisplayFileName(parentName + "/__init__.py");
      +  186  1
                   dependency.getProductEvidence().addEvidence(file.getName(),
      +  187   +
                           "PackageName", parentName, Confidence.HIGHEST);
      +  188   +
       
      +  189  1
                   final File[] fileList = parent.listFiles(PY_FILTER);
      +  190  1
                   if (fileList != null) {
      +  191  4
                       for (final File sourceFile : fileList) {
      +  192  3
                           analyzeFileContents(dependency, sourceFile);
      +  193   +
                       }
      +  194   +
                   }
      +  195  1
               } else {
      +  196   +
                   // copy, alter and set in case some other thread is iterating over
      +  197  0
                   final List<Dependency> dependencies = new ArrayList<Dependency>(
      +  198  0
                           engine.getDependencies());
      +  199  0
                   dependencies.remove(dependency);
      +  200  0
                   engine.setDependencies(dependencies);
      +  201   +
               }
      +  202  1
           }
      +  203   +
       
      +  204   +
           /**
      +  205   +
            * This should gather information from leading docstrings, file comments,
      +  206   +
            * and assignments to __version__, __title__, __summary__, __uri__, __url__,
      +  207   +
            * __home*page__, __author__, and their all caps equivalents.
      +  208   +
            *
      +  209   +
            * @param dependency the dependency being analyzed
      +  210   +
            * @param file the file name to analyze
      +  211   +
            * @return whether evidence was found
      +  212   +
            * @throws AnalysisException thrown if there is an unrecoverable error
      +  213   +
            */
      +  214   +
           private boolean analyzeFileContents(Dependency dependency, File file)
      +  215   +
                   throws AnalysisException {
      +  216   +
               String contents;
      +  217   +
               try {
      +  218  3
                   contents = FileUtils.readFileToString(file, Charset.defaultCharset()).trim();
      +  219  0
               } catch (IOException e) {
      +  220  0
                   throw new AnalysisException(
      +  221   +
                           "Problem occurred while reading dependency file.", e);
      +  222  3
               }
      +  223  3
               boolean found = false;
      +  224  3
               if (!contents.isEmpty()) {
      +  225  3
                   final String source = file.getName();
      +  226  6
                   found = gatherEvidence(VERSION_PATTERN, contents, source,
      +  227  3
                           dependency.getVersionEvidence(), "SourceVersion",
      +  228   +
                           Confidence.MEDIUM);
      +  229  3
                   found |= addSummaryInfo(dependency, SUMMARY_PATTERN, 4, contents,
      +  230   +
                           source, "summary");
      +  231  3
                   if (INIT_PY_FILTER.accept(file)) {
      +  232  1
                       found |= addSummaryInfo(dependency, MODULE_DOCSTRING, 2,
      +  233   +
                               contents, source, "docstring");
      +  234   +
                   }
      +  235  6
                   found |= gatherEvidence(TITLE_PATTERN, contents, source,
      +  236  3
                           dependency.getProductEvidence(), "SourceTitle",
      +  237   +
                           Confidence.LOW);
      +  238  3
                   final EvidenceCollection vendorEvidence = dependency
      +  239  3
                           .getVendorEvidence();
      +  240  3
                   found |= gatherEvidence(AUTHOR_PATTERN, contents, source,
      +  241   +
                           vendorEvidence, "SourceAuthor", Confidence.MEDIUM);
      +  242  3
                   found |= gatherHomePageEvidence(URI_PATTERN, vendorEvidence,
      +  243   +
                           source, "URL", contents);
      +  244  3
                   found |= gatherHomePageEvidence(HOMEPAGE_PATTERN,
      +  245   +
                           vendorEvidence, source, "HomePage", contents);
      +  246   +
               }
      +  247  3
               return found;
      +  248  
           }
      +  249   +
       
      +  250   +
           /**
      +  251   +
            * Adds summary information to the dependency
      +  252   +
            *
      +  253   +
            * @param dependency the dependency being analyzed
      +  254   +
            * @param pattern the pattern used to perform analysis
      +  255   +
            * @param group the group from the pattern that indicates the data to use
      +  256   +
            * @param contents the data being analyzed
      +  257   +
            * @param source the source name to use when recording the evidence
      +  258   +
            * @param key the key name to use when recording the evidence
      +  259   +
            * @return true if evidence was collected; otherwise false
      +  260   +
            */
      +  261   +
           private boolean addSummaryInfo(Dependency dependency, Pattern pattern,
      +  262   +
                   int group, String contents, String source, String key) {
      +  263  4
               final Matcher matcher = pattern.matcher(contents);
      +  264  4
               final boolean found = matcher.find();
      +  265  4
               if (found) {
      +  266  1
                   JarAnalyzer.addDescription(dependency, matcher.group(group),
      +  267   +
                           source, key);
      +  268   +
               }
      +  269  4
               return found;
      +  270   +
           }
      +  271   +
       
      +  272   +
           /**
      +  273   +
            * Collects evidence from the home page URL.
      +  274   +
            *
      +  275   +
            * @param pattern the pattern to match
      +  276   +
            * @param evidence the evidence collection to add the evidence to
      +  277   +
            * @param source the source of the evidence
      +  278   +
            * @param name the name of the evidence
      +  279   +
            * @param contents the home page URL
      +  280   +
            * @return true if evidence was collected; otherwise false
      +  281   +
            */
      +  282   +
           private boolean gatherHomePageEvidence(Pattern pattern,
      +  283   +
                   EvidenceCollection evidence, String source, String name,
      +  284   +
                   String contents) {
      +  285  6
               final Matcher matcher = pattern.matcher(contents);
      +  286  6
               boolean found = false;
      +  287  6
               if (matcher.find()) {
      +  288  1
                   final String url = matcher.group(4);
      +  289  1
                   if (UrlStringUtils.isUrl(url)) {
      +  290  1
                       found = true;
      +  291  1
                       evidence.addEvidence(source, name, url, Confidence.MEDIUM);
      +  292   +
                   }
      +  293   +
               }
      +  294  6
               return found;
      +  295   +
           }
      +  296   +
       
      +  297   +
           /**
      +  298   +
            * Gather evidence from a Python source file using the given string
      +  299   +
            * assignment regex pattern.
      +  300   +
            *
      +  301   +
            * @param pattern to scan contents with
      +  302   +
            * @param contents of Python source file
      +  303   +
            * @param source for storing evidence
      +  304   +
            * @param evidence to store evidence in
      +  305   +
            * @param name of evidence
      +  306   +
            * @param confidence in evidence
      +  307   +
            * @return whether evidence was found
      +  308   +
            */
      +  309   +
           private boolean gatherEvidence(Pattern pattern, String contents,
      +  310   +
                   String source, EvidenceCollection evidence, String name,
      +  311   +
                   Confidence confidence) {
      +  312  9
               final Matcher matcher = pattern.matcher(contents);
      +  313  9
               final boolean found = matcher.find();
      +  314  9
               if (found) {
      +  315  3
                   evidence.addEvidence(source, name, matcher.group(4), confidence);
      +  316   +
               }
      +  317  9
               return found;
      +  318   +
           }
      +  319   +
       
      +  320   +
           @Override
      +  321   +
           protected String getAnalyzerEnabledSettingKey() {
      +  322  9
               return Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED;
       323   +
           }
      +  324  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.RubyBundleAuditAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.RubyBundleAuditAnalyzer.html index c0c0af8b3..525e35978 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.RubyBundleAuditAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.RubyBundleAuditAnalyzer.html @@ -12,7 +12,7 @@
       
      - +
      Classes in this File Line Coverage Branch Coverage Complexity
      RubyBundleAuditAnalyzer
      16%
      32/200
      2%
      2/74
      5.154
      RubyBundleAuditAnalyzer
      14%
      32/217
      2%
      2/74
      5.846
       
      @@ -66,701 +66,736 @@  24  
       import java.io.InputStreamReader;
       25   -
       import java.util.ArrayList;
      +
       import java.io.UnsupportedEncodingException;
       26   -
       import java.util.HashMap;
      +
       import java.util.ArrayList;
       27   -
       import java.util.List;
      +
       import java.util.HashMap;
       28   -
       import java.util.Map;
      +
       import java.util.List;
       29   -
       import java.nio.charset.Charset;
      +
       import java.util.Map;
       30   -
       import org.apache.commons.io.FileUtils;
      +
       import java.nio.charset.Charset;
       31   -
       import org.owasp.dependencycheck.Engine;
      +
       import org.apache.commons.io.FileUtils;
       32   -
       import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
      +
       import org.owasp.dependencycheck.Engine;
       33   -
       import org.owasp.dependencycheck.data.nvdcve.CveDB;
      +
       import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
       34   -
       import org.owasp.dependencycheck.dependency.Confidence;
      +
       import org.owasp.dependencycheck.data.nvdcve.CveDB;
       35   -
       import org.owasp.dependencycheck.dependency.Dependency;
      +
       import org.owasp.dependencycheck.dependency.Confidence;
       36   -
       import org.owasp.dependencycheck.dependency.Reference;
      +
       import org.owasp.dependencycheck.dependency.Dependency;
       37   -
       import org.owasp.dependencycheck.dependency.Vulnerability;
      +
       import org.owasp.dependencycheck.dependency.Reference;
       38   -
       import org.owasp.dependencycheck.utils.FileFilterBuilder;
      +
       import org.owasp.dependencycheck.dependency.Vulnerability;
       39   -
       import org.owasp.dependencycheck.utils.Settings;
      +
       import org.owasp.dependencycheck.utils.FileFilterBuilder;
       40   -
       import org.slf4j.Logger;
      +
       import org.owasp.dependencycheck.utils.Settings;
       41   -
       import org.slf4j.LoggerFactory;
      +
       import org.slf4j.Logger;
       42   -
       import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
      +
       import org.slf4j.LoggerFactory;
       43   -
       
      +
       import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
       44   -
       /**
      +
       import org.owasp.dependencycheck.exception.InitializationException;
       45   -
        * Used to analyze Ruby Bundler Gemspec.lock files utilizing the 3rd party
      -  46   -
        * bundle-audit tool.
      -  47   -
        *
      -  48   -
        * @author Dale Visser
      -  49   -
        */
      -  50   -
       @Experimental
      -  51  24
       public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer {
      -  52  
       
      -  53  2
           private static final Logger LOGGER = LoggerFactory.getLogger(RubyBundleAuditAnalyzer.class);
      +  46   +
       /**
      +  47   +
        * Used to analyze Ruby Bundler Gemspec.lock files utilizing the 3rd party
      +  48   +
        * bundle-audit tool.
      +  49   +
        *
      +  50   +
        * @author Dale Visser
      +  51   +
        */
      +  52   +
       @Experimental
      +  53  12
       public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer {
       54  
       
       55  
           /**
       56   -
            * The name of the analyzer.
      +
            * The logger.
       57  
            */
      -  58   -
           private static final String ANALYZER_NAME = "Ruby Bundle Audit Analyzer";
      +  58  1
           private static final Logger LOGGER = LoggerFactory.getLogger(RubyBundleAuditAnalyzer.class);
       59  
       
       60  
           /**
       61   -
            * The phase that this analyzer is intended to run in.
      +
            * The name of the analyzer.
       62  
            */
      -  63  2
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_INFORMATION_COLLECTION;
      +  63   +
           private static final String ANALYZER_NAME = "Ruby Bundle Audit Analyzer";
       64   -
           /**
      -  65   -
            * The filter defining which files will be analyzed.
      -  66   -
            */
      -  67  2
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addFilenames("Gemfile.lock").build();
      -  68   -
           /**
      -  69   -
            * Name.
      -  70   -
            */
      -  71   -
           public static final String NAME = "Name: ";
      -  72   -
           /**
      -  73   -
            * Version.
      -  74   -
            */
      -  75   -
           public static final String VERSION = "Version: ";
      -  76   -
           /**
      -  77   -
            * Advisory.
      -  78   -
            */
      -  79   -
           public static final String ADVISORY = "Advisory: ";
      -  80   -
           /**
      -  81   -
            * Criticality.
      -  82   -
            */
      -  83   -
           public static final String CRITICALITY = "Criticality: ";
      -  84  
       
      +  65   +
           /**
      +  66   +
            * The phase that this analyzer is intended to run in.
      +  67   +
            */
      +  68  1
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_INFORMATION_COLLECTION;
      +  69   +
           /**
      +  70   +
            * The filter defining which files will be analyzed.
      +  71   +
            */
      +  72  1
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addFilenames("Gemfile.lock").build();
      +  73   +
           /**
      +  74   +
            * Name.
      +  75   +
            */
      +  76   +
           public static final String NAME = "Name: ";
      +  77   +
           /**
      +  78   +
            * Version.
      +  79   +
            */
      +  80   +
           public static final String VERSION = "Version: ";
      +  81   +
           /**
      +  82   +
            * Advisory.
      +  83   +
            */
      +  84   +
           public static final String ADVISORY = "Advisory: ";
       85  
           /**
       86   -
            * The DAL.
      +
            * Criticality.
       87  
            */
       88   -
           private CveDB cvedb;
      +
           public static final String CRITICALITY = "Criticality: ";
       89  
       
       90  
           /**
       91   -
            * @return a filter that accepts files named Gemfile.lock
      +
            * The DAL.
       92  
            */
       93   -
           @Override
      +
           private CveDB cvedb;
       94   -
           protected FileFilter getFileFilter() {
      -  95  1720
               return FILTER;
      +
       
      +  95   +
           /**
       96   -
           }
      +
            * @return a filter that accepts files named Gemfile.lock
       97   -
       
      +
            */
       98   -
           /**
      +
           @Override
       99   -
            * Launch bundle-audit.
      -  100   -
            *
      +
           protected FileFilter getFileFilter() {
      +  100  9
               return FILTER;
       101   -
            * @param folder directory that contains bundle audit
      +
           }
       102   -
            * @return a handle to the process
      +
       
       103   -
            * @throws AnalysisException thrown when there is an issue launching bundle
      +
           /**
       104   -
            * audit
      +
            * Launch bundle-audit.
       105   -
            */
      +
            *
       106   -
           private Process launchBundleAudit(File folder) throws AnalysisException {
      -  107  8
               if (!folder.isDirectory()) {
      -  108  0
                   throw new AnalysisException(String.format("%s should have been a directory.", folder.getAbsolutePath()));
      +
            * @param folder directory that contains bundle audit
      +  107   +
            * @return a handle to the process
      +  108   +
            * @throws AnalysisException thrown when there is an issue launching bundle
       109   +
            * audit
      +  110   +
            */
      +  111   +
           private Process launchBundleAudit(File folder) throws AnalysisException {
      +  112  4
               if (!folder.isDirectory()) {
      +  113  0
                   throw new AnalysisException(String.format("%s should have been a directory.", folder.getAbsolutePath()));
      +  114  
               }
      -  110  8
               final List<String> args = new ArrayList<String>();
      -  111  8
               final String bundleAuditPath = Settings.getString(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH);
      -  112  8
               args.add(null == bundleAuditPath ? "bundle-audit" : bundleAuditPath);
      -  113  8
               args.add("check");
      -  114  8
               args.add("--verbose");
      -  115  8
               final ProcessBuilder builder = new ProcessBuilder(args);
      -  116  8
               builder.directory(folder);
      -  117   -
               try {
      -  118  8
                   LOGGER.info("Launching: " + args + " from " + folder);
      -  119  8
                   return builder.start();
      -  120  8
               } catch (IOException ioe) {
      -  121  8
                   throw new AnalysisException("bundle-audit failure", ioe);
      +  115  4
               final List<String> args = new ArrayList<String>();
      +  116  4
               final String bundleAuditPath = Settings.getString(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH);
      +  117  4
               args.add(null == bundleAuditPath ? "bundle-audit" : bundleAuditPath);
      +  118  4
               args.add("check");
      +  119  4
               args.add("--verbose");
      +  120  4
               final ProcessBuilder builder = new ProcessBuilder(args);
      +  121  4
               builder.directory(folder);
       122   -
               }
      -  123   -
           }
      -  124   -
       
      -  125   -
           /**
      -  126   -
            * Initialize the analyzer. In this case, extract GrokAssembly.exe to a
      +
               try {
      +  123  4
                   LOGGER.info("Launching: " + args + " from " + folder);
      +  124  4
                   return builder.start();
      +  125  4
               } catch (IOException ioe) {
      +  126  4
                   throw new AnalysisException("bundle-audit failure", ioe);
       127   -
            * temporary location.
      +
               }
       128   -
            *
      +
           }
       129   -
            * @throws Exception if anything goes wrong
      +
       
       130   -
            */
      +
           /**
       131   -
           @Override
      +
            * Initialize the analyzer. In this case, extract GrokAssembly.exe to a
       132   -
           public void initializeFileTypeAnalyzer() throws Exception {
      +
            * temporary location.
       133   +
            *
      +  134   +
            * @throws InitializationException if anything goes wrong
      +  135   +
            */
      +  136   +
           @Override
      +  137   +
           public void initializeFileTypeAnalyzer() throws InitializationException {
      +  138  
               try {
      -  134  8
                   cvedb = new CveDB();
      -  135  8
                   cvedb.open();
      -  136  0
               } catch (DatabaseException ex) {
      -  137  0
                   LOGGER.warn("Exception opening the database");
      -  138  0
                   LOGGER.debug("error", ex);
      -  139  0
                   setEnabled(false);
      -  140  0
                   throw ex;
      -  141  8
               }
      -  142   +  139  4
                   cvedb = new CveDB();
      +  140  4
                   cvedb.open();
      +  141  0
               } catch (DatabaseException ex) {
      +  142  0
                   LOGGER.warn("Exception opening the database");
      +  143  0
                   LOGGER.debug("error", ex);
      +  144  0
                   setEnabled(false);
      +  145  0
                   throw new InitializationException("Error connecting to the database", ex);
      +  146  4
               }
      +  147  
               // Now, need to see if bundle-audit actually runs from this location.
      -  143  8
               Process process = null;
      -  144   +  148  4
               Process process = null;
      +  149  
               try {
      -  145  8
                   process = launchBundleAudit(Settings.getTempDirectory());
      -  146  8
               } catch (AnalysisException ae) {
      -  147  8
                   LOGGER.warn("Exception from bundle-audit process: {}. Disabling {}", ae.getCause(), ANALYZER_NAME);
      -  148  8
                   setEnabled(false);
      -  149  8
                   cvedb.close();
      -  150  8
                   cvedb = null;
      -  151  8
                   throw ae;
      -  152  0
               }
      -  153   +  150  4
                   process = launchBundleAudit(Settings.getTempDirectory());
      +  151  4
               } catch (AnalysisException ae) {
      +  152  
       
      -  154  0
               final int exitValue = process.waitFor();
      -  155  0
               if (0 == exitValue) {
      -  156  0
                   LOGGER.warn("Unexpected exit code from bundle-audit process. Disabling {}: {}", ANALYZER_NAME, exitValue);
      -  157  0
                   setEnabled(false);
      -  158  0
                   throw new AnalysisException("Unexpected exit code from bundle-audit process.");
      -  159   -
               } else {
      -  160  0
                   BufferedReader reader = null;
      -  161   -
                   try {
      -  162  0
                       reader = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8"));
      -  163  0
                       if (!reader.ready()) {
      -  164  0
                           LOGGER.warn("Bundle-audit error stream unexpectedly not ready. Disabling " + ANALYZER_NAME);
      -  165  0
                           setEnabled(false);
      -  166  0
                           throw new AnalysisException("Bundle-audit error stream unexpectedly not ready.");
      -  167   -
                       } else {
      -  168  0
                           final String line = reader.readLine();
      -  169  0
                           if (line == null || !line.contains("Errno::ENOENT")) {
      -  170  0
                               LOGGER.warn("Unexpected bundle-audit output. Disabling {}: {}", ANALYZER_NAME, line);
      -  171  0
                               setEnabled(false);
      -  172  0
                               throw new AnalysisException("Unexpected bundle-audit output.");
      -  173   -
                           }
      -  174   -
                       }
      +  153  4
                   setEnabled(false);
      +  154  4
                   cvedb.close();
      +  155  4
                   cvedb = null;
      +  156  4
                   final String msg = String.format("Exception from bundle-audit process: %s. Disabling %s", ae.getCause(), ANALYZER_NAME);
      +  157  4
                   throw new InitializationException(msg, ae);
      +  158  0
               } catch (IOException ex) {
      +  159  0
                   setEnabled(false);
      +  160  0
                   throw new InitializationException("Unable to create temporary file, the Ruby Bundle Audit Analyzer will be disabled", ex);
      +  161  0
               }
      +  162   +
       
      +  163   +
               final int exitValue;
      +  164   +
               try {
      +  165  0
                   exitValue = process.waitFor();
      +  166  0
               } catch (InterruptedException ex) {
      +  167  0
                   setEnabled(false);
      +  168  0
                   final String msg = String.format("Bundle-audit process was interupted. Disabling %s", ANALYZER_NAME);
      +  169  0
                   throw new InitializationException(msg);
      +  170  0
               }
      +  171  0
               if (0 == exitValue) {
      +  172  0
                   setEnabled(false);
      +  173  0
                   final String msg = String.format("Unexpected exit code from bundle-audit process. Disabling %s: %s", ANALYZER_NAME, exitValue);
      +  174  0
                   throw new InitializationException(msg);
       175   -
                   } finally {
      -  176  0
                       if (null != reader) {
      -  177  0
                           reader.close();
      -  178   -
                       }
      -  179   -
                   }
      -  180   -
               }
      -  181   -
       
      -  182  0
               if (isEnabled()) {
      -  183  0
                   LOGGER.info(ANALYZER_NAME + " is enabled. It is necessary to manually run \"bundle-audit update\" "
      -  184   -
                           + "occasionally to keep its database up to date.");
      -  185   -
               }
      -  186  0
           }
      -  187   -
       
      -  188   -
           /**
      +
               } else {
      +  176  0
                   BufferedReader reader = null;
      +  177   +
                   try {
      +  178  0
                       reader = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8"));
      +  179  0
                       if (!reader.ready()) {
      +  180  0
                           LOGGER.warn("Bundle-audit error stream unexpectedly not ready. Disabling " + ANALYZER_NAME);
      +  181  0
                           setEnabled(false);
      +  182  0
                           throw new InitializationException("Bundle-audit error stream unexpectedly not ready.");
      +  183   +
                       } else {
      +  184  0
                           final String line = reader.readLine();
      +  185  0
                           if (line == null || !line.contains("Errno::ENOENT")) {
      +  186  0
                               LOGGER.warn("Unexpected bundle-audit output. Disabling {}: {}", ANALYZER_NAME, line);
      +  187  0
                               setEnabled(false);
      +  188  0
                               throw new InitializationException("Unexpected bundle-audit output.");
       189   -
            * Returns the name of the analyzer.
      +
                           }
       190   -
            *
      -  191   -
            * @return the name of the analyzer.
      -  192   -
            */
      -  193   -
           @Override
      -  194   -
           public String getName() {
      -  195  32
               return ANALYZER_NAME;
      -  196   -
           }
      +
                       }
      +  191  0
                   } catch (UnsupportedEncodingException ex) {
      +  192  0
                       setEnabled(false);
      +  193  0
                       throw new InitializationException("Unexpected bundle-audit encoding.", ex);
      +  194  0
                   } catch (IOException ex) {
      +  195  0
                       setEnabled(false);
      +  196  0
                       throw new InitializationException("Unable to read bundle-audit output.", ex);
       197   -
       
      -  198   -
           /**
      +
                   } finally {
      +  198  0
                       if (null != reader) {
       199   -
            * Returns the phase that the analyzer is intended to run in.
      -  200   -
            *
      -  201   -
            * @return the phase that the analyzer is intended to run in.
      -  202   -
            */
      -  203   -
           @Override
      +
                           try {
      +  200  0
                               reader.close();
      +  201  0
                           } catch (IOException ex) {
      +  202  0
                               LOGGER.debug("Error closing reader", ex);
      +  203  0
                           }
       204   -
           public AnalysisPhase getAnalysisPhase() {
      -  205  8
               return ANALYSIS_PHASE;
      +
                       }
      +  205   +
                   }
       206   -
           }
      +
               }
       207  
       
      -  208   -
           /**
      -  209   -
            * Returns the key used in the properties file to reference the analyzer's
      +  208  0
               if (isEnabled()) {
      +  209  0
                   LOGGER.info(ANALYZER_NAME + " is enabled. It is necessary to manually run \"bundle-audit update\" "
       210   -
            * enabled property.
      +
                           + "occasionally to keep its database up to date.");
       211   -
            *
      -  212   -
            * @return the analyzer's enabled property setting key
      +
               }
      +  212  0
           }
       213   -
            */
      +
       
       214   -
           @Override
      +
           /**
       215   -
           protected String getAnalyzerEnabledSettingKey() {
      -  216  24
               return Settings.KEYS.ANALYZER_BUNDLE_AUDIT_ENABLED;
      +
            * Returns the name of the analyzer.
      +  216   +
            *
       217   -
           }
      +
            * @return the name of the analyzer.
       218   -
       
      +
            */
       219   -
           /**
      -  220   -
            * If {@link #analyzeFileType(Dependency, Engine)} is called, then we have
      -  221   -
            * successfully initialized, and it will be necessary to disable
      -  222   -
            * {@link RubyGemspecAnalyzer}.
      -  223   -
            */
      -  224  24
           private boolean needToDisableGemspecAnalyzer = true;
      -  225   -
       
      -  226   -
           /**
      -  227   -
            * Determines if the analyzer can analyze the given file type.
      -  228   -
            *
      -  229   -
            * @param dependency the dependency to determine if it can analyze
      -  230   -
            * @param engine the dependency-check engine
      -  231   -
            * @throws AnalysisException thrown if there is an analysis exception.
      -  232   -
            */
      -  233  
           @Override
      -  234   -
           protected void analyzeFileType(Dependency dependency, Engine engine)
      -  235   -
                   throws AnalysisException {
      -  236  0
               if (needToDisableGemspecAnalyzer) {
      -  237  0
                   boolean failed = true;
      -  238  0
                   final String className = RubyGemspecAnalyzer.class.getName();
      -  239  0
                   for (FileTypeAnalyzer analyzer : engine.getFileTypeAnalyzers()) {
      -  240  0
                       if (analyzer instanceof RubyBundlerAnalyzer) {
      -  241  0
                           ((RubyBundlerAnalyzer) analyzer).setEnabled(false);
      -  242  0
                           LOGGER.info("Disabled " + RubyBundlerAnalyzer.class.getName() + " to avoid noisy duplicate results.");
      -  243  0
                       } else if (analyzer instanceof RubyGemspecAnalyzer) {
      -  244  0
                           ((RubyGemspecAnalyzer) analyzer).setEnabled(false);
      -  245  0
                           LOGGER.info("Disabled " + className + " to avoid noisy duplicate results.");
      -  246  0
                           failed = false;
      -  247   -
                       }
      -  248  0
                   }
      -  249  0
                   if (failed) {
      -  250  0
                       LOGGER.warn("Did not find " + className + '.');
      -  251   -
                   }
      -  252  0
                   needToDisableGemspecAnalyzer = false;
      -  253   -
               }
      -  254  0
               final File parentFile = dependency.getActualFile().getParentFile();
      -  255  0
               final Process process = launchBundleAudit(parentFile);
      -  256   -
               try {
      -  257  0
                   process.waitFor();
      -  258  0
               } catch (InterruptedException ie) {
      -  259  0
                   throw new AnalysisException("bundle-audit process interrupted", ie);
      -  260  0
               }
      -  261  0
               BufferedReader rdr = null;
      -  262  0
               BufferedReader errReader = null;
      -  263   -
               try {
      -  264  0
                   errReader = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8"));
      -  265  0
                   while (errReader.ready()) {
      -  266  0
                       final String error = errReader.readLine();
      -  267  0
                       LOGGER.warn(error);
      -  268  0
                   }
      -  269  0
                   rdr = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8"));
      -  270  0
                   processBundlerAuditOutput(dependency, engine, rdr);
      -  271  0
               } catch (IOException ioe) {
      -  272  0
                   LOGGER.warn("bundle-audit failure", ioe);
      -  273   -
               } finally {
      -  274  0
                   if (errReader != null) {
      -  275   -
                       try {
      -  276  0
                           errReader.close();
      -  277  0
                       } catch (IOException ioe) {
      -  278  0
                           LOGGER.warn("bundle-audit close failure", ioe);
      -  279  0
                       }
      -  280   -
                   }
      -  281  0
                   if (null != rdr) {
      -  282   -
                       try {
      -  283  0
                           rdr.close();
      -  284  0
                       } catch (IOException ioe) {
      -  285  0
                           LOGGER.warn("bundle-audit close failure", ioe);
      -  286  0
                       }
      -  287   -
                   }
      -  288   -
               }
      -  289   -
       
      -  290  0
           }
      -  291   -
       
      -  292   -
           /**
      -  293   -
            * Processes the bundler audit output.
      -  294   -
            *
      -  295   -
            * @param original the dependency
      -  296   -
            * @param engine the dependency-check engine
      -  297   -
            * @param rdr the reader of the report
      -  298   -
            * @throws IOException thrown if the report cannot be read.
      -  299   -
            */
      -  300   -
           private void processBundlerAuditOutput(Dependency original, Engine engine, BufferedReader rdr) throws IOException {
      -  301  0
               final String parentName = original.getActualFile().getParentFile().getName();
      -  302  0
               final String fileName = original.getFileName();
      -  303  0
               final String filePath = original.getFilePath();
      -  304  0
               Dependency dependency = null;
      -  305  0
               Vulnerability vulnerability = null;
      -  306  0
               String gem = null;
      -  307  0
               final Map<String, Dependency> map = new HashMap<String, Dependency>();
      -  308  0
               boolean appendToDescription = false;
      -  309  0
               while (rdr.ready()) {
      -  310  0
                   final String nextLine = rdr.readLine();
      -  311  0
                   if (null == nextLine) {
      -  312  0
                       break;
      -  313  0
                   } else if (nextLine.startsWith(NAME)) {
      -  314  0
                       appendToDescription = false;
      -  315  0
                       gem = nextLine.substring(NAME.length());
      -  316  0
                       if (!map.containsKey(gem)) {
      -  317  0
                           map.put(gem, createDependencyForGem(engine, parentName, fileName, filePath, gem));
      -  318   -
                       }
      -  319  0
                       dependency = map.get(gem);
      -  320  0
                       LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine));
      -  321  0
                   } else if (nextLine.startsWith(VERSION)) {
      -  322  0
                       vulnerability = createVulnerability(parentName, dependency, gem, nextLine);
      -  323  0
                   } else if (nextLine.startsWith(ADVISORY)) {
      -  324  0
                       setVulnerabilityName(parentName, dependency, vulnerability, nextLine);
      -  325  0
                   } else if (nextLine.startsWith(CRITICALITY)) {
      -  326  0
                       addCriticalityToVulnerability(parentName, vulnerability, nextLine);
      -  327  0
                   } else if (nextLine.startsWith("URL: ")) {
      -  328  0
                       addReferenceToVulnerability(parentName, vulnerability, nextLine);
      -  329  0
                   } else if (nextLine.startsWith("Description:")) {
      -  330  0
                       appendToDescription = true;
      -  331  0
                       if (null != vulnerability) {
      -  332  0
                           vulnerability.setDescription("*** Vulnerability obtained from bundle-audit verbose report. "
      -  333   -
                                   + "Title link may not work. CPE below is guessed. CVSS score is estimated (-1.0 "
      -  334   -
                                   + " indicates unknown). See link below for full details. *** ");
      -  335   -
                       }
      -  336  0
                   } else if (appendToDescription) {
      -  337  0
                       if (null != vulnerability) {
      -  338  0
                           vulnerability.setDescription(vulnerability.getDescription() + nextLine + "\n");
      -  339   -
                       }
      -  340   -
                   }
      -  341  0
               }
      -  342  0
           }
      -  343   -
       
      -  344   -
           /**
      -  345   -
            * Sets the vulnerability name.
      -  346   -
            *
      -  347   -
            * @param parentName the parent name
      -  348   -
            * @param dependency the dependency
      -  349   -
            * @param vulnerability the vulnerability
      -  350   -
            * @param nextLine the line to parse
      -  351   -
            */
      -  352   -
           private void setVulnerabilityName(String parentName, Dependency dependency, Vulnerability vulnerability, String nextLine) {
      -  353  0
               final String advisory = nextLine.substring((ADVISORY.length()));
      -  354  0
               if (null != vulnerability) {
      -  355  0
                   vulnerability.setName(advisory);
      -  356   -
               }
      -  357  0
               if (null != dependency) {
      -  358  0
                   dependency.getVulnerabilities().add(vulnerability); // needed to wait for vulnerability name to avoid NPE
      -  359   -
               }
      -  360  0
               LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine));
      -  361  0
           }
      -  362   -
       
      -  363   -
           /**
      -  364   -
            * Adds a reference to the vulnerability.
      -  365   -
            *
      -  366   -
            * @param parentName the parent name
      -  367   -
            * @param vulnerability the vulnerability
      -  368   -
            * @param nextLine the line to parse
      -  369   -
            */
      -  370   -
           private void addReferenceToVulnerability(String parentName, Vulnerability vulnerability, String nextLine) {
      -  371  0
               final String url = nextLine.substring(("URL: ").length());
      -  372  0
               if (null != vulnerability) {
      -  373  0
                   final Reference ref = new Reference();
      -  374  0
                   ref.setName(vulnerability.getName());
      -  375  0
                   ref.setSource("bundle-audit");
      -  376  0
                   ref.setUrl(url);
      -  377  0
                   vulnerability.getReferences().add(ref);
      -  378   -
               }
      -  379  0
               LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine));
      -  380  0
           }
      -  381   -
       
      -  382   -
           /**
      -  383   -
            * Adds the criticality to the vulnerability
      -  384   -
            *
      -  385   -
            * @param parentName the parent name
      -  386   -
            * @param vulnerability the vulnerability
      -  387   -
            * @param nextLine the line to parse
      -  388   -
            */
      -  389   -
           private void addCriticalityToVulnerability(String parentName, Vulnerability vulnerability, String nextLine) {
      -  390  0
               if (null != vulnerability) {
      -  391  0
                   final String criticality = nextLine.substring(CRITICALITY.length()).trim();
      -  392  0
                   float score = -1.0f;
      -  393  0
                   Vulnerability v = null;
      -  394   -
                   try {
      -  395  0
                       v = cvedb.getVulnerability(vulnerability.getName());
      -  396  0
                   } catch (DatabaseException ex) {
      -  397  0
                       LOGGER.debug("Unable to look up vulnerability {}", vulnerability.getName());
      -  398  0
                   }
      -  399  0
                   if (v != null) {
      -  400  0
                       score = v.getCvssScore();
      -  401  0
                   } else if ("High".equalsIgnoreCase(criticality)) {
      -  402  0
                       score = 8.5f;
      -  403  0
                   } else if ("Medium".equalsIgnoreCase(criticality)) {
      -  404  0
                       score = 5.5f;
      -  405  0
                   } else if ("Low".equalsIgnoreCase(criticality)) {
      -  406  0
                       score = 2.0f;
      -  407   -
                   }
      -  408  0
                   vulnerability.setCvssScore(score);
      -  409   -
               }
      -  410  0
               LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine));
      -  411  0
           }
      -  412   -
       
      -  413   -
           /**
      -  414   -
            * Creates a vulnerability.
      -  415   -
            *
      -  416   -
            * @param parentName the parent name
      -  417   -
            * @param dependency the dependency
      -  418   -
            * @param gem the gem name
      -  419   -
            * @param nextLine the line to parse
      -  420   -
            * @return the vulnerability
      -  421   -
            */
      -  422   -
           private Vulnerability createVulnerability(String parentName, Dependency dependency, String gem, String nextLine) {
      -  423  0
               Vulnerability vulnerability = null;
      -  424  0
               if (null != dependency) {
      -  425  0
                   final String version = nextLine.substring(VERSION.length());
      -  426  0
                   dependency.getVersionEvidence().addEvidence(
      -  427   -
                           "bundler-audit",
      -  428   -
                           "Version",
      -  429   -
                           version,
      -  430   -
                           Confidence.HIGHEST);
      -  431  0
                   vulnerability = new Vulnerability(); // don't add to dependency until we have name set later
      -  432  0
                   vulnerability.setMatchedCPE(
      -  433  0
                           String.format("cpe:/a:%1$s_project:%1$s:%2$s::~~~ruby~~", gem, version),
      -  434   -
                           null);
      -  435  0
                   vulnerability.setCvssAccessVector("-");
      -  436  0
                   vulnerability.setCvssAccessComplexity("-");
      -  437  0
                   vulnerability.setCvssAuthentication("-");
      -  438  0
                   vulnerability.setCvssAvailabilityImpact("-");
      -  439  0
                   vulnerability.setCvssConfidentialityImpact("-");
      -  440  0
                   vulnerability.setCvssIntegrityImpact("-");
      -  441   -
               }
      -  442  0
               LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine));
      -  443  0
               return vulnerability;
      -  444   +  220   +
           public String getName() {
      +  221  15
               return ANALYZER_NAME;
      +  222  
           }
      -  445   +  223  
       
      -  446   +  224  
           /**
      -  447   -
            * Creates the dependency based off of the gem.
      -  448   +  225   +
            * Returns the phase that the analyzer is intended to run in.
      +  226  
            *
      -  449   -
            * @param engine the engine used for scanning
      -  450   -
            * @param parentName the gem parent
      -  451   -
            * @param fileName the file name
      -  452   -
            * @param filePath the file path
      -  453   -
            * @param gem the gem name
      -  454   -
            * @return the dependency to add
      -  455   -
            * @throws IOException thrown if a temporary gem file could not be written
      -  456   +  227   +
            * @return the phase that the analyzer is intended to run in.
      +  228  
            */
      -  457   -
           private Dependency createDependencyForGem(Engine engine, String parentName, String fileName, String filePath, String gem) throws IOException {
      -  458  0
               final File gemFile = new File(Settings.getTempDirectory(), gem + "_Gemfile.lock");
      -  459  0
               gemFile.createNewFile();
      -  460  0
               final String displayFileName = String.format("%s%c%s:%s", parentName, File.separatorChar, fileName, gem);
      -  461   +  229   +
           @Override
      +  230   +
           public AnalysisPhase getAnalysisPhase() {
      +  231  4
               return ANALYSIS_PHASE;
      +  232   +
           }
      +  233  
       
      -  462  0
               FileUtils.write(gemFile, displayFileName, Charset.defaultCharset()); // unique contents to avoid dependency bundling
      -  463  0
               final Dependency dependency = new Dependency(gemFile);
      -  464  0
               dependency.getProductEvidence().addEvidence("bundler-audit", "Name", gem, Confidence.HIGHEST);
      -  465  0
               dependency.setDisplayFileName(displayFileName);
      -  466  0
               dependency.setFileName(fileName);
      -  467  0
               dependency.setFilePath(filePath);
      -  468  0
               engine.getDependencies().add(dependency);
      -  469  0
               return dependency;
      +  234   +
           /**
      +  235   +
            * Returns the key used in the properties file to reference the analyzer's
      +  236   +
            * enabled property.
      +  237   +
            *
      +  238   +
            * @return the analyzer's enabled property setting key
      +  239   +
            */
      +  240   +
           @Override
      +  241   +
           protected String getAnalyzerEnabledSettingKey() {
      +  242  12
               return Settings.KEYS.ANALYZER_BUNDLE_AUDIT_ENABLED;
      +  243   +
           }
      +  244   +
       
      +  245   +
           /**
      +  246   +
            * If {@link #analyzeFileType(Dependency, Engine)} is called, then we have
      +  247   +
            * successfully initialized, and it will be necessary to disable
      +  248   +
            * {@link RubyGemspecAnalyzer}.
      +  249   +
            */
      +  250  12
           private boolean needToDisableGemspecAnalyzer = true;
      +  251   +
       
      +  252   +
           /**
      +  253   +
            * Determines if the analyzer can analyze the given file type.
      +  254   +
            *
      +  255   +
            * @param dependency the dependency to determine if it can analyze
      +  256   +
            * @param engine the dependency-check engine
      +  257   +
            * @throws AnalysisException thrown if there is an analysis exception.
      +  258   +
            */
      +  259   +
           @Override
      +  260   +
           protected void analyzeFileType(Dependency dependency, Engine engine)
      +  261   +
                   throws AnalysisException {
      +  262  0
               if (needToDisableGemspecAnalyzer) {
      +  263  0
                   boolean failed = true;
      +  264  0
                   final String className = RubyGemspecAnalyzer.class.getName();
      +  265  0
                   for (FileTypeAnalyzer analyzer : engine.getFileTypeAnalyzers()) {
      +  266  0
                       if (analyzer instanceof RubyBundlerAnalyzer) {
      +  267  0
                           ((RubyBundlerAnalyzer) analyzer).setEnabled(false);
      +  268  0
                           LOGGER.info("Disabled " + RubyBundlerAnalyzer.class.getName() + " to avoid noisy duplicate results.");
      +  269  0
                       } else if (analyzer instanceof RubyGemspecAnalyzer) {
      +  270  0
                           ((RubyGemspecAnalyzer) analyzer).setEnabled(false);
      +  271  0
                           LOGGER.info("Disabled " + className + " to avoid noisy duplicate results.");
      +  272  0
                           failed = false;
      +  273   +
                       }
      +  274  0
                   }
      +  275  0
                   if (failed) {
      +  276  0
                       LOGGER.warn("Did not find " + className + '.');
      +  277   +
                   }
      +  278  0
                   needToDisableGemspecAnalyzer = false;
      +  279   +
               }
      +  280  0
               final File parentFile = dependency.getActualFile().getParentFile();
      +  281  0
               final Process process = launchBundleAudit(parentFile);
      +  282   +
               try {
      +  283  0
                   process.waitFor();
      +  284  0
               } catch (InterruptedException ie) {
      +  285  0
                   throw new AnalysisException("bundle-audit process interrupted", ie);
      +  286  0
               }
      +  287  0
               BufferedReader rdr = null;
      +  288  0
               BufferedReader errReader = null;
      +  289   +
               try {
      +  290  0
                   errReader = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8"));
      +  291  0
                   while (errReader.ready()) {
      +  292  0
                       final String error = errReader.readLine();
      +  293  0
                       LOGGER.warn(error);
      +  294  0
                   }
      +  295  0
                   rdr = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8"));
      +  296  0
                   processBundlerAuditOutput(dependency, engine, rdr);
      +  297  0
               } catch (IOException ioe) {
      +  298  0
                   LOGGER.warn("bundle-audit failure", ioe);
      +  299   +
               } finally {
      +  300  0
                   if (errReader != null) {
      +  301   +
                       try {
      +  302  0
                           errReader.close();
      +  303  0
                       } catch (IOException ioe) {
      +  304  0
                           LOGGER.warn("bundle-audit close failure", ioe);
      +  305  0
                       }
      +  306   +
                   }
      +  307  0
                   if (null != rdr) {
      +  308   +
                       try {
      +  309  0
                           rdr.close();
      +  310  0
                       } catch (IOException ioe) {
      +  311  0
                           LOGGER.warn("bundle-audit close failure", ioe);
      +  312  0
                       }
      +  313   +
                   }
      +  314   +
               }
      +  315   +
       
      +  316  0
           }
      +  317   +
       
      +  318   +
           /**
      +  319   +
            * Processes the bundler audit output.
      +  320   +
            *
      +  321   +
            * @param original the dependency
      +  322   +
            * @param engine the dependency-check engine
      +  323   +
            * @param rdr the reader of the report
      +  324   +
            * @throws IOException thrown if the report cannot be read.
      +  325   +
            */
      +  326   +
           private void processBundlerAuditOutput(Dependency original, Engine engine, BufferedReader rdr) throws IOException {
      +  327  0
               final String parentName = original.getActualFile().getParentFile().getName();
      +  328  0
               final String fileName = original.getFileName();
      +  329  0
               final String filePath = original.getFilePath();
      +  330  0
               Dependency dependency = null;
      +  331  0
               Vulnerability vulnerability = null;
      +  332  0
               String gem = null;
      +  333  0
               final Map<String, Dependency> map = new HashMap<String, Dependency>();
      +  334  0
               boolean appendToDescription = false;
      +  335  0
               while (rdr.ready()) {
      +  336  0
                   final String nextLine = rdr.readLine();
      +  337  0
                   if (null == nextLine) {
      +  338  0
                       break;
      +  339  0
                   } else if (nextLine.startsWith(NAME)) {
      +  340  0
                       appendToDescription = false;
      +  341  0
                       gem = nextLine.substring(NAME.length());
      +  342  0
                       if (!map.containsKey(gem)) {
      +  343  0
                           map.put(gem, createDependencyForGem(engine, parentName, fileName, filePath, gem));
      +  344   +
                       }
      +  345  0
                       dependency = map.get(gem);
      +  346  0
                       LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine));
      +  347  0
                   } else if (nextLine.startsWith(VERSION)) {
      +  348  0
                       vulnerability = createVulnerability(parentName, dependency, gem, nextLine);
      +  349  0
                   } else if (nextLine.startsWith(ADVISORY)) {
      +  350  0
                       setVulnerabilityName(parentName, dependency, vulnerability, nextLine);
      +  351  0
                   } else if (nextLine.startsWith(CRITICALITY)) {
      +  352  0
                       addCriticalityToVulnerability(parentName, vulnerability, nextLine);
      +  353  0
                   } else if (nextLine.startsWith("URL: ")) {
      +  354  0
                       addReferenceToVulnerability(parentName, vulnerability, nextLine);
      +  355  0
                   } else if (nextLine.startsWith("Description:")) {
      +  356  0
                       appendToDescription = true;
      +  357  0
                       if (null != vulnerability) {
      +  358  0
                           vulnerability.setDescription("*** Vulnerability obtained from bundle-audit verbose report. "
      +  359   +
                                   + "Title link may not work. CPE below is guessed. CVSS score is estimated (-1.0 "
      +  360   +
                                   + " indicates unknown). See link below for full details. *** ");
      +  361   +
                       }
      +  362  0
                   } else if (appendToDescription) {
      +  363  0
                       if (null != vulnerability) {
      +  364  0
                           vulnerability.setDescription(vulnerability.getDescription() + nextLine + "\n");
      +  365   +
                       }
      +  366   +
                   }
      +  367  0
               }
      +  368  0
           }
      +  369   +
       
      +  370   +
           /**
      +  371   +
            * Sets the vulnerability name.
      +  372   +
            *
      +  373   +
            * @param parentName the parent name
      +  374   +
            * @param dependency the dependency
      +  375   +
            * @param vulnerability the vulnerability
      +  376   +
            * @param nextLine the line to parse
      +  377   +
            */
      +  378   +
           private void setVulnerabilityName(String parentName, Dependency dependency, Vulnerability vulnerability, String nextLine) {
      +  379  0
               final String advisory = nextLine.substring((ADVISORY.length()));
      +  380  0
               if (null != vulnerability) {
      +  381  0
                   vulnerability.setName(advisory);
      +  382   +
               }
      +  383  0
               if (null != dependency) {
      +  384  0
                   dependency.getVulnerabilities().add(vulnerability); // needed to wait for vulnerability name to avoid NPE
      +  385   +
               }
      +  386  0
               LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine));
      +  387  0
           }
      +  388   +
       
      +  389   +
           /**
      +  390   +
            * Adds a reference to the vulnerability.
      +  391   +
            *
      +  392   +
            * @param parentName the parent name
      +  393   +
            * @param vulnerability the vulnerability
      +  394   +
            * @param nextLine the line to parse
      +  395   +
            */
      +  396   +
           private void addReferenceToVulnerability(String parentName, Vulnerability vulnerability, String nextLine) {
      +  397  0
               final String url = nextLine.substring(("URL: ").length());
      +  398  0
               if (null != vulnerability) {
      +  399  0
                   final Reference ref = new Reference();
      +  400  0
                   ref.setName(vulnerability.getName());
      +  401  0
                   ref.setSource("bundle-audit");
      +  402  0
                   ref.setUrl(url);
      +  403  0
                   vulnerability.getReferences().add(ref);
      +  404   +
               }
      +  405  0
               LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine));
      +  406  0
           }
      +  407   +
       
      +  408   +
           /**
      +  409   +
            * Adds the criticality to the vulnerability
      +  410   +
            *
      +  411   +
            * @param parentName the parent name
      +  412   +
            * @param vulnerability the vulnerability
      +  413   +
            * @param nextLine the line to parse
      +  414   +
            */
      +  415   +
           private void addCriticalityToVulnerability(String parentName, Vulnerability vulnerability, String nextLine) {
      +  416  0
               if (null != vulnerability) {
      +  417  0
                   final String criticality = nextLine.substring(CRITICALITY.length()).trim();
      +  418  0
                   float score = -1.0f;
      +  419  0
                   Vulnerability v = null;
      +  420   +
                   try {
      +  421  0
                       v = cvedb.getVulnerability(vulnerability.getName());
      +  422  0
                   } catch (DatabaseException ex) {
      +  423  0
                       LOGGER.debug("Unable to look up vulnerability {}", vulnerability.getName());
      +  424  0
                   }
      +  425  0
                   if (v != null) {
      +  426  0
                       score = v.getCvssScore();
      +  427  0
                   } else if ("High".equalsIgnoreCase(criticality)) {
      +  428  0
                       score = 8.5f;
      +  429  0
                   } else if ("Medium".equalsIgnoreCase(criticality)) {
      +  430  0
                       score = 5.5f;
      +  431  0
                   } else if ("Low".equalsIgnoreCase(criticality)) {
      +  432  0
                       score = 2.0f;
      +  433   +
                   }
      +  434  0
                   vulnerability.setCvssScore(score);
      +  435   +
               }
      +  436  0
               LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine));
      +  437  0
           }
      +  438   +
       
      +  439   +
           /**
      +  440   +
            * Creates a vulnerability.
      +  441   +
            *
      +  442   +
            * @param parentName the parent name
      +  443   +
            * @param dependency the dependency
      +  444   +
            * @param gem the gem name
      +  445   +
            * @param nextLine the line to parse
      +  446   +
            * @return the vulnerability
      +  447   +
            */
      +  448   +
           private Vulnerability createVulnerability(String parentName, Dependency dependency, String gem, String nextLine) {
      +  449  0
               Vulnerability vulnerability = null;
      +  450  0
               if (null != dependency) {
      +  451  0
                   final String version = nextLine.substring(VERSION.length());
      +  452  0
                   dependency.getVersionEvidence().addEvidence(
      +  453   +
                           "bundler-audit",
      +  454   +
                           "Version",
      +  455   +
                           version,
      +  456   +
                           Confidence.HIGHEST);
      +  457  0
                   vulnerability = new Vulnerability(); // don't add to dependency until we have name set later
      +  458  0
                   vulnerability.setMatchedCPE(
      +  459  0
                           String.format("cpe:/a:%1$s_project:%1$s:%2$s::~~~ruby~~", gem, version),
      +  460   +
                           null);
      +  461  0
                   vulnerability.setCvssAccessVector("-");
      +  462  0
                   vulnerability.setCvssAccessComplexity("-");
      +  463  0
                   vulnerability.setCvssAuthentication("-");
      +  464  0
                   vulnerability.setCvssAvailabilityImpact("-");
      +  465  0
                   vulnerability.setCvssConfidentialityImpact("-");
      +  466  0
                   vulnerability.setCvssIntegrityImpact("-");
      +  467   +
               }
      +  468  0
               LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine));
      +  469  0
               return vulnerability;
       470  
           }
       471   +
       
      +  472   +
           /**
      +  473   +
            * Creates the dependency based off of the gem.
      +  474   +
            *
      +  475   +
            * @param engine the engine used for scanning
      +  476   +
            * @param parentName the gem parent
      +  477   +
            * @param fileName the file name
      +  478   +
            * @param filePath the file path
      +  479   +
            * @param gem the gem name
      +  480   +
            * @return the dependency to add
      +  481   +
            * @throws IOException thrown if a temporary gem file could not be written
      +  482   +
            */
      +  483   +
           private Dependency createDependencyForGem(Engine engine, String parentName, String fileName, String filePath, String gem) throws IOException {
      +  484  0
               final File gemFile = new File(Settings.getTempDirectory(), gem + "_Gemfile.lock");
      +  485  0
               gemFile.createNewFile();
      +  486  0
               final String displayFileName = String.format("%s%c%s:%s", parentName, File.separatorChar, fileName, gem);
      +  487   +
       
      +  488  0
               FileUtils.write(gemFile, displayFileName, Charset.defaultCharset()); // unique contents to avoid dependency bundling
      +  489  0
               final Dependency dependency = new Dependency(gemFile);
      +  490  0
               dependency.getProductEvidence().addEvidence("bundler-audit", "Name", gem, Confidence.HIGHEST);
      +  491  0
               dependency.setDisplayFileName(displayFileName);
      +  492  0
               dependency.setFileName(fileName);
      +  493  0
               dependency.setFilePath(filePath);
      +  494  0
               engine.getDependencies().add(dependency);
      +  495  0
               return dependency;
      +  496   +
           }
      +  497  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.RubyBundlerAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.RubyBundlerAnalyzer.html index a1d5799ae..6e203c679 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.RubyBundlerAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.RubyBundlerAnalyzer.html @@ -114,7 +114,7 @@
        */
       48  
       @Experimental
      -  49  18
       public class RubyBundlerAnalyzer extends RubyGemspecAnalyzer {
      +  49  9
       public class RubyBundlerAnalyzer extends RubyGemspecAnalyzer {
       50  
       
       51   @@ -161,7 +161,7 @@
           @Override
       72  
           public String getName() {
      -  73  30
               return ANALYZER_NAME;
      +  73  15
               return ANALYZER_NAME;
       74  
           }
       75   @@ -186,15 +186,15 @@
           public boolean accept(File pathname) {
       85  
       
      -  86  1722
               boolean accepted = super.accept(pathname);
      -  87  1722
               if (accepted) {
      -  88  8
                   final File parentDir = pathname.getParentFile();
      -  89  8
                   accepted = parentDir != null && parentDir.getName().equals(SPECIFICATIONS);
      +  86  12
               boolean accepted = super.accept(pathname);
      +  87  12
               if (accepted) {
      +  88  4
                   final File parentDir = pathname.getParentFile();
      +  89  4
                   accepted = parentDir != null && parentDir.getName().equals(SPECIFICATIONS);
       90  
               }
       91  
       
      -  92  1722
               return accepted;
      +  92  12
               return accepted;
       93  
           }
       94   @@ -205,68 +205,70 @@
           protected void analyzeFileType(Dependency dependency, Engine engine)
       97  
                   throws AnalysisException {
      -  98  4
               super.analyzeFileType(dependency, engine);
      +  98  2
               super.analyzeFileType(dependency, engine);
       99  
       
       100  
               //find the corresponding gem folder for this .gemspec stub by "bundle install --deployment"
      -  101  4
               final File gemspecFile = dependency.getActualFile();
      -  102  4
               final String gemFileName = gemspecFile.getName();
      -  103  4
               final String gemName = gemFileName.substring(0, gemFileName.lastIndexOf(".gemspec"));
      -  104  4
               final File specificationsDir = gemspecFile.getParentFile();
      -  105  4
               if (specificationsDir != null && specificationsDir.getName().equals(SPECIFICATIONS) && specificationsDir.exists()) {
      -  106  4
                   final File parentDir = specificationsDir.getParentFile();
      -  107  4
                   if (parentDir != null && parentDir.exists()) {
      -  108  4
                       final File gemsDir = new File(parentDir, GEMS);
      -  109  4
                       if (gemsDir.exists()) {
      -  110  4
                           final File[] matchingFiles = gemsDir.listFiles(new FilenameFilter() {
      +  101  2
               final File gemspecFile = dependency.getActualFile();
      +  102  2
               final String gemFileName = gemspecFile.getName();
      +  103  2
               final String gemName = gemFileName.substring(0, gemFileName.lastIndexOf(".gemspec"));
      +  104  2
               final File specificationsDir = gemspecFile.getParentFile();
      +  105  2
               if (specificationsDir != null && specificationsDir.getName().equals(SPECIFICATIONS) && specificationsDir.exists()) {
      +  106  2
                   final File parentDir = specificationsDir.getParentFile();
      +  107  2
                   if (parentDir != null && parentDir.exists()) {
      +  108  2
                       final File gemsDir = new File(parentDir, GEMS);
      +  109  2
                       if (gemsDir.exists()) {
      +  110  2
                           final File[] matchingFiles = gemsDir.listFiles(new FilenameFilter() {
       111   +
                               @Override
      +  112  
                               public boolean accept(File dir, String name) {
      -  112  4
                                   return name.equals(gemName);
      -  113   -
                               }
      +  113  2
                                   return name.equals(gemName);
       114   -
                           });
      -  115   -
       
      -  116  4
                           if (matchingFiles != null && matchingFiles.length > 0) {
      -  117  0
                               final String gemPath = matchingFiles[0].getAbsolutePath();
      -  118  0
                               if (dependency.getActualFilePath().equals(dependency.getFilePath())) {
      -  119  0
                                   if (gemPath != null) {
      -  120  0
                                       dependency.setPackagePath(gemPath);
      -  121   -
                                   }
      -  122   -
                               } else {
      -  123   -
                                   //.gemspec's actualFilePath and filePath are different when it's from a compressed file
      -  124   -
                                   //in which case actualFilePath is the temp directory used by decompression.
      -  125   -
                                   //packagePath should use the filePath of the identified gem file in "gems" folder
      -  126  0
                                   final File gemspecStub = new File(dependency.getFilePath());
      -  127  0
                                   final File specDir = gemspecStub.getParentFile();
      -  128  0
                                   if (specDir != null && specDir.getName().equals(SPECIFICATIONS)) {
      -  129  0
                                       final File gemsDir2 = new File(specDir.getParentFile(), GEMS);
      -  130  0
                                       final File packageDir = new File(gemsDir2, gemName);
      -  131  0
                                       dependency.setPackagePath(packageDir.getAbsolutePath());
      -  132   -
                                   }
      -  133  
                               }
      +  115   +
                           });
      +  116   +
       
      +  117  2
                           if (matchingFiles != null && matchingFiles.length > 0) {
      +  118  0
                               final String gemPath = matchingFiles[0].getAbsolutePath();
      +  119  0
                               if (dependency.getActualFilePath().equals(dependency.getFilePath())) {
      +  120  0
                                   if (gemPath != null) {
      +  121  0
                                       dependency.setPackagePath(gemPath);
      +  122   +
                                   }
      +  123   +
                               } else {
      +  124   +
                                   //.gemspec's actualFilePath and filePath are different when it's from a compressed file
      +  125   +
                                   //in which case actualFilePath is the temp directory used by decompression.
      +  126   +
                                   //packagePath should use the filePath of the identified gem file in "gems" folder
      +  127  0
                                   final File gemspecStub = new File(dependency.getFilePath());
      +  128  0
                                   final File specDir = gemspecStub.getParentFile();
      +  129  0
                                   if (specDir != null && specDir.getName().equals(SPECIFICATIONS)) {
      +  130  0
                                       final File gemsDir2 = new File(specDir.getParentFile(), GEMS);
      +  131  0
                                       final File packageDir = new File(gemsDir2, gemName);
      +  132  0
                                       dependency.setPackagePath(packageDir.getAbsolutePath());
      +  133   +
                                   }
       134   -
                           }
      +
                               }
       135   -
                       }
      +
                           }
       136   -
                   }
      +
                       }
       137   +
                   }
      +  138  
               }
      -  138  4
           }
      -  139   +  139  2
           }
      +  140  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.RubyGemspecAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.RubyGemspecAnalyzer.html index 77a248268..50dcf9e47 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.RubyGemspecAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.RubyGemspecAnalyzer.html @@ -87,362 +87,366 @@  34  
       import org.owasp.dependencycheck.dependency.EvidenceCollection;
       35   -
       import org.owasp.dependencycheck.utils.FileFilterBuilder;
      +
       import org.owasp.dependencycheck.exception.InitializationException;
       36   -
       import org.owasp.dependencycheck.utils.Settings;
      +
       import org.owasp.dependencycheck.utils.FileFilterBuilder;
       37   -
       import org.slf4j.Logger;
      +
       import org.owasp.dependencycheck.utils.Settings;
       38   -
       import org.slf4j.LoggerFactory;
      +
       import org.slf4j.Logger;
       39   -
       
      +
       import org.slf4j.LoggerFactory;
       40   -
       /**
      +
       
       41   -
        * Used to analyze Ruby Gem specifications and collect information that can be
      +
       /**
       42   -
        * used to determine the associated CPE. Regular expressions are used to parse
      +
        * Used to analyze Ruby Gem specifications and collect information that can be
       43   -
        * the well-defined Ruby syntax that forms the specification.
      +
        * used to determine the associated CPE. Regular expressions are used to parse
       44   -
        *
      +
        * the well-defined Ruby syntax that forms the specification.
       45   -
        * @author Dale Visser
      +
        *
       46   -
        */
      +
        * @author Dale Visser
       47   +
        */
      +  48  
       @Experimental
      -  48  36
       public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer {
      -  49   -
       
      +  49  18
       public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer {
       50   -
           /**
      +
       
       51   -
            * The logger.
      +
           /**
       52   +
            * The logger.
      +  53  
            */
      -  53  2
           private static final Logger LOGGER = LoggerFactory.getLogger(RubyGemspecAnalyzer.class);
      -  54   -
           /**
      +  54  1
           private static final Logger LOGGER = LoggerFactory.getLogger(RubyGemspecAnalyzer.class);
       55   -
            * The name of the analyzer.
      +
           /**
       56   -
            */
      +
            * The name of the analyzer.
       57   -
           private static final String ANALYZER_NAME = "Ruby Gemspec Analyzer";
      +
            */
       58   -
       
      +
           private static final String ANALYZER_NAME = "Ruby Gemspec Analyzer";
       59   -
           /**
      +
       
       60   -
            * The phase that this analyzer is intended to run in.
      +
           /**
       61   +
            * The phase that this analyzer is intended to run in.
      +  62  
            */
      -  62  2
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
      -  63   -
       
      +  63  1
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
       64   -
           /**
      +
       
       65   -
            * The gemspec file extension.
      +
           /**
       66   -
            */
      +
            * The gemspec file extension.
       67   -
           private static final String GEMSPEC = "gemspec";
      +
            */
       68   -
       
      +
           private static final String GEMSPEC = "gemspec";
       69   -
           /**
      +
       
       70   -
            * The file filter containing the list of file extensions that can be
      +
           /**
       71   -
            * analyzed.
      +
            * The file filter containing the list of file extensions that can be
       72   +
            * analyzed.
      +  73  
            */
      -  73  2
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(GEMSPEC).build();
      -  74   -
           //TODO: support Rakefile
      +  74  1
           private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(GEMSPEC).build();
       75   -
           //= FileFilterBuilder.newInstance().addExtensions(GEMSPEC).addFilenames("Rakefile").build();
      +
           //TODO: support Rakefile
       76   -
       
      +
           //= FileFilterBuilder.newInstance().addExtensions(GEMSPEC).addFilenames("Rakefile").build();
       77   -
           /**
      +
       
       78   -
            * The name of the version file.
      +
           /**
       79   -
            */
      +
            * The name of the version file.
       80   -
           private static final String VERSION_FILE_NAME = "VERSION";
      +
            */
       81   -
       
      +
           private static final String VERSION_FILE_NAME = "VERSION";
       82   -
           /**
      +
       
       83   -
            * @return a filter that accepts files matching the glob pattern, *.gemspec
      +
           /**
       84   -
            */
      +
            * @return a filter that accepts files matching the glob pattern, *.gemspec
       85   -
           @Override
      +
            */
       86   +
           @Override
      +  87  
           protected FileFilter getFileFilter() {
      -  87  3442
               return FILTER;
      -  88   -
           }
      +  88  23
               return FILTER;
       89   -
       
      +
           }
       90   -
           @Override
      +
       
       91   -
           protected void initializeFileTypeAnalyzer() throws Exception {
      +
           @Override
       92   +
           protected void initializeFileTypeAnalyzer() throws InitializationException {
      +  93  
               // NO-OP
      -  93  16
           }
      -  94   -
       
      +  94  8
           }
       95   -
           /**
      +
       
       96   -
            * Returns the name of the analyzer.
      +
           /**
       97   -
            *
      +
            * Returns the name of the analyzer.
       98   -
            * @return the name of the analyzer.
      +
            *
       99   -
            */
      +
            * @return the name of the analyzer.
       100   -
           @Override
      +
            */
       101   +
           @Override
      +  102  
           public String getName() {
      -  102  30
               return ANALYZER_NAME;
      -  103   -
           }
      +  103  15
               return ANALYZER_NAME;
       104   -
       
      +
           }
       105   -
           /**
      +
       
       106   -
            * Returns the phase that the analyzer is intended to run in.
      +
           /**
       107   -
            *
      +
            * Returns the phase that the analyzer is intended to run in.
       108   -
            * @return the phase that the analyzer is intended to run in.
      +
            *
       109   -
            */
      +
            * @return the phase that the analyzer is intended to run in.
       110   -
           @Override
      +
            */
       111   +
           @Override
      +  112  
           public AnalysisPhase getAnalysisPhase() {
      -  112  16
               return ANALYSIS_PHASE;
      -  113   -
           }
      +  113  8
               return ANALYSIS_PHASE;
       114   -
       
      +
           }
       115   -
           /**
      +
       
       116   -
            * Returns the key used in the properties file to reference the analyzer's
      +
           /**
       117   -
            * enabled property.
      +
            * Returns the key used in the properties file to reference the analyzer's
       118   -
            *
      +
            * enabled property.
       119   -
            * @return the analyzer's enabled property setting key
      +
            *
       120   -
            */
      +
            * @return the analyzer's enabled property setting key
       121   -
           @Override
      +
            */
       122   -
           protected String getAnalyzerEnabledSettingKey() {
      -  123  36
               return Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED;
      -  124   -
           }
      -  125   -
       
      -  126   -
           /**
      -  127   -
            * The capture group #1 is the block variable.
      -  128   -
            */
      -  129  2
           private static final Pattern GEMSPEC_BLOCK_INIT = Pattern.compile("Gem::Specification\\.new\\s+?do\\s+?\\|(.+?)\\|");
      -  130   -
       
      -  131  
           @Override
      -  132   -
           protected void analyzeFileType(Dependency dependency, Engine engine)
      -  133   -
                   throws AnalysisException {
      -  134   -
               String contents;
      -  135   -
               try {
      -  136  8
                   contents = FileUtils.readFileToString(dependency.getActualFile(), Charset.defaultCharset());
      -  137  0
               } catch (IOException e) {
      -  138  0
                   throw new AnalysisException(
      -  139   -
                           "Problem occurred while reading dependency file.", e);
      -  140  8
               }
      -  141  8
               final Matcher matcher = GEMSPEC_BLOCK_INIT.matcher(contents);
      -  142  8
               if (matcher.find()) {
      -  143  8
                   contents = contents.substring(matcher.end());
      -  144  8
                   final String blockVariable = matcher.group(1);
      -  145   -
       
      -  146  8
                   final EvidenceCollection vendor = dependency.getVendorEvidence();
      -  147  8
                   final EvidenceCollection product = dependency.getProductEvidence();
      -  148  8
                   final String name = addStringEvidence(product, contents, blockVariable, "name", "name", Confidence.HIGHEST);
      -  149  8
                   if (!name.isEmpty()) {
      -  150  8
                       vendor.addEvidence(GEMSPEC, "name_project", name + "_project", Confidence.LOW);
      -  151   -
                   }
      -  152  8
                   addStringEvidence(product, contents, blockVariable, "summary", "summary", Confidence.LOW);
      -  153   -
       
      -  154  8
                   addStringEvidence(vendor, contents, blockVariable, "author", "authors?", Confidence.HIGHEST);
      -  155  8
                   addStringEvidence(vendor, contents, blockVariable, "email", "emails?", Confidence.MEDIUM);
      -  156  8
                   addStringEvidence(vendor, contents, blockVariable, "homepage", "homepage", Confidence.HIGHEST);
      -  157  8
                   addStringEvidence(vendor, contents, blockVariable, "license", "licen[cs]es?", Confidence.HIGHEST);
      -  158   -
       
      -  159  8
                   final String value = addStringEvidence(dependency.getVersionEvidence(), contents,
      -  160   -
                           blockVariable, "version", "version", Confidence.HIGHEST);
      -  161  8
                   if (value.length() < 1) {
      -  162  0
                       addEvidenceFromVersionFile(dependency.getActualFile(), dependency.getVersionEvidence());
      -  163   -
                   }
      -  164   -
               }
      -  165   -
       
      -  166  8
               setPackagePath(dependency);
      -  167  8
           }
      -  168   -
       
      -  169   -
           /**
      -  170   -
            * Adds the specified evidence to the given evidence collection.
      -  171   -
            *
      -  172   -
            * @param evidences the collection to add the evidence to
      -  173   -
            * @param contents the evidence contents
      -  174   -
            * @param blockVariable the variable
      -  175   -
            * @param field the field
      -  176   -
            * @param fieldPattern the field pattern
      -  177   -
            * @param confidence the confidence of the evidence
      -  178   -
            * @return the evidence string value added
      -  179   -
            */
      -  180   -
           private String addStringEvidence(EvidenceCollection evidences, String contents,
      -  181   -
                   String blockVariable, String field, String fieldPattern, Confidence confidence) {
      -  182  56
               String value = "";
      -  183   -
       
      -  184   -
               //capture array value between [ ]
      -  185  112
               final Matcher arrayMatcher = Pattern.compile(
      -  186  112
                       String.format("\\s*?%s\\.%s\\s*?=\\s*?\\[(.*?)\\]", blockVariable, fieldPattern), Pattern.CASE_INSENSITIVE).matcher(contents);
      -  187  56
               if (arrayMatcher.find()) {
      -  188  22
                   final String arrayValue = arrayMatcher.group(1);
      -  189  22
                   value = arrayValue.replaceAll("['\"]", "").trim(); //strip quotes
      -  190  22
               } else { //capture single value between quotes
      -  191  68
                   final Matcher matcher = Pattern.compile(
      -  192  68
                           String.format("\\s*?%s\\.%s\\s*?=\\s*?(['\"])(.*?)\\1", blockVariable, fieldPattern), Pattern.CASE_INSENSITIVE).matcher(contents);
      -  193  34
                   if (matcher.find()) {
      -  194  34
                       value = matcher.group(2);
      -  195   -
                   }
      -  196   -
               }
      -  197  56
               if (value.length() > 0) {
      -  198  56
                   evidences.addEvidence(GEMSPEC, field, value, confidence);
      -  199   -
               }
      -  200   -
       
      -  201  56
               return value;
      -  202   +  123   +
           protected String getAnalyzerEnabledSettingKey() {
      +  124  18
               return Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED;
      +  125  
           }
      -  203   +  126  
       
      -  204   +  127  
           /**
      -  205   -
            * Adds evidence from the version file.
      -  206   -
            *
      -  207   -
            * @param dependencyFile the dependency being analyzed
      -  208   -
            * @param versionEvidences the version evidence
      -  209   +  128   +
            * The capture group #1 is the block variable.
      +  129  
            */
      -  210   -
           private void addEvidenceFromVersionFile(File dependencyFile, EvidenceCollection versionEvidences) {
      -  211  0
               final File parentDir = dependencyFile.getParentFile();
      -  212  0
               if (parentDir != null) {
      -  213  0
                   final File[] matchingFiles = parentDir.listFiles(new FilenameFilter() {
      -  214   -
                       public boolean accept(File dir, String name) {
      -  215  0
                           return name.contains(VERSION_FILE_NAME);
      -  216   -
                       }
      -  217   -
                   });
      -  218  0
                   for (File f : matchingFiles) {
      -  219   -
                       try {
      -  220  0
                           final List<String> lines = FileUtils.readLines(f, Charset.defaultCharset());
      -  221  0
                           if (lines.size() == 1) { //TODO other checking?
      -  222  0
                               final String value = lines.get(0).trim();
      -  223  0
                               versionEvidences.addEvidence(GEMSPEC, "version", value, Confidence.HIGH);
      -  224   -
                           }
      -  225  0
                       } catch (IOException e) {
      -  226  0
                           LOGGER.debug("Error reading gemspec", e);
      -  227  0
                       }
      -  228   +  130  1
           private static final Pattern GEMSPEC_BLOCK_INIT = Pattern.compile("Gem::Specification\\.new\\s+?do\\s+?\\|(.+?)\\|");
      +  131   +
       
      +  132   +
           @Override
      +  133   +
           protected void analyzeFileType(Dependency dependency, Engine engine)
      +  134   +
                   throws AnalysisException {
      +  135   +
               String contents;
      +  136   +
               try {
      +  137  4
                   contents = FileUtils.readFileToString(dependency.getActualFile(), Charset.defaultCharset());
      +  138  0
               } catch (IOException e) {
      +  139  0
                   throw new AnalysisException(
      +  140   +
                           "Problem occurred while reading dependency file.", e);
      +  141  4
               }
      +  142  4
               final Matcher matcher = GEMSPEC_BLOCK_INIT.matcher(contents);
      +  143  4
               if (matcher.find()) {
      +  144  4
                   contents = contents.substring(matcher.end());
      +  145  4
                   final String blockVariable = matcher.group(1);
      +  146   +
       
      +  147  4
                   final EvidenceCollection vendor = dependency.getVendorEvidence();
      +  148  4
                   final EvidenceCollection product = dependency.getProductEvidence();
      +  149  4
                   final String name = addStringEvidence(product, contents, blockVariable, "name", "name", Confidence.HIGHEST);
      +  150  4
                   if (!name.isEmpty()) {
      +  151  4
                       vendor.addEvidence(GEMSPEC, "name_project", name + "_project", Confidence.LOW);
      +  152  
                   }
      -  229   -
               }
      -  230  0
           }
      -  231   +  153  4
                   addStringEvidence(product, contents, blockVariable, "summary", "summary", Confidence.LOW);
      +  154  
       
      -  232   -
           /**
      -  233   -
            * Sets the package path on the dependency.
      -  234   -
            *
      -  235   -
            * @param dep the dependency to alter
      -  236   -
            */
      -  237   -
           private void setPackagePath(Dependency dep) {
      -  238  8
               final File file = new File(dep.getFilePath());
      -  239  8
               final String parent = file.getParent();
      -  240  8
               if (parent != null) {
      -  241  8
                   dep.setPackagePath(parent);
      -  242   +  155  4
                   addStringEvidence(vendor, contents, blockVariable, "author", "authors?", Confidence.HIGHEST);
      +  156  4
                   addStringEvidence(vendor, contents, blockVariable, "email", "emails?", Confidence.MEDIUM);
      +  157  4
                   addStringEvidence(vendor, contents, blockVariable, "homepage", "homepage", Confidence.HIGHEST);
      +  158  4
                   addStringEvidence(vendor, contents, blockVariable, "license", "licen[cs]es?", Confidence.HIGHEST);
      +  159   +
       
      +  160  4
                   final String value = addStringEvidence(dependency.getVersionEvidence(), contents,
      +  161   +
                           blockVariable, "version", "version", Confidence.HIGHEST);
      +  162  4
                   if (value.length() < 1) {
      +  163  0
                       addEvidenceFromVersionFile(dependency.getActualFile(), dependency.getVersionEvidence());
      +  164   +
                   }
      +  165  
               }
      -  243  8
           }
      +  166   +
       
      +  167  4
               setPackagePath(dependency);
      +  168  4
           }
      +  169   +
       
      +  170   +
           /**
      +  171   +
            * Adds the specified evidence to the given evidence collection.
      +  172   +
            *
      +  173   +
            * @param evidences the collection to add the evidence to
      +  174   +
            * @param contents the evidence contents
      +  175   +
            * @param blockVariable the variable
      +  176   +
            * @param field the field
      +  177   +
            * @param fieldPattern the field pattern
      +  178   +
            * @param confidence the confidence of the evidence
      +  179   +
            * @return the evidence string value added
      +  180   +
            */
      +  181   +
           private String addStringEvidence(EvidenceCollection evidences, String contents,
      +  182   +
                   String blockVariable, String field, String fieldPattern, Confidence confidence) {
      +  183  28
               String value = "";
      +  184   +
       
      +  185   +
               //capture array value between [ ]
      +  186  56
               final Matcher arrayMatcher = Pattern.compile(
      +  187  56
                       String.format("\\s*?%s\\.%s\\s*?=\\s*?\\[(.*?)\\]", blockVariable, fieldPattern), Pattern.CASE_INSENSITIVE).matcher(contents);
      +  188  28
               if (arrayMatcher.find()) {
      +  189  11
                   final String arrayValue = arrayMatcher.group(1);
      +  190  11
                   value = arrayValue.replaceAll("['\"]", "").trim(); //strip quotes
      +  191  11
               } else { //capture single value between quotes
      +  192  34
                   final Matcher matcher = Pattern.compile(
      +  193  34
                           String.format("\\s*?%s\\.%s\\s*?=\\s*?(['\"])(.*?)\\1", blockVariable, fieldPattern), Pattern.CASE_INSENSITIVE).matcher(contents);
      +  194  17
                   if (matcher.find()) {
      +  195  17
                       value = matcher.group(2);
      +  196   +
                   }
      +  197   +
               }
      +  198  28
               if (value.length() > 0) {
      +  199  28
                   evidences.addEvidence(GEMSPEC, field, value, confidence);
      +  200   +
               }
      +  201   +
       
      +  202  28
               return value;
      +  203   +
           }
      +  204   +
       
      +  205   +
           /**
      +  206   +
            * Adds evidence from the version file.
      +  207   +
            *
      +  208   +
            * @param dependencyFile the dependency being analyzed
      +  209   +
            * @param versionEvidences the version evidence
      +  210   +
            */
      +  211   +
           private void addEvidenceFromVersionFile(File dependencyFile, EvidenceCollection versionEvidences) {
      +  212  0
               final File parentDir = dependencyFile.getParentFile();
      +  213  0
               if (parentDir != null) {
      +  214  0
                   final File[] matchingFiles = parentDir.listFiles(new FilenameFilter() {
      +  215   +
                       @Override
      +  216   +
                       public boolean accept(File dir, String name) {
      +  217  0
                           return name.contains(VERSION_FILE_NAME);
      +  218   +
                       }
      +  219   +
                   });
      +  220  0
                   for (File f : matchingFiles) {
      +  221   +
                       try {
      +  222  0
                           final List<String> lines = FileUtils.readLines(f, Charset.defaultCharset());
      +  223  0
                           if (lines.size() == 1) { //TODO other checking?
      +  224  0
                               final String value = lines.get(0).trim();
      +  225  0
                               versionEvidences.addEvidence(GEMSPEC, "version", value, Confidence.HIGH);
      +  226   +
                           }
      +  227  0
                       } catch (IOException e) {
      +  228  0
                           LOGGER.debug("Error reading gemspec", e);
      +  229  0
                       }
      +  230   +
                   }
      +  231   +
               }
      +  232  0
           }
      +  233   +
       
      +  234   +
           /**
      +  235   +
            * Sets the package path on the dependency.
      +  236   +
            *
      +  237   +
            * @param dep the dependency to alter
      +  238   +
            */
      +  239   +
           private void setPackagePath(Dependency dep) {
      +  240  4
               final File file = new File(dep.getFilePath());
      +  241  4
               final String parent = file.getParent();
      +  242  4
               if (parent != null) {
      +  243  4
                   dep.setPackagePath(parent);
       244   +
               }
      +  245  4
           }
      +  246  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.VulnerabilitySuppressionAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.VulnerabilitySuppressionAnalyzer.html index ded91cd37..f172d0c3c 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.VulnerabilitySuppressionAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.VulnerabilitySuppressionAnalyzer.html @@ -62,7 +62,7 @@  22  
       import org.owasp.dependencycheck.dependency.Dependency;
       23   -
       import org.owasp.dependencycheck.suppression.SuppressionRule;
      +
       import org.owasp.dependencycheck.xml.suppression.SuppressionRule;
       24  
       
       25   @@ -77,7 +77,7 @@
        * @author Jeremy Long
       30  
        */
      -  31  12
       public class VulnerabilitySuppressionAnalyzer extends AbstractSuppressionAnalyzer {
      +  31  6
       public class VulnerabilitySuppressionAnalyzer extends AbstractSuppressionAnalyzer {
       32  
       
       33   @@ -96,7 +96,7 @@
            * The phase that this analyzer is intended to run in.
       40  
            */
      -  41  2
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.POST_FINDING_ANALYSIS;
      +  41  1
           private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.POST_FINDING_ANALYSIS;
       42  
       
       43   @@ -113,7 +113,7 @@
           @Override
       49  
           public String getName() {
      -  50  32
               return ANALYZER_NAME;
      +  50  16
               return ANALYZER_NAME;
       51  
           }
       52   @@ -132,7 +132,7 @@
           @Override
       59  
           public AnalysisPhase getAnalysisPhase() {
      -  60  8
               return ANALYSIS_PHASE;
      +  60  4
               return ANALYSIS_PHASE;
       61  
           }
       62   @@ -145,20 +145,20 @@
           public void analyze(final Dependency dependency, final Engine engine) throws AnalysisException {
       66  
       
      -  67  8
               if (getRules() == null || getRules().size() <= 0) {
      +  67  4
               if (getRules() == null || getRules().size() <= 0) {
       68  0
                   return;
       69  
               }
       70  
       
      -  71  8
               for (final SuppressionRule rule : getRules()) {
      -  72  440
                   rule.process(dependency);
      -  73  440
               }
      -  74  8
           }
      +  71  4
               for (final SuppressionRule rule : getRules()) {
      +  72  224
                   rule.process(dependency);
      +  73  224
               }
      +  74  4
           }
       75  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.exception.AnalysisException.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.exception.AnalysisException.html index d3227fc9f..d603e0ffc 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.exception.AnalysisException.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.exception.AnalysisException.html @@ -103,8 +103,8 @@
            */
       44  
           public AnalysisException(String msg) {
      -  45  2
               super(msg);
      -  46  2
           }
      +  45  1
               super(msg);
      +  46  1
           }
       47  
       
       48   @@ -137,12 +137,12 @@
            */
       63  
           public AnalysisException(String msg, Throwable ex) {
      -  64  8
               super(msg, ex);
      -  65  8
           }
      +  64  4
               super(msg, ex);
      +  65  4
           }
       66  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.exception.ArchiveExtractionException.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.exception.ArchiveExtractionException.html index 0cd43b97f..bb62eeeb1 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.exception.ArchiveExtractionException.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.exception.ArchiveExtractionException.html @@ -143,6 +143,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.central.CentralSearch.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.central.CentralSearch.html index 4880dda23..d22de8f31 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.central.CentralSearch.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.central.CentralSearch.html @@ -133,7 +133,7 @@
            * Used for logging.
       58  
            */
      -  59  2
           private static final Logger LOGGER = LoggerFactory.getLogger(CentralSearch.class);
      +  59  1
           private static final Logger LOGGER = LoggerFactory.getLogger(CentralSearch.class);
       60  
       
       61   @@ -148,18 +148,18 @@
            * end in /select)
       66  
            */
      -  67  10
           public CentralSearch(URL rootURL) {
      -  68  10
               this.rootURL = rootURL;
      -  69  10
               if (null != Settings.getString(Settings.KEYS.PROXY_SERVER)) {
      +  67  5
           public CentralSearch(URL rootURL) {
      +  68  5
               this.rootURL = rootURL;
      +  69  5
               if (null != Settings.getString(Settings.KEYS.PROXY_SERVER)) {
       70  0
                   useProxy = true;
       71  0
                   LOGGER.debug("Using proxy");
       72  
               } else {
      -  73  10
                   useProxy = false;
      -  74  10
                   LOGGER.debug("Not using proxy");
      +  73  5
                   useProxy = false;
      +  74  5
                   LOGGER.debug("Not using proxy");
       75  
               }
      -  76  10
           }
      +  76  5
           }
       77  
       
       78   @@ -180,16 +180,16 @@
            */
       86  
           public List<MavenArtifact> searchSha1(String sha1) throws IOException {
      -  87  10
               if (null == sha1 || !sha1.matches("^[0-9A-Fa-f]{40}$")) {
      -  88  4
                   throw new IllegalArgumentException("Invalid SHA1 format");
      +  87  5
               if (null == sha1 || !sha1.matches("^[0-9A-Fa-f]{40}$")) {
      +  88  2
                   throw new IllegalArgumentException("Invalid SHA1 format");
       89  
               }
       90  
       
      -  91  6
               final URL url = new URL(rootURL + String.format("?q=1:\"%s\"&wt=xml", sha1));
      +  91  3
               final URL url = new URL(rootURL + String.format("?q=1:\"%s\"&wt=xml", sha1));
       92  
       
      -  93  6
               LOGGER.debug("Searching Central url {}", url);
      +  93  3
               LOGGER.debug("Searching Central url {}", url);
       94  
       
       95   @@ -200,62 +200,62 @@
               // 2) Otherwise, don't use the proxy (either the proxy isn't configured,
       98  
               // or proxy is specifically set to false)
      -  99  6
               final HttpURLConnection conn = URLConnectionFactory.createHttpURLConnection(url, useProxy);
      +  99  3
               final HttpURLConnection conn = URLConnectionFactory.createHttpURLConnection(url, useProxy);
       100  
       
      -  101  6
               conn.setDoOutput(true);
      +  101  3
               conn.setDoOutput(true);
       102  
       
       103  
               // JSON would be more elegant, but there's not currently a dependency
       104  
               // on JSON, so don't want to add one just for this
      -  105  6
               conn.addRequestProperty("Accept", "application/xml");
      -  106  6
               conn.connect();
      +  105  3
               conn.addRequestProperty("Accept", "application/xml");
      +  106  3
               conn.connect();
       107  
       
      -  108  6
               if (conn.getResponseCode() == 200) {
      -  109  6
                   boolean missing = false;
      +  108  3
               if (conn.getResponseCode() == 200) {
      +  109  3
                   boolean missing = false;
       110  
                   try {
       111  
                       final DocumentBuilder builder = DocumentBuilderFactory
      -  112  6
                               .newInstance().newDocumentBuilder();
      -  113  6
                       final Document doc = builder.parse(conn.getInputStream());
      -  114  6
                       final XPath xpath = XPathFactory.newInstance().newXPath();
      -  115  6
                       final String numFound = xpath.evaluate("/response/result/@numFound", doc);
      -  116  6
                       if ("0".equals(numFound)) {
      -  117  2
                           missing = true;
      +  112  3
                               .newInstance().newDocumentBuilder();
      +  113  3
                       final Document doc = builder.parse(conn.getInputStream());
      +  114  3
                       final XPath xpath = XPathFactory.newInstance().newXPath();
      +  115  3
                       final String numFound = xpath.evaluate("/response/result/@numFound", doc);
      +  116  3
                       if ("0".equals(numFound)) {
      +  117  1
                           missing = true;
       118  
                       } else {
      -  119  4
                           final List<MavenArtifact> result = new ArrayList<MavenArtifact>();
      -  120  4
                           final NodeList docs = (NodeList) xpath.evaluate("/response/result/doc", doc, XPathConstants.NODESET);
      -  121  10
                           for (int i = 0; i < docs.getLength(); i++) {
      -  122  6
                               final String g = xpath.evaluate("./str[@name='g']", docs.item(i));
      -  123  6
                               LOGGER.trace("GroupId: {}", g);
      -  124  6
                               final String a = xpath.evaluate("./str[@name='a']", docs.item(i));
      -  125  6
                               LOGGER.trace("ArtifactId: {}", a);
      -  126  6
                               final String v = xpath.evaluate("./str[@name='v']", docs.item(i));
      -  127  6
                               NodeList atts = (NodeList) xpath.evaluate("./arr[@name='ec']/str", docs.item(i), XPathConstants.NODESET);
      -  128  6
                               boolean pomAvailable = false;
      -  129  6
                               boolean jarAvailable = false;
      -  130  28
                               for (int x = 0; x < atts.getLength(); x++) {
      -  131  22
                                   final String tmp = xpath.evaluate(".", atts.item(x));
      -  132  22
                                   if (".pom".equals(tmp)) {
      -  133  6
                                       pomAvailable = true;
      -  134  16
                                   } else if (".jar".equals(tmp)) {
      -  135  6
                                       jarAvailable = true;
      +  119  2
                           final List<MavenArtifact> result = new ArrayList<MavenArtifact>();
      +  120  2
                           final NodeList docs = (NodeList) xpath.evaluate("/response/result/doc", doc, XPathConstants.NODESET);
      +  121  5
                           for (int i = 0; i < docs.getLength(); i++) {
      +  122  3
                               final String g = xpath.evaluate("./str[@name='g']", docs.item(i));
      +  123  3
                               LOGGER.trace("GroupId: {}", g);
      +  124  3
                               final String a = xpath.evaluate("./str[@name='a']", docs.item(i));
      +  125  3
                               LOGGER.trace("ArtifactId: {}", a);
      +  126  3
                               final String v = xpath.evaluate("./str[@name='v']", docs.item(i));
      +  127  3
                               NodeList atts = (NodeList) xpath.evaluate("./arr[@name='ec']/str", docs.item(i), XPathConstants.NODESET);
      +  128  3
                               boolean pomAvailable = false;
      +  129  3
                               boolean jarAvailable = false;
      +  130  14
                               for (int x = 0; x < atts.getLength(); x++) {
      +  131  11
                                   final String tmp = xpath.evaluate(".", atts.item(x));
      +  132  11
                                   if (".pom".equals(tmp)) {
      +  133  3
                                       pomAvailable = true;
      +  134  8
                                   } else if (".jar".equals(tmp)) {
      +  135  3
                                       jarAvailable = true;
       136  
                                   }
       137  
                               }
       138  
       
      -  139  6
                               atts = (NodeList) xpath.evaluate("./arr[@name='tags']/str", docs.item(i), XPathConstants.NODESET);
      -  140  6
                               boolean useHTTPS = false;
      -  141  42
                               for (int x = 0; x < atts.getLength(); x++) {
      -  142  36
                                   final String tmp = xpath.evaluate(".", atts.item(x));
      -  143  36
                                   if ("https".equals(tmp)) {
      +  139  3
                               atts = (NodeList) xpath.evaluate("./arr[@name='tags']/str", docs.item(i), XPathConstants.NODESET);
      +  140  3
                               boolean useHTTPS = false;
      +  141  21
                               for (int x = 0; x < atts.getLength(); x++) {
      +  142  18
                                   final String tmp = xpath.evaluate(".", atts.item(x));
      +  143  18
                                   if ("https".equals(tmp)) {
       144  0
                                       useHTTPS = true;
       145  
                                   }
      @@ -263,13 +263,13 @@
                               }
       147  
       
      -  148  6
                               LOGGER.trace("Version: {}", v);
      -  149  6
                               result.add(new MavenArtifact(g, a, v, jarAvailable, pomAvailable, useHTTPS));
      +  148  3
                               LOGGER.trace("Version: {}", v);
      +  149  3
                               result.add(new MavenArtifact(g, a, v, jarAvailable, pomAvailable, useHTTPS));
       150  
                           }
       151  
       
      -  152  4
                           return result;
      +  152  2
                           return result;
       153  
                       }
       154  0
                   } catch (Throwable e) {
      @@ -278,11 +278,11 @@  156  
                       // from well
       157  0
                       throw new IOException(e.getMessage(), e);
      -  158  2
                   }
      +  158  1
                   }
       159  
       
      -  160  2
                   if (missing) {
      -  161  2
                       throw new FileNotFoundException("Artifact not found in Central");
      +  160  1
                   if (missing) {
      +  161  1
                       throw new FileNotFoundException("Artifact not found in Central");
       162  
                   }
       163  0
               } else {
      @@ -300,6 +300,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.composer.ComposerDependency.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.composer.ComposerDependency.html index c2c755b05..7fceaf379 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.composer.ComposerDependency.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.composer.ComposerDependency.html @@ -113,11 +113,11 @@
            * @param version the version
       48  
            */
      -  49  122
           public ComposerDependency(String group, String project, String version) {
      -  50  122
               this.group = group;
      -  51  122
               this.project = project;
      -  52  122
               this.version = version;
      -  53  122
           }
      +  49  61
           public ComposerDependency(String group, String project, String version) {
      +  50  61
               this.group = group;
      +  51  61
               this.project = project;
      +  52  61
               this.version = version;
      +  53  61
           }
       54  
       
       55   @@ -132,7 +132,7 @@
            */
       60  
           public String getGroup() {
      -  61  180
               return group;
      +  61  90
               return group;
       62  
           }
       63   @@ -149,7 +149,7 @@
            */
       69  
           public String getProject() {
      -  70  180
               return project;
      +  70  90
               return project;
       71  
           }
       72   @@ -166,7 +166,7 @@
            */
       78  
           public String getVersion() {
      -  79  60
               return version;
      +  79  30
               return version;
       80  
           }
       81   @@ -175,28 +175,28 @@
           @Override
       83  
           public boolean equals(Object o) {
      -  84  56
               if (this == o) {
      +  84  28
               if (this == o) {
       85  0
                   return true;
       86  
               }
      -  87  56
               if (!(o instanceof ComposerDependency)) {
      +  87  28
               if (!(o instanceof ComposerDependency)) {
       88  0
                   return false;
       89  
               }
       90  
       
      -  91  56
               final ComposerDependency that = (ComposerDependency) o;
      +  91  28
               final ComposerDependency that = (ComposerDependency) o;
       92  
       
      -  93  56
               if (group != null ? !group.equals(that.group) : that.group != null) {
      -  94  34
                   return false;
      +  93  28
               if (group != null ? !group.equals(that.group) : that.group != null) {
      +  94  17
                   return false;
       95  
               }
      -  96  22
               if (project != null ? !project.equals(that.project) : that.project != null) {
      -  97  20
                   return false;
      +  96  11
               if (project != null ? !project.equals(that.project) : that.project != null) {
      +  97  10
                   return false;
       98  
               }
      -  99  2
               return !(version != null ? !version.equals(that.version) : that.version != null);
      +  99  1
               return !(version != null ? !version.equals(that.version) : that.version != null);
       100  
       
       101   @@ -217,6 +217,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.composer.ComposerException.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.composer.ComposerException.html index 7617cab43..422f1fb32 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.composer.ComposerException.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.composer.ComposerException.html @@ -121,12 +121,12 @@
            */
       54  
           public ComposerException(String message, Throwable cause) {
      -  55  6
               super(message, cause);
      -  56  6
           }
      +  55  3
               super(message, cause);
      +  56  3
           }
       57  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.composer.ComposerLockParser.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.composer.ComposerLockParser.html index cff1aeda4..e733613a7 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.composer.ComposerLockParser.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.composer.ComposerLockParser.html @@ -131,7 +131,7 @@
            * The LOGGER
       57  
            */
      -  58  2
           private static final Logger LOGGER = LoggerFactory.getLogger(ComposerLockParser.class);
      +  58  1
           private static final Logger LOGGER = LoggerFactory.getLogger(ComposerLockParser.class);
       59  
       
       60   @@ -144,12 +144,12 @@
            * @param inputStream the InputStream to parse
       64  
            */
      -  65  10
           public ComposerLockParser(InputStream inputStream) {
      -  66  10
               LOGGER.info("Creating a ComposerLockParser");
      -  67  10
               this.inputStream = inputStream;
      -  68  10
               this.jsonReader = Json.createReader(inputStream);
      -  69  10
               this.composerDependencies = new ArrayList<ComposerDependency>();
      -  70  10
           }
      +  65  5
           public ComposerLockParser(InputStream inputStream) {
      +  66  5
               LOGGER.info("Creating a ComposerLockParser");
      +  67  5
               this.inputStream = inputStream;
      +  68  5
               this.jsonReader = Json.createReader(inputStream);
      +  69  5
               this.composerDependencies = new ArrayList<ComposerDependency>();
      +  70  5
           }
       71  
       
       72   @@ -160,30 +160,30 @@
            */
       75  
           public void process() {
      -  76  10
               LOGGER.info("Beginning Composer lock processing");
      +  76  5
               LOGGER.info("Beginning Composer lock processing");
       77  
               try {
      -  78  10
                   final JsonObject composer = jsonReader.readObject();
      -  79  6
                   if (composer.containsKey("packages")) {
      -  80  6
                       LOGGER.debug("Found packages");
      -  81  6
                       final JsonArray packages = composer.getJsonArray("packages");
      -  82  4
                       for (JsonObject pkg : packages.getValuesAs(JsonObject.class)) {
      -  83  120
                           if (pkg.containsKey("name")) {
      -  84  120
                               final String groupName = pkg.getString("name");
      -  85  120
                               if (groupName.indexOf('/') >= 0 && groupName.indexOf('/') <= groupName.length() - 1) {
      -  86  120
                                   if (pkg.containsKey("version")) {
      -  87  120
                                       final String group = groupName.substring(0, groupName.indexOf('/'));
      -  88  120
                                       final String project = groupName.substring(groupName.indexOf('/') + 1);
      -  89  120
                                       String version = pkg.getString("version");
      +  78  5
                   final JsonObject composer = jsonReader.readObject();
      +  79  3
                   if (composer.containsKey("packages")) {
      +  80  3
                       LOGGER.debug("Found packages");
      +  81  3
                       final JsonArray packages = composer.getJsonArray("packages");
      +  82  2
                       for (JsonObject pkg : packages.getValuesAs(JsonObject.class)) {
      +  83  60
                           if (pkg.containsKey("name")) {
      +  84  60
                               final String groupName = pkg.getString("name");
      +  85  60
                               if (groupName.indexOf('/') >= 0 && groupName.indexOf('/') <= groupName.length() - 1) {
      +  86  60
                                   if (pkg.containsKey("version")) {
      +  87  60
                                       final String group = groupName.substring(0, groupName.indexOf('/'));
      +  88  60
                                       final String project = groupName.substring(groupName.indexOf('/') + 1);
      +  89  60
                                       String version = pkg.getString("version");
       90  
                                       // Some version nubmers begin with v - which doesn't end up matching CPE's
      -  91  120
                                       if (version.startsWith("v")) {
      -  92  84
                                           version = version.substring(1);
      +  91  60
                                       if (version.startsWith("v")) {
      +  92  42
                                           version = version.substring(1);
       93  
                                       }
      -  94  120
                                       LOGGER.debug("Got package {}/{}/{}", group, project, version);
      -  95  120
                                       composerDependencies.add(new ComposerDependency(group, project, version));
      -  96  120
                                   } else {
      +  94  60
                                       LOGGER.debug("Got package {}/{}/{}", group, project, version);
      +  95  60
                                       composerDependencies.add(new ComposerDependency(group, project, version));
      +  96  60
                                   } else {
       97  0
                                       LOGGER.debug("Group/package {} does not have a version", groupName);
       98  
                                   }
      @@ -194,19 +194,19 @@
                               }
       102  
                           }
      -  103  120
                       }
      +  103  60
                       }
       104  
                   }
      -  105  2
               } catch (JsonParsingException jsonpe) {
      -  106  2
                   throw new ComposerException("Error parsing stream", jsonpe);
      -  107  2
               } catch (JsonException jsone) {
      -  108  2
                   throw new ComposerException("Error reading stream", jsone);
      +  105  1
               } catch (JsonParsingException jsonpe) {
      +  106  1
                   throw new ComposerException("Error parsing stream", jsonpe);
      +  107  1
               } catch (JsonException jsone) {
      +  108  1
                   throw new ComposerException("Error reading stream", jsone);
       109  0
               } catch (IllegalStateException ise) {
       110  0
                   throw new ComposerException("Illegal state in composer stream", ise);
      -  111  2
               } catch (ClassCastException cce) {
      -  112  2
                   throw new ComposerException("Not exactly composer lock", cce);
      -  113  4
               }
      -  114  4
           }
      +  111  1
               } catch (ClassCastException cce) {
      +  112  1
                   throw new ComposerException("Not exactly composer lock", cce);
      +  113  2
               }
      +  114  2
           }
       115  
       
       116   @@ -221,13 +221,13 @@
            */
       121  
           public List<ComposerDependency> getDependencies() {
      -  122  6
               return composerDependencies;
      +  122  3
               return composerDependencies;
       123  
           }
       124  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cpe.CpeMemoryIndex.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cpe.CpeMemoryIndex.html index 760b9d2c2..37403a392 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cpe.CpeMemoryIndex.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cpe.CpeMemoryIndex.html @@ -12,7 +12,7 @@
       
      - +
      Classes in this File Line Coverage Branch Coverage Complexity
      CpeMemoryIndex
      79%
      79/99
      50%
      12/24
      3.077
      CpeMemoryIndex
      79%
      77/97
      50%
      12/24
      3.25
       
      @@ -98,472 +98,454 @@  40  
       import org.apache.lucene.store.RAMDirectory;
       41   -
       import org.owasp.dependencycheck.data.lucene.FieldAnalyzer;
      -  42  
       import org.owasp.dependencycheck.data.lucene.LuceneUtils;
      -  43   +  42  
       import org.owasp.dependencycheck.data.lucene.SearchFieldAnalyzer;
      -  44   +  43  
       import org.owasp.dependencycheck.data.nvdcve.CveDB;
      -  45   +  44  
       import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
      -  46   +  45  
       import org.owasp.dependencycheck.utils.Pair;
      -  47   +  46  
       import org.slf4j.Logger;
      -  48   +  47  
       import org.slf4j.LoggerFactory;
      +  48   +
       
       49   -
       
      -  50  
       /**
      +  50   +
        * An in memory lucene index that contains the vendor/product combinations from
       51   -
        * An in memory lucene index that contains the vendor/product combinations from the CPE (application) identifiers within the NVD
      +
        * the CPE (application) identifiers within the NVD CVE data.
       52   -
        * CVE data.
      -  53  
        *
      -  54   +  53  
        * @author Jeremy Long
      -  55   +  54  
        */
      -  56   +  55  
       public final class CpeMemoryIndex {
      +  56   +
       
       57   -
       
      +
           /**
       58   -
           /**
      -  59  
            * The logger.
      -  60   +  59  
            */
      -  61  2
           private static final Logger LOGGER = LoggerFactory.getLogger(CpeMemoryIndex.class);
      +  60  1
           private static final Logger LOGGER = LoggerFactory.getLogger(CpeMemoryIndex.class);
      +  61   +
           /**
       62   -
           /**
      -  63  
            * singleton instance.
      -  64   +  63  
            */
      -  65  2
           private static final CpeMemoryIndex INSTANCE = new CpeMemoryIndex();
      +  64  1
           private static final CpeMemoryIndex INSTANCE = new CpeMemoryIndex();
      +  65   +
       
       66   -
       
      +
           /**
       67   -
           /**
      -  68  
            * private constructor for singleton.
      -  69   +  68  
            */
      -  70  2
           private CpeMemoryIndex() {
      -  71  2
           }
      +  69  1
           private CpeMemoryIndex() {
      +  70  1
           }
      +  71   +
       
       72   -
       
      +
           /**
       73   -
           /**
      -  74  
            * Gets the singleton instance of the CpeMemoryIndex.
      +  74   +
            *
       75   -
            *
      -  76  
            * @return the instance of the CpeMemoryIndex
      +  76   +
            */
       77   -
            */
      -  78  
           public static CpeMemoryIndex getInstance() {
      -  79  4
               return INSTANCE;
      +  78  2
               return INSTANCE;
      +  79   +
           }
       80   -
           }
      +
           /**
       81   -
           /**
      -  82  
            * The in memory Lucene index.
      +  82   +
            */
       83   -
            */
      -  84  
           private RAMDirectory index;
      +  84   +
           /**
       85   -
           /**
      -  86  
            * The Lucene IndexReader.
      +  86   +
            */
       87   -
            */
      -  88  
           private IndexReader indexReader;
      +  88   +
           /**
       89   -
           /**
      -  90  
            * The Lucene IndexSearcher.
      +  90   +
            */
       91   -
            */
      -  92  
           private IndexSearcher indexSearcher;
      +  92   +
           /**
       93   -
           /**
      -  94  
            * The Lucene Analyzer used for Searching.
      +  94   +
            */
       95   -
            */
      -  96  
           private Analyzer searchingAnalyzer;
      +  96   +
           /**
       97   -
           /**
      -  98  
            * The Lucene QueryParser used for Searching.
      +  98   +
            */
       99   -
            */
      -  100  
           private QueryParser queryParser;
      +  100   +
           /**
       101   -
           /**
      -  102  
            * The search field analyzer for the product field.
      +  102   +
            */
       103   -
            */
      +
           private SearchFieldAnalyzer productFieldAnalyzer;
       104   -
           private SearchFieldAnalyzer productSearchFieldAnalyzer;
      +
           /**
       105   -
           /**
      -  106  
            * The search field analyzer for the vendor field.
      +  106   +
            */
       107   -
            */
      +
           private SearchFieldAnalyzer vendorFieldAnalyzer;
       108   -
           private SearchFieldAnalyzer vendorSearchFieldAnalyzer;
      +
       
       109   -
       
      +
           /**
       110   -
           /**
      -  111  
            * Creates and loads data into an in memory index.
      +  111   +
            *
       112   -
            *
      -  113  
            * @param cve the data source to retrieve the cpe data
      -  114   +  113  
            * @throws IndexException thrown if there is an error creating the index
      +  114   +
            */
       115   -
            */
      -  116  
           public void open(CveDB cve) throws IndexException {
      -  117  4
               synchronized (INSTANCE) {
      -  118  4
                   if (!openState) {
      -  119  4
                       index = new RAMDirectory();
      -  120  4
                       buildIndex(cve);
      -  121   +  116  2
               synchronized (INSTANCE) {
      +  117  2
                   if (!openState) {
      +  118  2
                       index = new RAMDirectory();
      +  119  2
                       buildIndex(cve);
      +  120  
                       try {
      -  122  4
                           indexReader = DirectoryReader.open(index);
      -  123  0
                       } catch (IOException ex) {
      -  124  0
                           throw new IndexException(ex);
      -  125  4
                       }
      -  126  4
                       indexSearcher = new IndexSearcher(indexReader);
      -  127  4
                       searchingAnalyzer = createSearchingAnalyzer();
      -  128  4
                       queryParser = new QueryParser(LuceneUtils.CURRENT_VERSION, Fields.DOCUMENT_KEY, searchingAnalyzer);
      -  129  4
                       openState = true;
      -  130   +  121  2
                           indexReader = DirectoryReader.open(index);
      +  122  0
                       } catch (IOException ex) {
      +  123  0
                           throw new IndexException(ex);
      +  124  2
                       }
      +  125  2
                       indexSearcher = new IndexSearcher(indexReader);
      +  126  2
                       searchingAnalyzer = createSearchingAnalyzer();
      +  127  2
                       queryParser = new QueryParser(LuceneUtils.CURRENT_VERSION, Fields.DOCUMENT_KEY, searchingAnalyzer);
      +  128  2
                       openState = true;
      +  129  
                   }
      -  131  4
               }
      -  132  4
           }
      +  130  2
               }
      +  131  2
           }
      +  132   +
           /**
       133   -
           /**
      -  134  
            * A flag indicating whether or not the index is open.
      -  135   +  134  
            */
      -  136  2
           private boolean openState = false;
      +  135  1
           private boolean openState = false;
      +  136   +
       
       137   -
       
      +
           /**
       138   -
           /**
      -  139  
            * returns whether or not the index is open.
      +  139   +
            *
       140   -
            *
      -  141  
            * @return whether or not the index is open
      +  141   +
            */
       142   -
            */
      -  143  
           public boolean isOpen() {
      -  144  0
               return openState;
      +  143  0
               return openState;
      +  144   +
           }
       145   -
           }
      +
       
       146   -
       
      +
           /**
       147   -
           /**
      -  148   -
            * Creates the indexing analyzer for the CPE Index.
      -  149   -
            *
      -  150   -
            * @return the CPE Analyzer.
      -  151   -
            */
      -  152   -
           private Analyzer createIndexingAnalyzer() {
      -  153  4
               final Map<String, Analyzer> fieldAnalyzers = new HashMap<String, Analyzer>();
      -  154  4
               fieldAnalyzers.put(Fields.DOCUMENT_KEY, new KeywordAnalyzer());
      -  155  4
               return new PerFieldAnalyzerWrapper(new FieldAnalyzer(LuceneUtils.CURRENT_VERSION), fieldAnalyzers);
      -  156   -
           }
      -  157   -
       
      -  158   -
           /**
      -  159  
            * Creates an Analyzer for searching the CPE Index.
      -  160   +  148  
            *
      -  161   +  149  
            * @return the CPE Analyzer.
      -  162   +  150  
            */
      -  163   +  151  
           private Analyzer createSearchingAnalyzer() {
      -  164  4
               final Map<String, Analyzer> fieldAnalyzers = new HashMap<String, Analyzer>();
      -  165  4
               fieldAnalyzers.put(Fields.DOCUMENT_KEY, new KeywordAnalyzer());
      -  166  4
               productSearchFieldAnalyzer = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION);
      -  167  4
               vendorSearchFieldAnalyzer = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION);
      -  168  4
               fieldAnalyzers.put(Fields.PRODUCT, productSearchFieldAnalyzer);
      -  169  4
               fieldAnalyzers.put(Fields.VENDOR, vendorSearchFieldAnalyzer);
      -  170   +  152  4
               final Map<String, Analyzer> fieldAnalyzers = new HashMap<String, Analyzer>();
      +  153  4
               fieldAnalyzers.put(Fields.DOCUMENT_KEY, new KeywordAnalyzer());
      +  154  4
               productFieldAnalyzer = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION);
      +  155  4
               vendorFieldAnalyzer = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION);
      +  156  4
               fieldAnalyzers.put(Fields.PRODUCT, productFieldAnalyzer);
      +  157  4
               fieldAnalyzers.put(Fields.VENDOR, vendorFieldAnalyzer);
      +  158  
       
      -  171  4
               return new PerFieldAnalyzerWrapper(new FieldAnalyzer(LuceneUtils.CURRENT_VERSION), fieldAnalyzers);
      -  172   +  159  4
               return new PerFieldAnalyzerWrapper(new KeywordAnalyzer(), fieldAnalyzers);
      +  160  
           }
      -  173   +  161  
       
      -  174   +  162  
           /**
      -  175   +  163  
            * Closes the CPE Index.
      -  176   +  164  
            */
      -  177   +  165  
           public void close() {
      -  178  4
               if (searchingAnalyzer != null) {
      -  179  4
                   searchingAnalyzer.close();
      -  180  4
                   searchingAnalyzer = null;
      -  181   +  166  2
               if (searchingAnalyzer != null) {
      +  167  2
                   searchingAnalyzer.close();
      +  168  2
                   searchingAnalyzer = null;
      +  169  
               }
      -  182  4
               if (indexReader != null) {
      +  170  2
               if (indexReader != null) {
      +  171   +
                   try {
      +  172  2
                       indexReader.close();
      +  173  0
                   } catch (IOException ex) {
      +  174  0
                       LOGGER.trace("", ex);
      +  175  2
                   }
      +  176  2
                   indexReader = null;
      +  177   +
               }
      +  178  2
               queryParser = null;
      +  179  2
               indexSearcher = null;
      +  180  2
               if (index != null) {
      +  181  2
                   index.close();
      +  182  2
                   index = null;
       183   -
                   try {
      -  184  4
                       indexReader.close();
      -  185  0
                   } catch (IOException ex) {
      -  186  0
                       LOGGER.trace("", ex);
      -  187  4
                   }
      -  188  4
                   indexReader = null;
      -  189  
               }
      -  190  4
               queryParser = null;
      -  191  4
               indexSearcher = null;
      -  192  4
               if (index != null) {
      -  193  4
                   index.close();
      -  194  4
                   index = null;
      -  195   -
               }
      -  196  4
               openState = false;
      -  197  4
           }
      -  198   +  184  2
               openState = false;
      +  185  2
           }
      +  186  
       
      -  199   +  187  
           /**
      -  200   +  188  
            * Builds the CPE Lucene Index based off of the data within the CveDB.
      -  201   +  189  
            *
      -  202   +  190  
            * @param cve the data base containing the CPE data
      -  203   +  191  
            * @throws IndexException thrown if there is an issue creating the index
      -  204   +  192  
            */
      -  205   +  193  
           private void buildIndex(CveDB cve) throws IndexException {
      -  206  4
               Analyzer analyzer = null;
      -  207  4
               IndexWriter indexWriter = null;
      -  208   +  194  2
               Analyzer analyzer = null;
      +  195  2
               IndexWriter indexWriter = null;
      +  196  
               try {
      -  209  4
                   analyzer = createIndexingAnalyzer();
      -  210  4
                   final IndexWriterConfig conf = new IndexWriterConfig(LuceneUtils.CURRENT_VERSION, analyzer);
      -  211  4
                   indexWriter = new IndexWriter(index, conf);
      -  212   +  197  2
                   analyzer = createSearchingAnalyzer();
      +  198  2
                   final IndexWriterConfig conf = new IndexWriterConfig(LuceneUtils.CURRENT_VERSION, analyzer);
      +  199  2
                   indexWriter = new IndexWriter(index, conf);
      +  200  
                   try {
      -  213   +  201  
                       // Tip: reuse the Document and Fields for performance...
      -  214   +  202  
                       // See "Re-use Document and Field instances" from
      -  215   +  203  
                       // http://wiki.apache.org/lucene-java/ImproveIndexingSpeed
      -  216  4
                       final Document doc = new Document();
      -  217  4
                       final Field v = new TextField(Fields.VENDOR, Fields.VENDOR, Field.Store.YES);
      -  218  4
                       final Field p = new TextField(Fields.PRODUCT, Fields.PRODUCT, Field.Store.YES);
      -  219  4
                       doc.add(v);
      -  220  4
                       doc.add(p);
      -  221   +  204  2
                       final Document doc = new Document();
      +  205  2
                       final Field v = new TextField(Fields.VENDOR, Fields.VENDOR, Field.Store.YES);
      +  206  2
                       final Field p = new TextField(Fields.PRODUCT, Fields.PRODUCT, Field.Store.YES);
      +  207  2
                       doc.add(v);
      +  208  2
                       doc.add(p);
      +  209  
       
      -  222  4
                       final Set<Pair<String, String>> data = cve.getVendorProductList();
      -  223  4
                       for (Pair<String, String> pair : data) {
      -  224  103668
                           v.setStringValue(pair.getLeft());
      -  225  103668
                           p.setStringValue(pair.getRight());
      -  226  103668
                           indexWriter.addDocument(doc);
      -  227  103668
                       }
      -  228  0
                   } catch (DatabaseException ex) {
      -  229  0
                       LOGGER.debug("", ex);
      -  230  0
                       throw new IndexException("Error reading CPE data", ex);
      -  231  4
                   }
      -  232  0
               } catch (CorruptIndexException ex) {
      -  233  0
                   throw new IndexException("Unable to close an in-memory index", ex);
      -  234  0
               } catch (IOException ex) {
      -  235  0
                   throw new IndexException("Unable to close an in-memory index", ex);
      -  236   +  210  2
                       final Set<Pair<String, String>> data = cve.getVendorProductList();
      +  211  2
                       for (Pair<String, String> pair : data) {
      +  212  52138
                           v.setStringValue(pair.getLeft());
      +  213  52138
                           p.setStringValue(pair.getRight());
      +  214  52138
                           indexWriter.addDocument(doc);
      +  215  52138
                           resetFieldAnalyzer();
      +  216  52138
                       }
      +  217  0
                   } catch (DatabaseException ex) {
      +  218  0
                       LOGGER.debug("", ex);
      +  219  0
                       throw new IndexException("Error reading CPE data", ex);
      +  220  2
                   }
      +  221  0
               } catch (CorruptIndexException ex) {
      +  222  0
                   throw new IndexException("Unable to close an in-memory index", ex);
      +  223  0
               } catch (IOException ex) {
      +  224  0
                   throw new IndexException("Unable to close an in-memory index", ex);
      +  225  
               } finally {
      -  237  4
                   if (indexWriter != null) {
      -  238   +  226  2
                   if (indexWriter != null) {
      +  227  
                       try {
      -  239   +  228  
                           try {
      -  240  4
                               indexWriter.commit();
      -  241   +  229  2
                               indexWriter.commit();
      +  230  
                           } finally {
      -  242  4
                               indexWriter.close(true);
      -  243  4
                           }
      -  244  0
                       } catch (CorruptIndexException ex) {
      -  245  0
                           throw new IndexException("Unable to close an in-memory index", ex);
      -  246  0
                       } catch (IOException ex) {
      -  247  0
                           throw new IndexException("Unable to close an in-memory index", ex);
      -  248  4
                       }
      -  249  4
                       if (analyzer != null) {
      -  250  4
                           analyzer.close();
      -  251   +  231  2
                               indexWriter.close(true);
      +  232  2
                           }
      +  233  0
                       } catch (CorruptIndexException ex) {
      +  234  0
                           throw new IndexException("Unable to close an in-memory index", ex);
      +  235  0
                       } catch (IOException ex) {
      +  236  0
                           throw new IndexException("Unable to close an in-memory index", ex);
      +  237  2
                       }
      +  238  2
                       if (analyzer != null) {
      +  239  2
                           analyzer.close();
      +  240  
                       }
      -  252   +  241  
                   }
      -  253   +  242  
               }
      -  254  4
           }
      -  255   +  243  2
           }
      +  244  
       
      +  245   +
           /**
      +  246   +
            * Resets the product and vendor field analyzers.
      +  247   +
            */
      +  248   +
           private void resetFieldAnalyzer() {
      +  249  52149
               if (productFieldAnalyzer != null) {
      +  250  52149
                   productFieldAnalyzer.clear();
      +  251   +
               }
      +  252  52149
               if (vendorFieldAnalyzer != null) {
      +  253  52149
                   vendorFieldAnalyzer.clear();
      +  254   +
               }
      +  255  52149
           }
       256   -
           /**
      +
       
       257   -
            * Resets the searching analyzers
      +
           /**
       258   -
            */
      -  259   -
           private void resetSearchingAnalyzer() {
      -  260  22
               if (productSearchFieldAnalyzer != null) {
      -  261  22
                   productSearchFieldAnalyzer.clear();
      -  262   -
               }
      -  263  22
               if (vendorSearchFieldAnalyzer != null) {
      -  264  22
                   vendorSearchFieldAnalyzer.clear();
      -  265   -
               }
      -  266  22
           }
      -  267   -
       
      -  268   -
           /**
      -  269  
            * Searches the index using the given search string.
      -  270   +  259  
            *
      -  271   +  260  
            * @param searchString the query text
      -  272   +  261  
            * @param maxQueryResults the maximum number of documents to return
      -  273   +  262  
            * @return the TopDocs found by the search
      -  274   +  263  
            * @throws ParseException thrown when the searchString is invalid
      -  275   -
            * @throws IOException is thrown if there is an issue with the underlying Index
      -  276   +  264   +
            * @throws IOException is thrown if there is an issue with the underlying
      +  265   +
            * Index
      +  266  
            */
      -  277   +  267  
           public TopDocs search(String searchString, int maxQueryResults) throws ParseException, IOException {
      -  278  22
               if (searchString == null || searchString.trim().isEmpty()) {
      -  279  0
                   throw new ParseException("Query is null or empty");
      -  280   +  268  11
               if (searchString == null || searchString.trim().isEmpty()) {
      +  269  0
                   throw new ParseException("Query is null or empty");
      +  270  
               }
      -  281  22
               LOGGER.debug(searchString);
      -  282  22
               final Query query = queryParser.parse(searchString);
      -  283  22
               return search(query, maxQueryResults);
      -  284   +  271  11
               LOGGER.debug(searchString);
      +  272  11
               final Query query = queryParser.parse(searchString);
      +  273  11
               return search(query, maxQueryResults);
      +  274  
           }
      -  285   +  275  
       
      -  286   +  276  
           /**
      -  287   +  277  
            * Searches the index using the given query.
      -  288   +  278  
            *
      -  289   +  279  
            * @param query the query used to search the index
      -  290   +  280  
            * @param maxQueryResults the max number of results to return
      -  291   +  281  
            * @return the TopDocs found be the query
      -  292   +  282  
            * @throws CorruptIndexException thrown if the Index is corrupt
      -  293   +  283  
            * @throws IOException thrown if there is an IOException
      -  294   +  284  
            */
      -  295   +  285  
           public TopDocs search(Query query, int maxQueryResults) throws CorruptIndexException, IOException {
      -  296  22
               resetSearchingAnalyzer();
      -  297  22
               return indexSearcher.search(query, maxQueryResults);
      -  298   +  286  11
               resetFieldAnalyzer();
      +  287  11
               return indexSearcher.search(query, maxQueryResults);
      +  288  
           }
      -  299   +  289  
       
      -  300   +  290  
           /**
      -  301   +  291  
            * Retrieves a document from the Index.
      -  302   +  292  
            *
      -  303   +  293  
            * @param documentId the id of the document to retrieve
      -  304   +  294  
            * @return the Document
      -  305   +  295  
            * @throws IOException thrown if there is an IOException
      -  306   +  296  
            */
      -  307   +  297  
           public Document getDocument(int documentId) throws IOException {
      -  308  90
               return indexSearcher.doc(documentId);
      -  309   +  298  46
               return indexSearcher.doc(documentId);
      +  299  
           }
      -  310   +  300  
       
      -  311   +  301  
           /**
      -  312   +  302  
            * Returns the number of CPE entries stored in the index.
      -  313   +  303  
            *
      -  314   +  304  
            * @return the number of CPE entries stored in the index
      -  315   +  305  
            */
      -  316   +  306  
           public int numDocs() {
      -  317  0
               if (indexReader == null) {
      -  318  0
                   return -1;
      -  319   +  307  0
               if (indexReader == null) {
      +  308  0
                   return -1;
      +  309  
               }
      -  320  0
               return indexReader.numDocs();
      -  321   +  310  0
               return indexReader.numDocs();
      +  311  
           }
      -  322   +  312  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cpe.Fields.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cpe.Fields.html index b9132d16a..607f8dc12 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cpe.Fields.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cpe.Fields.html @@ -107,6 +107,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cpe.IndexEntry.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cpe.IndexEntry.html index 41297f58d..5b4d55430 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cpe.IndexEntry.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cpe.IndexEntry.html @@ -73,7 +73,7 @@
        * @author Jeremy Long
       28  
        */
      -  29  3274
       public class IndexEntry implements Serializable {
      +  29  1638
       public class IndexEntry implements Serializable {
       30  
       
       31   @@ -151,7 +151,7 @@
            */
       70  
           public String getVendor() {
      -  71  62
               return vendor;
      +  71  31
               return vendor;
       72  
           }
       73   @@ -168,8 +168,8 @@
            */
       79  
           public void setVendor(String vendor) {
      -  80  3278
               this.vendor = vendor;
      -  81  3278
           }
      +  80  1640
               this.vendor = vendor;
      +  81  1640
           }
       82  
           /**
       83   @@ -192,7 +192,7 @@
            */
       92  
           public String getProduct() {
      -  93  132
               return product;
      +  93  67
               return product;
       94  
           }
       95   @@ -209,8 +209,8 @@
            */
       101  
           public void setProduct(String product) {
      -  102  3276
               this.product = product;
      -  103  3276
           }
      +  102  1639
               this.product = product;
      +  103  1639
           }
       104  
           /**
       105   @@ -250,8 +250,8 @@
            */
       123  
           public void setSearchScore(float searchScore) {
      -  124  90
               this.searchScore = searchScore;
      -  125  90
           }
      +  124  46
               this.searchScore = searchScore;
      +  125  46
           }
       126  
       
       127   @@ -290,19 +290,19 @@
            */
       144  
           public void parseName(String cpeName) throws UnsupportedEncodingException {
      -  145  2
               if (cpeName != null && cpeName.length() > 7) {
      -  146  2
                   final String[] data = cpeName.substring(7).split(":");
      -  147  2
                   if (data.length >= 1) {
      -  148  2
                       vendor = URLDecoder.decode(data[0].replace("+", "%2B"), "UTF-8");
      -  149  2
                       if (data.length >= 2) {
      -  150  2
                           product = URLDecoder.decode(data[1].replace("+", "%2B"), "UTF-8");
      +  145  1
               if (cpeName != null && cpeName.length() > 7) {
      +  146  1
                   final String[] data = cpeName.substring(7).split(":");
      +  147  1
                   if (data.length >= 1) {
      +  148  1
                       vendor = URLDecoder.decode(data[0].replace("+", "%2B"), "UTF-8");
      +  149  1
                       if (data.length >= 2) {
      +  150  1
                           product = URLDecoder.decode(data[1].replace("+", "%2B"), "UTF-8");
       151  
                       }
       152  
                   }
       153  
               }
      -  154  2
           }
      +  154  1
           }
       155  
       
       156   @@ -320,21 +320,21 @@
           @Override
       164  
           public boolean equals(Object obj) {
      -  165  708
               if (obj == null) {
      +  165  381
               if (obj == null) {
       166  0
                   return false;
       167  
               }
      -  168  708
               if (getClass() != obj.getClass()) {
      +  168  381
               if (getClass() != obj.getClass()) {
       169  0
                   return false;
       170  
               }
      -  171  708
               final IndexEntry other = (IndexEntry) obj;
      -  172  708
               if ((this.vendor == null) ? (other.vendor != null) : !this.vendor.equals(other.vendor)) {
      -  173  690
                   return false;
      +  171  381
               final IndexEntry other = (IndexEntry) obj;
      +  172  381
               if ((this.vendor == null) ? (other.vendor != null) : !this.vendor.equals(other.vendor)) {
      +  173  376
                   return false;
       174  
               }
      -  175  18
               if ((this.product == null) ? (other.product != null) : !this.product.equals(other.product)) {
      -  176  18
                   return false;
      +  175  5
               if ((this.product == null) ? (other.product != null) : !this.product.equals(other.product)) {
      +  176  5
                   return false;
       177  
               }
       178  0
               return true;
      @@ -363,6 +363,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cpe.IndexException.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cpe.IndexException.html index fde2206ef..5f2a95069 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cpe.IndexException.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cpe.IndexException.html @@ -143,6 +143,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cwe.CweDB.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cwe.CweDB.html index 080a9be61..6ed238a03 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cwe.CweDB.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cwe.CweDB.html @@ -91,7 +91,7 @@
            * The Logger.
       37  
            */
      -  38  2
           private static final Logger LOGGER = LoggerFactory.getLogger(CweDB.class);
      +  38  1
           private static final Logger LOGGER = LoggerFactory.getLogger(CweDB.class);
       39  
       
       40   @@ -110,7 +110,7 @@
            * A HashMap of the CWE data.
       48  
            */
      -  49  2
           private static final Map<String, String> CWE = loadData();
      +  49  1
           private static final Map<String, String> CWE = loadData();
       50  
       
       51   @@ -125,16 +125,16 @@
            */
       56  
           private static Map<String, String> loadData() {
      -  57  2
               ObjectInputStream oin = null;
      +  57  1
               ObjectInputStream oin = null;
       58  
               try {
      -  59  2
                   final String filePath = "data/cwe.hashmap.serialized";
      -  60  2
                   final InputStream input = CweDB.class.getClassLoader().getResourceAsStream(filePath);
      -  61  2
                   oin = new ObjectInputStream(input);
      +  59  1
                   final String filePath = "data/cwe.hashmap.serialized";
      +  60  1
                   final InputStream input = CweDB.class.getClassLoader().getResourceAsStream(filePath);
      +  61  1
                   oin = new ObjectInputStream(input);
       62  
                   @SuppressWarnings("unchecked")
      -  63  2
                   final Map<String, String> ret = (HashMap<String, String>) oin.readObject();
      -  64  4
                   return ret;
      +  63  1
                   final Map<String, String> ret = (HashMap<String, String>) oin.readObject();
      +  64  2
                   return ret;
       65  0
               } catch (ClassNotFoundException ex) {
       66  0
                   LOGGER.warn("Unable to load CWE data. This should not be an issue.");
       67  0
                   LOGGER.debug("", ex);
      @@ -143,13 +143,13 @@  70  0
                   LOGGER.debug("", ex);
       71  
               } finally {
      -  72  2
                   if (oin != null) {
      +  72  1
                   if (oin != null) {
       73  
                       try {
      -  74  2
                           oin.close();
      +  74  1
                           oin.close();
       75  0
                       } catch (IOException ex) {
       76  0
                           LOGGER.trace("", ex);
      -  77  2
                       }
      +  77  1
                       }
       78  
                   }
       79   @@ -175,8 +175,8 @@
            */
       90  
           public static String getCweName(String cweId) {
      -  91  18
               if (cweId != null) {
      -  92  18
                   return CWE.get(cweId);
      +  91  9
               if (cweId != null) {
      +  92  9
                   return CWE.get(cweId);
       93  
               }
       94  0
               return null;
      @@ -186,6 +186,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cwe.CweHandler.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cwe.CweHandler.html index 0bb5a1bca..510905b81 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cwe.CweHandler.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.cwe.CweHandler.html @@ -121,6 +121,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.AbstractTokenizingFilter.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.AbstractTokenizingFilter.html index 14ddafc54..be660b4de 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.AbstractTokenizingFilter.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.AbstractTokenizingFilter.html @@ -85,7 +85,7 @@
            * The char term attribute.
       34  
            */
      -  35  25
           private final CharTermAttribute termAtt = addAttribute(CharTermAttribute.class);
      +  35  16
           private final CharTermAttribute termAtt = addAttribute(CharTermAttribute.class);
       36  
       
       37   @@ -100,7 +100,7 @@
            */
       42  
           protected CharTermAttribute getTermAtt() {
      -  43  59324
               return termAtt;
      +  43  603638
               return termAtt;
       44  
           }
       45   @@ -125,7 +125,7 @@
            */
       55  
           protected LinkedList<String> getTokens() {
      -  56  59312
               return tokens;
      +  56  603637
               return tokens;
       57  
           }
       58   @@ -142,9 +142,9 @@
            */
       64  
           public AbstractTokenizingFilter(TokenStream stream) {
      -  65  25
               super(stream);
      -  66  25
               tokens = new LinkedList<String>();
      -  67  25
           }
      +  65  16
               super(stream);
      +  66  16
               tokens = new LinkedList<String>();
      +  67  16
           }
       68  
       
       69   @@ -159,20 +159,20 @@
            */
       74  
           protected boolean addTerm() {
      -  75  59187
               final boolean termAdded = !tokens.isEmpty();
      -  76  59187
               if (termAdded) {
      -  77  39863
                   final String term = tokens.pop();
      -  78  39861
                   clearAttributes();
      -  79  39873
                   termAtt.append(term);
      +  75  603545
               final boolean termAdded = !tokens.isEmpty();
      +  76  603548
               if (termAdded) {
      +  77  210017
                   final String term = tokens.pop();
      +  78  210017
                   clearAttributes();
      +  79  210014
                   termAtt.append(term);
       80  
               }
      -  81  59182
               return termAdded;
      +  81  603548
               return termAdded;
       82  
           }
       83  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.AlphaNumericTokenizer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.AlphaNumericTokenizer.html index b93fde078..1c11ac532 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.AlphaNumericTokenizer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.AlphaNumericTokenizer.html @@ -91,8 +91,8 @@
            */
       37  
           public AlphaNumericTokenizer(Version matchVersion, Reader in) {
      -  38  22
               super(matchVersion, in);
      -  39  22
           }
      +  38  11
               super(matchVersion, in);
      +  39  11
           }
       40  
       
       41   @@ -131,13 +131,13 @@
           @Override
       59  
           protected boolean isTokenChar(int c) {
      -  60  2489074
               return Character.isLetter(c) || Character.isDigit(c);
      +  60  1253271
               return Character.isLetter(c) || Character.isDigit(c);
       61  
           }
       62  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.DependencySimilarity.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.DependencySimilarity.html index 03a7b1137..70ba8dd6b 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.DependencySimilarity.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.DependencySimilarity.html @@ -111,6 +111,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.FieldAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.FieldAnalyzer.html index 373c8b55d..ed4ee5474 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.FieldAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.FieldAnalyzer.html @@ -80,96 +80,104 @@  31  
        * <p>
       32   -
        * A Lucene Analyzer that utilizes the WhitespaceTokenizer, WordDelimiterFilter, LowerCaseFilter, and StopFilter. The intended
      +
        * A Lucene Analyzer that utilizes the WhitespaceTokenizer, WordDelimiterFilter,
       33   -
        * purpose of this Analyzer is to index the CPE fields vendor and product.</p>
      +
        * LowerCaseFilter, and StopFilter. The intended purpose of this Analyzer is to
       34   -
        *
      +
        * index the CPE fields vendor and product.</p>
       35   -
        * @author Jeremy Long
      +
        *
       36   -
        */
      +
        * @author Jeremy Long
       37   -
       public class FieldAnalyzer extends Analyzer {
      +
        * @deprecated the field analyzer should not be used, instead use the
       38   -
       
      +
        * SearchFieldAnalyzer so that the token analyzing filter is used.
       39   -
           /**
      +
        */
       40   -
            * The Lucene Version used.
      +
       @Deprecated
       41   -
            */
      +
       public class FieldAnalyzer extends Analyzer {
       42   -
           private final Version version;
      +
       
       43   -
       
      +
           /**
       44   -
           /**
      +
            * The Lucene Version used.
       45   -
            * Creates a new FieldAnalyzer.
      +
            */
       46   -
            *
      +
           private final Version version;
       47   -
            * @param version the Lucene version
      +
       
       48   -
            */
      -  49  10
           public FieldAnalyzer(Version version) {
      -  50  10
               this.version = version;
      -  51  10
           }
      -  52   -
       
      -  53  
           /**
      -  54   -
            * Creates the TokenStreamComponents
      -  55   +  49   +
            * Creates a new FieldAnalyzer.
      +  50  
            *
      -  56   -
            * @param fieldName the field name being analyzed
      -  57   -
            * @param reader the reader containing the input
      -  58   -
            * @return the TokenStreamComponents
      -  59   +  51   +
            * @param version the Lucene version
      +  52  
            */
      +  53  1
           public FieldAnalyzer(Version version) {
      +  54  1
               this.version = version;
      +  55  1
           }
      +  56   +
       
      +  57   +
           /**
      +  58   +
            * Creates the TokenStreamComponents
      +  59   +
            *
       60   -
           @Override
      +
            * @param fieldName the field name being analyzed
       61   -
           protected TokenStreamComponents createComponents(String fieldName, Reader reader) {
      -  62  10
               final Tokenizer source = new AlphaNumericTokenizer(version, reader);
      +
            * @param reader the reader containing the input
      +  62   +
            * @return the TokenStreamComponents
       63   -
       
      -  64  10
               TokenStream stream = source;
      +
            */
      +  64   +
           @Override
       65   -
       
      -  66  10
               stream = new WordDelimiterFilter(stream,
      +
           protected TokenStreamComponents createComponents(String fieldName, Reader reader) {
      +  66  1
               final Tokenizer source = new AlphaNumericTokenizer(version, reader);
       67   -
                       WordDelimiterFilter.CATENATE_WORDS
      -  68   -
                       | WordDelimiterFilter.GENERATE_WORD_PARTS
      +
       
      +  68  1
               TokenStream stream = source;
       69   -
                       | WordDelimiterFilter.GENERATE_NUMBER_PARTS
      -  70   -
                       | WordDelimiterFilter.PRESERVE_ORIGINAL
      +
       
      +  70  1
               stream = new WordDelimiterFilter(stream,
       71   -
                       | WordDelimiterFilter.SPLIT_ON_CASE_CHANGE
      +
                       WordDelimiterFilter.CATENATE_WORDS
       72   -
                       | WordDelimiterFilter.SPLIT_ON_NUMERICS
      +
                       | WordDelimiterFilter.GENERATE_WORD_PARTS
       73   -
                       | WordDelimiterFilter.STEM_ENGLISH_POSSESSIVE, null);
      +
                       | WordDelimiterFilter.GENERATE_NUMBER_PARTS
       74   -
       
      -  75  10
               stream = new LowerCaseFilter(version, stream);
      -  76  10
               stream = new StopFilter(version, stream, StopAnalyzer.ENGLISH_STOP_WORDS_SET);
      +
                       | WordDelimiterFilter.PRESERVE_ORIGINAL
      +  75   +
                       | WordDelimiterFilter.SPLIT_ON_CASE_CHANGE
      +  76   +
                       | WordDelimiterFilter.SPLIT_ON_NUMERICS
       77   +
                       | WordDelimiterFilter.STEM_ENGLISH_POSSESSIVE, null);
      +  78  
       
      -  78  10
               return new TokenStreamComponents(source, stream);
      -  79   +  79  1
               stream = new LowerCaseFilter(version, stream);
      +  80  1
               stream = new StopFilter(version, stream, StopAnalyzer.ENGLISH_STOP_WORDS_SET);
      +  81   +
       
      +  82  1
               return new TokenStreamComponents(source, stream);
      +  83  
           }
      -  80   +  84  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.LuceneUtils.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.LuceneUtils.html index 89095ee8f..ecbfecb50 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.LuceneUtils.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.LuceneUtils.html @@ -85,7 +85,7 @@
            * base.
       34  
            */
      -  35  2
           public static final Version CURRENT_VERSION = Version.LUCENE_47;
      +  35  1
           public static final Version CURRENT_VERSION = Version.LUCENE_47;
       36  
       
       37   @@ -124,15 +124,15 @@
                   final CharSequence text) {
       55  
       
      -  56  232
               if (text == null || buf == null) {
      -  57  2
                   return;
      +  56  113
               if (text == null || buf == null) {
      +  57  1
                   return;
       58  
               }
       59  
       
      -  60  2950
               for (int i = 0; i < text.length(); i++) {
      -  61  2720
                   final char c = text.charAt(i);
      -  62  2720
                   switch (c) {
      +  60  1445
               for (int i = 0; i < text.length(); i++) {
      +  61  1333
                   final char c = text.charAt(i);
      +  62  1333
                   switch (c) {
       63  
                       case '+':
       64   @@ -171,17 +171,17 @@
                       case '/':
       81  
                       case '\\': //it is supposed to fall through here
      -  82  116
                           buf.append('\\');
      +  82  58
                           buf.append('\\');
       83  
                       default:
      -  84  2720
                           buf.append(c);
      +  84  1333
                           buf.append(c);
       85  
                           break;
       86  
                   }
       87  
               }
      -  88  230
           }
      +  88  112
           }
       89  
       
       90   @@ -198,20 +198,20 @@
            */
       96  
           public static String escapeLuceneQuery(final CharSequence text) {
      -  97  4
               if (text == null) {
      -  98  2
                   return null;
      +  97  2
               if (text == null) {
      +  98  1
                   return null;
       99  
               }
      -  100  2
               final int size = text.length() << 1;
      -  101  2
               final StringBuilder buf = new StringBuilder(size);
      -  102  2
               appendEscapedLuceneQuery(buf, text);
      -  103  2
               return buf.toString();
      +  100  1
               final int size = text.length() << 1;
      +  101  1
               final StringBuilder buf = new StringBuilder(size);
      +  102  1
               appendEscapedLuceneQuery(buf, text);
      +  103  1
               return buf.toString();
       104  
           }
       105  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.SearchFieldAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.SearchFieldAnalyzer.html index 0a685ec92..a8a32a9c5 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.SearchFieldAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.SearchFieldAnalyzer.html @@ -117,9 +117,9 @@
            * @param version the Lucene version
       50  
            */
      -  51  12
           public SearchFieldAnalyzer(Version version) {
      -  52  12
               this.version = version;
      -  53  12
           }
      +  51  10
           public SearchFieldAnalyzer(Version version) {
      +  52  10
               this.version = version;
      +  53  10
           }
       54  
       
       55   @@ -140,13 +140,13 @@
           @Override
       63  
           protected TokenStreamComponents createComponents(String fieldName, Reader reader) {
      -  64  12
               final Tokenizer source = new AlphaNumericTokenizer(version, reader);
      +  64  10
               final Tokenizer source = new AlphaNumericTokenizer(version, reader);
       65  
       
      -  66  12
               TokenStream stream = source;
      +  66  10
               TokenStream stream = source;
       67  
       
      -  68  12
               stream = new WordDelimiterFilter(stream,
      +  68  10
               stream = new WordDelimiterFilter(stream,
       69  
                       WordDelimiterFilter.GENERATE_WORD_PARTS
       70   @@ -161,14 +161,14 @@
                       | WordDelimiterFilter.STEM_ENGLISH_POSSESSIVE, null);
       75  
       
      -  76  12
               stream = new LowerCaseFilter(version, stream);
      -  77  12
               stream = new UrlTokenizingFilter(stream);
      -  78  12
               concatenatingFilter = new TokenPairConcatenatingFilter(stream);
      -  79  12
               stream = concatenatingFilter;
      -  80  12
               stream = new StopFilter(version, stream, StopAnalyzer.ENGLISH_STOP_WORDS_SET);
      +  76  10
               stream = new LowerCaseFilter(version, stream);
      +  77  10
               stream = new UrlTokenizingFilter(stream);
      +  78  10
               concatenatingFilter = new TokenPairConcatenatingFilter(stream);
      +  79  10
               stream = concatenatingFilter;
      +  80  10
               stream = new StopFilter(version, stream, StopAnalyzer.ENGLISH_STOP_WORDS_SET);
       81  
       
      -  82  12
               return new TokenStreamComponents(source, stream);
      +  82  10
               return new TokenStreamComponents(source, stream);
       83  
           }
       84   @@ -187,15 +187,15 @@
            */
       91  
           public void clear() {
      -  92  48
               if (concatenatingFilter != null) {
      -  93  48
                   concatenatingFilter.clear();
      +  92  104300
               if (concatenatingFilter != null) {
      +  93  104300
                   concatenatingFilter.clear();
       94  
               }
      -  95  48
           }
      +  95  104300
           }
       96  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.TokenPairConcatenatingFilter.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.TokenPairConcatenatingFilter.html index 8022ef45f..c345415fe 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.TokenPairConcatenatingFilter.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.TokenPairConcatenatingFilter.html @@ -93,7 +93,7 @@
            * The char term attribute.
       38  
            */
      -  39  16
           private final CharTermAttribute termAtt = addAttribute(CharTermAttribute.class);
      +  39  12
           private final CharTermAttribute termAtt = addAttribute(CharTermAttribute.class);
       40  
           /**
       41   @@ -124,7 +124,7 @@
            */
       54  
           protected String getPreviousWord() {
      -  55  4
               return previousWord;
      +  55  2
               return previousWord;
       56  
           }
       57   @@ -141,7 +141,7 @@
            */
       63  
           protected LinkedList<String> getWords() {
      -  64  2
               return words;
      +  64  1
               return words;
       65  
           }
       66   @@ -158,9 +158,9 @@
            */
       72  
           public TokenPairConcatenatingFilter(TokenStream stream) {
      -  73  16
               super(stream);
      -  74  16
               words = new LinkedList<String>();
      -  75  16
           }
      +  73  12
               super(stream);
      +  74  12
               words = new LinkedList<String>();
      +  75  12
           }
       76  
       
       77   @@ -185,35 +185,35 @@
       
       87  
               //collect all the terms into the words collection
      -  88  1906
               while (input.incrementToken()) {
      -  89  536
                   final String word = new String(termAtt.buffer(), 0, termAtt.length());
      -  90  536
                   words.add(word);
      -  91  536
               }
      +  88  578223
               while (input.incrementToken()) {
      +  89  192691
                   final String word = new String(termAtt.buffer(), 0, termAtt.length());
      +  90  192691
                   words.add(word);
      +  91  192691
               }
       92  
       
       93  
               //if we have a previousTerm - write it out as its own token concatenated
       94  
               // with the current word (if one is available).
      -  95  1370
               if (previousWord != null && !words.isEmpty()) {
      -  96  480
                   final String word = words.getFirst();
      -  97  480
                   clearAttributes();
      -  98  480
                   termAtt.append(previousWord).append(word);
      -  99  480
                   previousWord = null;
      -  100  480
                   return true;
      +  95  385532
               if (previousWord != null && !words.isEmpty()) {
      +  96  88389
                   final String word = words.getFirst();
      +  97  88389
                   clearAttributes();
      +  98  88389
                   termAtt.append(previousWord).append(word);
      +  99  88389
                   previousWord = null;
      +  100  88389
                   return true;
       101  
               }
       102  
               //if we have words, write it out as a single token
      -  103  890
               if (!words.isEmpty()) {
      -  104  536
                   final String word = words.removeFirst();
      -  105  536
                   clearAttributes();
      -  106  536
                   termAtt.append(word);
      -  107  536
                   previousWord = word;
      -  108  536
                   return true;
      +  103  297143
               if (!words.isEmpty()) {
      +  104  192691
                   final String word = words.removeFirst();
      +  105  192691
                   clearAttributes();
      +  106  192691
                   termAtt.append(word);
      +  107  192691
                   previousWord = word;
      +  108  192691
                   return true;
       109  
               }
      -  110  354
               return false;
      +  110  104452
               return false;
       111  
           }
       112   @@ -232,9 +232,9 @@
            */
       119  
           public void clear() {
      -  120  50
               previousWord = null;
      -  121  50
               words.clear();
      -  122  50
           }
      +  120  104301
               previousWord = null;
      +  121  104301
               words.clear();
      +  122  104301
           }
       123  
       
       124   @@ -306,6 +306,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.UrlTokenizingFilter.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.UrlTokenizingFilter.html index 7a1742c92..dd3fbdd91 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.UrlTokenizingFilter.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.lucene.UrlTokenizingFilter.html @@ -101,7 +101,7 @@
            * The logger.
       42  
            */
      -  43  2
           private static final Logger LOGGER = LoggerFactory.getLogger(UrlTokenizingFilter.class);
      +  43  1
           private static final Logger LOGGER = LoggerFactory.getLogger(UrlTokenizingFilter.class);
       44  
       
       45   @@ -116,8 +116,8 @@
            */
       50  
           public UrlTokenizingFilter(TokenStream stream) {
      -  51  25
               super(stream);
      -  52  25
           }
      +  51  16
               super(stream);
      +  52  16
           }
       53  
       
       54   @@ -138,22 +138,22 @@
           @Override
       62  
           public boolean incrementToken() throws IOException {
      -  63  59271
               final LinkedList<String> tokens = getTokens();
      -  64  59310
               final CharTermAttribute termAtt = getTermAtt();
      -  65  59323
               if (tokens.isEmpty() && input.incrementToken()) {
      -  66  39843
                   final String text = new String(termAtt.buffer(), 0, termAtt.length());
      -  67  39848
                   if (UrlStringUtils.containsUrl(text)) {
      -  68  12
                       final String[] parts = text.split("\\s");
      -  69  24
                       for (String part : parts) {
      -  70  12
                           if (UrlStringUtils.isUrl(part)) {
      +  63  603636
               final LinkedList<String> tokens = getTokens();
      +  64  603638
               final CharTermAttribute termAtt = getTermAtt();
      +  65  603639
               if (tokens.isEmpty() && input.incrementToken()) {
      +  66  210014
                   final String text = new String(termAtt.buffer(), 0, termAtt.length());
      +  67  210014
                   if (UrlStringUtils.containsUrl(text)) {
      +  68  6
                       final String[] parts = text.split("\\s");
      +  69  12
                       for (String part : parts) {
      +  70  6
                           if (UrlStringUtils.isUrl(part)) {
       71  
                               try {
      -  72  12
                                   final List<String> data = UrlStringUtils.extractImportantUrlData(part);
      -  73  12
                                   tokens.addAll(data);
      +  72  6
                                   final List<String> data = UrlStringUtils.extractImportantUrlData(part);
      +  73  6
                                   tokens.addAll(data);
       74  0
                               } catch (MalformedURLException ex) {
       75  0
                                   LOGGER.debug("error parsing {}", part, ex);
       76  0
                                   tokens.add(part);
      -  77  12
                               }
      +  77  6
                               }
       78  
                           } else {
       79  0
                               tokens.add(part);
      @@ -161,19 +161,19 @@
                           }
       81  
                       }
      -  82  12
                   } else {
      -  83  39832
                       tokens.add(text);
      +  82  6
                   } else {
      +  83  210005
                       tokens.add(text);
       84  
                   }
       85  
               }
      -  86  59181
               return addTerm();
      +  86  603546
               return addTerm();
       87  
           }
       88  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nexus.MavenArtifact.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nexus.MavenArtifact.html index d4d204b95..4652d6b1e 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nexus.MavenArtifact.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nexus.MavenArtifact.html @@ -178,36 +178,36 @@
            * @param secureDownload if the jar and pom files should be downloaded using HTTPS.
       84  
            */
      -  85  6
           public MavenArtifact(String groupId, String artifactId, String version, boolean jarAvailable, boolean pomAvailable, boolean secureDownload) {
      -  86  6
               this.groupId = groupId;
      -  87  6
               this.artifactId = artifactId;
      -  88  6
               this.version = version;
      +  85  3
           public MavenArtifact(String groupId, String artifactId, String version, boolean jarAvailable, boolean pomAvailable, boolean secureDownload) {
      +  86  3
               this.groupId = groupId;
      +  87  3
               this.artifactId = artifactId;
      +  88  3
               this.version = version;
       89  
               String base;
      -  90  6
               if (secureDownload) {
      +  90  3
               if (secureDownload) {
       91  0
                   base = "https:" + CENTRAL_CONTENT_URL;
       92  
               } else {
      -  93  6
                   base = "http:" + CENTRAL_CONTENT_URL;
      +  93  3
                   base = "http:" + CENTRAL_CONTENT_URL;
       94  
               }
      -  95  6
               if (jarAvailable) {
      +  95  3
               if (jarAvailable) {
       96  
                   //org/springframework/spring-core/3.2.0.RELEASE/spring-core-3.2.0.RELEASE.pom
      -  97  6
                   this.artifactUrl = base + groupId.replace('.', '/') + '/' + artifactId + '/'
      +  97  3
                   this.artifactUrl = base + groupId.replace('.', '/') + '/' + artifactId + '/'
       98  
                           + version + '/' + artifactId + '-' + version + ".jar";
       99  
               }
      -  100  6
               if (pomAvailable) {
      +  100  3
               if (pomAvailable) {
       101  
                   //org/springframework/spring-core/3.2.0.RELEASE/spring-core-3.2.0.RELEASE.pom
      -  102  6
                   this.pomUrl = base + groupId.replace('.', '/') + '/' + artifactId + '/'
      +  102  3
                   this.pomUrl = base + groupId.replace('.', '/') + '/' + artifactId + '/'
       103  
                           + version + '/' + artifactId + '-' + version + ".pom";
       104  
               }
      -  105  6
           }
      +  105  3
           }
       106  
       
       107   @@ -226,12 +226,12 @@
            * @param url the artifactLink url
       114  
            */
      -  115  4
           public MavenArtifact(String groupId, String artifactId, String version, String url) {
      -  116  4
               this.groupId = groupId;
      -  117  4
               this.artifactId = artifactId;
      -  118  4
               this.version = version;
      -  119  4
               this.artifactUrl = url;
      -  120  4
           }
      +  115  2
           public MavenArtifact(String groupId, String artifactId, String version, String url) {
      +  116  2
               this.groupId = groupId;
      +  117  2
               this.artifactId = artifactId;
      +  118  2
               this.version = version;
      +  119  2
               this.artifactUrl = url;
      +  120  2
           }
       121  
       
       122   @@ -248,7 +248,7 @@
           @Override
       128  
           public String toString() {
      -  129  2
               return String.format("%s:%s:%s", groupId, artifactId, version);
      +  129  1
               return String.format("%s:%s:%s", groupId, artifactId, version);
       130  
           }
       131   @@ -281,7 +281,7 @@
            */
       146  
           public String getGroupId() {
      -  147  10
               return groupId;
      +  147  5
               return groupId;
       148  
           }
       149   @@ -314,7 +314,7 @@
            */
       164  
           public String getArtifactId() {
      -  165  10
               return artifactId;
      +  165  5
               return artifactId;
       166  
           }
       167   @@ -347,7 +347,7 @@
            */
       182  
           public String getVersion() {
      -  183  10
               return version;
      +  183  5
               return version;
       184  
           }
       185   @@ -380,7 +380,7 @@
            */
       200  
           public String getArtifactUrl() {
      -  201  8
               return artifactUrl;
      +  201  4
               return artifactUrl;
       202  
           }
       203   @@ -426,6 +426,6 @@
       // vim: cc=120:sw=4:ts=4:sts=4
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nexus.NexusSearch.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nexus.NexusSearch.html index 7360eb387..ea0334940 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nexus.NexusSearch.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nexus.NexusSearch.html @@ -327,6 +327,6 @@
       // vim: cc=120:sw=4:ts=4:sts=4
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nuget.NugetPackage.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nuget.NugetPackage.html index 9dfecdcfc..fd3599d2c 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nuget.NugetPackage.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nuget.NugetPackage.html @@ -133,8 +133,8 @@
            * Creates an empty NugetPackage.
       58  
            */
      -  59  4
           public NugetPackage() {
      -  60  4
           }
      +  59  2
           public NugetPackage() {
      +  60  2
           }
       61  
       
       62   @@ -147,8 +147,8 @@
            */
       66  
           public void setId(String id) {
      -  67  2
               this.id = id;
      -  68  2
           }
      +  67  1
               this.id = id;
      +  68  1
           }
       69  
       
       70   @@ -161,7 +161,7 @@
            */
       74  
           public String getId() {
      -  75  2
               return id;
      +  75  1
               return id;
       76  
           }
       77   @@ -176,8 +176,8 @@
            */
       82  
           public void setVersion(String version) {
      -  83  2
               this.version = version;
      -  84  2
           }
      +  83  1
               this.version = version;
      +  84  1
           }
       85  
       
       86   @@ -190,7 +190,7 @@
            */
       90  
           public String getVersion() {
      -  91  2
               return version;
      +  91  1
               return version;
       92  
           }
       93   @@ -205,8 +205,8 @@
            */
       98  
           public void setTitle(String title) {
      -  99  2
               this.title = title;
      -  100  2
           }
      +  99  1
               this.title = title;
      +  100  1
           }
       101  
       
       102   @@ -219,7 +219,7 @@
            */
       106  
           public String getTitle() {
      -  107  2
               return title;
      +  107  1
               return title;
       108  
           }
       109   @@ -234,8 +234,8 @@
            */
       114  
           public void setAuthors(String authors) {
      -  115  2
               this.authors = authors;
      -  116  2
           }
      +  115  1
               this.authors = authors;
      +  116  1
           }
       117  
       
       118   @@ -248,7 +248,7 @@
            */
       122  
           public String getAuthors() {
      -  123  2
               return authors;
      +  123  1
               return authors;
       124  
           }
       125   @@ -263,8 +263,8 @@
            */
       130  
           public void setOwners(String owners) {
      -  131  2
               this.owners = owners;
      -  132  2
           }
      +  131  1
               this.owners = owners;
      +  132  1
           }
       133  
       
       134   @@ -277,7 +277,7 @@
            */
       138  
           public String getOwners() {
      -  139  2
               return owners;
      +  139  1
               return owners;
       140  
           }
       141   @@ -292,8 +292,8 @@
            */
       146  
           public void setLicenseUrl(String licenseUrl) {
      -  147  2
               this.licenseUrl = licenseUrl;
      -  148  2
           }
      +  147  1
               this.licenseUrl = licenseUrl;
      +  148  1
           }
       149  
       
       150   @@ -306,7 +306,7 @@
            */
       154  
           public String getLicenseUrl() {
      -  155  2
               return licenseUrl;
      +  155  1
               return licenseUrl;
       156  
           }
       157   @@ -352,6 +352,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nuget.NuspecParseException.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nuget.NuspecParseException.html index 1c0e2cae2..de40fc40a 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nuget.NuspecParseException.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nuget.NuspecParseException.html @@ -113,8 +113,8 @@
            */
       49  
           public NuspecParseException(String message) {
      -  50  2
               super(message);
      -  51  2
           }
      +  50  1
               super(message);
      +  51  1
           }
       52  
       
       53   @@ -141,12 +141,12 @@
            */
       64  
           public NuspecParseException(String message, Throwable cause) {
      -  65  4
               super(message, cause);
      -  66  4
           }
      +  65  2
               super(message, cause);
      +  66  2
           }
       67  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nuget.NuspecParser.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nuget.NuspecParser.html index 5899f0f61..9a194ab36 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nuget.NuspecParser.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nuget.NuspecParser.html @@ -93,6 +93,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nuget.XPathNuspecParser.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nuget.XPathNuspecParser.html index a1803ef3e..ec9b9a007 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nuget.XPathNuspecParser.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nuget.XPathNuspecParser.html @@ -81,7 +81,7 @@
        * @author colezlaw
       32  
        */
      -  33  6
       public class XPathNuspecParser implements NuspecParser {
      +  33  3
       public class XPathNuspecParser implements NuspecParser {
       34  
       
       35   @@ -98,8 +98,8 @@
            */
       41  
           private String getOrNull(Node n) {
      -  42  6
               if (n != null) {
      -  43  6
                   return n.getTextContent();
      +  42  3
               if (n != null) {
      +  43  3
                   return n.getTextContent();
       44  
               } else {
       45  0
                   return null;
      @@ -129,29 +129,29 @@
           public NugetPackage parse(InputStream stream) throws NuspecParseException {
       58  
               try {
      -  59  6
                   final Document d = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(stream);
      -  60  4
                   final XPath xpath = XPathFactory.newInstance().newXPath();
      -  61  4
                   final NugetPackage nuspec = new NugetPackage();
      +  59  3
                   final Document d = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(stream);
      +  60  2
                   final XPath xpath = XPathFactory.newInstance().newXPath();
      +  61  2
                   final NugetPackage nuspec = new NugetPackage();
       62  
       
      -  63  4
                   if (xpath.evaluate("/package/metadata/id", d, XPathConstants.NODE) == null
      -  64  2
                           || xpath.evaluate("/package/metadata/version", d, XPathConstants.NODE) == null
      -  65  2
                           || xpath.evaluate("/package/metadata/authors", d, XPathConstants.NODE) == null
      -  66  2
                           || xpath.evaluate("/package/metadata/description", d, XPathConstants.NODE) == null) {
      -  67  2
                       throw new NuspecParseException("Invalid Nuspec format");
      +  63  2
                   if (xpath.evaluate("/package/metadata/id", d, XPathConstants.NODE) == null
      +  64  1
                           || xpath.evaluate("/package/metadata/version", d, XPathConstants.NODE) == null
      +  65  1
                           || xpath.evaluate("/package/metadata/authors", d, XPathConstants.NODE) == null
      +  66  1
                           || xpath.evaluate("/package/metadata/description", d, XPathConstants.NODE) == null) {
      +  67  1
                       throw new NuspecParseException("Invalid Nuspec format");
       68  
                   }
       69  
       
      -  70  2
                   nuspec.setId(xpath.evaluate("/package/metadata/id", d));
      -  71  2
                   nuspec.setVersion(xpath.evaluate("/package/metadata/version", d));
      -  72  2
                   nuspec.setAuthors(xpath.evaluate("/package/metadata/authors", d));
      -  73  2
                   nuspec.setOwners(getOrNull((Node) xpath.evaluate("/package/metadata/owners", d, XPathConstants.NODE)));
      -  74  2
                   nuspec.setLicenseUrl(getOrNull((Node) xpath.evaluate("/package/metadata/licenseUrl", d, XPathConstants.NODE)));
      -  75  2
                   nuspec.setTitle(getOrNull((Node) xpath.evaluate("/package/metadata/title", d, XPathConstants.NODE)));
      -  76  2
                   return nuspec;
      -  77  4
               } catch (Throwable e) {
      -  78  4
                   throw new NuspecParseException("Unable to parse nuspec", e);
      +  70  1
                   nuspec.setId(xpath.evaluate("/package/metadata/id", d));
      +  71  1
                   nuspec.setVersion(xpath.evaluate("/package/metadata/version", d));
      +  72  1
                   nuspec.setAuthors(xpath.evaluate("/package/metadata/authors", d));
      +  73  1
                   nuspec.setOwners(getOrNull((Node) xpath.evaluate("/package/metadata/owners", d, XPathConstants.NODE)));
      +  74  1
                   nuspec.setLicenseUrl(getOrNull((Node) xpath.evaluate("/package/metadata/licenseUrl", d, XPathConstants.NODE)));
      +  75  1
                   nuspec.setTitle(getOrNull((Node) xpath.evaluate("/package/metadata/title", d, XPathConstants.NODE)));
      +  76  1
                   return nuspec;
      +  77  2
               } catch (Throwable e) {
      +  78  2
                   throw new NuspecParseException("Unable to parse nuspec", e);
       79  
               }
       80   @@ -160,6 +160,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.ConnectionFactory.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.ConnectionFactory.html index 1c56da9b5..3414bc9df 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.ConnectionFactory.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.ConnectionFactory.html @@ -62,7 +62,7 @@  22  
       import java.io.InputStream;
       23   -
       import java.sql.CallableStatement;
      +
       import java.sql.PreparedStatement;
       24  
       import java.sql.Connection;
       25   @@ -113,14 +113,14 @@
            * The Logger.
       48  
            */
      -  49  2
           private static final Logger LOGGER = LoggerFactory.getLogger(ConnectionFactory.class);
      +  49  1
           private static final Logger LOGGER = LoggerFactory.getLogger(ConnectionFactory.class);
       50  
           /**
       51  
            * The version of the current DB Schema.
       52  
            */
      -  53  2
           public static final String DB_SCHEMA_VERSION = Settings.getString(Settings.KEYS.DB_VERSION);
      +  53  1
           public static final String DB_SCHEMA_VERSION = Settings.getString(Settings.KEYS.DB_VERSION);
       54  
           /**
       55   @@ -151,28 +151,28 @@
            * The database driver used to connect to the database.
       68  
            */
      -  69  2
           private static Driver driver = null;
      +  69  1
           private static Driver driver = null;
       70  
           /**
       71  
            * The database connection string.
       72  
            */
      -  73  2
           private static String connectionString = null;
      +  73  1
           private static String connectionString = null;
       74  
           /**
       75  
            * The username to connect to the database.
       76  
            */
      -  77  2
           private static String userName = null;
      +  77  1
           private static String userName = null;
       78  
           /**
       79  
            * The password for the database.
       80  
            */
      -  81  2
           private static String password = null;
      +  81  1
           private static String password = null;
       82  
       
       83   @@ -201,42 +201,42 @@
           public static synchronized void initialize() throws DatabaseException {
       96  
               //this only needs to be called once.
      -  97  38
               if (connectionString != null) {
      -  98  34
                   return;
      +  97  19
               if (connectionString != null) {
      +  98  17
                   return;
       99  
               }
      -  100  4
               Connection conn = null;
      +  100  2
               Connection conn = null;
       101  
               try {
       102  
                   //load the driver if necessary
      -  103  4
                   final String driverName = Settings.getString(Settings.KEYS.DB_DRIVER_NAME, "");
      -  104  4
                   if (!driverName.isEmpty()) { //likely need to load the correct driver
      -  105  4
                       LOGGER.debug("Loading driver: {}", driverName);
      -  106  4
                       final String driverPath = Settings.getString(Settings.KEYS.DB_DRIVER_PATH, "");
      +  103  2
                   final String driverName = Settings.getString(Settings.KEYS.DB_DRIVER_NAME, "");
      +  104  2
                   if (!driverName.isEmpty()) { //likely need to load the correct driver
      +  105  2
                       LOGGER.debug("Loading driver: {}", driverName);
      +  106  2
                       final String driverPath = Settings.getString(Settings.KEYS.DB_DRIVER_PATH, "");
       107  
                       try {
      -  108  4
                           if (!driverPath.isEmpty()) {
      +  108  2
                           if (!driverPath.isEmpty()) {
       109  0
                               LOGGER.debug("Loading driver from: {}", driverPath);
       110  0
                               driver = DriverLoader.load(driverName, driverPath);
       111  
                           } else {
      -  112  4
                               driver = DriverLoader.load(driverName);
      +  112  2
                               driver = DriverLoader.load(driverName);
       113  
                           }
       114  0
                       } catch (DriverLoadException ex) {
       115  0
                           LOGGER.debug("Unable to load database driver", ex);
       116  0
                           throw new DatabaseException("Unable to load database driver");
      -  117  4
                       }
      +  117  2
                       }
       118  
                   }
      -  119  4
                   userName = Settings.getString(Settings.KEYS.DB_USER, "dcuser");
      +  119  2
                   userName = Settings.getString(Settings.KEYS.DB_USER, "dcuser");
       120  
                   //yes, yes - hard-coded password - only if there isn't one in the properties file.
      -  121  4
                   password = Settings.getString(Settings.KEYS.DB_PASSWORD, "DC-Pass1337!");
      +  121  2
                   password = Settings.getString(Settings.KEYS.DB_PASSWORD, "DC-Pass1337!");
       122  
                   try {
      -  123  4
                       connectionString = Settings.getConnectionString(
      +  123  2
                       connectionString = Settings.getConnectionString(
       124  
                               Settings.KEYS.DB_CONNECTION_STRING,
       125   @@ -246,27 +246,27 @@  128  
                               "Unable to retrieve the database connection string", ex);
       129  0
                       throw new DatabaseException("Unable to retrieve the database connection string");
      -  130  4
                   }
      -  131  4
                   boolean shouldCreateSchema = false;
      +  130  2
                   }
      +  131  2
                   boolean shouldCreateSchema = false;
       132  
                   try {
      -  133  4
                       if (connectionString.startsWith("jdbc:h2:file:")) { //H2
      -  134  4
                           shouldCreateSchema = !h2DataFileExists();
      -  135  4
                           LOGGER.debug("Need to create DB Structure: {}", shouldCreateSchema);
      +  133  2
                       if (connectionString.startsWith("jdbc:h2:file:")) { //H2
      +  134  2
                           shouldCreateSchema = !h2DataFileExists();
      +  135  2
                           LOGGER.debug("Need to create DB Structure: {}", shouldCreateSchema);
       136  
                       }
       137  0
                   } catch (IOException ioex) {
       138  0
                       LOGGER.debug("Unable to verify database exists", ioex);
       139  0
                       throw new DatabaseException("Unable to verify database exists");
      -  140  4
                   }
      -  141  4
                   LOGGER.debug("Loading database connection");
      -  142  4
                   LOGGER.debug("Connection String: {}", connectionString);
      -  143  4
                   LOGGER.debug("Database User: {}", userName);
      +  140  2
                   }
      +  141  2
                   LOGGER.debug("Loading database connection");
      +  142  2
                   LOGGER.debug("Connection String: {}", connectionString);
      +  143  2
                   LOGGER.debug("Database User: {}", userName);
       144  
       
       145  
                   try {
      -  146  4
                       conn = DriverManager.getConnection(connectionString, userName, password);
      +  146  2
                       conn = DriverManager.getConnection(connectionString, userName, password);
       147  0
                   } catch (SQLException ex) {
       148  0
                       if (ex.getMessage().contains("java.net.UnknownHostException") && connectionString.contains("AUTO_SERVER=TRUE;")) {
       149  0
                           connectionString = connectionString.replace("AUTO_SERVER=TRUE;", "");
      @@ -287,10 +287,10 @@  161  0
                           throw new DatabaseException("Unable to connect to the database");
       162  
                       }
      -  163  4
                   }
      +  163  2
                   }
       164  
       
      -  165  4
                   if (shouldCreateSchema) {
      +  165  2
                   if (shouldCreateSchema) {
       166  
                       try {
       167  0
                           createTables(conn);
      @@ -302,25 +302,25 @@
                   }
       173  
                   try {
      -  174  4
                       ensureSchemaVersion(conn);
      +  174  2
                       ensureSchemaVersion(conn);
       175  0
                   } catch (DatabaseException dex) {
       176  0
                       LOGGER.debug("", dex);
       177  0
                       throw new DatabaseException("Database schema does not match this version of dependency-check", dex);
      -  178  4
                   }
      +  178  2
                   }
       179  
               } finally {
      -  180  4
                   if (conn != null) {
      +  180  2
                   if (conn != null) {
       181  
                       try {
      -  182  4
                           conn.close();
      +  182  2
                           conn.close();
       183  0
                       } catch (SQLException ex) {
       184  0
                           LOGGER.debug("An error occurred closing the connection", ex);
      -  185  4
                       }
      +  185  2
                       }
       186  
                   }
       187  
               }
      -  188  4
           }
      +  188  2
           }
       189  
       
       190   @@ -335,24 +335,24 @@
            */
       195  
           public static synchronized void cleanup() {
      -  196  2
               if (driver != null) {
      +  196  1
               if (driver != null) {
       197  
                   try {
      -  198  2
                       DriverManager.deregisterDriver(driver);
      +  198  1
                       DriverManager.deregisterDriver(driver);
       199  0
                   } catch (SQLException ex) {
       200  0
                       LOGGER.debug("An error occurred unloading the database driver", ex);
       201  0
                   } catch (Throwable unexpected) {
       202  0
                       LOGGER.debug(
       203  
                               "An unexpected throwable occurred unloading the database driver", unexpected);
      -  204  2
                   }
      -  205  2
                   driver = null;
      +  204  1
                   }
      +  205  1
                   driver = null;
       206  
               }
      -  207  2
               connectionString = null;
      -  208  2
               userName = null;
      -  209  2
               password = null;
      -  210  2
           }
      +  207  1
               connectionString = null;
      +  208  1
               userName = null;
      +  209  1
               password = null;
      +  210  1
           }
       211  
       
       212   @@ -369,16 +369,16 @@
            */
       218  
           public static Connection getConnection() throws DatabaseException {
      -  219  28
               initialize();
      -  220  28
               Connection conn = null;
      +  219  14
               initialize();
      +  220  14
               Connection conn = null;
       221  
               try {
      -  222  28
                   conn = DriverManager.getConnection(connectionString, userName, password);
      +  222  14
                   conn = DriverManager.getConnection(connectionString, userName, password);
       223  0
               } catch (SQLException ex) {
       224  0
                   LOGGER.debug("", ex);
       225  0
                   throw new DatabaseException("Unable to connect to the database");
      -  226  28
               }
      -  227  28
               return conn;
      +  226  14
               }
      +  227  14
               return conn;
       228  
           }
       229   @@ -397,10 +397,10 @@
            */
       236  
           private static boolean h2DataFileExists() throws IOException {
      -  237  4
               final File dir = Settings.getDataDirectory();
      -  238  4
               final String fileName = Settings.getString(Settings.KEYS.DB_FILE_NAME);
      -  239  4
               final File file = new File(dir, fileName);
      -  240  4
               return file.exists();
      +  237  2
               final File dir = Settings.getDataDirectory();
      +  238  2
               final String fileName = Settings.getString(Settings.KEYS.DB_FILE_NAME);
      +  239  2
               final File file = new File(dir, fileName);
      +  240  2
               return file.exists();
       241  
           }
       242   @@ -551,7 +551,7 @@
            * Counter to ensure that calls to ensureSchemaVersion does not end up in an endless loop.
       344  
            */
      -  345  2
           private static int callDepth = 0;
      +  345  1
           private static int callDepth = 0;
       346  
       
       347   @@ -568,18 +568,18 @@
            */
       353  
           private static void ensureSchemaVersion(Connection conn) throws DatabaseException {
      -  354  4
               ResultSet rs = null;
      -  355  4
               CallableStatement cs = null;
      +  354  2
               ResultSet rs = null;
      +  355  2
               PreparedStatement ps = null;
       356  
               try {
       357  
                   //TODO convert this to use DatabaseProperties
      -  358  4
                   cs = conn.prepareCall("SELECT value FROM properties WHERE id = 'version'");
      -  359  4
                   rs = cs.executeQuery();
      -  360  4
                   if (rs.next()) {
      -  361  4
                       final DependencyVersion appDbVersion = DependencyVersionUtil.parseVersion(DB_SCHEMA_VERSION);
      -  362  4
                       final DependencyVersion db = DependencyVersionUtil.parseVersion(rs.getString(1));
      -  363  4
                       if (appDbVersion.compareTo(db) > 0) {
      +  358  2
                   ps = conn.prepareStatement("SELECT value FROM properties WHERE id = 'version'");
      +  359  2
                   rs = ps.executeQuery();
      +  360  2
                   if (rs.next()) {
      +  361  2
                       final DependencyVersion appDbVersion = DependencyVersionUtil.parseVersion(DB_SCHEMA_VERSION);
      +  362  2
                       final DependencyVersion db = DependencyVersionUtil.parseVersion(rs.getString(1));
      +  363  2
                       if (appDbVersion.compareTo(db) > 0) {
       364  0
                           LOGGER.debug("Current Schema: {}", DB_SCHEMA_VERSION);
       365  0
                           LOGGER.debug("DB Schema: {}", rs.getString(1));
       366  0
                           updateSchema(conn, appDbVersion, db);
      @@ -589,7 +589,7 @@
                           }
       370  
                       }
      -  371  4
                   } else {
      +  371  2
                   } else {
       372  0
                       throw new DatabaseException("Database schema is missing");
       373  
                   }
      @@ -598,14 +598,14 @@  376  0
                   throw new DatabaseException("Unable to check the database schema version");
       377  
               } finally {
      -  378  4
                   DBUtils.closeResultSet(rs);
      -  379  4
                   DBUtils.closeStatement(cs);
      -  380  4
               }
      -  381  4
           }
      +  378  2
                   DBUtils.closeResultSet(rs);
      +  379  2
                   DBUtils.closeStatement(ps);
      +  380  2
               }
      +  381  2
           }
       382  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.CorruptDatabaseException.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.CorruptDatabaseException.html index 8fc0c7482..3d1c721f4 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.CorruptDatabaseException.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.CorruptDatabaseException.html @@ -115,6 +115,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.CveDB.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.CveDB.html index 4c392cc17..10fbad8ab 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.CveDB.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.CveDB.html @@ -60,1231 +60,1227 @@  21  
       import java.io.UnsupportedEncodingException;
       22   -
       import java.sql.CallableStatement;
      -  23  
       import java.sql.Connection;
      -  24   +  23  
       import java.sql.PreparedStatement;
      -  25   +  24  
       import java.sql.ResultSet;
      -  26   +  25  
       import java.sql.SQLException;
      -  27   +  26  
       import java.sql.Statement;
      -  28   +  27  
       import java.util.ArrayList;
      -  29   +  28  
       import java.util.HashMap;
      -  30   +  29  
       import java.util.HashSet;
      -  31   +  30  
       import java.util.List;
      -  32   +  31  
       import java.util.Locale;
      -  33   +  32  
       import java.util.Map;
      -  34   +  33  
       import java.util.Map.Entry;
      -  35   +  34  
       import java.util.MissingResourceException;
      -  36   +  35  
       import java.util.Properties;
      -  37   +  36  
       import java.util.ResourceBundle;
      -  38   +  37  
       import java.util.Set;
      -  39   +  38  
       import org.owasp.dependencycheck.data.cwe.CweDB;
      -  40   +  39  
       import org.owasp.dependencycheck.dependency.Reference;
      -  41   +  40  
       import org.owasp.dependencycheck.dependency.Vulnerability;
      -  42   +  41  
       import org.owasp.dependencycheck.dependency.VulnerableSoftware;
      -  43   +  42  
       import org.owasp.dependencycheck.utils.DBUtils;
      -  44   +  43  
       import org.owasp.dependencycheck.utils.DependencyVersion;
      -  45   +  44  
       import org.owasp.dependencycheck.utils.DependencyVersionUtil;
      -  46   +  45  
       import org.owasp.dependencycheck.utils.Pair;
      -  47   +  46  
       import org.owasp.dependencycheck.utils.Settings;
      -  48   +  47  
       import org.slf4j.Logger;
      -  49   +  48  
       import org.slf4j.LoggerFactory;
      +  49   +
       
       50   -
       
      -  51  
       /**
      -  52   +  51  
        * The database holding information about the NVD CVE data.
      -  53   +  52  
        *
      -  54   +  53  
        * @author Jeremy Long
      -  55   +  54  
        */
      -  56   +  55  
       public class CveDB {
      +  56   +
       
       57   -
       
      +
           /**
       58   -
           /**
      -  59  
            * The logger.
      -  60   +  59  
            */
      -  61  2
           private static final Logger LOGGER = LoggerFactory.getLogger(CveDB.class);
      +  60  1
           private static final Logger LOGGER = LoggerFactory.getLogger(CveDB.class);
      +  61   +
           /**
       62   -
           /**
      -  63  
            * Database connection
      +  63   +
            */
       64   -
            */
      -  65  
           private Connection conn;
      +  65   +
           /**
       66   -
           /**
      -  67  
            * The bundle of statements used when accessing the database.
      -  68   +  67  
            */
      -  69  26
           private ResourceBundle statementBundle = null;
      +  68  13
           private ResourceBundle statementBundle = null;
      +  69   +
       
       70   -
       
      +
           /**
       71   -
           /**
      -  72   -
            * Creates a new CveDB object and opens the database
      -  73   -
            * connection. Note, the connection must be closed by the caller by calling
      -  74   -
            * the close method. ======= Does the underlying connection support batch
      -  75   -
            * operations?
      -  76   -
            */
      -  77   -
           private boolean batchSupported;
      -  78   -
       
      -  79   -
           /**
      -  80  
            * Creates a new CveDB object and opens the database connection. Note, the
      -  81   +  72  
            * connection must be closed by the caller by calling the close method.
      -  82   -
            * 
      -  83   +  73   +
            * ======= Does the underlying connection support batch operations?
      +  74   +
            */
      +  75   +
           private boolean batchSupported;
      +  76   +
       
      +  77   +
           /**
      +  78   +
            * Creates a new CveDB object and opens the database connection. Note, the
      +  79   +
            * connection must be closed by the caller by calling the close method.
      +  80   +
            *
      +  81  
            * @throws DatabaseException thrown if there is an exception opening the
      -  84   +  82  
            * database.
      -  85   +  83  
            */
      -  86   +  84  
           public CveDB() throws DatabaseException {
      -  87  26
               super();
      +  85  13
               super();
      +  86   +
               try {
      +  87  13
                   open();
       88   -
               try {
      -  89  26
                   open();
      -  90  
                   try {
      -  91  26
                       final String databaseProductName = conn.getMetaData().getDatabaseProductName();
      -  92  26
                       batchSupported = conn.getMetaData().supportsBatchUpdates();
      -  93  26
                       LOGGER.debug("Database dialect: {}", databaseProductName);
      -  94  26
                       final Locale dbDialect = new Locale(databaseProductName);
      -  95  26
                       statementBundle = ResourceBundle.getBundle("data/dbStatements", dbDialect);
      -  96  0
                   } catch (SQLException se) {
      -  97  0
                       LOGGER.warn("Problem loading database specific dialect!", se);
      -  98  0
                       statementBundle = ResourceBundle.getBundle("data/dbStatements");
      -  99  26
                   }
      -  100  26
                   databaseProperties = new DatabaseProperties(this);
      -  101  0
               } catch (DatabaseException ex) {
      -  102  0
                   throw ex;
      -  103  26
               }
      -  104  26
           }
      +  89  13
                       final String databaseProductName = conn.getMetaData().getDatabaseProductName();
      +  90  13
                       batchSupported = conn.getMetaData().supportsBatchUpdates();
      +  91  13
                       LOGGER.debug("Database dialect: {}", databaseProductName);
      +  92  13
                       final Locale dbDialect = new Locale(databaseProductName);
      +  93  13
                       statementBundle = ResourceBundle.getBundle("data/dbStatements", dbDialect);
      +  94  0
                   } catch (SQLException se) {
      +  95  0
                       LOGGER.warn("Problem loading database specific dialect!", se);
      +  96  0
                       statementBundle = ResourceBundle.getBundle("data/dbStatements");
      +  97  13
                   }
      +  98  13
                   databaseProperties = new DatabaseProperties(this);
      +  99  0
               } catch (DatabaseException ex) {
      +  100  0
                   throw ex;
      +  101  13
               }
      +  102  13
           }
      +  103   +
       
      +  104   +
           /**
       105   -
       
      -  106   -
           /**
      -  107  
            * Returns the database connection.
      -  108   +  106  
            *
      -  109   +  107  
            * @return the database connection
      -  110   +  108  
            */
      -  111   +  109  
           protected Connection getConnection() {
      -  112  90
               return conn;
      +  110  45
               return conn;
      +  111   +
           }
      +  112   +
       
       113   -
           }
      +
           /**
       114   -
       
      -  115   -
           /**
      -  116  
            * Opens the database connection. If the database does not exist, it will
      -  117   +  115  
            * create a new one.
      -  118   +  116  
            *
      -  119   +  117  
            * @throws DatabaseException thrown if there is an error opening the
      -  120   +  118  
            * database connection
      -  121   +  119  
            */
      -  122   +  120  
           public final void open() throws DatabaseException {
      -  123  52
               if (!isOpen()) {
      -  124  26
                   conn = ConnectionFactory.getConnection();
      +  121  26
               if (!isOpen()) {
      +  122  13
                   conn = ConnectionFactory.getConnection();
      +  123   +
               }
      +  124  26
           }
       125   -
               }
      -  126  52
           }
      +
       
      +  126   +
           /**
       127   -
       
      -  128   -
           /**
      -  129  
            * Closes the DB4O database. Close should be called on this object when it
      -  130   +  128  
            * is done being used.
      -  131   +  129  
            */
      -  132   +  130  
           public void close() {
      -  133  49
               if (conn != null) {
      -  134   +  131  25
               if (conn != null) {
      +  132  
                   try {
      -  135  26
                       conn.close();
      -  136  0
                   } catch (SQLException ex) {
      -  137  0
                       LOGGER.error("There was an error attempting to close the CveDB, see the log for more details.");
      -  138  0
                       LOGGER.debug("", ex);
      -  139  0
                   } catch (Throwable ex) {
      -  140  0
                       LOGGER.error("There was an exception attempting to close the CveDB, see the log for more details.");
      -  141  0
                       LOGGER.debug("", ex);
      -  142  26
                   }
      -  143  26
                   conn = null;
      -  144   +  133  13
                       conn.close();
      +  134  0
                   } catch (SQLException ex) {
      +  135  0
                       LOGGER.error("There was an error attempting to close the CveDB, see the log for more details.");
      +  136  0
                       LOGGER.debug("", ex);
      +  137  0
                   } catch (Throwable ex) {
      +  138  0
                       LOGGER.error("There was an exception attempting to close the CveDB, see the log for more details.");
      +  139  0
                       LOGGER.debug("", ex);
      +  140  13
                   }
      +  141  13
                   conn = null;
      +  142  
               }
      -  145  49
           }
      +  143  25
           }
      +  144   +
       
      +  145   +
           /**
       146   -
       
      -  147   -
           /**
      -  148  
            * Returns whether the database connection is open or closed.
      -  149   +  147  
            *
      -  150   +  148  
            * @return whether the database connection is open or closed
      -  151   +  149  
            */
      -  152   +  150  
           public boolean isOpen() {
      -  153  52
               return conn != null;
      +  151  26
               return conn != null;
      +  152   +
           }
      +  153   +
       
       154   -
           }
      +
           /**
       155   -
       
      -  156   -
           /**
      -  157  
            * Commits all completed transactions.
      -  158   +  156  
            *
      -  159   +  157  
            * @throws SQLException thrown if a SQL Exception occurs
      -  160   +  158  
            */
      -  161   +  159  
           public void commit() throws SQLException {
      -  162   +  160  
               //temporary remove this as autocommit is on.
      -  163   +  161  
               //if (conn != null) {
      -  164   +  162  
               //    conn.commit();
      -  165   +  163  
               //}
      -  166  0
           }
      +  164  0
           }
      +  165   +
       
      +  166   +
           /**
       167   -
       
      -  168   -
           /**
      -  169  
            * Cleans up the object and ensures that "close" has been called.
      -  170   +  168  
            *
      -  171   +  169  
            * @throws Throwable thrown if there is a problem
      -  172   +  170  
            */
      -  173   +  171  
           @Override
      -  174   +  172  
           @SuppressWarnings("FinalizeDeclaration")
      -  175   +  173  
           protected void finalize() throws Throwable {
      -  176  23
               LOGGER.debug("Entering finalize");
      -  177  23
               close();
      -  178  23
               super.finalize();
      -  179  23
           }
      -  180   +  174  12
               LOGGER.debug("Entering finalize");
      +  175  12
               close();
      +  176  12
               super.finalize();
      +  177  12
           }
      +  178  
           /**
      -  181   +  179  
            * Database properties object containing the 'properties' from the database
      -  182   +  180  
            * table.
      -  183   +  181  
            */
      -  184   +  182  
           private DatabaseProperties databaseProperties;
      +  183   +
       
      +  184   +
           /**
       185   -
       
      -  186   -
           /**
      -  187  
            * Get the value of databaseProperties.
      -  188   +  186  
            *
      -  189   +  187  
            * @return the value of databaseProperties
      -  190   +  188  
            */
      -  191   +  189  
           public DatabaseProperties getDatabaseProperties() {
      -  192  6
               return databaseProperties;
      +  190  3
               return databaseProperties;
      +  191   +
           }
      +  192   +
       
       193   -
           }
      +
           /**
       194   -
       
      -  195   -
           /**
      -  196  
            * Searches the CPE entries in the database and retrieves all entries for a
      -  197   +  195  
            * given vendor and product combination. The returned list will include all
      -  198   +  196  
            * versions of the product that are registered in the NVD CVE data.
      -  199   +  197  
            *
      -  200   +  198  
            * @param vendor the identified vendor name of the dependency being analyzed
      -  201   +  199  
            * @param product the identified name of the product of the dependency being
      -  202   +  200  
            * analyzed
      -  203   +  201  
            * @return a set of vulnerable software
      -  204   +  202  
            */
      -  205   +  203  
           public Set<VulnerableSoftware> getCPEs(String vendor, String product) {
      -  206  6
               final Set<VulnerableSoftware> cpe = new HashSet<VulnerableSoftware>();
      -  207  6
               ResultSet rs = null;
      -  208  6
               PreparedStatement ps = null;
      -  209   +  204  3
               final Set<VulnerableSoftware> cpe = new HashSet<VulnerableSoftware>();
      +  205  3
               ResultSet rs = null;
      +  206  3
               PreparedStatement ps = null;
      +  207  
               try {
      -  210  6
                   ps = getConnection().prepareStatement(statementBundle.getString("SELECT_CPE_ENTRIES"));
      -  211  6
                   ps.setString(1, vendor);
      -  212  6
                   ps.setString(2, product);
      -  213  6
                   rs = ps.executeQuery();
      -  214   +  208  3
                   ps = getConnection().prepareStatement(statementBundle.getString("SELECT_CPE_ENTRIES"));
      +  209  3
                   ps.setString(1, vendor);
      +  210  3
                   ps.setString(2, product);
      +  211  3
                   rs = ps.executeQuery();
      +  212  
       
      -  215  224
                   while (rs.next()) {
      -  216  218
                       final VulnerableSoftware vs = new VulnerableSoftware();
      -  217  218
                       vs.setCpe(rs.getString(1));
      -  218  218
                       cpe.add(vs);
      -  219  218
                   }
      -  220  0
               } catch (SQLException ex) {
      -  221  0
                   LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details.");
      -  222  0
                   LOGGER.debug("", ex);
      -  223   +  213  112
                   while (rs.next()) {
      +  214  109
                       final VulnerableSoftware vs = new VulnerableSoftware();
      +  215  109
                       vs.setCpe(rs.getString(1));
      +  216  109
                       cpe.add(vs);
      +  217  109
                   }
      +  218  0
               } catch (SQLException ex) {
      +  219  0
                   LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details.");
      +  220  0
                   LOGGER.debug("", ex);
      +  221  
               } finally {
      -  224  6
                   DBUtils.closeResultSet(rs);
      -  225  6
                   DBUtils.closeStatement(ps);
      -  226  6
               }
      -  227  6
               return cpe;
      +  222  3
                   DBUtils.closeResultSet(rs);
      +  223  3
                   DBUtils.closeStatement(ps);
      +  224  3
               }
      +  225  3
               return cpe;
      +  226   +
           }
      +  227   +
       
       228   -
           }
      +
           /**
       229   -
       
      -  230   -
           /**
      -  231  
            * Returns the entire list of vendor/product combinations.
      -  232   +  230  
            *
      -  233   +  231  
            * @return the entire list of vendor/product combinations
      -  234   +  232  
            * @throws DatabaseException thrown when there is an error retrieving the
      -  235   +  233  
            * data from the DB
      -  236   +  234  
            */
      -  237   +  235  
           public Set<Pair<String, String>> getVendorProductList() throws DatabaseException {
      -  238  4
               final Set<Pair<String, String>> data = new HashSet<Pair<String, String>>();
      -  239  4
               ResultSet rs = null;
      -  240  4
               PreparedStatement ps = null;
      -  241   +  236  2
               final Set<Pair<String, String>> data = new HashSet<Pair<String, String>>();
      +  237  2
               ResultSet rs = null;
      +  238  2
               PreparedStatement ps = null;
      +  239  
               try {
      -  242  4
                   ps = getConnection().prepareStatement(statementBundle.getString("SELECT_VENDOR_PRODUCT_LIST"));
      -  243  4
                   rs = ps.executeQuery();
      -  244  103672
                   while (rs.next()) {
      -  245  103668
                       data.add(new Pair<String, String>(rs.getString(1), rs.getString(2)));
      -  246   +  240  2
                   ps = getConnection().prepareStatement(statementBundle.getString("SELECT_VENDOR_PRODUCT_LIST"));
      +  241  2
                   rs = ps.executeQuery();
      +  242  52140
                   while (rs.next()) {
      +  243  52138
                       data.add(new Pair<String, String>(rs.getString(1), rs.getString(2)));
      +  244  
                   }
      -  247  0
               } catch (SQLException ex) {
      -  248  0
                   final String msg = "An unexpected SQL Exception occurred; please see the verbose log for more details.";
      -  249  0
                   throw new DatabaseException(msg, ex);
      -  250   +  245  0
               } catch (SQLException ex) {
      +  246  0
                   final String msg = "An unexpected SQL Exception occurred; please see the verbose log for more details.";
      +  247  0
                   throw new DatabaseException(msg, ex);
      +  248  
               } finally {
      -  251  4
                   DBUtils.closeResultSet(rs);
      -  252  4
                   DBUtils.closeStatement(ps);
      -  253  4
               }
      -  254  4
               return data;
      +  249  2
                   DBUtils.closeResultSet(rs);
      +  250  2
                   DBUtils.closeStatement(ps);
      +  251  2
               }
      +  252  2
               return data;
      +  253   +
           }
      +  254   +
       
       255   -
           }
      +
           /**
       256   -
       
      -  257   -
           /**
      -  258  
            * Returns a set of properties.
      -  259   +  257  
            *
      -  260   +  258  
            * @return the properties from the database
      -  261   +  259  
            */
      -  262   +  260  
           Properties getProperties() {
      -  263  26
               final Properties prop = new Properties();
      -  264  26
               PreparedStatement ps = null;
      -  265  26
               ResultSet rs = null;
      -  266   +  261  13
               final Properties prop = new Properties();
      +  262  13
               PreparedStatement ps = null;
      +  263  13
               ResultSet rs = null;
      +  264  
               try {
      -  267  26
                   ps = getConnection().prepareStatement(statementBundle.getString("SELECT_PROPERTIES"));
      -  268  26
                   rs = ps.executeQuery();
      -  269  546
                   while (rs.next()) {
      -  270  520
                       prop.setProperty(rs.getString(1), rs.getString(2));
      -  271   +  265  13
                   ps = getConnection().prepareStatement(statementBundle.getString("SELECT_PROPERTIES"));
      +  266  13
                   rs = ps.executeQuery();
      +  267  273
                   while (rs.next()) {
      +  268  260
                       prop.setProperty(rs.getString(1), rs.getString(2));
      +  269  
                   }
      -  272  0
               } catch (SQLException ex) {
      -  273  0
                   LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details.");
      -  274  0
                   LOGGER.debug("", ex);
      -  275   +  270  0
               } catch (SQLException ex) {
      +  271  0
                   LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details.");
      +  272  0
                   LOGGER.debug("", ex);
      +  273  
               } finally {
      -  276  26
                   DBUtils.closeStatement(ps);
      -  277  26
                   DBUtils.closeResultSet(rs);
      -  278  26
               }
      -  279  26
               return prop;
      +  274  13
                   DBUtils.closeStatement(ps);
      +  275  13
                   DBUtils.closeResultSet(rs);
      +  276  13
               }
      +  277  13
               return prop;
      +  278   +
           }
      +  279   +
       
       280   -
           }
      +
           /**
       281   -
       
      -  282   -
           /**
      -  283  
            * Saves a property to the database.
      -  284   +  282  
            *
      -  285   +  283  
            * @param key the property key
      -  286   +  284  
            * @param value the property value
      -  287   +  285  
            */
      -  288   +  286  
           void saveProperty(String key, String value) {
      -  289   +  287  
               try {
      +  288   +
                   try {
      +  289  0
                       final PreparedStatement mergeProperty = getConnection().prepareStatement(statementBundle.getString("MERGE_PROPERTY"));
       290   -
                   try {
      -  291  0
                       final PreparedStatement mergeProperty = getConnection().prepareStatement(statementBundle.getString("MERGE_PROPERTY"));
      -  292  
                       try {
      -  293  0
                           mergeProperty.setString(1, key);
      -  294  0
                           mergeProperty.setString(2, value);
      -  295  0
                           mergeProperty.executeUpdate();
      -  296   +  291  0
                           mergeProperty.setString(1, key);
      +  292  0
                           mergeProperty.setString(2, value);
      +  293  0
                           mergeProperty.executeUpdate();
      +  294  
                       } finally {
      -  297  0
                           DBUtils.closeStatement(mergeProperty);
      -  298  0
                       }
      -  299  0
                   } catch (MissingResourceException mre) {
      -  300   +  295  0
                           DBUtils.closeStatement(mergeProperty);
      +  296  0
                       }
      +  297  0
                   } catch (MissingResourceException mre) {
      +  298  
                       // No Merge statement, so doing an Update/Insert...
      -  301  0
                       PreparedStatement updateProperty = null;
      -  302  0
                       PreparedStatement insertProperty = null;
      -  303   +  299  0
                       PreparedStatement updateProperty = null;
      +  300  0
                       PreparedStatement insertProperty = null;
      +  301  
                       try {
      -  304  0
                           updateProperty = getConnection().prepareStatement(statementBundle.getString("UPDATE_PROPERTY"));
      -  305  0
                           updateProperty.setString(1, value);
      -  306  0
                           updateProperty.setString(2, key);
      -  307  0
                           if (updateProperty.executeUpdate() == 0) {
      -  308  0
                               insertProperty = getConnection().prepareStatement(statementBundle.getString("INSERT_PROPERTY"));
      -  309  0
                               insertProperty.setString(1, key);
      -  310  0
                               insertProperty.setString(2, value);
      -  311  0
                               insertProperty.executeUpdate();
      -  312   +  302  0
                           updateProperty = getConnection().prepareStatement(statementBundle.getString("UPDATE_PROPERTY"));
      +  303  0
                           updateProperty.setString(1, value);
      +  304  0
                           updateProperty.setString(2, key);
      +  305  0
                           if (updateProperty.executeUpdate() == 0) {
      +  306  0
                               insertProperty = getConnection().prepareStatement(statementBundle.getString("INSERT_PROPERTY"));
      +  307  0
                               insertProperty.setString(1, key);
      +  308  0
                               insertProperty.setString(2, value);
      +  309  0
                               insertProperty.executeUpdate();
      +  310  
                           }
      -  313   +  311  
                       } finally {
      -  314  0
                           DBUtils.closeStatement(updateProperty);
      -  315  0
                           DBUtils.closeStatement(insertProperty);
      -  316  0
                       }
      -  317  0
                   }
      -  318  0
               } catch (SQLException ex) {
      -  319  0
                   LOGGER.warn("Unable to save property '{}' with a value of '{}' to the database", key, value);
      -  320  0
                   LOGGER.debug("", ex);
      -  321  0
               }
      -  322  0
           }
      +  312  0
                           DBUtils.closeStatement(updateProperty);
      +  313  0
                           DBUtils.closeStatement(insertProperty);
      +  314  0
                       }
      +  315  0
                   }
      +  316  0
               } catch (SQLException ex) {
      +  317  0
                   LOGGER.warn("Unable to save property '{}' with a value of '{}' to the database", key, value);
      +  318  0
                   LOGGER.debug("", ex);
      +  319  0
               }
      +  320  0
           }
      +  321   +
       
      +  322   +
           /**
       323   -
       
      -  324   -
           /**
      -  325  
            * Retrieves the vulnerabilities associated with the specified CPE.
      -  326   +  324  
            *
      -  327   +  325  
            * @param cpeStr the CPE name
      -  328   +  326  
            * @return a list of Vulnerabilities
      -  329   +  327  
            * @throws DatabaseException thrown if there is an exception retrieving data
      -  330   +  328  
            */
      -  331   +  329  
           public List<Vulnerability> getVulnerabilities(String cpeStr) throws DatabaseException {
      -  332  6
               final VulnerableSoftware cpe = new VulnerableSoftware();
      -  333   +  330  3
               final VulnerableSoftware cpe = new VulnerableSoftware();
      +  331  
               try {
      -  334  6
                   cpe.parseName(cpeStr);
      -  335  0
               } catch (UnsupportedEncodingException ex) {
      -  336  0
                   LOGGER.trace("", ex);
      -  337  6
               }
      -  338  6
               final DependencyVersion detectedVersion = parseDependencyVersion(cpe);
      -  339  6
               final List<Vulnerability> vulnerabilities = new ArrayList<Vulnerability>();
      -  340   +  332  3
                   cpe.parseName(cpeStr);
      +  333  0
               } catch (UnsupportedEncodingException ex) {
      +  334  0
                   LOGGER.trace("", ex);
      +  335  3
               }
      +  336  3
               final DependencyVersion detectedVersion = parseDependencyVersion(cpe);
      +  337  3
               final List<Vulnerability> vulnerabilities = new ArrayList<Vulnerability>();
      +  338  
       
      -  341  6
               PreparedStatement ps = null;
      -  342  6
               ResultSet rs = null;
      -  343   +  339  3
               PreparedStatement ps = null;
      +  340  3
               ResultSet rs = null;
      +  341  
               try {
      -  344  6
                   ps = getConnection().prepareStatement(statementBundle.getString("SELECT_CVE_FROM_SOFTWARE"));
      -  345  6
                   ps.setString(1, cpe.getVendor());
      -  346  6
                   ps.setString(2, cpe.getProduct());
      -  347  6
                   rs = ps.executeQuery();
      -  348  6
                   String currentCVE = "";
      -  349   +  342  3
                   ps = getConnection().prepareStatement(statementBundle.getString("SELECT_CVE_FROM_SOFTWARE"));
      +  343  3
                   ps.setString(1, cpe.getVendor());
      +  344  3
                   ps.setString(2, cpe.getProduct());
      +  345  3
                   rs = ps.executeQuery();
      +  346  3
                   String currentCVE = "";
      +  347  
       
      -  350  6
                   final Map<String, Boolean> vulnSoftware = new HashMap<String, Boolean>();
      -  351  564
                   while (rs.next()) {
      -  352  558
                       final String cveId = rs.getString(1);
      -  353  558
                       if (!currentCVE.equals(cveId)) { //check for match and add
      -  354  20
                           final Entry<String, Boolean> matchedCPE = getMatchingSoftware(vulnSoftware, cpe.getVendor(), cpe.getProduct(), detectedVersion);
      -  355  20
                           if (matchedCPE != null) {
      -  356  12
                               final Vulnerability v = getVulnerability(currentCVE);
      -  357  12
                               v.setMatchedCPE(matchedCPE.getKey(), matchedCPE.getValue() ? "Y" : null);
      -  358  12
                               vulnerabilities.add(v);
      -  359   +  348  3
                   final Map<String, Boolean> vulnSoftware = new HashMap<String, Boolean>();
      +  349  282
                   while (rs.next()) {
      +  350  279
                       final String cveId = rs.getString(1);
      +  351  279
                       if (!currentCVE.equals(cveId)) { //check for match and add
      +  352  10
                           final Entry<String, Boolean> matchedCPE = getMatchingSoftware(vulnSoftware, cpe.getVendor(), cpe.getProduct(), detectedVersion);
      +  353  10
                           if (matchedCPE != null) {
      +  354  6
                               final Vulnerability v = getVulnerability(currentCVE);
      +  355  6
                               v.setMatchedCPE(matchedCPE.getKey(), matchedCPE.getValue() ? "Y" : null);
      +  356  6
                               vulnerabilities.add(v);
      +  357  
                           }
      -  360  20
                           vulnSoftware.clear();
      -  361  20
                           currentCVE = cveId;
      -  362   +  358  10
                           vulnSoftware.clear();
      +  359  10
                           currentCVE = cveId;
      +  360  
                       }
      -  363   +  361  
       
      -  364  558
                       final String cpeId = rs.getString(2);
      -  365  558
                       final String previous = rs.getString(3);
      -  366  558
                       final Boolean p = previous != null && !previous.isEmpty();
      -  367  558
                       vulnSoftware.put(cpeId, p);
      -  368  558
                   }
      -  369   +  362  279
                       final String cpeId = rs.getString(2);
      +  363  279
                       final String previous = rs.getString(3);
      +  364  279
                       final Boolean p = previous != null && !previous.isEmpty();
      +  365  279
                       vulnSoftware.put(cpeId, p);
      +  366  279
                   }
      +  367  
                   //remember to process the last set of CVE/CPE entries
      -  370  6
                   final Entry<String, Boolean> matchedCPE = getMatchingSoftware(vulnSoftware, cpe.getVendor(), cpe.getProduct(), detectedVersion);
      -  371  6
                   if (matchedCPE != null) {
      -  372  4
                       final Vulnerability v = getVulnerability(currentCVE);
      -  373  4
                       v.setMatchedCPE(matchedCPE.getKey(), matchedCPE.getValue() ? "Y" : null);
      -  374  4
                       vulnerabilities.add(v);
      -  375   +  368  3
                   final Entry<String, Boolean> matchedCPE = getMatchingSoftware(vulnSoftware, cpe.getVendor(), cpe.getProduct(), detectedVersion);
      +  369  3
                   if (matchedCPE != null) {
      +  370  2
                       final Vulnerability v = getVulnerability(currentCVE);
      +  371  2
                       v.setMatchedCPE(matchedCPE.getKey(), matchedCPE.getValue() ? "Y" : null);
      +  372  2
                       vulnerabilities.add(v);
      +  373  
                   }
      -  376  0
               } catch (SQLException ex) {
      -  377  0
                   throw new DatabaseException("Exception retrieving vulnerability for " + cpeStr, ex);
      -  378   +  374  0
               } catch (SQLException ex) {
      +  375  0
                   throw new DatabaseException("Exception retrieving vulnerability for " + cpeStr, ex);
      +  376  
               } finally {
      -  379  6
                   DBUtils.closeResultSet(rs);
      -  380  6
                   DBUtils.closeStatement(ps);
      -  381  6
               }
      -  382  6
               return vulnerabilities;
      +  377  3
                   DBUtils.closeResultSet(rs);
      +  378  3
                   DBUtils.closeStatement(ps);
      +  379  3
               }
      +  380  3
               return vulnerabilities;
      +  381   +
           }
      +  382   +
       
       383   -
           }
      +
           /**
       384   -
       
      -  385   -
           /**
      -  386  
            * Gets a vulnerability for the provided CVE.
      -  387   +  385  
            *
      -  388   +  386  
            * @param cve the CVE to lookup
      -  389   +  387  
            * @return a vulnerability object
      -  390   +  388  
            * @throws DatabaseException if an exception occurs
      -  391   +  389  
            */
      -  392   +  390  
           public Vulnerability getVulnerability(String cve) throws DatabaseException {
      -  393  16
               PreparedStatement psV = null;
      -  394  16
               PreparedStatement psR = null;
      -  395  16
               PreparedStatement psS = null;
      -  396  16
               ResultSet rsV = null;
      -  397  16
               ResultSet rsR = null;
      -  398  16
               ResultSet rsS = null;
      -  399  16
               Vulnerability vuln = null;
      -  400   +  391  8
               PreparedStatement psV = null;
      +  392  8
               PreparedStatement psR = null;
      +  393  8
               PreparedStatement psS = null;
      +  394  8
               ResultSet rsV = null;
      +  395  8
               ResultSet rsR = null;
      +  396  8
               ResultSet rsS = null;
      +  397  8
               Vulnerability vuln = null;
      +  398  
       
      -  401   +  399  
               try {
      -  402  16
                   psV = getConnection().prepareStatement(statementBundle.getString("SELECT_VULNERABILITY"));
      -  403  16
                   psV.setString(1, cve);
      -  404  16
                   rsV = psV.executeQuery();
      -  405  16
                   if (rsV.next()) {
      -  406  16
                       vuln = new Vulnerability();
      -  407  16
                       vuln.setName(cve);
      -  408  16
                       vuln.setDescription(rsV.getString(2));
      -  409  16
                       String cwe = rsV.getString(3);
      -  410  16
                       if (cwe != null) {
      -  411  16
                           final String name = CweDB.getCweName(cwe);
      -  412  16
                           if (name != null) {
      -  413  14
                               cwe += ' ' + name;
      -  414   +  400  8
                   psV = getConnection().prepareStatement(statementBundle.getString("SELECT_VULNERABILITY"));
      +  401  8
                   psV.setString(1, cve);
      +  402  8
                   rsV = psV.executeQuery();
      +  403  8
                   if (rsV.next()) {
      +  404  8
                       vuln = new Vulnerability();
      +  405  8
                       vuln.setName(cve);
      +  406  8
                       vuln.setDescription(rsV.getString(2));
      +  407  8
                       String cwe = rsV.getString(3);
      +  408  8
                       if (cwe != null) {
      +  409  8
                           final String name = CweDB.getCweName(cwe);
      +  410  8
                           if (name != null) {
      +  411  7
                               cwe += ' ' + name;
      +  412  
                           }
      -  415   +  413  
                       }
      -  416  16
                       final int cveId = rsV.getInt(1);
      -  417  16
                       vuln.setCwe(cwe);
      -  418  16
                       vuln.setCvssScore(rsV.getFloat(4));
      -  419  16
                       vuln.setCvssAccessVector(rsV.getString(5));
      -  420  16
                       vuln.setCvssAccessComplexity(rsV.getString(6));
      -  421  16
                       vuln.setCvssAuthentication(rsV.getString(7));
      -  422  16
                       vuln.setCvssConfidentialityImpact(rsV.getString(8));
      -  423  16
                       vuln.setCvssIntegrityImpact(rsV.getString(9));
      -  424  16
                       vuln.setCvssAvailabilityImpact(rsV.getString(10));
      -  425   +  414  8
                       final int cveId = rsV.getInt(1);
      +  415  8
                       vuln.setCwe(cwe);
      +  416  8
                       vuln.setCvssScore(rsV.getFloat(4));
      +  417  8
                       vuln.setCvssAccessVector(rsV.getString(5));
      +  418  8
                       vuln.setCvssAccessComplexity(rsV.getString(6));
      +  419  8
                       vuln.setCvssAuthentication(rsV.getString(7));
      +  420  8
                       vuln.setCvssConfidentialityImpact(rsV.getString(8));
      +  421  8
                       vuln.setCvssIntegrityImpact(rsV.getString(9));
      +  422  8
                       vuln.setCvssAvailabilityImpact(rsV.getString(10));
      +  423  
       
      -  426  16
                       psR = getConnection().prepareStatement(statementBundle.getString("SELECT_REFERENCES"));
      -  427  16
                       psR.setInt(1, cveId);
      -  428  16
                       rsR = psR.executeQuery();
      -  429  152
                       while (rsR.next()) {
      -  430  136
                           vuln.addReference(rsR.getString(1), rsR.getString(2), rsR.getString(3));
      -  431   +  424  8
                       psR = getConnection().prepareStatement(statementBundle.getString("SELECT_REFERENCES"));
      +  425  8
                       psR.setInt(1, cveId);
      +  426  8
                       rsR = psR.executeQuery();
      +  427  76
                       while (rsR.next()) {
      +  428  68
                           vuln.addReference(rsR.getString(1), rsR.getString(2), rsR.getString(3));
      +  429  
                       }
      -  432  16
                       psS = getConnection().prepareStatement(statementBundle.getString("SELECT_SOFTWARE"));
      -  433  16
                       psS.setInt(1, cveId);
      -  434  16
                       rsS = psS.executeQuery();
      -  435  488
                       while (rsS.next()) {
      -  436  472
                           final String cpe = rsS.getString(1);
      -  437  472
                           final String prevVersion = rsS.getString(2);
      -  438  472
                           if (prevVersion == null) {
      -  439  456
                               vuln.addVulnerableSoftware(cpe);
      -  440   +  430  8
                       psS = getConnection().prepareStatement(statementBundle.getString("SELECT_SOFTWARE"));
      +  431  8
                       psS.setInt(1, cveId);
      +  432  8
                       rsS = psS.executeQuery();
      +  433  244
                       while (rsS.next()) {
      +  434  236
                           final String cpe = rsS.getString(1);
      +  435  236
                           final String prevVersion = rsS.getString(2);
      +  436  236
                           if (prevVersion == null) {
      +  437  228
                               vuln.addVulnerableSoftware(cpe);
      +  438  
                           } else {
      -  441  16
                               vuln.addVulnerableSoftware(cpe, prevVersion);
      +  439  8
                               vuln.addVulnerableSoftware(cpe, prevVersion);
      +  440   +
                           }
      +  441  236
                       }
       442   -
                           }
      -  443  472
                       }
      -  444  
                   }
      -  445  0
               } catch (SQLException ex) {
      -  446  0
                   throw new DatabaseException("Error retrieving " + cve, ex);
      -  447   +  443  0
               } catch (SQLException ex) {
      +  444  0
                   throw new DatabaseException("Error retrieving " + cve, ex);
      +  445  
               } finally {
      -  448  16
                   DBUtils.closeResultSet(rsV);
      -  449  16
                   DBUtils.closeResultSet(rsR);
      -  450  16
                   DBUtils.closeResultSet(rsS);
      -  451  16
                   DBUtils.closeStatement(psV);
      -  452  16
                   DBUtils.closeStatement(psR);
      -  453  16
                   DBUtils.closeStatement(psS);
      -  454  16
               }
      -  455  16
               return vuln;
      +  446  8
                   DBUtils.closeResultSet(rsV);
      +  447  8
                   DBUtils.closeResultSet(rsR);
      +  448  8
                   DBUtils.closeResultSet(rsS);
      +  449  8
                   DBUtils.closeStatement(psV);
      +  450  8
                   DBUtils.closeStatement(psR);
      +  451  8
                   DBUtils.closeStatement(psS);
      +  452  8
               }
      +  453  8
               return vuln;
      +  454   +
           }
      +  455   +
       
       456   -
           }
      +
           /**
       457   -
       
      -  458   -
           /**
      -  459  
            * Updates the vulnerability within the database. If the vulnerability does
      -  460   +  458  
            * not exist it will be added.
      -  461   +  459  
            *
      -  462   +  460  
            * @param vuln the vulnerability to add to the database
      -  463   +  461  
            * @throws DatabaseException is thrown if the database
      -  464   +  462  
            */
      -  465   +  463  
           public void updateVulnerability(Vulnerability vuln) throws DatabaseException {
      -  466  0
               PreparedStatement selectVulnerabilityId = null;
      -  467  0
               PreparedStatement deleteVulnerability = null;
      -  468  0
               PreparedStatement deleteReferences = null;
      -  469  0
               PreparedStatement deleteSoftware = null;
      -  470  0
               PreparedStatement updateVulnerability = null;
      -  471  0
               PreparedStatement insertVulnerability = null;
      -  472  0
               PreparedStatement insertReference = null;
      -  473  0
               PreparedStatement selectCpeId = null;
      -  474  0
               PreparedStatement insertCpe = null;
      -  475  0
               PreparedStatement insertSoftware = null;
      -  476   +  464  0
               PreparedStatement selectVulnerabilityId = null;
      +  465  0
               PreparedStatement deleteVulnerability = null;
      +  466  0
               PreparedStatement deleteReferences = null;
      +  467  0
               PreparedStatement deleteSoftware = null;
      +  468  0
               PreparedStatement updateVulnerability = null;
      +  469  0
               PreparedStatement insertVulnerability = null;
      +  470  0
               PreparedStatement insertReference = null;
      +  471  0
               PreparedStatement selectCpeId = null;
      +  472  0
               PreparedStatement insertCpe = null;
      +  473  0
               PreparedStatement insertSoftware = null;
      +  474  
       
      -  477   +  475  
               try {
      -  478  0
                   selectVulnerabilityId = getConnection().prepareStatement(statementBundle.getString("SELECT_VULNERABILITY_ID"));
      -  479  0
                   deleteVulnerability = getConnection().prepareStatement(statementBundle.getString("DELETE_VULNERABILITY"));
      -  480  0
                   deleteReferences = getConnection().prepareStatement(statementBundle.getString("DELETE_REFERENCE"));
      -  481  0
                   deleteSoftware = getConnection().prepareStatement(statementBundle.getString("DELETE_SOFTWARE"));
      -  482  0
                   updateVulnerability = getConnection().prepareStatement(statementBundle.getString("UPDATE_VULNERABILITY"));
      -  483  0
                   final String[] ids = {"id"};
      -  484  0
                   insertVulnerability = getConnection().prepareStatement(statementBundle.getString("INSERT_VULNERABILITY"),
      -  485   +  476  0
                   selectVulnerabilityId = getConnection().prepareStatement(statementBundle.getString("SELECT_VULNERABILITY_ID"));
      +  477  0
                   deleteVulnerability = getConnection().prepareStatement(statementBundle.getString("DELETE_VULNERABILITY"));
      +  478  0
                   deleteReferences = getConnection().prepareStatement(statementBundle.getString("DELETE_REFERENCE"));
      +  479  0
                   deleteSoftware = getConnection().prepareStatement(statementBundle.getString("DELETE_SOFTWARE"));
      +  480  0
                   updateVulnerability = getConnection().prepareStatement(statementBundle.getString("UPDATE_VULNERABILITY"));
      +  481  0
                   final String[] ids = {"id"};
      +  482  0
                   insertVulnerability = getConnection().prepareStatement(statementBundle.getString("INSERT_VULNERABILITY"),
      +  483  
                           //Statement.RETURN_GENERATED_KEYS);
      -  486   +  484  
                           ids);
      -  487  0
                   insertReference = getConnection().prepareStatement(statementBundle.getString("INSERT_REFERENCE"));
      -  488  0
                   selectCpeId = getConnection().prepareStatement(statementBundle.getString("SELECT_CPE_ID"));
      -  489  0
                   insertCpe = getConnection().prepareStatement(statementBundle.getString("INSERT_CPE"),
      -  490   +  485  0
                   insertReference = getConnection().prepareStatement(statementBundle.getString("INSERT_REFERENCE"));
      +  486  0
                   selectCpeId = getConnection().prepareStatement(statementBundle.getString("SELECT_CPE_ID"));
      +  487  0
                   insertCpe = getConnection().prepareStatement(statementBundle.getString("INSERT_CPE"),
      +  488  
                           //Statement.RETURN_GENERATED_KEYS);
      -  491   +  489  
                           ids);
      -  492  0
                   insertSoftware = getConnection().prepareStatement(statementBundle.getString("INSERT_SOFTWARE"));
      -  493  0
                   int vulnerabilityId = 0;
      -  494  0
                   selectVulnerabilityId.setString(1, vuln.getName());
      -  495  0
                   ResultSet rs = selectVulnerabilityId.executeQuery();
      -  496  0
                   if (rs.next()) {
      -  497  0
                       vulnerabilityId = rs.getInt(1);
      -  498   +  490  0
                   insertSoftware = getConnection().prepareStatement(statementBundle.getString("INSERT_SOFTWARE"));
      +  491  0
                   int vulnerabilityId = 0;
      +  492  0
                   selectVulnerabilityId.setString(1, vuln.getName());
      +  493  0
                   ResultSet rs = selectVulnerabilityId.executeQuery();
      +  494  0
                   if (rs.next()) {
      +  495  0
                       vulnerabilityId = rs.getInt(1);
      +  496  
                       // first delete any existing vulnerability info. We don't know what was updated. yes, slower but atm easier.
      -  499  0
                       deleteReferences.setInt(1, vulnerabilityId);
      -  500  0
                       deleteReferences.execute();
      -  501  0
                       deleteSoftware.setInt(1, vulnerabilityId);
      -  502  0
                       deleteSoftware.execute();
      -  503   +  497  0
                       deleteReferences.setInt(1, vulnerabilityId);
      +  498  0
                       deleteReferences.execute();
      +  499  0
                       deleteSoftware.setInt(1, vulnerabilityId);
      +  500  0
                       deleteSoftware.execute();
      +  501  
                   }
      -  504  0
                   DBUtils.closeResultSet(rs);
      -  505  0
                   rs = null;
      -  506   +  502  0
                   DBUtils.closeResultSet(rs);
      +  503  0
                   rs = null;
      +  504  
       
      -  507  0
                   if (vulnerabilityId != 0) {
      -  508  0
                       if (vuln.getDescription().contains("** REJECT **")) {
      -  509  0
                           deleteVulnerability.setInt(1, vulnerabilityId);
      -  510  0
                           deleteVulnerability.executeUpdate();
      -  511   +  505  0
                   if (vulnerabilityId != 0) {
      +  506  0
                       if (vuln.getDescription().contains("** REJECT **")) {
      +  507  0
                           deleteVulnerability.setInt(1, vulnerabilityId);
      +  508  0
                           deleteVulnerability.executeUpdate();
      +  509  
                       } else {
      -  512  0
                           updateVulnerability.setString(1, vuln.getDescription());
      -  513  0
                           updateVulnerability.setString(2, vuln.getCwe());
      -  514  0
                           updateVulnerability.setFloat(3, vuln.getCvssScore());
      -  515  0
                           updateVulnerability.setString(4, vuln.getCvssAccessVector());
      -  516  0
                           updateVulnerability.setString(5, vuln.getCvssAccessComplexity());
      -  517  0
                           updateVulnerability.setString(6, vuln.getCvssAuthentication());
      -  518  0
                           updateVulnerability.setString(7, vuln.getCvssConfidentialityImpact());
      -  519  0
                           updateVulnerability.setString(8, vuln.getCvssIntegrityImpact());
      -  520  0
                           updateVulnerability.setString(9, vuln.getCvssAvailabilityImpact());
      -  521  0
                           updateVulnerability.setInt(10, vulnerabilityId);
      -  522  0
                           updateVulnerability.executeUpdate();
      -  523   +  510  0
                           updateVulnerability.setString(1, vuln.getDescription());
      +  511  0
                           updateVulnerability.setString(2, vuln.getCwe());
      +  512  0
                           updateVulnerability.setFloat(3, vuln.getCvssScore());
      +  513  0
                           updateVulnerability.setString(4, vuln.getCvssAccessVector());
      +  514  0
                           updateVulnerability.setString(5, vuln.getCvssAccessComplexity());
      +  515  0
                           updateVulnerability.setString(6, vuln.getCvssAuthentication());
      +  516  0
                           updateVulnerability.setString(7, vuln.getCvssConfidentialityImpact());
      +  517  0
                           updateVulnerability.setString(8, vuln.getCvssIntegrityImpact());
      +  518  0
                           updateVulnerability.setString(9, vuln.getCvssAvailabilityImpact());
      +  519  0
                           updateVulnerability.setInt(10, vulnerabilityId);
      +  520  0
                           updateVulnerability.executeUpdate();
      +  521  
                       }
      -  524   +  522  
                   } else {
      -  525  0
                       insertVulnerability.setString(1, vuln.getName());
      -  526  0
                       insertVulnerability.setString(2, vuln.getDescription());
      -  527  0
                       insertVulnerability.setString(3, vuln.getCwe());
      -  528  0
                       insertVulnerability.setFloat(4, vuln.getCvssScore());
      -  529  0
                       insertVulnerability.setString(5, vuln.getCvssAccessVector());
      -  530  0
                       insertVulnerability.setString(6, vuln.getCvssAccessComplexity());
      -  531  0
                       insertVulnerability.setString(7, vuln.getCvssAuthentication());
      -  532  0
                       insertVulnerability.setString(8, vuln.getCvssConfidentialityImpact());
      -  533  0
                       insertVulnerability.setString(9, vuln.getCvssIntegrityImpact());
      -  534  0
                       insertVulnerability.setString(10, vuln.getCvssAvailabilityImpact());
      -  535  0
                       insertVulnerability.execute();
      -  536   +  523  0
                       insertVulnerability.setString(1, vuln.getName());
      +  524  0
                       insertVulnerability.setString(2, vuln.getDescription());
      +  525  0
                       insertVulnerability.setString(3, vuln.getCwe());
      +  526  0
                       insertVulnerability.setFloat(4, vuln.getCvssScore());
      +  527  0
                       insertVulnerability.setString(5, vuln.getCvssAccessVector());
      +  528  0
                       insertVulnerability.setString(6, vuln.getCvssAccessComplexity());
      +  529  0
                       insertVulnerability.setString(7, vuln.getCvssAuthentication());
      +  530  0
                       insertVulnerability.setString(8, vuln.getCvssConfidentialityImpact());
      +  531  0
                       insertVulnerability.setString(9, vuln.getCvssIntegrityImpact());
      +  532  0
                       insertVulnerability.setString(10, vuln.getCvssAvailabilityImpact());
      +  533  0
                       insertVulnerability.execute();
      +  534  
                       try {
      -  537  0
                           rs = insertVulnerability.getGeneratedKeys();
      -  538  0
                           rs.next();
      -  539  0
                           vulnerabilityId = rs.getInt(1);
      -  540  0
                       } catch (SQLException ex) {
      -  541  0
                           final String msg = String.format("Unable to retrieve id for new vulnerability for '%s'", vuln.getName());
      -  542  0
                           throw new DatabaseException(msg, ex);
      -  543   +  535  0
                           rs = insertVulnerability.getGeneratedKeys();
      +  536  0
                           rs.next();
      +  537  0
                           vulnerabilityId = rs.getInt(1);
      +  538  0
                       } catch (SQLException ex) {
      +  539  0
                           final String msg = String.format("Unable to retrieve id for new vulnerability for '%s'", vuln.getName());
      +  540  0
                           throw new DatabaseException(msg, ex);
      +  541  
                       } finally {
      -  544  0
                           DBUtils.closeResultSet(rs);
      -  545  0
                           rs = null;
      -  546  0
                       }
      -  547   +  542  0
                           DBUtils.closeResultSet(rs);
      +  543  0
                           rs = null;
      +  544  0
                       }
      +  545  
                   }
      -  548   +  546  
       
      -  549  0
                   for (Reference r : vuln.getReferences()) {
      -  550  0
                       insertReference.setInt(1, vulnerabilityId);
      -  551  0
                       insertReference.setString(2, r.getName());
      -  552  0
                       insertReference.setString(3, r.getUrl());
      -  553  0
                       insertReference.setString(4, r.getSource());
      -  554   +  547  0
                   for (Reference r : vuln.getReferences()) {
      +  548  0
                       insertReference.setInt(1, vulnerabilityId);
      +  549  0
                       insertReference.setString(2, r.getName());
      +  550  0
                       insertReference.setString(3, r.getUrl());
      +  551  0
                       insertReference.setString(4, r.getSource());
      +  552  
       
      -  555  0
                       if (batchSupported) {
      -  556  0
                           insertReference.addBatch();
      +  553  0
                       if (batchSupported) {
      +  554  0
                           insertReference.addBatch();
      +  555   +
                       } else {
      +  556  0
                           insertReference.execute();
       557   -
                       } else {
      -  558  0
                           insertReference.execute();
      +
                       }
      +  558  0
                   }
       559   -
                       }
      -  560  0
                   }
      -  561  
       
      -  562  0
                   if (batchSupported) {
      -  563  0
                       insertReference.executeBatch();
      -  564   +  560  0
                   if (batchSupported) {
      +  561  0
                       insertReference.executeBatch();
      +  562  
                   }
      -  565   +  563  
       
      -  566  0
                   for (VulnerableSoftware s : vuln.getVulnerableSoftware()) {
      -  567  0
                       int cpeProductId = 0;
      -  568  0
                       selectCpeId.setString(1, s.getName());
      -  569   +  564  0
                   for (VulnerableSoftware s : vuln.getVulnerableSoftware()) {
      +  565  0
                       int cpeProductId = 0;
      +  566  0
                       selectCpeId.setString(1, s.getName());
      +  567  
                       try {
      -  570  0
                           rs = selectCpeId.executeQuery();
      -  571  0
                           if (rs.next()) {
      -  572  0
                               cpeProductId = rs.getInt(1);
      -  573   +  568  0
                           rs = selectCpeId.executeQuery();
      +  569  0
                           if (rs.next()) {
      +  570  0
                               cpeProductId = rs.getInt(1);
      +  571  
                           }
      -  574  0
                       } catch (SQLException ex) {
      -  575  0
                           throw new DatabaseException("Unable to get primary key for new cpe: " + s.getName(), ex);
      -  576   +  572  0
                       } catch (SQLException ex) {
      +  573  0
                           throw new DatabaseException("Unable to get primary key for new cpe: " + s.getName(), ex);
      +  574  
                       } finally {
      -  577  0
                           DBUtils.closeResultSet(rs);
      -  578  0
                           rs = null;
      -  579  0
                       }
      -  580   +  575  0
                           DBUtils.closeResultSet(rs);
      +  576  0
                           rs = null;
      +  577  0
                       }
      +  578  
       
      -  581  0
                       if (cpeProductId == 0) {
      -  582  0
                           insertCpe.setString(1, s.getName());
      -  583  0
                           insertCpe.setString(2, s.getVendor());
      -  584  0
                           insertCpe.setString(3, s.getProduct());
      -  585  0
                           insertCpe.executeUpdate();
      -  586  0
                           cpeProductId = DBUtils.getGeneratedKey(insertCpe);
      -  587   +  579  0
                       if (cpeProductId == 0) {
      +  580  0
                           insertCpe.setString(1, s.getName());
      +  581  0
                           insertCpe.setString(2, s.getVendor());
      +  582  0
                           insertCpe.setString(3, s.getProduct());
      +  583  0
                           insertCpe.executeUpdate();
      +  584  0
                           cpeProductId = DBUtils.getGeneratedKey(insertCpe);
      +  585  
                       }
      -  588  0
                       if (cpeProductId == 0) {
      -  589  0
                           throw new DatabaseException("Unable to retrieve cpeProductId - no data returned");
      -  590   +  586  0
                       if (cpeProductId == 0) {
      +  587  0
                           throw new DatabaseException("Unable to retrieve cpeProductId - no data returned");
      +  588  
                       }
      -  591   +  589  
       
      -  592  0
                       insertSoftware.setInt(1, vulnerabilityId);
      -  593  0
                       insertSoftware.setInt(2, cpeProductId);
      -  594   +  590  0
                       insertSoftware.setInt(1, vulnerabilityId);
      +  591  0
                       insertSoftware.setInt(2, cpeProductId);
      +  592  
       
      -  595  0
                       if (s.getPreviousVersion() == null) {
      -  596  0
                           insertSoftware.setNull(3, java.sql.Types.VARCHAR);
      +  593  0
                       if (s.getPreviousVersion() == null) {
      +  594  0
                           insertSoftware.setNull(3, java.sql.Types.VARCHAR);
      +  595   +
                       } else {
      +  596  0
                           insertSoftware.setString(3, s.getPreviousVersion());
       597   -
                       } else {
      -  598  0
                           insertSoftware.setString(3, s.getPreviousVersion());
      -  599  
                       }
      -  600  0
                       if (batchSupported) {
      -  601  0
                           insertSoftware.addBatch();
      -  602   +  598  0
                       if (batchSupported) {
      +  599  0
                           insertSoftware.addBatch();
      +  600  
                       } else {
      -  603   +  601  
                           try {
      -  604  0
                               insertSoftware.execute();
      -  605  0
                           } catch (SQLException ex) {
      -  606  0
                               if (ex.getMessage().contains("Duplicate entry")) {
      -  607  0
                                   final String msg = String.format("Duplicate software key identified in '%s:%s'", vuln.getName(), s.getName());
      -  608  0
                                   LOGGER.debug(msg, ex);
      -  609  0
                               } else {
      -  610  0
                                   throw ex;
      -  611   +  602  0
                               insertSoftware.execute();
      +  603  0
                           } catch (SQLException ex) {
      +  604  0
                               if (ex.getMessage().contains("Duplicate entry")) {
      +  605  0
                                   final String msg = String.format("Duplicate software key identified in '%s:%s'", vuln.getName(), s.getName());
      +  606  0
                                   LOGGER.debug(msg, ex);
      +  607  0
                               } else {
      +  608  0
                                   throw ex;
      +  609  
                               }
      -  612  0
                           }
      -  613   +  610  0
                           }
      +  611  
                       }
      -  614  0
                   }
      -  615  0
                   if (batchSupported) {
      -  616  0
                       insertSoftware.executeBatch();
      -  617   +  612  0
                   }
      +  613  0
                   if (batchSupported) {
      +  614  0
                       insertSoftware.executeBatch();
      +  615  
                   }
      -  618  0
               } catch (SQLException ex) {
      -  619  0
                   final String msg = String.format("Error updating '%s'", vuln.getName());
      -  620  0
                   LOGGER.debug(msg, ex);
      -  621  0
                   throw new DatabaseException(msg, ex);
      -  622   +  616  0
               } catch (SQLException ex) {
      +  617  0
                   final String msg = String.format("Error updating '%s'", vuln.getName());
      +  618  0
                   LOGGER.debug(msg, ex);
      +  619  0
                   throw new DatabaseException(msg, ex);
      +  620  
               } finally {
      -  623  0
                   DBUtils.closeStatement(selectVulnerabilityId);
      -  624  0
                   DBUtils.closeStatement(deleteReferences);
      -  625  0
                   DBUtils.closeStatement(deleteSoftware);
      -  626  0
                   DBUtils.closeStatement(updateVulnerability);
      -  627  0
                   DBUtils.closeStatement(deleteVulnerability);
      -  628  0
                   DBUtils.closeStatement(insertVulnerability);
      -  629  0
                   DBUtils.closeStatement(insertReference);
      -  630  0
                   DBUtils.closeStatement(selectCpeId);
      -  631  0
                   DBUtils.closeStatement(insertCpe);
      -  632  0
                   DBUtils.closeStatement(insertSoftware);
      -  633  0
               }
      -  634  0
           }
      +  621  0
                   DBUtils.closeStatement(selectVulnerabilityId);
      +  622  0
                   DBUtils.closeStatement(deleteReferences);
      +  623  0
                   DBUtils.closeStatement(deleteSoftware);
      +  624  0
                   DBUtils.closeStatement(updateVulnerability);
      +  625  0
                   DBUtils.closeStatement(deleteVulnerability);
      +  626  0
                   DBUtils.closeStatement(insertVulnerability);
      +  627  0
                   DBUtils.closeStatement(insertReference);
      +  628  0
                   DBUtils.closeStatement(selectCpeId);
      +  629  0
                   DBUtils.closeStatement(insertCpe);
      +  630  0
                   DBUtils.closeStatement(insertSoftware);
      +  631  0
               }
      +  632  0
           }
      +  633   +
       
      +  634   +
           /**
       635   -
       
      -  636   -
           /**
      -  637  
            * Checks to see if data exists so that analysis can be performed.
      -  638   +  636  
            *
      -  639   +  637  
            * @return <code>true</code> if data exists; otherwise <code>false</code>
      -  640   +  638  
            */
      -  641   +  639  
           public boolean dataExists() {
      -  642  4
               Statement cs = null;
      -  643  4
               ResultSet rs = null;
      -  644   +  640  2
               Statement cs = null;
      +  641  2
               ResultSet rs = null;
      +  642  
               try {
      -  645  4
                   cs = conn.createStatement();
      -  646  4
                   rs = cs.executeQuery("SELECT COUNT(*) records FROM cpeEntry");
      -  647  4
                   if (rs.next()) {
      -  648  4
                       if (rs.getInt(1) > 0) {
      -  649  8
                           return true;
      -  650   +  643  2
                   cs = conn.createStatement();
      +  644  2
                   rs = cs.executeQuery("SELECT COUNT(*) records FROM cpeEntry");
      +  645  2
                   if (rs.next()) {
      +  646  2
                       if (rs.getInt(1) > 0) {
      +  647  4
                           return true;
      +  648  
                       }
      +  649   +
                   }
      +  650  0
               } catch (SQLException ex) {
       651   -
                   }
      -  652  0
               } catch (SQLException ex) {
      -  653  
                   String dd;
      -  654   +  652  
                   try {
      -  655  0
                       dd = Settings.getDataDirectory().getAbsolutePath();
      -  656  0
                   } catch (IOException ex1) {
      -  657  0
                       dd = Settings.getString(Settings.KEYS.DATA_DIRECTORY);
      -  658  0
                   }
      -  659  0
                   LOGGER.error("Unable to access the local database.\n\nEnsure that '{}' is a writable directory. "
      -  660   +  653  0
                       dd = Settings.getDataDirectory().getAbsolutePath();
      +  654  0
                   } catch (IOException ex1) {
      +  655  0
                       dd = Settings.getString(Settings.KEYS.DATA_DIRECTORY);
      +  656  0
                   }
      +  657  0
                   LOGGER.error("Unable to access the local database.\n\nEnsure that '{}' is a writable directory. "
      +  658  
                           + "If the problem persist try deleting the files in '{}' and running {} again. If the problem continues, please "
      -  661   +  659  
                           + "create a log file (see documentation at http://jeremylong.github.io/DependencyCheck/) and open a ticket at "
      -  662   +  660  
                           + "https://github.com/jeremylong/DependencyCheck/issues and include the log file.\n\n",
      -  663  0
                           dd, dd, Settings.getString(Settings.KEYS.APPLICATION_VAME));
      -  664  0
                   LOGGER.debug("", ex);
      -  665   +  661  0
                           dd, dd, Settings.getString(Settings.KEYS.APPLICATION_VAME));
      +  662  0
                   LOGGER.debug("", ex);
      +  663  
               } finally {
      -  666  4
                   DBUtils.closeResultSet(rs);
      -  667  4
                   DBUtils.closeStatement(cs);
      -  668  0
               }
      -  669  0
               return false;
      -  670   +  664  2
                   DBUtils.closeResultSet(rs);
      +  665  2
                   DBUtils.closeStatement(cs);
      +  666  0
               }
      +  667  0
               return false;
      +  668  
           }
      +  669   +
       
      +  670   +
           /**
       671   -
       
      -  672   -
           /**
      -  673  
            * It is possible that orphaned rows may be generated during database
      -  674   +  672  
            * updates. This should be called after all updates have been completed to
      -  675   +  673  
            * ensure orphan entries are removed.
      -  676   +  674  
            */
      -  677   +  675  
           public void cleanupDatabase() {
      -  678  0
               PreparedStatement ps = null;
      -  679   +  676  0
               PreparedStatement ps = null;
      +  677  
               try {
      -  680  0
                   ps = getConnection().prepareStatement(statementBundle.getString("CLEANUP_ORPHANS"));
      -  681  0
                   if (ps != null) {
      -  682  0
                       ps.executeUpdate();
      -  683   +  678  0
                   ps = getConnection().prepareStatement(statementBundle.getString("CLEANUP_ORPHANS"));
      +  679  0
                   if (ps != null) {
      +  680  0
                       ps.executeUpdate();
      +  681  
                   }
      -  684  0
               } catch (SQLException ex) {
      -  685  0
                   LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details.");
      -  686  0
                   LOGGER.debug("", ex);
      -  687   +  682  0
               } catch (SQLException ex) {
      +  683  0
                   LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details.");
      +  684  0
                   LOGGER.debug("", ex);
      +  685  
               } finally {
      -  688  0
                   DBUtils.closeStatement(ps);
      -  689  0
               }
      -  690  0
           }
      -  691   +  686  0
                   DBUtils.closeStatement(ps);
      +  687  0
               }
      +  688  0
           }
      +  689  
       
      -  692   +  690  
           /**
      -  693   +  691  
            * Determines if the given identifiedVersion is affected by the given cpeId
      -  694   +  692  
            * and previous version flag. A non-null, non-empty string passed to the
      -  695   +  693  
            * previous version argument indicates that all previous versions are
      -  696   +  694  
            * affected.
      -  697   +  695  
            *
      -  698   +  696  
            * @param vendor the vendor of the dependency being analyzed
      -  699   +  697  
            * @param product the product name of the dependency being analyzed
      -  700   +  698  
            * @param vulnerableSoftware a map of the vulnerable software with a boolean
      -  701   +  699  
            * indicating if all previous versions are affected
      -  702   +  700  
            * @param identifiedVersion the identified version of the dependency being
      -  703   +  701  
            * analyzed
      -  704   +  702  
            * @return true if the identified version is affected, otherwise false
      -  705   +  703  
            */
      -  706   +  704  
           Entry<String, Boolean> getMatchingSoftware(Map<String, Boolean> vulnerableSoftware, String vendor, String product,
      -  707   +  705  
                   DependencyVersion identifiedVersion) {
      +  706   +
       
      +  707  13
               final boolean isVersionTwoADifferentProduct = "apache".equals(vendor) && "struts".equals(product);
       708  
       
      -  709  26
               final boolean isVersionTwoADifferentProduct = "apache".equals(vendor) && "struts".equals(product);
      -  710   -
       
      -  711  26
               final Set<String> majorVersionsAffectingAllPrevious = new HashSet<String>();
      -  712  26
               final boolean matchesAnyPrevious = identifiedVersion == null || "-".equals(identifiedVersion.toString());
      -  713  26
               String majorVersionMatch = null;
      -  714  26
               for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) {
      -  715  558
                   final DependencyVersion v = parseDependencyVersion(entry.getKey());
      -  716  558
                   if (v == null || "-".equals(v.toString())) { //all versions
      -  717  0
                       return entry;
      -  718   +  709  13
               final Set<String> majorVersionsAffectingAllPrevious = new HashSet<String>();
      +  710  13
               final boolean matchesAnyPrevious = identifiedVersion == null || "-".equals(identifiedVersion.toString());
      +  711  13
               String majorVersionMatch = null;
      +  712  13
               for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) {
      +  713  279
                   final DependencyVersion v = parseDependencyVersion(entry.getKey());
      +  714  279
                   if (v == null || "-".equals(v.toString())) { //all versions
      +  715  0
                       return entry;
      +  716  
                   }
      -  719  558
                   if (entry.getValue()) {
      -  720  16
                       if (matchesAnyPrevious) {
      -  721  0
                           return entry;
      -  722   +  717  279
                   if (entry.getValue()) {
      +  718  8
                       if (matchesAnyPrevious) {
      +  719  0
                           return entry;
      +  720  
                       }
      -  723  16
                       if (identifiedVersion != null && identifiedVersion.getVersionParts().get(0).equals(v.getVersionParts().get(0))) {
      -  724  12
                           majorVersionMatch = v.getVersionParts().get(0);
      +  721  8
                       if (identifiedVersion != null && identifiedVersion.getVersionParts().get(0).equals(v.getVersionParts().get(0))) {
      +  722  6
                           majorVersionMatch = v.getVersionParts().get(0);
      +  723   +
                       }
      +  724  8
                       majorVersionsAffectingAllPrevious.add(v.getVersionParts().get(0));
       725   -
                       }
      -  726  16
                       majorVersionsAffectingAllPrevious.add(v.getVersionParts().get(0));
      -  727  
                   }
      -  728  558
               }
      -  729  26
               if (matchesAnyPrevious) {
      -  730  0
                   return null;
      -  731   +  726  279
               }
      +  727  13
               if (matchesAnyPrevious) {
      +  728  0
                   return null;
      +  729  
               }
      +  730   +
       
      +  731  13
               final boolean canSkipVersions = majorVersionMatch != null && majorVersionsAffectingAllPrevious.size() > 1;
       732   -
       
      -  733  26
               final boolean canSkipVersions = majorVersionMatch != null && majorVersionsAffectingAllPrevious.size() > 1;
      -  734  
               //yes, we are iterating over this twice. The first time we are skipping versions those that affect all versions
      -  735   +  733  
               //then later we process those that affect all versions. This could be done with sorting...
      -  736  26
               for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) {
      -  737  474
                   if (!entry.getValue()) {
      -  738  458
                       final DependencyVersion v = parseDependencyVersion(entry.getKey());
      -  739   +  734  13
               for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) {
      +  735  237
                   if (!entry.getValue()) {
      +  736  229
                       final DependencyVersion v = parseDependencyVersion(entry.getKey());
      +  737  
                       //this can't dereference a null 'majorVersionMatch' as canSkipVersions accounts for this.
      -  740  458
                       if (canSkipVersions && !majorVersionMatch.equals(v.getVersionParts().get(0))) {
      -  741  16
                           continue;
      +  738  229
                       if (canSkipVersions && !majorVersionMatch.equals(v.getVersionParts().get(0))) {
      +  739  8
                           continue;
      +  740   +
                       }
      +  741   +
                       //this can't dereference a null 'identifiedVersion' because if it was null we would have exited
       742   -
                       }
      -  743   -
                       //this can't dereference a null 'identifiedVersion' because if it was null we would have exited
      -  744  
                       //in the above loop or just after loop (if matchesAnyPrevious return null).
      -  745  442
                       if (identifiedVersion.equals(v)) {
      -  746  16
                           return entry;
      -  747   +  743  221
                       if (identifiedVersion.equals(v)) {
      +  744  8
                           return entry;
      +  745  
                       }
      -  748   +  746  
                   }
      -  749  442
               }
      -  750  10
               for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) {
      -  751  112
                   if (entry.getValue()) {
      -  752  0
                       final DependencyVersion v = parseDependencyVersion(entry.getKey());
      -  753   +  747  221
               }
      +  748  5
               for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) {
      +  749  56
                   if (entry.getValue()) {
      +  750  0
                       final DependencyVersion v = parseDependencyVersion(entry.getKey());
      +  751  
                       //this can't dereference a null 'majorVersionMatch' as canSkipVersions accounts for this.
      -  754  0
                       if (canSkipVersions && !majorVersionMatch.equals(v.getVersionParts().get(0))) {
      -  755  0
                           continue;
      -  756   +  752  0
                       if (canSkipVersions && !majorVersionMatch.equals(v.getVersionParts().get(0))) {
      +  753  0
                           continue;
      +  754  
                       }
      -  757   +  755  
                       //this can't dereference a null 'identifiedVersion' because if it was null we would have exited
      -  758   +  756  
                       //in the above loop or just after loop (if matchesAnyPrevious return null).
      -  759  0
                       if (entry.getValue() && identifiedVersion.compareTo(v) <= 0) {
      -  760  0
                           if (!(isVersionTwoADifferentProduct && !identifiedVersion.getVersionParts().get(0).equals(v.getVersionParts().get(0)))) {
      -  761  0
                               return entry;
      -  762   +  757  0
                       if (entry.getValue() && identifiedVersion.compareTo(v) <= 0) {
      +  758  0
                           if (!(isVersionTwoADifferentProduct && !identifiedVersion.getVersionParts().get(0).equals(v.getVersionParts().get(0)))) {
      +  759  0
                               return entry;
      +  760  
                           }
      -  763   +  761  
                       }
      -  764   +  762  
                   }
      -  765  112
               }
      -  766  10
               return null;
      +  763  56
               }
      +  764  5
               return null;
      +  765   +
           }
      +  766   +
       
       767   -
           }
      +
           /**
       768   -
       
      -  769   -
           /**
      -  770  
            * Parses the version (including revision) from a CPE identifier. If no
      -  771   +  769  
            * version is identified then a '-' is returned.
      -  772   +  770  
            *
      -  773   +  771  
            * @param cpeStr a cpe identifier
      +  772   +
            * @return a dependency version
      +  773   +
            */
       774   -
            * @return a dependency version
      -  775   -
            */
      -  776  
           private DependencyVersion parseDependencyVersion(String cpeStr) {
      -  777  1016
               final VulnerableSoftware cpe = new VulnerableSoftware();
      -  778   +  775  508
               final VulnerableSoftware cpe = new VulnerableSoftware();
      +  776  
               try {
      -  779  1016
                   cpe.parseName(cpeStr);
      -  780  0
               } catch (UnsupportedEncodingException ex) {
      -  781   +  777  508
                   cpe.parseName(cpeStr);
      +  778  0
               } catch (UnsupportedEncodingException ex) {
      +  779  
                   //never going to happen.
      -  782  0
                   LOGGER.trace("", ex);
      -  783  1016
               }
      -  784  1016
               return parseDependencyVersion(cpe);
      +  780  0
                   LOGGER.trace("", ex);
      +  781  508
               }
      +  782  508
               return parseDependencyVersion(cpe);
      +  783   +
           }
      +  784   +
       
       785   -
           }
      +
           /**
       786   -
       
      -  787   -
           /**
      -  788  
            * Takes a CPE and parses out the version number. If no version is
      -  789   +  787  
            * identified then a '-' is returned.
      -  790   +  788  
            *
      -  791   +  789  
            * @param cpe a cpe object
      -  792   +  790  
            * @return a dependency version
      -  793   +  791  
            */
      -  794   +  792  
           private DependencyVersion parseDependencyVersion(VulnerableSoftware cpe) {
      -  795   +  793  
               final DependencyVersion cpeVersion;
      -  796  1022
               if (cpe.getVersion() != null && !cpe.getVersion().isEmpty()) {
      -  797   +  794  511
               if (cpe.getVersion() != null && !cpe.getVersion().isEmpty()) {
      +  795  
                   final String versionText;
      -  798  1022
                   if (cpe.getUpdate() != null && !cpe.getUpdate().isEmpty()) {
      -  799  226
                       versionText = String.format("%s.%s", cpe.getVersion(), cpe.getUpdate());
      -  800   +  796  511
                   if (cpe.getUpdate() != null && !cpe.getUpdate().isEmpty()) {
      +  797  113
                       versionText = String.format("%s.%s", cpe.getVersion(), cpe.getUpdate());
      +  798  
                   } else {
      -  801  796
                       versionText = cpe.getVersion();
      -  802   +  799  398
                       versionText = cpe.getVersion();
      +  800  
                   }
      -  803  1022
                   cpeVersion = DependencyVersionUtil.parseVersion(versionText);
      -  804  1022
               } else {
      -  805  0
                   cpeVersion = new DependencyVersion("-");
      -  806   +  801  511
                   cpeVersion = DependencyVersionUtil.parseVersion(versionText);
      +  802  511
               } else {
      +  803  0
                   cpeVersion = new DependencyVersion("-");
      +  804  
               }
      -  807  1022
               return cpeVersion;
      -  808   +  805  511
               return cpeVersion;
      +  806  
           }
      +  807   +
       
      +  808   +
           /**
       809   -
       
      -  810   -
           /**
      -  811  
            * This method is only referenced in unused code.
      -  812   +  810  
            *
      -  813   +  811  
            * Deletes unused dictionary entries from the database.
      -  814   +  812  
            */
      -  815   +  813  
           public void deleteUnusedCpe() {
      -  816  0
               CallableStatement cs = null;
      -  817   +  814  0
               PreparedStatement ps = null;
      +  815  
               try {
      -  818  0
                   cs = getConnection().prepareCall(statementBundle.getString("DELETE_UNUSED_DICT_CPE"));
      -  819  0
                   cs.executeUpdate();
      -  820  0
               } catch (SQLException ex) {
      -  821  0
                   LOGGER.error("Unable to delete CPE dictionary entries", ex);
      -  822   +  816  0
                   ps = getConnection().prepareStatement(statementBundle.getString("DELETE_UNUSED_DICT_CPE"));
      +  817  0
                   ps.executeUpdate();
      +  818  0
               } catch (SQLException ex) {
      +  819  0
                   LOGGER.error("Unable to delete CPE dictionary entries", ex);
      +  820  
               } finally {
      -  823  0
                   DBUtils.closeStatement(cs);
      -  824  0
               }
      -  825  0
           }
      -  826   +  821  0
                   DBUtils.closeStatement(ps);
      +  822  0
               }
      +  823  0
           }
      +  824  
       
      -  827   +  825  
           /**
      -  828   +  826  
            * This method is only referenced in unused code and will likely break on
      -  829   +  827  
            * MySQL if ever used due to the MERGE statement.
      +  828   +
            *
      +  829   +
            * Merges CPE entries into the database.
       830  
            *
       831   -
            * Merges CPE entries into the database.
      -  832   -
            *
      -  833  
            * @param cpe the CPE identifier
      -  834   +  832  
            * @param vendor the CPE vendor
      -  835   +  833  
            * @param product the CPE product
      -  836   +  834  
            */
      -  837   +  835  
           public void addCpe(String cpe, String vendor, String product) {
      -  838  0
               PreparedStatement ps = null;
      -  839   +  836  0
               PreparedStatement ps = null;
      +  837  
               try {
      -  840  0
                   ps = getConnection().prepareCall(statementBundle.getString("ADD_DICT_CPE"));
      -  841  0
                   ps.setString(1, cpe);
      -  842  0
                   ps.setString(2, vendor);
      -  843  0
                   ps.setString(3, product);
      -  844  0
                   ps.executeUpdate();
      -  845  0
               } catch (SQLException ex) {
      -  846  0
                   LOGGER.error("Unable to add CPE dictionary entry", ex);
      -  847   +  838  0
                   ps = getConnection().prepareStatement(statementBundle.getString("ADD_DICT_CPE"));
      +  839  0
                   ps.setString(1, cpe);
      +  840  0
                   ps.setString(2, vendor);
      +  841  0
                   ps.setString(3, product);
      +  842  0
                   ps.executeUpdate();
      +  843  0
               } catch (SQLException ex) {
      +  844  0
                   LOGGER.error("Unable to add CPE dictionary entry", ex);
      +  845  
               } finally {
      -  848  0
                   DBUtils.closeStatement(ps);
      -  849  0
               }
      -  850  0
           }
      -  851   +  846  0
                   DBUtils.closeStatement(ps);
      +  847  0
               }
      +  848  0
           }
      +  849  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.DatabaseException.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.DatabaseException.html index 409b13ce0..fecdb29b2 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.DatabaseException.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.DatabaseException.html @@ -131,6 +131,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.DatabaseProperties.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.DatabaseProperties.html index ad662ca8c..3bec7a7e5 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.DatabaseProperties.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.DatabaseProperties.html @@ -99,7 +99,7 @@
            * The Logger.
       41  
            */
      -  42  2
           private static final Logger LOGGER = LoggerFactory.getLogger(DatabaseProperties.class);
      +  42  1
           private static final Logger LOGGER = LoggerFactory.getLogger(DatabaseProperties.class);
       43  
           /**
       44   @@ -182,10 +182,10 @@
            * @param cveDB the database object holding the properties
       83  
            */
      -  84  26
           DatabaseProperties(CveDB cveDB) {
      -  85  26
               this.cveDB = cveDB;
      -  86  26
               this.properties = cveDB.getProperties();
      -  87  26
           }
      +  84  13
           DatabaseProperties(CveDB cveDB) {
      +  85  13
               this.cveDB = cveDB;
      +  86  13
               this.properties = cveDB.getProperties();
      +  87  13
           }
       88  
       
       89   @@ -302,7 +302,7 @@
            */
       150  
           public Properties getProperties() {
      -  151  2
               return properties;
      +  151  1
               return properties;
       152  
           }
       153   @@ -352,6 +352,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.DriverLoadException.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.DriverLoadException.html index b3eb3366f..1795e002e 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.DriverLoadException.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.DriverLoadException.html @@ -125,12 +125,12 @@
            */
       56  
           public DriverLoadException(String msg, Throwable ex) {
      -  57  6
               super(msg, ex);
      -  58  6
           }
      +  57  3
               super(msg, ex);
      +  58  3
           }
       59  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.DriverLoader.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.DriverLoader.html index a681eeb81..41ffda4e6 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.DriverLoader.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.DriverLoader.html @@ -106,7 +106,7 @@
            * The logger.
       44  
            */
      -  45  2
           private static final Logger LOGGER = LoggerFactory.getLogger(DriverLoader.class);
      +  45  1
           private static final Logger LOGGER = LoggerFactory.getLogger(DriverLoader.class);
       46  
       
       47   @@ -135,8 +135,8 @@
            */
       60  
           public static Driver load(String className) throws DriverLoadException {
      -  61  8
               final ClassLoader loader = DriverLoader.class.getClassLoader(); //ClassLoader.getSystemClassLoader();
      -  62  8
               return load(className, loader);
      +  61  4
               final ClassLoader loader = DriverLoader.class.getClassLoader(); //ClassLoader.getSystemClassLoader();
      +  62  4
               return load(className, loader);
       63  
           }
       64   @@ -165,53 +165,53 @@
            */
       76  
           public static Driver load(String className, String pathToDriver) throws DriverLoadException {
      -  77  8
               final URLClassLoader parent = (URLClassLoader) ClassLoader.getSystemClassLoader();
      -  78  8
               final List<URL> urls = new ArrayList<URL>();
      -  79  8
               final String[] paths = pathToDriver.split(File.pathSeparator);
      -  80  18
               for (String path : paths) {
      -  81  10
                   final File file = new File(path);
      -  82  10
                   if (file.isDirectory()) {
      -  83  4
                       final File[] files = file.listFiles();
      -  84  4
                       if (files != null) {
      -  85  82
                           for (File f : files) {
      +  77  4
               final URLClassLoader parent = (URLClassLoader) ClassLoader.getSystemClassLoader();
      +  78  4
               final List<URL> urls = new ArrayList<URL>();
      +  79  4
               final String[] paths = pathToDriver.split(File.pathSeparator);
      +  80  9
               for (String path : paths) {
      +  81  5
                   final File file = new File(path);
      +  82  5
                   if (file.isDirectory()) {
      +  83  2
                       final File[] files = file.listFiles();
      +  84  2
                       if (files != null) {
      +  85  43
                           for (File f : files) {
       86  
                               try {
      -  87  78
                                   urls.add(f.toURI().toURL());
      +  87  41
                                   urls.add(f.toURI().toURL());
       88  0
                               } catch (MalformedURLException ex) {
       89  0
                                   LOGGER.debug("Unable to load database driver '{}'; invalid path provided '{}'",
       90  0
                                           className, f.getAbsoluteFile(), ex);
       91  0
                                   throw new DriverLoadException("Unable to load database driver. Invalid path provided", ex);
      -  92  78
                               }
      +  92  41
                               }
       93  
                           }
       94  
                       }
      -  95  4
                   } else if (file.exists()) {
      +  95  2
                   } else if (file.exists()) {
       96  
                       try {
      -  97  4
                           urls.add(file.toURI().toURL());
      +  97  2
                           urls.add(file.toURI().toURL());
       98  0
                       } catch (MalformedURLException ex) {
       99  0
                           LOGGER.debug("Unable to load database driver '{}'; invalid path provided '{}'",
       100  0
                                   className, file.getAbsoluteFile(), ex);
       101  0
                           throw new DriverLoadException("Unable to load database driver. Invalid path provided", ex);
      -  102  4
                       }
      +  102  2
                       }
       103  
                   }
       104  
               }
      -  105  8
               final URLClassLoader loader = AccessController.doPrivileged(new PrivilegedAction<URLClassLoader>() {
      +  105  4
               final URLClassLoader loader = AccessController.doPrivileged(new PrivilegedAction<URLClassLoader>() {
       106  
                   @Override
       107  
                   public URLClassLoader run() {
      -  108  8
                       return new URLClassLoader(urls.toArray(new URL[urls.size()]), parent);
      +  108  4
                       return new URLClassLoader(urls.toArray(new URL[urls.size()]), parent);
       109  
                   }
       110  
               });
       111  
       
      -  112  8
               return load(className, loader);
      +  112  4
               return load(className, loader);
       113  
           }
       114   @@ -236,19 +236,19 @@
           private static Driver load(String className, ClassLoader loader) throws DriverLoadException {
       124  
               try {
      -  125  16
                   final Class c = Class.forName(className, true, loader);
      +  125  8
                   final Class c = Class.forName(className, true, loader);
       126  
                   //final Class c = loader.loadClass(className);
      -  127  10
                   final Driver driver = (Driver) c.newInstance();
      -  128  10
                   final Driver shim = new DriverShim(driver);
      +  127  5
                   final Driver driver = (Driver) c.newInstance();
      +  128  5
                   final Driver shim = new DriverShim(driver);
       129  
                   //using the DriverShim to get around the fact that the DriverManager won't register a driver not in the base class path
      -  130  10
                   DriverManager.registerDriver(shim);
      -  131  10
                   return shim;
      -  132  6
               } catch (ClassNotFoundException ex) {
      -  133  6
                   final String msg = String.format("Unable to load database driver '%s'", className);
      -  134  6
                   LOGGER.debug(msg, ex);
      -  135  6
                   throw new DriverLoadException(msg, ex);
      +  130  5
                   DriverManager.registerDriver(shim);
      +  131  5
                   return shim;
      +  132  3
               } catch (ClassNotFoundException ex) {
      +  133  3
                   final String msg = String.format("Unable to load database driver '%s'", className);
      +  134  3
                   LOGGER.debug(msg, ex);
      +  135  3
                   throw new DriverLoadException(msg, ex);
       136  0
               } catch (InstantiationException ex) {
       137  0
                   final String msg = String.format("Unable to load database driver '%s'", className);
       138  0
                   LOGGER.debug(msg, ex);
      @@ -269,6 +269,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.DriverShim.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.DriverShim.html index 27e61559d..35e0ad329 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.DriverShim.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.nvdcve.DriverShim.html @@ -107,7 +107,7 @@
            * The logger.
       45  
            */
      -  46  2
           private static final Logger LOGGER = LoggerFactory.getLogger(DriverShim.class);
      +  46  1
           private static final Logger LOGGER = LoggerFactory.getLogger(DriverShim.class);
       47  
           /**
       48   @@ -128,9 +128,9 @@
            * @param driver the database driver to wrap
       56  
            */
      -  57  10
           DriverShim(Driver driver) {
      -  58  10
               this.driver = driver;
      -  59  10
           }
      +  57  5
           DriverShim(Driver driver) {
      +  58  5
               this.driver = driver;
      +  59  5
           }
       60  
       
       61   @@ -155,7 +155,7 @@
           @Override
       71  
           public boolean acceptsURL(String url) throws SQLException {
      -  72  2
               return this.driver.acceptsURL(url);
      +  72  1
               return this.driver.acceptsURL(url);
       73  
           }
       74   @@ -387,13 +387,13 @@
           @Override
       202  
           public String toString() {
      -  203  18
               return "DriverShim{" + "driver=" + driver + '}';
      +  203  9
               return "DriverShim{" + "driver=" + driver + '}';
       204  
           }
       205  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.BaseUpdater.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.BaseUpdater.html index f82c3a233..4ec38fd8c 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.BaseUpdater.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.BaseUpdater.html @@ -77,7 +77,7 @@
        * @author Jeremy Long
       30  
        */
      -  31  8
       public abstract class BaseUpdater {
      +  31  4
       public abstract class BaseUpdater {
       32  
       
       33   @@ -86,7 +86,7 @@
            * Static logger.
       35  
            */
      -  36  2
           private static final Logger LOGGER = LoggerFactory.getLogger(BaseUpdater.class);
      +  36  1
           private static final Logger LOGGER = LoggerFactory.getLogger(BaseUpdater.class);
       37  
           /**
       38   @@ -101,19 +101,19 @@
            * Reference to the Cve Database.
       43  
            */
      -  44  8
           private CveDB cveDB = null;
      +  44  4
           private CveDB cveDB = null;
       45  
       
       46  
           protected CveDB getCveDB() {
      -  47  2
               return cveDB;
      +  47  1
               return cveDB;
       48  
           }
       49  
       
       50  
           protected DatabaseProperties getProperties() {
      -  51  2
               return properties;
      +  51  1
               return properties;
       52  
           }
       53   @@ -126,18 +126,18 @@
            */
       57  
           protected void closeDataStores() {
      -  58  6
               if (cveDB != null) {
      +  58  3
               if (cveDB != null) {
       59  
                   try {
      -  60  6
                       cveDB.close();
      -  61  6
                       cveDB = null;
      -  62  6
                       properties = null;
      +  60  3
                       cveDB.close();
      +  61  3
                       cveDB = null;
      +  62  3
                       properties = null;
       63  0
                   } catch (Throwable ignore) {
       64  0
                       LOGGER.trace("Error closing the database", ignore);
      -  65  6
                   }
      +  65  3
                   }
       66  
               }
      -  67  6
           }
      +  67  3
           }
       68  
       
       69   @@ -152,25 +152,25 @@
            */
       74  
           protected final void openDataStores() throws UpdateException {
      -  75  6
               if (cveDB != null) {
      +  75  3
               if (cveDB != null) {
       76  0
                   return;
       77  
               }
       78  
               try {
      -  79  6
                   cveDB = new CveDB();
      -  80  6
                   cveDB.open();
      -  81  6
                   properties = cveDB.getDatabaseProperties();
      +  79  3
                   cveDB = new CveDB();
      +  80  3
                   cveDB.open();
      +  81  3
                   properties = cveDB.getDatabaseProperties();
       82  0
               } catch (DatabaseException ex) {
       83  0
                   closeDataStores();
       84  0
                   LOGGER.debug("Database Exception opening databases", ex);
       85  0
                   throw new UpdateException("Error updating the database, please see the log file for more details.");
      -  86  6
               }
      -  87  6
           }
      +  86  3
               }
      +  87  3
           }
       88  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.CachedWebDataSource.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.CachedWebDataSource.html index ae930fb2f..d59f7ac8d 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.CachedWebDataSource.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.CachedWebDataSource.html @@ -93,6 +93,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.CpeUpdater.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.CpeUpdater.html index 397604c40..665ca2df1 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.CpeUpdater.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.CpeUpdater.html @@ -344,6 +344,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.EngineVersionCheck.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.EngineVersionCheck.html index 4bfc482cb..8fd578130 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.EngineVersionCheck.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.EngineVersionCheck.html @@ -94,29 +94,29 @@  38  
       /**
       39   -
        *
      +
        * Checks the gh-pages dependency-check site to determine the current released
       40   -
        * @author Jeremy Long
      +
        * version number. If the released version number is greater then the running
       41   -
        */
      -  42  4
       public class EngineVersionCheck implements CachedWebDataSource {
      +
        * version number a warning is printed recommending that an upgrade be
      +  42   +
        * performed.
       43   -
       
      +
        *
       44   -
           /**
      +
        * @author Jeremy Long
       45   -
            * Static logger.
      -  46   -
            */
      -  47  2
           private static final Logger LOGGER = LoggerFactory.getLogger(EngineVersionCheck.class);
      +
        */
      +  46  2
       public class EngineVersionCheck implements CachedWebDataSource {
      +  47   +
       
       48  
           /**
       49   -
            * The property key indicating when the last version check occurred.
      +
            * Static logger.
       50  
            */
      -  51   -
           public static final String ENGINE_VERSION_CHECKED_ON = "VersionCheckOn";
      +  51  1
           private static final Logger LOGGER = LoggerFactory.getLogger(EngineVersionCheck.class);
       52  
           /**
       53   @@ -124,258 +124,290 @@  54  
            */
       55   -
           public static final String CURRENT_ENGINE_RELEASE = "CurrentEngineRelease";
      +
           public static final String ENGINE_VERSION_CHECKED_ON = "VersionCheckOn";
       56  
           /**
       57   -
            * Reference to the Cve Database.
      +
            * The property key indicating when the last version check occurred.
       58  
            */
      -  59  4
           private CveDB cveDB = null;
      +  59   +
           public static final String CURRENT_ENGINE_RELEASE = "CurrentEngineRelease";
       60   -
       
      +
           /**
       61   -
           /**
      +
            * Reference to the Cve Database.
       62   -
            * The version retrieved from the database properties or web to check against.
      -  63  
            */
      +  63  2
           private CveDB cveDB = null;
       64   -
           private String updateToVersion;
      +
       
       65   -
       
      +
           /**
       66   -
           /**
      +
            * The version retrieved from the database properties or web to check
       67   -
            * Getter for updateToVersion - only used for testing. Represents the version retrieved from the database.
      +
            * against.
       68   -
            *
      +
            */
       69   -
            * @return the version to test
      +
           private String updateToVersion;
       70   -
            */
      +
       
       71   -
           protected String getUpdateToVersion() {
      -  72  0
               return updateToVersion;
      +
           /**
      +  72   +
            * Getter for updateToVersion - only used for testing. Represents the
       73   -
           }
      +
            * version retrieved from the database.
       74   -
       
      +
            *
       75   -
           /**
      +
            * @return the version to test
       76   -
            * Setter for updateToVersion - only used for testing. Represents the version retrieved from the database.
      +
            */
       77   -
            *
      -  78   -
            * @param version the version to test
      +
           protected String getUpdateToVersion() {
      +  78  0
               return updateToVersion;
       79   -
            */
      +
           }
       80   -
           protected void setUpdateToVersion(String version) {
      -  81  14
               updateToVersion = version;
      -  82  14
           }
      +
       
      +  81   +
           /**
      +  82   +
            * Setter for updateToVersion - only used for testing. Represents the
       83   -
       
      +
            * version retrieved from the database.
       84   -
           @Override
      +
            *
       85   -
           public void update() throws UpdateException {
      +
            * @param version the version to test
       86   -
       
      +
            */
       87   +
           protected void setUpdateToVersion(String version) {
      +  88  7
               updateToVersion = version;
      +  89  7
           }
      +  90   +
       
      +  91   +
           /**
      +  92   +
            * Downloads the current released version number and compares it to the
      +  93   +
            * running engine's version number. If the released version number is newer
      +  94   +
            * a warning is printed recommending an upgrade.
      +  95   +
            *
      +  96   +
            * @throws UpdateException thrown if the local database properties could not
      +  97   +
            * be updated
      +  98   +
            */
      +  99   +
           @Override
      +  100   +
           public void update() throws UpdateException {
      +  101  
               try {
      -  88  0
                   if (Settings.getBoolean(Settings.KEYS.AUTO_UPDATE)) {
      -  89  0
                       openDatabase();
      -  90  0
                       LOGGER.debug("Begin Engine Version Check");
      -  91  0
                       final DatabaseProperties properties = cveDB.getDatabaseProperties();
      -  92  0
                       final long lastChecked = Long.parseLong(properties.getProperty(ENGINE_VERSION_CHECKED_ON, "0"));
      -  93  0
                       final long now = System.currentTimeMillis();
      -  94  0
                       updateToVersion = properties.getProperty(CURRENT_ENGINE_RELEASE, "");
      -  95  0
                       final String currentVersion = Settings.getString(Settings.KEYS.APPLICATION_VERSION, "0.0.0");
      -  96  0
                       LOGGER.debug("Last checked: {}", lastChecked);
      -  97  0
                       LOGGER.debug("Now: {}", now);
      -  98  0
                       LOGGER.debug("Current version: {}", currentVersion);
      -  99  0
                       final boolean updateNeeded = shouldUpdate(lastChecked, now, properties, currentVersion);
      -  100  0
                       if (updateNeeded) {
      -  101  0
                           LOGGER.warn("A new version of dependency-check is available. Consider updating to version {}.",
      -  102   -
                                   updateToVersion);
      -  103   -
                       }
      -  104   -
                   }
      -  105  0
               } catch (DatabaseException ex) {
      -  106  0
                   LOGGER.debug("Database Exception opening databases to retrieve properties", ex);
      -  107  0
                   throw new UpdateException("Error occured updating database properties.");
      -  108  0
               } catch (InvalidSettingException ex) {
      -  109  0
                   LOGGER.debug("Unable to determine if autoupdate is enabled", ex);
      -  110   -
               } finally {
      -  111  0
                   closeDatabase();
      -  112   -
       
      -  113  0
               }
      -  114  0
           }
      -  115   -
       
      +  102  0
                   if (Settings.getBoolean(Settings.KEYS.AUTO_UPDATE)) {
      +  103  0
                       openDatabase();
      +  104  0
                       LOGGER.debug("Begin Engine Version Check");
      +  105  0
                       final DatabaseProperties properties = cveDB.getDatabaseProperties();
      +  106  0
                       final long lastChecked = Long.parseLong(properties.getProperty(ENGINE_VERSION_CHECKED_ON, "0"));
      +  107  0
                       final long now = System.currentTimeMillis();
      +  108  0
                       updateToVersion = properties.getProperty(CURRENT_ENGINE_RELEASE, "");
      +  109  0
                       final String currentVersion = Settings.getString(Settings.KEYS.APPLICATION_VERSION, "0.0.0");
      +  110  0
                       LOGGER.debug("Last checked: {}", lastChecked);
      +  111  0
                       LOGGER.debug("Now: {}", now);
      +  112  0
                       LOGGER.debug("Current version: {}", currentVersion);
      +  113  0
                       final boolean updateNeeded = shouldUpdate(lastChecked, now, properties, currentVersion);
      +  114  0
                       if (updateNeeded) {
      +  115  0
                           LOGGER.warn("A new version of dependency-check is available. Consider updating to version {}.",
       116   -
           /**
      +
                                   updateToVersion);
       117   -
            * Determines if a new version of the dependency-check engine has been released.
      -  118   -
            *
      -  119   -
            * @param lastChecked the epoch time of the last version check
      -  120   -
            * @param now the current epoch time
      -  121   -
            * @param properties the database properties object
      -  122   -
            * @param currentVersion the current version of dependency-check
      -  123   -
            * @return <code>true</code> if a newer version of the database has been released; otherwise <code>false</code>
      -  124   -
            * @throws UpdateException thrown if there is an error connecting to the github documentation site or accessing the local
      -  125   -
            * database.
      -  126   -
            */
      -  127   -
           protected boolean shouldUpdate(final long lastChecked, final long now, final DatabaseProperties properties,
      -  128   -
                   String currentVersion) throws UpdateException {
      -  129   -
               //check every 30 days if we know there is an update, otherwise check every 7 days
      -  130  14
               final int checkRange = 30;
      -  131  14
               if (!DateUtil.withinDateRange(lastChecked, now, checkRange)) {
      -  132  4
                   LOGGER.debug("Checking web for new version.");
      -  133  4
                   final String currentRelease = getCurrentReleaseVersion();
      -  134  4
                   if (currentRelease != null) {
      -  135  4
                       final DependencyVersion v = new DependencyVersion(currentRelease);
      -  136  4
                       if (v.getVersionParts() != null && v.getVersionParts().size() >= 3) {
      -  137  4
                           updateToVersion = v.toString();
      -  138  4
                           if (!currentRelease.equals(updateToVersion)) {
      -  139  0
                               properties.save(CURRENT_ENGINE_RELEASE, updateToVersion);
      -  140   -
                           }
      -  141  4
                           properties.save(ENGINE_VERSION_CHECKED_ON, Long.toString(now));
      -  142  
                       }
      -  143   +  118  
                   }
      -  144  4
                   LOGGER.debug("Current Release: {}", updateToVersion);
      -  145   -
               }
      -  146  14
               if (updateToVersion == null) {
      -  147  0
                   LOGGER.debug("Unable to obtain current release");
      -  148  0
                   return false;
      -  149   -
               }
      -  150  14
               final DependencyVersion running = new DependencyVersion(currentVersion);
      -  151  14
               final DependencyVersion released = new DependencyVersion(updateToVersion);
      -  152  14
               if (running.compareTo(released) < 0) {
      -  153  6
                   LOGGER.debug("Upgrade recommended");
      -  154  6
                   return true;
      -  155   -
               }
      -  156  8
               LOGGER.debug("Upgrade not needed");
      -  157  8
               return false;
      -  158   -
           }
      -  159   -
       
      -  160   -
           /**
      -  161   -
            * Opens the CVE and CPE data stores.
      -  162   -
            *
      -  163   -
            * @throws DatabaseException thrown if a data store cannot be opened
      -  164   -
            */
      -  165   -
           protected final void openDatabase() throws DatabaseException {
      -  166  0
               if (cveDB != null) {
      -  167  0
                   return;
      -  168   -
               }
      -  169  0
               cveDB = new CveDB();
      -  170  0
               cveDB.open();
      -  171  0
           }
      -  172   -
       
      -  173   -
           /**
      -  174   -
            * Closes the CVE and CPE data stores.
      -  175   -
            */
      -  176   -
           protected void closeDatabase() {
      -  177  0
               if (cveDB != null) {
      -  178   -
                   try {
      -  179  0
                       cveDB.close();
      -  180  0
                       cveDB = null;
      -  181  0
                   } catch (Throwable ignore) {
      -  182  0
                       LOGGER.trace("Error closing the cveDB", ignore);
      -  183  0
                   }
      -  184   -
               }
      -  185  0
           }
      -  186   -
       
      -  187   -
           /**
      -  188   -
            * Retrieves the current released version number from the github documentation site.
      -  189   -
            *
      -  190   -
            * @return the current released version number
      -  191   -
            */
      -  192   -
           protected String getCurrentReleaseVersion() {
      -  193  6
               HttpURLConnection conn = null;
      -  194   -
               try {
      -  195  6
                   final String str = Settings.getString(Settings.KEYS.ENGINE_VERSION_CHECK_URL, "http://jeremylong.github.io/DependencyCheck/current.txt");
      -  196  6
                   final URL url = new URL(str);
      -  197  6
                   conn = URLConnectionFactory.createHttpURLConnection(url);
      -  198  6
                   conn.connect();
      -  199  6
                   if (conn.getResponseCode() != 200) {
      -  200  0
                       return null;
      -  201   -
                   }
      -  202  6
                   final String releaseVersion = IOUtils.toString(conn.getInputStream(), "UTF-8");
      -  203  6
                   if (releaseVersion != null) {
      -  204  12
                       return releaseVersion.trim();
      -  205   -
                   }
      -  206  0
               } catch (MalformedURLException ex) {
      -  207  0
                   LOGGER.debug("unable to retrieve current release version of dependency-check", ex);
      -  208  0
               } catch (URLConnectionFailureException ex) {
      -  209  0
                   LOGGER.debug("unable to retrieve current release version of dependency-check", ex);
      -  210  0
               } catch (IOException ex) {
      -  211  0
                   LOGGER.debug("unable to retrieve current release version of dependency-check", ex);
      -  212   +  119  0
               } catch (DatabaseException ex) {
      +  120  0
                   LOGGER.debug("Database Exception opening databases to retrieve properties", ex);
      +  121  0
                   throw new UpdateException("Error occured updating database properties.");
      +  122  0
               } catch (InvalidSettingException ex) {
      +  123  0
                   LOGGER.debug("Unable to determine if autoupdate is enabled", ex);
      +  124  
               } finally {
      -  213  6
                   if (conn != null) {
      -  214  6
                       conn.disconnect();
      -  215   +  125  0
                   closeDatabase();
      +  126  0
               }
      +  127  0
           }
      +  128   +
       
      +  129   +
           /**
      +  130   +
            * Determines if a new version of the dependency-check engine has been
      +  131   +
            * released.
      +  132   +
            *
      +  133   +
            * @param lastChecked the epoch time of the last version check
      +  134   +
            * @param now the current epoch time
      +  135   +
            * @param properties the database properties object
      +  136   +
            * @param currentVersion the current version of dependency-check
      +  137   +
            * @return <code>true</code> if a newer version of the database has been
      +  138   +
            * released; otherwise <code>false</code>
      +  139   +
            * @throws UpdateException thrown if there is an error connecting to the
      +  140   +
            * github documentation site or accessing the local database.
      +  141   +
            */
      +  142   +
           protected boolean shouldUpdate(final long lastChecked, final long now, final DatabaseProperties properties,
      +  143   +
                   String currentVersion) throws UpdateException {
      +  144   +
               //check every 30 days if we know there is an update, otherwise check every 7 days
      +  145  7
               final int checkRange = 30;
      +  146  7
               if (!DateUtil.withinDateRange(lastChecked, now, checkRange)) {
      +  147  2
                   LOGGER.debug("Checking web for new version.");
      +  148  2
                   final String currentRelease = getCurrentReleaseVersion();
      +  149  2
                   if (currentRelease != null) {
      +  150  2
                       final DependencyVersion v = new DependencyVersion(currentRelease);
      +  151  2
                       if (v.getVersionParts() != null && v.getVersionParts().size() >= 3) {
      +  152  2
                           updateToVersion = v.toString();
      +  153  2
                           if (!currentRelease.equals(updateToVersion)) {
      +  154  0
                               properties.save(CURRENT_ENGINE_RELEASE, updateToVersion);
      +  155   +
                           }
      +  156  2
                           properties.save(ENGINE_VERSION_CHECKED_ON, Long.toString(now));
      +  157   +
                       }
      +  158  
                   }
      -  216   +  159  2
                   LOGGER.debug("Current Release: {}", updateToVersion);
      +  160  
               }
      -  217  0
               return null;
      -  218   +  161  7
               if (updateToVersion == null) {
      +  162  0
                   LOGGER.debug("Unable to obtain current release");
      +  163  0
                   return false;
      +  164   +
               }
      +  165  7
               final DependencyVersion running = new DependencyVersion(currentVersion);
      +  166  7
               final DependencyVersion released = new DependencyVersion(updateToVersion);
      +  167  7
               if (running.compareTo(released) < 0) {
      +  168  3
                   LOGGER.debug("Upgrade recommended");
      +  169  3
                   return true;
      +  170   +
               }
      +  171  4
               LOGGER.debug("Upgrade not needed");
      +  172  4
               return false;
      +  173  
           }
      -  219   +  174   +
       
      +  175   +
           /**
      +  176   +
            * Opens the CVE and CPE data stores.
      +  177   +
            *
      +  178   +
            * @throws DatabaseException thrown if a data store cannot be opened
      +  179   +
            */
      +  180   +
           protected final void openDatabase() throws DatabaseException {
      +  181  0
               if (cveDB != null) {
      +  182  0
                   return;
      +  183   +
               }
      +  184  0
               cveDB = new CveDB();
      +  185  0
               cveDB.open();
      +  186  0
           }
      +  187   +
       
      +  188   +
           /**
      +  189   +
            * Closes the CVE and CPE data stores.
      +  190   +
            */
      +  191   +
           protected void closeDatabase() {
      +  192  0
               if (cveDB != null) {
      +  193   +
                   try {
      +  194  0
                       cveDB.close();
      +  195  0
                       cveDB = null;
      +  196  0
                   } catch (Throwable ignore) {
      +  197  0
                       LOGGER.trace("Error closing the cveDB", ignore);
      +  198  0
                   }
      +  199   +
               }
      +  200  0
           }
      +  201   +
       
      +  202   +
           /**
      +  203   +
            * Retrieves the current released version number from the github
      +  204   +
            * documentation site.
      +  205   +
            *
      +  206   +
            * @return the current released version number
      +  207   +
            */
      +  208   +
           protected String getCurrentReleaseVersion() {
      +  209  3
               HttpURLConnection conn = null;
      +  210   +
               try {
      +  211  3
                   final String str = Settings.getString(Settings.KEYS.ENGINE_VERSION_CHECK_URL, "http://jeremylong.github.io/DependencyCheck/current.txt");
      +  212  3
                   final URL url = new URL(str);
      +  213  3
                   conn = URLConnectionFactory.createHttpURLConnection(url);
      +  214  3
                   conn.connect();
      +  215  3
                   if (conn.getResponseCode() != 200) {
      +  216  0
                       return null;
      +  217   +
                   }
      +  218  3
                   final String releaseVersion = IOUtils.toString(conn.getInputStream(), "UTF-8");
      +  219  3
                   if (releaseVersion != null) {
      +  220  6
                       return releaseVersion.trim();
      +  221   +
                   }
      +  222  0
               } catch (MalformedURLException ex) {
      +  223  0
                   LOGGER.debug("Unable to retrieve current release version of dependency-check", ex);
      +  224  0
               } catch (URLConnectionFailureException ex) {
      +  225  0
                   LOGGER.debug("Unable to retrieve current release version of dependency-check", ex);
      +  226  0
               } catch (IOException ex) {
      +  227  0
                   LOGGER.debug("Unable to retrieve current release version of dependency-check", ex);
      +  228   +
               } finally {
      +  229  3
                   if (conn != null) {
      +  230  3
                       conn.disconnect();
      +  231   +
                   }
      +  232   +
               }
      +  233  0
               return null;
      +  234   +
           }
      +  235  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.NvdCveUpdater.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.NvdCveUpdater.html index aaa40c9b6..eda3067db 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.NvdCveUpdater.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.NvdCveUpdater.html @@ -12,7 +12,7 @@
       
      - +
      Classes in this File Line Coverage Branch Coverage Complexity
      NvdCveUpdater
      0%
      0/164
      0%
      0/64
      10.167
      NvdCveUpdater
      0%
      0/163
      0%
      0/64
      10.5
       
      @@ -121,7 +121,7 @@  52  
           /**
       53   -
            * The logger
      +
            * The logger.
       54  
            */
       55  0
           private static final Logger LOGGER = LoggerFactory.getLogger(NvdCveUpdater.class);
      @@ -137,436 +137,429 @@  61  
           /**
       62   -
            * <p>
      +
            * Downloads the latest NVD CVE XML file from the web and imports it into
       63   -
            * Downloads the latest NVD CVE XML file from the web and imports it into
      -  64   -
            * the current CVE Database.</p>
      -  65   -
            *
      -  66   -
            * @throws UpdateException is thrown if there is an error updating the
      -  67   -
            * database
      -  68   -
            */
      -  69   -
           @Override
      -  70   -
           public void update() throws UpdateException {
      -  71   -
               try {
      -  72  0
                   openDataStores();
      -  73  0
                   boolean autoUpdate = true;
      -  74   -
                   try {
      -  75  0
                       autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE);
      -  76  0
                   } catch (InvalidSettingException ex) {
      -  77  0
                       LOGGER.debug("Invalid setting for auto-update; using true.");
      -  78  0
                   }
      -  79  0
                   if (autoUpdate && checkUpdate()) {
      -  80  0
                       final UpdateableNvdCve updateable = getUpdatesNeeded();
      -  81  0
                       getProperties().save(DatabaseProperties.LAST_CHECKED, Long.toString(System.currentTimeMillis()));
      -  82  0
                       if (updateable.isUpdateNeeded()) {
      -  83  0
                           performUpdate(updateable);
      -  84   -
                       }
      -  85   -
                   }
      -  86  0
               } catch (MalformedURLException ex) {
      -  87  0
                   LOGGER.warn(
      -  88   -
                           "NVD CVE properties files contain an invalid URL, unable to update the data to use the most current data.");
      -  89  0
                   LOGGER.debug("", ex);
      -  90  0
               } catch (DownloadFailedException ex) {
      -  91  0
                   LOGGER.warn(
      -  92   -
                           "Unable to download the NVD CVE data; the results may not include the most recent CPE/CVEs from the NVD.");
      -  93  0
                   if (Settings.getString(Settings.KEYS.PROXY_SERVER) == null) {
      -  94  0
                       LOGGER.info(
      -  95   -
                               "If you are behind a proxy you may need to configure dependency-check to use the proxy.");
      -  96   -
                   }
      -  97  0
                   LOGGER.debug("", ex);
      -  98   -
               } finally {
      -  99  0
                   closeDataStores();
      -  100  0
               }
      -  101  0
           }
      -  102   -
       
      -  103   -
           /**
      -  104   -
            * Checks if the NVD CVE XML files were last checked recently. As an
      -  105   -
            * optimization, we can avoid repetitive checks against the NVD. Setting
      -  106   -
            * CVE_CHECK_VALID_FOR_HOURS determines the duration since last check before
      -  107   -
            * checking again. A database property stores the timestamp of the last
      -  108   -
            * check.
      -  109   -
            *
      -  110   -
            * @return true to proceed with the check, or false to skip.
      -  111   -
            * @throws UpdateException thrown when there is an issue checking for
      -  112   -
            * updates.
      -  113   -
            */
      -  114   -
           private boolean checkUpdate() throws UpdateException {
      -  115  0
               boolean proceed = true;
      -  116   -
               // If the valid setting has not been specified, then we proceed to check...
      -  117  0
               final int validForHours = Settings.getInt(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, 0);
      -  118  0
               if (dataExists() && 0 < validForHours) {
      -  119   -
                   // ms Valid = valid (hours) x 60 min/hour x 60 sec/min x 1000 ms/sec
      -  120  0
                   final long msValid = validForHours * 60L * 60L * 1000L;
      -  121  0
                   final long lastChecked = Long.parseLong(getProperties().getProperty(DatabaseProperties.LAST_CHECKED, "0"));
      -  122  0
                   final long now = System.currentTimeMillis();
      -  123  0
                   proceed = (now - lastChecked) > msValid;
      -  124  0
                   if (!proceed) {
      -  125  0
                       LOGGER.info("Skipping NVD check since last check was within {} hours.", validForHours);
      -  126  0
                       LOGGER.debug("Last NVD was at {}, and now {} is within {} ms.",
      -  127  0
                               lastChecked, now, msValid);
      -  128   -
                   }
      -  129   -
               }
      -  130  0
               return proceed;
      -  131   -
           }
      -  132   -
       
      -  133   -
           /**
      -  134   -
            * Checks the CVE Index to ensure data exists and analysis can continue.
      -  135   -
            *
      -  136   -
            * @return true if the database contains data
      -  137   -
            */
      -  138   -
           private boolean dataExists() {
      -  139  0
               CveDB cve = null;
      -  140   -
               try {
      -  141  0
                   cve = new CveDB();
      -  142  0
                   cve.open();
      -  143  0
                   return cve.dataExists();
      -  144  0
               } catch (DatabaseException ex) {
      -  145  0
                   return false;
      -  146   -
               } finally {
      -  147  0
                   if (cve != null) {
      -  148  0
                       cve.close();
      -  149   -
                   }
      -  150   -
               }
      -  151   -
           }
      -  152   -
       
      -  153   -
           /**
      -  154   -
            * Downloads the latest NVD CVE XML file from the web and imports it into
      -  155  
            * the current CVE Database.
      -  156   +  64  
            *
      -  157   -
            * @param updateable a collection of NVD CVE data file references that need
      -  158   -
            * to be downloaded and processed to update the database
      -  159   +  65  
            * @throws UpdateException is thrown if there is an error updating the
      -  160   +  66  
            * database
      -  161   +  67  
            */
      -  162   -
           public void performUpdate(UpdateableNvdCve updateable) throws UpdateException {
      -  163  0
               int maxUpdates = 0;
      -  164   +  68   +
           @Override
      +  69   +
           public void update() throws UpdateException {
      +  70  
               try {
      -  165  0
                   for (NvdCveInfo cve : updateable) {
      -  166  0
                       if (cve.getNeedsUpdate()) {
      -  167  0
                           maxUpdates += 1;
      -  168   +  71  0
                   openDataStores();
      +  72  0
                   boolean autoUpdate = true;
      +  73   +
                   try {
      +  74  0
                       autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE);
      +  75  0
                   } catch (InvalidSettingException ex) {
      +  76  0
                       LOGGER.debug("Invalid setting for auto-update; using true.");
      +  77  0
                   }
      +  78  0
                   if (autoUpdate && checkUpdate()) {
      +  79  0
                       final UpdateableNvdCve updateable = getUpdatesNeeded();
      +  80  0
                       getProperties().save(DatabaseProperties.LAST_CHECKED, Long.toString(System.currentTimeMillis()));
      +  81  0
                       if (updateable.isUpdateNeeded()) {
      +  82  0
                           performUpdate(updateable);
      +  83  
                       }
      -  169  0
                   }
      -  170  0
                   if (maxUpdates <= 0) {
      -  171  0
                       return;
      +  84   +
                   }
      +  85  0
               } catch (MalformedURLException ex) {
      +  86  0
                   throw new UpdateException("NVD CVE properties files contain an invalid URL, unable to update the data to use the most current data.", ex);
      +  87  0
               } catch (DownloadFailedException ex) {
      +  88  0
                   LOGGER.warn(
      +  89   +
                           "Unable to download the NVD CVE data; the results may not include the most recent CPE/CVEs from the NVD.");
      +  90  0
                   if (Settings.getString(Settings.KEYS.PROXY_SERVER) == null) {
      +  91  0
                       LOGGER.info(
      +  92   +
                               "If you are behind a proxy you may need to configure dependency-check to use the proxy.");
      +  93   +
                   }
      +  94  0
                   throw new UpdateException("Unable to download the NVD CVE data.", ex);
      +  95   +
               } finally {
      +  96  0
                   closeDataStores();
      +  97  0
               }
      +  98  0
           }
      +  99   +
       
      +  100   +
           /**
      +  101   +
            * Checks if the NVD CVE XML files were last checked recently. As an
      +  102   +
            * optimization, we can avoid repetitive checks against the NVD. Setting
      +  103   +
            * CVE_CHECK_VALID_FOR_HOURS determines the duration since last check before
      +  104   +
            * checking again. A database property stores the timestamp of the last
      +  105   +
            * check.
      +  106   +
            *
      +  107   +
            * @return true to proceed with the check, or false to skip
      +  108   +
            * @throws UpdateException thrown when there is an issue checking for
      +  109   +
            * updates
      +  110   +
            */
      +  111   +
           private boolean checkUpdate() throws UpdateException {
      +  112  0
               boolean proceed = true;
      +  113   +
               // If the valid setting has not been specified, then we proceed to check...
      +  114  0
               final int validForHours = Settings.getInt(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, 0);
      +  115  0
               if (dataExists() && 0 < validForHours) {
      +  116   +
                   // ms Valid = valid (hours) x 60 min/hour x 60 sec/min x 1000 ms/sec
      +  117  0
                   final long msValid = validForHours * 60L * 60L * 1000L;
      +  118  0
                   final long lastChecked = Long.parseLong(getProperties().getProperty(DatabaseProperties.LAST_CHECKED, "0"));
      +  119  0
                   final long now = System.currentTimeMillis();
      +  120  0
                   proceed = (now - lastChecked) > msValid;
      +  121  0
                   if (!proceed) {
      +  122  0
                       LOGGER.info("Skipping NVD check since last check was within {} hours.", validForHours);
      +  123  0
                       LOGGER.debug("Last NVD was at {}, and now {} is within {} ms.",
      +  124  0
                               lastChecked, now, msValid);
      +  125   +
                   }
      +  126   +
               }
      +  127  0
               return proceed;
      +  128   +
           }
      +  129   +
       
      +  130   +
           /**
      +  131   +
            * Checks the CVE Index to ensure data exists and analysis can continue.
      +  132   +
            *
      +  133   +
            * @return true if the database contains data
      +  134   +
            */
      +  135   +
           private boolean dataExists() {
      +  136  0
               CveDB cve = null;
      +  137   +
               try {
      +  138  0
                   cve = new CveDB();
      +  139  0
                   cve.open();
      +  140  0
                   return cve.dataExists();
      +  141  0
               } catch (DatabaseException ex) {
      +  142  0
                   return false;
      +  143   +
               } finally {
      +  144  0
                   if (cve != null) {
      +  145  0
                       cve.close();
      +  146   +
                   }
      +  147   +
               }
      +  148   +
           }
      +  149   +
       
      +  150   +
           /**
      +  151   +
            * Downloads the latest NVD CVE XML file from the web and imports it into
      +  152   +
            * the current CVE Database.
      +  153   +
            *
      +  154   +
            * @param updateable a collection of NVD CVE data file references that need
      +  155   +
            * to be downloaded and processed to update the database
      +  156   +
            * @throws UpdateException is thrown if there is an error updating the
      +  157   +
            * database
      +  158   +
            */
      +  159   +
           public void performUpdate(UpdateableNvdCve updateable) throws UpdateException {
      +  160  0
               int maxUpdates = 0;
      +  161   +
               try {
      +  162  0
                   for (NvdCveInfo cve : updateable) {
      +  163  0
                       if (cve.getNeedsUpdate()) {
      +  164  0
                           maxUpdates += 1;
      +  165   +
                       }
      +  166  0
                   }
      +  167  0
                   if (maxUpdates <= 0) {
      +  168  0
                       return;
      +  169   +
                   }
      +  170  0
                   if (maxUpdates > 3) {
      +  171  0
                       LOGGER.info("NVD CVE requires several updates; this could take a couple of minutes.");
       172  
                   }
      -  173  0
                   if (maxUpdates > 3) {
      -  174  0
                       LOGGER.info(
      +  173  0
                   if (maxUpdates > 0) {
      +  174  0
                       openDataStores();
       175   -
                               "NVD CVE requires several updates; this could take a couple of minutes.");
      +
                   }
       176   -
                   }
      -  177  0
                   if (maxUpdates > 0) {
      -  178  0
                       openDataStores();
      -  179   -
                   }
      -  180  
       
      -  181  0
                   final int poolSize = (MAX_THREAD_POOL_SIZE < maxUpdates) ? MAX_THREAD_POOL_SIZE : maxUpdates;
      -  182   +  177  0
                   final int poolSize = (MAX_THREAD_POOL_SIZE < maxUpdates) ? MAX_THREAD_POOL_SIZE : maxUpdates;
      +  178   +
       
      +  179  0
                   final ExecutorService downloadExecutors = Executors.newFixedThreadPool(poolSize);
      +  180  0
                   final ExecutorService processExecutor = Executors.newSingleThreadExecutor();
      +  181  0
                   final Set<Future<Future<ProcessTask>>> downloadFutures = new HashSet<Future<Future<ProcessTask>>>(maxUpdates);
      +  182  0
                   for (NvdCveInfo cve : updateable) {
      +  183  0
                       if (cve.getNeedsUpdate()) {
      +  184  0
                           final DownloadTask call = new DownloadTask(cve, processExecutor, getCveDB(), Settings.getInstance());
      +  185  0
                           downloadFutures.add(downloadExecutors.submit(call));
      +  186   +
                       }
      +  187  0
                   }
      +  188  0
                   downloadExecutors.shutdown();
      +  189  
       
      -  183  0
                   final ExecutorService downloadExecutors = Executors.newFixedThreadPool(poolSize);
      -  184  0
                   final ExecutorService processExecutor = Executors.newSingleThreadExecutor();
      -  185  0
                   final Set<Future<Future<ProcessTask>>> downloadFutures = new HashSet<Future<Future<ProcessTask>>>(maxUpdates);
      -  186  0
                   for (NvdCveInfo cve : updateable) {
      -  187  0
                       if (cve.getNeedsUpdate()) {
      -  188  0
                           final DownloadTask call = new DownloadTask(cve, processExecutor, getCveDB(), Settings.getInstance());
      -  189  0
                           downloadFutures.add(downloadExecutors.submit(call));
       190   -
                       }
      -  191  0
                   }
      -  192  0
                   downloadExecutors.shutdown();
      -  193   -
       
      -  194  
                   //next, move the future future processTasks to just future processTasks
      -  195  0
                   final Set<Future<ProcessTask>> processFutures = new HashSet<Future<ProcessTask>>(maxUpdates);
      -  196  0
                   for (Future<Future<ProcessTask>> future : downloadFutures) {
      -  197  0
                       Future<ProcessTask> task = null;
      -  198   +  191  0
                   final Set<Future<ProcessTask>> processFutures = new HashSet<Future<ProcessTask>>(maxUpdates);
      +  192  0
                   for (Future<Future<ProcessTask>> future : downloadFutures) {
      +  193  0
                       Future<ProcessTask> task = null;
      +  194  
                       try {
      -  199  0
                           task = future.get();
      -  200  0
                       } catch (InterruptedException ex) {
      -  201  0
                           downloadExecutors.shutdownNow();
      -  202  0
                           processExecutor.shutdownNow();
      -  203   +  195  0
                           task = future.get();
      +  196  0
                       } catch (InterruptedException ex) {
      +  197  0
                           downloadExecutors.shutdownNow();
      +  198  0
                           processExecutor.shutdownNow();
      +  199  
       
      -  204  0
                           LOGGER.debug("Thread was interrupted during download", ex);
      -  205  0
                           throw new UpdateException("The download was interrupted", ex);
      -  206  0
                       } catch (ExecutionException ex) {
      -  207  0
                           downloadExecutors.shutdownNow();
      -  208  0
                           processExecutor.shutdownNow();
      -  209   +  200  0
                           LOGGER.debug("Thread was interrupted during download", ex);
      +  201  0
                           throw new UpdateException("The download was interrupted", ex);
      +  202  0
                       } catch (ExecutionException ex) {
      +  203  0
                           downloadExecutors.shutdownNow();
      +  204  0
                           processExecutor.shutdownNow();
      +  205  
       
      -  210  0
                           LOGGER.debug("Thread was interrupted during download execution", ex);
      -  211  0
                           throw new UpdateException("The execution of the download was interrupted", ex);
      -  212  0
                       }
      -  213  0
                       if (task == null) {
      -  214  0
                           downloadExecutors.shutdownNow();
      -  215  0
                           processExecutor.shutdownNow();
      -  216  0
                           LOGGER.debug("Thread was interrupted during download");
      -  217  0
                           throw new UpdateException("The download was interrupted; unable to complete the update");
      -  218   +  206  0
                           LOGGER.debug("Thread was interrupted during download execution", ex);
      +  207  0
                           throw new UpdateException("The execution of the download was interrupted", ex);
      +  208  0
                       }
      +  209  0
                       if (task == null) {
      +  210  0
                           downloadExecutors.shutdownNow();
      +  211  0
                           processExecutor.shutdownNow();
      +  212  0
                           LOGGER.debug("Thread was interrupted during download");
      +  213  0
                           throw new UpdateException("The download was interrupted; unable to complete the update");
      +  214  
                       } else {
      -  219  0
                           processFutures.add(task);
      +  215  0
                           processFutures.add(task);
      +  216   +
                       }
      +  217  0
                   }
      +  218   +
       
      +  219  0
                   for (Future<ProcessTask> future : processFutures) {
       220   -
                       }
      -  221  0
                   }
      -  222   -
       
      -  223  0
                   for (Future<ProcessTask> future : processFutures) {
      -  224  
                       try {
      -  225  0
                           final ProcessTask task = future.get();
      -  226  0
                           if (task.getException() != null) {
      -  227  0
                               throw task.getException();
      -  228   +  221  0
                           final ProcessTask task = future.get();
      +  222  0
                           if (task.getException() != null) {
      +  223  0
                               throw task.getException();
      +  224  
                           }
      -  229  0
                       } catch (InterruptedException ex) {
      +  225  0
                       } catch (InterruptedException ex) {
      +  226  0
                           processExecutor.shutdownNow();
      +  227  0
                           LOGGER.debug("Thread was interrupted during processing", ex);
      +  228  0
                           throw new UpdateException(ex);
      +  229  0
                       } catch (ExecutionException ex) {
       230  0
                           processExecutor.shutdownNow();
      -  231  0
                           LOGGER.debug("Thread was interrupted during processing", ex);
      +  231  0
                           LOGGER.debug("Execution Exception during process", ex);
       232  0
                           throw new UpdateException(ex);
      -  233  0
                       } catch (ExecutionException ex) {
      -  234  0
                           processExecutor.shutdownNow();
      -  235  0
                           LOGGER.debug("Execution Exception during process", ex);
      -  236  0
                           throw new UpdateException(ex);
      -  237   +  233  
                       } finally {
      -  238  0
                           processExecutor.shutdown();
      -  239  0
                       }
      -  240  0
                   }
      -  241   +  234  0
                           processExecutor.shutdown();
      +  235  0
                       }
      +  236  0
                   }
      +  237  
       
      -  242  0
                   if (maxUpdates >= 1) { //ensure the modified file date gets written (we may not have actually updated it)
      -  243  0
                       getProperties().save(updateable.get(MODIFIED));
      -  244  0
                       LOGGER.info("Begin database maintenance.");
      -  245  0
                       getCveDB().cleanupDatabase();
      -  246  0
                       LOGGER.info("End database maintenance.");
      -  247   +  238  0
                   if (maxUpdates >= 1) { //ensure the modified file date gets written (we may not have actually updated it)
      +  239  0
                       getProperties().save(updateable.get(MODIFIED));
      +  240  0
                       LOGGER.info("Begin database maintenance.");
      +  241  0
                       getCveDB().cleanupDatabase();
      +  242  0
                       LOGGER.info("End database maintenance.");
      +  243  
                   }
      -  248   +  244  
               } finally {
      -  249  0
                   closeDataStores();
      -  250  0
               }
      -  251  0
           }
      -  252   +  245  0
                   closeDataStores();
      +  246  0
               }
      +  247  0
           }
      +  248  
       
      -  253   +  249  
           /**
      -  254   +  250  
            * Determines if the index needs to be updated. This is done by fetching the
      -  255   +  251  
            * NVD CVE meta data and checking the last update date. If the data needs to
      -  256   +  252  
            * be refreshed this method will return the NvdCveUrl for the files that
      -  257   +  253  
            * need to be updated.
      -  258   +  254  
            *
      -  259   +  255  
            * @return the collection of files that need to be updated
      -  260   +  256  
            * @throws MalformedURLException is thrown if the URL for the NVD CVE Meta
      -  261   +  257  
            * data is incorrect
      -  262   +  258  
            * @throws DownloadFailedException is thrown if there is an error.
      -  263   +  259  
            * downloading the NVD CVE download data file
      -  264   +  260  
            * @throws UpdateException Is thrown if there is an issue with the last
      -  265   +  261  
            * updated properties file
      -  266   +  262  
            */
      -  267   +  263  
           protected final UpdateableNvdCve getUpdatesNeeded() throws MalformedURLException, DownloadFailedException, UpdateException {
      -  268  0
               UpdateableNvdCve updates = null;
      -  269   +  264  0
               UpdateableNvdCve updates = null;
      +  265  
               try {
      -  270  0
                   updates = retrieveCurrentTimestampsFromWeb();
      -  271  0
               } catch (InvalidDataException ex) {
      -  272  0
                   final String msg = "Unable to retrieve valid timestamp from nvd cve downloads page";
      -  273  0
                   LOGGER.debug(msg, ex);
      -  274  0
                   throw new DownloadFailedException(msg, ex);
      -  275  0
               } catch (InvalidSettingException ex) {
      -  276  0
                   LOGGER.debug("Invalid setting found when retrieving timestamps", ex);
      -  277  0
                   throw new DownloadFailedException("Invalid settings", ex);
      -  278  0
               }
      -  279   +  266  0
                   updates = retrieveCurrentTimestampsFromWeb();
      +  267  0
               } catch (InvalidDataException ex) {
      +  268  0
                   final String msg = "Unable to retrieve valid timestamp from nvd cve downloads page";
      +  269  0
                   LOGGER.debug(msg, ex);
      +  270  0
                   throw new DownloadFailedException(msg, ex);
      +  271  0
               } catch (InvalidSettingException ex) {
      +  272  0
                   LOGGER.debug("Invalid setting found when retrieving timestamps", ex);
      +  273  0
                   throw new DownloadFailedException("Invalid settings", ex);
      +  274  0
               }
      +  275  
       
      -  280  0
               if (updates == null) {
      -  281  0
                   throw new DownloadFailedException("Unable to retrieve the timestamps of the currently published NVD CVE data");
      -  282   +  276  0
               if (updates == null) {
      +  277  0
                   throw new DownloadFailedException("Unable to retrieve the timestamps of the currently published NVD CVE data");
      +  278  
               }
      -  283  0
               if (!getProperties().isEmpty()) {
      -  284   +  279  0
               if (!getProperties().isEmpty()) {
      +  280  
                   try {
      -  285  0
                       final long lastUpdated = Long.parseLong(getProperties().getProperty(DatabaseProperties.LAST_UPDATED, "0"));
      -  286  0
                       final long now = System.currentTimeMillis();
      -  287  0
                       final int days = Settings.getInt(Settings.KEYS.CVE_MODIFIED_VALID_FOR_DAYS, 7);
      -  288  0
                       if (lastUpdated == updates.getTimeStamp(MODIFIED)) {
      -  289  0
                           updates.clear(); //we don't need to update anything.
      -  290  0
                       } else if (DateUtil.withinDateRange(lastUpdated, now, days)) {
      -  291  0
                           for (NvdCveInfo entry : updates) {
      -  292  0
                               if (MODIFIED.equals(entry.getId())) {
      -  293  0
                                   entry.setNeedsUpdate(true);
      +  281  0
                       final long lastUpdated = Long.parseLong(getProperties().getProperty(DatabaseProperties.LAST_UPDATED, "0"));
      +  282  0
                       final long now = System.currentTimeMillis();
      +  283  0
                       final int days = Settings.getInt(Settings.KEYS.CVE_MODIFIED_VALID_FOR_DAYS, 7);
      +  284  0
                       if (lastUpdated == updates.getTimeStamp(MODIFIED)) {
      +  285  0
                           updates.clear(); //we don't need to update anything.
      +  286  0
                       } else if (DateUtil.withinDateRange(lastUpdated, now, days)) {
      +  287  0
                           for (NvdCveInfo entry : updates) {
      +  288  0
                               if (MODIFIED.equals(entry.getId())) {
      +  289  0
                                   entry.setNeedsUpdate(true);
      +  290   +
                               } else {
      +  291  0
                                   entry.setNeedsUpdate(false);
      +  292   +
                               }
      +  293  0
                           }
       294   -
                               } else {
      -  295  0
                                   entry.setNeedsUpdate(false);
      -  296   -
                               }
      -  297  0
                           }
      -  298  
                       } else { //we figure out which of the several XML files need to be downloaded.
      -  299  0
                           for (NvdCveInfo entry : updates) {
      -  300  0
                               if (MODIFIED.equals(entry.getId())) {
      -  301  0
                                   entry.setNeedsUpdate(true);
      -  302   +  295  0
                           for (NvdCveInfo entry : updates) {
      +  296  0
                               if (MODIFIED.equals(entry.getId())) {
      +  297  0
                                   entry.setNeedsUpdate(true);
      +  298  
                               } else {
      -  303  0
                                   long currentTimestamp = 0;
      -  304   +  299  0
                                   long currentTimestamp = 0;
      +  300  
                                   try {
      -  305  0
                                       currentTimestamp = Long.parseLong(getProperties().getProperty(DatabaseProperties.LAST_UPDATED_BASE
      -  306  0
                                               + entry.getId(), "0"));
      -  307  0
                                   } catch (NumberFormatException ex) {
      -  308  0
                                       LOGGER.debug("Error parsing '{}' '{}' from nvdcve.lastupdated",
      -  309  0
                                               DatabaseProperties.LAST_UPDATED_BASE, entry.getId(), ex);
      -  310  0
                                   }
      -  311  0
                                   if (currentTimestamp == entry.getTimestamp()) {
      -  312  0
                                       entry.setNeedsUpdate(false);
      -  313   +  301  0
                                       currentTimestamp = Long.parseLong(getProperties().getProperty(DatabaseProperties.LAST_UPDATED_BASE
      +  302  0
                                               + entry.getId(), "0"));
      +  303  0
                                   } catch (NumberFormatException ex) {
      +  304  0
                                       LOGGER.debug("Error parsing '{}' '{}' from nvdcve.lastupdated",
      +  305  0
                                               DatabaseProperties.LAST_UPDATED_BASE, entry.getId(), ex);
      +  306  0
                                   }
      +  307  0
                                   if (currentTimestamp == entry.getTimestamp()) {
      +  308  0
                                       entry.setNeedsUpdate(false);
      +  309  
                                   }
      -  314   +  310  
                               }
      -  315  0
                           }
      -  316   +  311  0
                           }
      +  312  
                       }
      -  317  0
                   } catch (NumberFormatException ex) {
      -  318  0
                       LOGGER.warn("An invalid schema version or timestamp exists in the data.properties file.");
      -  319  0
                       LOGGER.debug("", ex);
      -  320  0
                   }
      +  313  0
                   } catch (NumberFormatException ex) {
      +  314  0
                       LOGGER.warn("An invalid schema version or timestamp exists in the data.properties file.");
      +  315  0
                       LOGGER.debug("", ex);
      +  316  0
                   }
      +  317   +
               }
      +  318  0
               return updates;
      +  319   +
           }
      +  320   +
       
       321   -
               }
      -  322  0
               return updates;
      -  323   -
           }
      -  324   -
       
      -  325  
           /**
      -  326   +  322  
            * Retrieves the timestamps from the NVD CVE meta data file.
      -  327   +  323  
            *
      -  328   +  324  
            * @return the timestamp from the currently published nvdcve downloads page
      -  329   +  325  
            * @throws MalformedURLException thrown if the URL for the NVD CCE Meta data
      -  330   +  326  
            * is incorrect.
      -  331   +  327  
            * @throws DownloadFailedException thrown if there is an error downloading
      -  332   +  328  
            * the nvd cve meta data file
      -  333   +  329  
            * @throws InvalidDataException thrown if there is an exception parsing the
      -  334   +  330  
            * timestamps
      -  335   +  331  
            * @throws InvalidSettingException thrown if the settings are invalid
      -  336   +  332  
            */
      -  337   +  333  
           private UpdateableNvdCve retrieveCurrentTimestampsFromWeb()
      -  338   +  334  
                   throws MalformedURLException, DownloadFailedException, InvalidDataException, InvalidSettingException {
      +  335   +
       
      +  336  0
               final UpdateableNvdCve updates = new UpdateableNvdCve();
      +  337  0
               updates.add(MODIFIED, Settings.getString(Settings.KEYS.CVE_MODIFIED_20_URL),
      +  338  0
                       Settings.getString(Settings.KEYS.CVE_MODIFIED_12_URL),
       339   -
       
      -  340  0
               final UpdateableNvdCve updates = new UpdateableNvdCve();
      -  341  0
               updates.add(MODIFIED, Settings.getString(Settings.KEYS.CVE_MODIFIED_20_URL),
      -  342  0
                       Settings.getString(Settings.KEYS.CVE_MODIFIED_12_URL),
      -  343  
                       false);
      -  344   +  340  
       
      -  345  0
               final int start = Settings.getInt(Settings.KEYS.CVE_START_YEAR);
      -  346  0
               final int end = Calendar.getInstance().get(Calendar.YEAR);
      -  347  0
               final String baseUrl20 = Settings.getString(Settings.KEYS.CVE_SCHEMA_2_0);
      -  348  0
               final String baseUrl12 = Settings.getString(Settings.KEYS.CVE_SCHEMA_1_2);
      -  349  0
               for (int i = start; i <= end; i++) {
      -  350  0
                   updates.add(Integer.toString(i), String.format(baseUrl20, i),
      -  351  0
                           String.format(baseUrl12, i),
      -  352   +  341  0
               final int start = Settings.getInt(Settings.KEYS.CVE_START_YEAR);
      +  342  0
               final int end = Calendar.getInstance().get(Calendar.YEAR);
      +  343  0
               final String baseUrl20 = Settings.getString(Settings.KEYS.CVE_SCHEMA_2_0);
      +  344  0
               final String baseUrl12 = Settings.getString(Settings.KEYS.CVE_SCHEMA_1_2);
      +  345  0
               for (int i = start; i <= end; i++) {
      +  346  0
                   updates.add(Integer.toString(i), String.format(baseUrl20, i),
      +  347  0
                           String.format(baseUrl12, i),
      +  348  
                           true);
      -  353   +  349  
               }
      -  354  0
               return updates;
      -  355   +  350  0
               return updates;
      +  351  
           }
      -  356   +  352  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.UpdateService.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.UpdateService.html index e9dd2ba02..85ba483a0 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.UpdateService.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.UpdateService.html @@ -121,6 +121,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.cpe.CPEHandler.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.cpe.CPEHandler.html index 80d4976ad..06735d5c9 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.cpe.CPEHandler.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.cpe.CPEHandler.html @@ -12,7 +12,7 @@
       
      - +
      Classes in this File Line Coverage Branch Coverage Complexity
      CPEHandler
      0%
      0/30
      0%
      0/16
      1.611
      CPEHandler
      0%
      0/31
      0%
      0/16
      1.611
      CPEHandler$Element
      0%
      0/17
      N/A
      1.611
      @@ -67,640 +67,661 @@  24  
       import org.owasp.dependencycheck.data.update.exception.InvalidDataException;
       25   -
       import org.slf4j.Logger;
      +
       import org.owasp.dependencycheck.utils.Settings;
       26   -
       import org.slf4j.LoggerFactory;
      +
       import org.slf4j.Logger;
       27   -
       import org.xml.sax.Attributes;
      +
       import org.slf4j.LoggerFactory;
       28   -
       import org.xml.sax.SAXException;
      +
       import org.xml.sax.Attributes;
       29   -
       import org.xml.sax.helpers.DefaultHandler;
      +
       import org.xml.sax.SAXException;
       30   -
       
      +
       import org.xml.sax.helpers.DefaultHandler;
       31   -
       /**
      +
       
       32   -
        * A SAX Handler that will parse the CPE XML and load it into the databse.
      +
       /**
       33   -
        *
      +
        * A SAX Handler that will parse the CPE XML and load it into the databse.
       34   -
        * @author Jeremy Long
      +
        *
       35   +
        * @author Jeremy Long
      +  36  
        */
      -  36  0
       public class CPEHandler extends DefaultHandler {
      -  37   -
       
      +  37  0
       public class CPEHandler extends DefaultHandler {
       38   -
           /**
      +
       
       39   -
            * The current CPE schema.
      +
           /**
       40   -
            */
      +
            * The current CPE schema.
       41   -
           private static final String CURRENT_SCHEMA_VERSION = "2.3";
      +
            */
       42   -
           /**
      +
           private static final String CURRENT_SCHEMA_VERSION = "2.3";
       43   -
            * The text content of the node being processed. This can be used during the end element event.
      +
           /**
       44   +
            * The Starts with expression to filter CVE entries by CPE.
      +  45  
            */
      -  45  0
           private StringBuilder nodeText = null;
      -  46   -
           /**
      +  46  0
           private static final String CPE_STARTS_WITH = Settings.getString(Settings.KEYS.CVE_CPE_STARTS_WITH_FILTER, "cpe:/a:");
       47   -
            * A reference to the current element.
      +
           /**
       48   -
            */
      -  49  0
           private final Element current = new Element();
      +
            * The text content of the node being processed. This can be used during the
      +  49   +
            * end element event.
       50   -
           /**
      -  51   -
            * The logger.
      +
            */
      +  51  0
           private StringBuilder nodeText = null;
       52   -
            */
      -  53  0
           private static final Logger LOGGER = LoggerFactory.getLogger(NvdCveUpdater.class);
      +
           /**
      +  53   +
            * A reference to the current element.
       54   -
           /**
      -  55   -
            * The list of CPE values.
      +
            */
      +  55  0
           private final Element current = new Element();
       56   -
            */
      -  57  0
           private final List<Cpe> data = new ArrayList<Cpe>();
      +
           /**
      +  57   +
            * The logger.
       58   -
       
      -  59   -
           /**
      +
            */
      +  59  0
           private static final Logger LOGGER = LoggerFactory.getLogger(NvdCveUpdater.class);
       60   -
            * Returns the list of CPE values.
      +
           /**
       61   -
            *
      +
            * The list of CPE values.
       62   -
            * @return the list of CPE values
      -  63  
            */
      +  63  0
           private final List<Cpe> data = new ArrayList<Cpe>();
       64   -
           public List<Cpe> getData() {
      -  65  0
               return data;
      +
       
      +  65   +
           /**
       66   -
           }
      +
            * Returns the list of CPE values.
       67   -
       
      +
            *
       68   -
           /**
      +
            * @return the list of CPE values
       69   -
            * Handles the start element event.
      +
            */
       70   -
            *
      -  71   -
            * @param uri the elements uri
      +
           public List<Cpe> getData() {
      +  71  0
               return data;
       72   -
            * @param localName the local name
      +
           }
       73   -
            * @param qName the qualified name
      +
       
       74   -
            * @param attributes the attributes
      +
           /**
       75   -
            * @throws SAXException thrown if there is an exception processing the element
      +
            * Handles the start element event.
       76   -
            */
      +
            *
       77   -
           @Override
      +
            * @param uri the elements uri
       78   -
           public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
      -  79  0
               nodeText = null;
      -  80  0
               current.setNode(qName);
      -  81  0
               if (current.isCpeItemNode()) {
      -  82  0
                   final String temp = attributes.getValue("deprecated");
      -  83  0
                   final String value = attributes.getValue("name");
      -  84  0
                   final boolean delete = "true".equalsIgnoreCase(temp);
      -  85  0
                   if (!delete && value.startsWith("cpe:/a:") && value.length() > 7) {
      -  86   -
                       try {
      -  87  0
                           final Cpe cpe = new Cpe(value);
      -  88  0
                           data.add(cpe);
      -  89  0
                       } catch (UnsupportedEncodingException ex) {
      -  90  0
                           LOGGER.debug("Unable to parse the CPE", ex);
      -  91  0
                       } catch (InvalidDataException ex) {
      -  92  0
                           LOGGER.debug("CPE is not the correct format", ex);
      -  93  0
                       }
      -  94   -
                   }
      -  95  0
               } else if (current.isSchemaVersionNode()) {
      -  96  0
                   nodeText = new StringBuilder(3);
      -  97   -
               }
      -  98   -
       //        } else if (current.isTitleNode()) {
      -  99   -
       //            //do nothing
      -  100   -
       //        } else if (current.isMetaNode()) {
      -  101   -
       //            //do nothing
      -  102   -
       //        } else if (current.isTimestampNode()) {
      -  103   -
       //            //do nothing
      -  104   -
       //        } else if (current.isCpeListNode()) {
      -  105   -
       //            //do nothing
      -  106   -
       //        } else if (current.isNotesNode()) {
      -  107   -
       //            //do nothing
      -  108   -
       //        } else if (current.isNoteNode()) {
      -  109   -
       //            //do nothing
      -  110   -
       //        } else if (current.isCheckNode()) {
      -  111   -
       //            //do nothing
      -  112   -
       //        } else if (current.isGeneratorNode()) {
      -  113   -
       //            //do nothing
      -  114   -
       //        } else if (current.isProductNameNode()) {
      -  115   -
       //            //do nothing
      -  116   -
       //        } else if (current.isProductVersionNode()) {
      -  117   -
       //            //do nothing
      -  118  0
           }
      -  119   -
       
      -  120   -
           /**
      -  121   -
            * Reads the characters in the current node.
      -  122   -
            *
      -  123   -
            * @param ch the char array
      -  124   -
            * @param start the start position of the data read
      -  125   -
            * @param length the length of the data read
      -  126   -
            * @throws SAXException thrown if there is an exception processing the characters
      -  127   -
            */
      -  128   -
           @Override
      -  129   -
           public void characters(char[] ch, int start, int length) throws SAXException {
      -  130  0
               if (nodeText != null) {
      -  131  0
                   nodeText.append(ch, start, length);
      -  132   -
               }
      -  133  0
           }
      -  134   -
       
      -  135   -
           /**
      -  136   -
            * Handles the end element event. Stores the CPE data in the Cve Database if the cpe item node is ending.
      -  137   -
            *
      -  138   -
            * @param uri the element's uri
      -  139  
            * @param localName the local name
      -  140   +  79  
            * @param qName the qualified name
      -  141   -
            * @throws SAXException thrown if there is an exception processing the element
      -  142   +  80   +
            * @param attributes the attributes
      +  81   +
            * @throws SAXException thrown if there is an exception processing the
      +  82   +
            * element
      +  83  
            */
      -  143   +  84  
           @Override
      -  144   -
           public void endElement(String uri, String localName, String qName) throws SAXException {
      -  145  0
               current.setNode(qName);
      -  146  0
               if (current.isSchemaVersionNode() && !CURRENT_SCHEMA_VERSION.equals(nodeText.toString())) {
      -  147  0
                   throw new SAXException("ERROR: Unexpecgted CPE Schema Version, expected: "
      -  148   -
                           + CURRENT_SCHEMA_VERSION + ", file is: " + nodeText);
      -  149   -
       
      -  150   +  85   +
           public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
      +  86  0
               nodeText = null;
      +  87  0
               current.setNode(qName);
      +  88  0
               if (current.isCpeItemNode()) {
      +  89  0
                   final String temp = attributes.getValue("deprecated");
      +  90  0
                   final String value = attributes.getValue("name");
      +  91  0
                   final boolean delete = "true".equalsIgnoreCase(temp);
      +  92  0
                   if (!delete && value.startsWith(CPE_STARTS_WITH) && value.length() > 7) {
      +  93   +
                       try {
      +  94  0
                           final Cpe cpe = new Cpe(value);
      +  95  0
                           data.add(cpe);
      +  96  0
                       } catch (UnsupportedEncodingException ex) {
      +  97  0
                           LOGGER.debug("Unable to parse the CPE", ex);
      +  98  0
                       } catch (InvalidDataException ex) {
      +  99  0
                           LOGGER.debug("CPE is not the correct format", ex);
      +  100  0
                       }
      +  101   +
                   }
      +  102  0
               } else if (current.isSchemaVersionNode()) {
      +  103  0
                   nodeText = new StringBuilder(3);
      +  104  
               }
      -  151   -
       //        } else if (current.isCpeItemNode()) {
      -  152   -
       //            //do nothing
      -  153   +  105  
       //        } else if (current.isTitleNode()) {
      -  154   +  106  
       //            //do nothing
      -  155   -
       //        } else if (current.isCpeListNode()) {
      -  156   -
       //            //do nothing
      -  157   +  107  
       //        } else if (current.isMetaNode()) {
      -  158   +  108  
       //            //do nothing
      -  159   +  109   +
       //        } else if (current.isTimestampNode()) {
      +  110   +
       //            //do nothing
      +  111   +
       //        } else if (current.isCpeListNode()) {
      +  112   +
       //            //do nothing
      +  113  
       //        } else if (current.isNotesNode()) {
      -  160   +  114  
       //            //do nothing
      -  161   +  115  
       //        } else if (current.isNoteNode()) {
      +  116   +
       //            //do nothing
      +  117   +
       //        } else if (current.isCheckNode()) {
      +  118   +
       //            //do nothing
      +  119   +
       //        } else if (current.isGeneratorNode()) {
      +  120   +
       //            //do nothing
      +  121   +
       //        } else if (current.isProductNameNode()) {
      +  122   +
       //            //do nothing
      +  123   +
       //        } else if (current.isProductVersionNode()) {
      +  124   +
       //            //do nothing
      +  125  0
           }
      +  126   +
       
      +  127   +
           /**
      +  128   +
            * Reads the characters in the current node.
      +  129   +
            *
      +  130   +
            * @param ch the char array
      +  131   +
            * @param start the start position of the data read
      +  132   +
            * @param length the length of the data read
      +  133   +
            * @throws SAXException thrown if there is an exception processing the
      +  134   +
            * characters
      +  135   +
            */
      +  136   +
           @Override
      +  137   +
           public void characters(char[] ch, int start, int length) throws SAXException {
      +  138  0
               if (nodeText != null) {
      +  139  0
                   nodeText.append(ch, start, length);
      +  140   +
               }
      +  141  0
           }
      +  142   +
       
      +  143   +
           /**
      +  144   +
            * Handles the end element event. Stores the CPE data in the Cve Database if
      +  145   +
            * the cpe item node is ending.
      +  146   +
            *
      +  147   +
            * @param uri the element's uri
      +  148   +
            * @param localName the local name
      +  149   +
            * @param qName the qualified name
      +  150   +
            * @throws SAXException thrown if there is an exception processing the
      +  151   +
            * element
      +  152   +
            */
      +  153   +
           @Override
      +  154   +
           public void endElement(String uri, String localName, String qName) throws SAXException {
      +  155  0
               current.setNode(qName);
      +  156  0
               if (current.isSchemaVersionNode() && !CURRENT_SCHEMA_VERSION.equals(nodeText.toString())) {
      +  157  0
                   throw new SAXException("ERROR: Unexpecgted CPE Schema Version, expected: "
      +  158   +
                           + CURRENT_SCHEMA_VERSION + ", file is: " + nodeText);
      +  159   +
       
      +  160   +
               }
      +  161   +
       //        } else if (current.isCpeItemNode()) {
       162  
       //            //do nothing
       163   -
       //        } else if (current.isCheckNode()) {
      +
       //        } else if (current.isTitleNode()) {
       164  
       //            //do nothing
       165   -
       //        } else if (current.isGeneratorNode()) {
      +
       //        } else if (current.isCpeListNode()) {
       166  
       //            //do nothing
       167   -
       //        } else if (current.isProductNameNode()) {
      +
       //        } else if (current.isMetaNode()) {
       168  
       //            //do nothing
       169   -
       //        } else if (current.isProductVersionNode()) {
      +
       //        } else if (current.isNotesNode()) {
       170  
       //            //do nothing
       171   -
       //        else if (current.isTimestampNode()) {
      +
       //        } else if (current.isNoteNode()) {
       172  
       //            //do nothing
       173   -
       //        } else {
      +
       //        } else if (current.isCheckNode()) {
       174   -
       //            throw new SAXException("ERROR STATE: Unexpected qName '" + qName + "'");
      +
       //            //do nothing
       175   -
       //        }
      -  176  0
           }
      +
       //        } else if (current.isGeneratorNode()) {
      +  176   +
       //            //do nothing
       177   -
       
      +
       //        } else if (current.isProductNameNode()) {
       178   -
           // <editor-fold defaultstate="collapsed" desc="The Element Class that maintains state information about the current node">
      +
       //            //do nothing
       179   -
           /**
      +
       //        } else if (current.isProductVersionNode()) {
       180   -
            * A simple class to maintain information about the current element while parsing the CPE XML.
      +
       //            //do nothing
       181   -
            */
      -  182  0
           protected static final class Element {
      +
       //        else if (current.isTimestampNode()) {
      +  182   +
       //            //do nothing
       183   -
       
      +
       //        } else {
       184   -
               /**
      +
       //            throw new SAXException("ERROR STATE: Unexpected qName '" + qName + "'");
       185   -
                * A node type in the CPE Schema 2.2
      -  186   -
                */
      +
       //        }
      +  186  0
           }
       187   -
               public static final String CPE_LIST = "cpe-list";
      -  188   -
               /**
      -  189   -
                * A node type in the CPE Schema 2.2
      -  190   -
                */
      -  191   -
               public static final String CPE_ITEM = "cpe-item";
      -  192   -
               /**
      -  193   -
                * A node type in the CPE Schema 2.2
      -  194   -
                */
      -  195   -
               public static final String TITLE = "title";
      -  196   -
               /**
      -  197   -
                * A node type in the CPE Schema 2.2
      -  198   -
                */
      -  199   -
               public static final String NOTES = "notes";
      -  200   -
               /**
      -  201   -
                * A node type in the CPE Schema 2.2
      -  202   -
                */
      -  203   -
               public static final String NOTE = "note";
      -  204   -
               /**
      -  205   -
                * A node type in the CPE Schema 2.2
      -  206   -
                */
      -  207   -
               public static final String CHECK = "check";
      -  208   -
               /**
      -  209   -
                * A node type in the CPE Schema 2.2
      -  210   -
                */
      -  211   -
               public static final String META = "meta:item-metadata";
      -  212   -
               /**
      -  213   -
                * A node type in the CPE Schema 2.2
      -  214   -
                */
      -  215   -
               public static final String GENERATOR = "generator";
      -  216   -
               /**
      -  217   -
                * A node type in the CPE Schema 2.2
      -  218   -
                */
      -  219   -
               public static final String PRODUCT_NAME = "product_name";
      -  220   -
               /**
      -  221   -
                * A node type in the CPE Schema 2.2
      -  222   -
                */
      -  223   -
               public static final String PRODUCT_VERSION = "product_version";
      -  224   -
               /**
      -  225   -
                * A node type in the CPE Schema 2.2
      -  226   -
                */
      -  227   -
               public static final String SCHEMA_VERSION = "schema_version";
      -  228   -
               /**
      -  229   -
                * A node type in the CPE Schema 2.2
      -  230   -
                */
      -  231   -
               public static final String TIMESTAMP = "timestamp";
      -  232   -
               /**
      -  233   -
                * A reference to the current node.
      -  234   -
                */
      -  235  0
               private String node = null;
      -  236  
       
      -  237   +  188   +
           // <editor-fold defaultstate="collapsed" desc="The Element Class that maintains state information about the current node">
      +  189   +
           /**
      +  190   +
            * A simple class to maintain information about the current element while
      +  191   +
            * parsing the CPE XML.
      +  192   +
            */
      +  193  0
           protected static final class Element {
      +  194   +
       
      +  195  
               /**
      +  196   +
                * A node type in the CPE Schema 2.2
      +  197   +
                */
      +  198   +
               public static final String CPE_LIST = "cpe-list";
      +  199   +
               /**
      +  200   +
                * A node type in the CPE Schema 2.2
      +  201   +
                */
      +  202   +
               public static final String CPE_ITEM = "cpe-item";
      +  203   +
               /**
      +  204   +
                * A node type in the CPE Schema 2.2
      +  205   +
                */
      +  206   +
               public static final String TITLE = "title";
      +  207   +
               /**
      +  208   +
                * A node type in the CPE Schema 2.2
      +  209   +
                */
      +  210   +
               public static final String NOTES = "notes";
      +  211   +
               /**
      +  212   +
                * A node type in the CPE Schema 2.2
      +  213   +
                */
      +  214   +
               public static final String NOTE = "note";
      +  215   +
               /**
      +  216   +
                * A node type in the CPE Schema 2.2
      +  217   +
                */
      +  218   +
               public static final String CHECK = "check";
      +  219   +
               /**
      +  220   +
                * A node type in the CPE Schema 2.2
      +  221   +
                */
      +  222   +
               public static final String META = "meta:item-metadata";
      +  223   +
               /**
      +  224   +
                * A node type in the CPE Schema 2.2
      +  225   +
                */
      +  226   +
               public static final String GENERATOR = "generator";
      +  227   +
               /**
      +  228   +
                * A node type in the CPE Schema 2.2
      +  229   +
                */
      +  230   +
               public static final String PRODUCT_NAME = "product_name";
      +  231   +
               /**
      +  232   +
                * A node type in the CPE Schema 2.2
      +  233   +
                */
      +  234   +
               public static final String PRODUCT_VERSION = "product_version";
      +  235   +
               /**
      +  236   +
                * A node type in the CPE Schema 2.2
      +  237   +
                */
       238   -
                * Gets the value of node
      +
               public static final String SCHEMA_VERSION = "schema_version";
       239   -
                *
      +
               /**
       240   -
                * @return the value of node
      +
                * A node type in the CPE Schema 2.2
       241  
                */
       242   -
               public String getNode() {
      -  243  0
                   return this.node;
      +
               public static final String TIMESTAMP = "timestamp";
      +  243   +
               /**
       244   -
               }
      +
                * A reference to the current node.
       245   -
       
      -  246   -
               /**
      +
                */
      +  246  0
               private String node = null;
       247   -
                * Sets the value of node
      +
       
       248   -
                *
      +
               /**
       249   -
                * @param node new value of node
      +
                * Gets the value of node
       250   -
                */
      +
                *
       251   -
               public void setNode(String node) {
      -  252  0
                   this.node = node;
      -  253  0
               }
      -  254   -
       
      +
                * @return the value of node
      +  252   +
                */
      +  253   +
               public String getNode() {
      +  254  0
                   return this.node;
       255   -
               /**
      +
               }
       256   -
                * Checks if the handler is at the CPE_LIST node
      +
       
       257   -
                *
      +
               /**
       258   -
                * @return true or false
      +
                * Sets the value of node
       259   -
                */
      +
                *
       260   -
               public boolean isCpeListNode() {
      -  261  0
                   return CPE_LIST.equals(node);
      +
                * @param node new value of node
      +  261   +
                */
       262   -
               }
      -  263   -
       
      -  264   -
               /**
      +
               public void setNode(String node) {
      +  263  0
                   this.node = node;
      +  264  0
               }
       265   -
                * Checks if the handler is at the CPE_ITEM node
      +
       
       266   -
                *
      +
               /**
       267   -
                * @return true or false
      +
                * Checks if the handler is at the CPE_LIST node
       268   -
                */
      +
                *
       269   -
               public boolean isCpeItemNode() {
      -  270  0
                   return CPE_ITEM.equals(node);
      +
                * @return true or false
      +  270   +
                */
       271   -
               }
      -  272   -
       
      +
               public boolean isCpeListNode() {
      +  272  0
                   return CPE_LIST.equals(node);
       273   -
               /**
      +
               }
       274   -
                * Checks if the handler is at the TITLE node
      +
       
       275   -
                *
      +
               /**
       276   -
                * @return true or false
      +
                * Checks if the handler is at the CPE_ITEM node
       277   -
                */
      +
                *
       278   -
               public boolean isTitleNode() {
      -  279  0
                   return TITLE.equals(node);
      +
                * @return true or false
      +  279   +
                */
       280   -
               }
      -  281   -
       
      +
               public boolean isCpeItemNode() {
      +  281  0
                   return CPE_ITEM.equals(node);
       282   -
               /**
      +
               }
       283   -
                * Checks if the handler is at the NOTES node
      +
       
       284   -
                *
      +
               /**
       285   -
                * @return true or false
      +
                * Checks if the handler is at the TITLE node
       286   -
                */
      +
                *
       287   -
               public boolean isNotesNode() {
      -  288  0
                   return NOTES.equals(node);
      +
                * @return true or false
      +  288   +
                */
       289   -
               }
      -  290   -
       
      +
               public boolean isTitleNode() {
      +  290  0
                   return TITLE.equals(node);
       291   -
               /**
      +
               }
       292   -
                * Checks if the handler is at the NOTE node
      +
       
       293   -
                *
      +
               /**
       294   -
                * @return true or false
      +
                * Checks if the handler is at the NOTES node
       295   -
                */
      +
                *
       296   -
               public boolean isNoteNode() {
      -  297  0
                   return NOTE.equals(node);
      +
                * @return true or false
      +  297   +
                */
       298   -
               }
      -  299   -
       
      +
               public boolean isNotesNode() {
      +  299  0
                   return NOTES.equals(node);
       300   -
               /**
      +
               }
       301   -
                * Checks if the handler is at the CHECK node
      +
       
       302   -
                *
      +
               /**
       303   -
                * @return true or false
      +
                * Checks if the handler is at the NOTE node
       304   -
                */
      +
                *
       305   -
               public boolean isCheckNode() {
      -  306  0
                   return CHECK.equals(node);
      +
                * @return true or false
      +  306   +
                */
       307   -
               }
      -  308   -
       
      +
               public boolean isNoteNode() {
      +  308  0
                   return NOTE.equals(node);
       309   -
               /**
      +
               }
       310   -
                * Checks if the handler is at the META node
      +
       
       311   -
                *
      +
               /**
       312   -
                * @return true or false
      +
                * Checks if the handler is at the CHECK node
       313   -
                */
      +
                *
       314   -
               public boolean isMetaNode() {
      -  315  0
                   return META.equals(node);
      +
                * @return true or false
      +  315   +
                */
       316   -
               }
      -  317   -
       
      +
               public boolean isCheckNode() {
      +  317  0
                   return CHECK.equals(node);
       318   -
               /**
      +
               }
       319   -
                * Checks if the handler is at the GENERATOR node
      +
       
       320   -
                *
      +
               /**
       321   -
                * @return true or false
      +
                * Checks if the handler is at the META node
       322   -
                */
      +
                *
       323   -
               public boolean isGeneratorNode() {
      -  324  0
                   return GENERATOR.equals(node);
      +
                * @return true or false
      +  324   +
                */
       325   -
               }
      -  326   -
       
      +
               public boolean isMetaNode() {
      +  326  0
                   return META.equals(node);
       327   -
               /**
      +
               }
       328   -
                * Checks if the handler is at the PRODUCT_NAME node
      +
       
       329   -
                *
      +
               /**
       330   -
                * @return true or false
      +
                * Checks if the handler is at the GENERATOR node
       331   -
                */
      +
                *
       332   -
               public boolean isProductNameNode() {
      -  333  0
                   return PRODUCT_NAME.equals(node);
      +
                * @return true or false
      +  333   +
                */
       334   -
               }
      -  335   -
       
      +
               public boolean isGeneratorNode() {
      +  335  0
                   return GENERATOR.equals(node);
       336   -
               /**
      +
               }
       337   -
                * Checks if the handler is at the PRODUCT_VERSION node
      +
       
       338   -
                *
      +
               /**
       339   -
                * @return true or false
      +
                * Checks if the handler is at the PRODUCT_NAME node
       340   -
                */
      +
                *
       341   -
               public boolean isProductVersionNode() {
      -  342  0
                   return PRODUCT_VERSION.equals(node);
      +
                * @return true or false
      +  342   +
                */
       343   -
               }
      -  344   -
       
      +
               public boolean isProductNameNode() {
      +  344  0
                   return PRODUCT_NAME.equals(node);
       345   -
               /**
      +
               }
       346   -
                * Checks if the handler is at the SCHEMA_VERSION node
      -  347   -
                *
      -  348   -
                * @return true or false
      -  349   -
                */
      -  350   -
               public boolean isSchemaVersionNode() {
      -  351  0
                   return SCHEMA_VERSION.equals(node);
      -  352   -
               }
      -  353  
       
      -  354   +  347  
               /**
      -  355   -
                * Checks if the handler is at the TIMESTAMP node
      -  356   +  348   +
                * Checks if the handler is at the PRODUCT_VERSION node
      +  349  
                *
      -  357   +  350  
                * @return true or false
      -  358   +  351  
                */
      -  359   -
               public boolean isTimestampNode() {
      -  360  0
                   return TIMESTAMP.equals(node);
      -  361   +  352   +
               public boolean isProductVersionNode() {
      +  353  0
                   return PRODUCT_VERSION.equals(node);
      +  354  
               }
      -  362   -
           }
      +  355   +
       
      +  356   +
               /**
      +  357   +
                * Checks if the handler is at the SCHEMA_VERSION node
      +  358   +
                *
      +  359   +
                * @return true or false
      +  360   +
                */
      +  361   +
               public boolean isSchemaVersionNode() {
      +  362  0
                   return SCHEMA_VERSION.equals(node);
       363   -
           // </editor-fold>
      +
               }
       364   +
       
      +  365   +
               /**
      +  366   +
                * Checks if the handler is at the TIMESTAMP node
      +  367   +
                *
      +  368   +
                * @return true or false
      +  369   +
                */
      +  370   +
               public boolean isTimestampNode() {
      +  371  0
                   return TIMESTAMP.equals(node);
      +  372   +
               }
      +  373   +
           }
      +  374   +
           // </editor-fold>
      +  375  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.cpe.Cpe.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.cpe.Cpe.html index 4e1980116..75683cc92 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.cpe.Cpe.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.cpe.Cpe.html @@ -251,6 +251,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.exception.InvalidDataException.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.exception.InvalidDataException.html index a4edfd858..65c63eb6a 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.exception.InvalidDataException.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.exception.InvalidDataException.html @@ -115,6 +115,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.exception.UpdateException.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.exception.UpdateException.html index 3e684e6b1..b90d0e918 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.exception.UpdateException.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.exception.UpdateException.html @@ -56,97 +56,93 @@  19  
       
       20   -
       import java.io.IOException;
      -  21   -
       
      -  22  
       /**
      -  23   +  21  
        * An exception used when an error occurs reading a setting.
      -  24   +  22  
        *
      -  25   +  23  
        * @author Jeremy Long
      -  26   +  24  
        */
      +  25   +
       public class UpdateException extends Exception {
      +  26   +
       
       27   -
       public class UpdateException extends IOException {
      +
           /**
       28   -
       
      -  29   -
           /**
      -  30  
            * The serial version uid.
      -  31   +  29  
            */
      -  32   +  30  
           private static final long serialVersionUID = 1L;
      +  31   +
       
      +  32   +
           /**
       33   -
       
      +
            * Creates a new UpdateException.
       34   -
           /**
      +
            */
       35   -
            * Creates a new UpdateException.
      -  36   -
            */
      -  37  
           public UpdateException() {
      -  38  0
               super();
      -  39  0
           }
      +  36  0
               super();
      +  37  0
           }
      +  38   +
       
      +  39   +
           /**
       40   -
       
      +
            * Creates a new UpdateException.
       41   -
           /**
      +
            *
       42   -
            * Creates a new UpdateException.
      +
            * @param msg a message for the exception.
       43   -
            *
      +
            */
       44   -
            * @param msg a message for the exception.
      -  45   -
            */
      -  46  
           public UpdateException(String msg) {
      -  47  0
               super(msg);
      -  48  0
           }
      +  45  0
               super(msg);
      +  46  0
           }
      +  47   +
       
      +  48   +
           /**
       49   -
       
      +
            * Creates a new UpdateException.
       50   -
           /**
      +
            *
       51   -
            * Creates a new UpdateException.
      +
            * @param ex the cause of the update exception.
       52   -
            *
      +
            */
       53   -
            * @param ex the cause of the update exception.
      -  54   -
            */
      -  55  
           public UpdateException(Throwable ex) {
      -  56  0
               super(ex);
      -  57  0
           }
      -  58   +  54  0
               super(ex);
      +  55  0
           }
      +  56  
       
      -  59   +  57  
           /**
      -  60   +  58  
            * Creates a new UpdateException.
      -  61   +  59  
            *
      -  62   +  60  
            * @param msg a message for the exception.
      -  63   +  61  
            * @param ex the cause of the update exception.
      -  64   +  62  
            */
      -  65   +  63  
           public UpdateException(String msg, Throwable ex) {
      -  66  0
               super(msg, ex);
      -  67  0
           }
      -  68   +  64  0
               super(msg, ex);
      +  65  0
           }
      +  66  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.DownloadTask.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.DownloadTask.html index 0133e2d04..f1e240d6d 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.DownloadTask.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.DownloadTask.html @@ -114,7 +114,7 @@
            * The Logger.
       49  
            */
      -  50  2
           private static final Logger LOGGER = LoggerFactory.getLogger(DownloadTask.class);
      +  50  1
           private static final Logger LOGGER = LoggerFactory.getLogger(DownloadTask.class);
       51  
       
       52   @@ -137,11 +137,11 @@
            * @throws UpdateException thrown if temporary files could not be created
       61  
            */
      -  62  2
           public DownloadTask(NvdCveInfo nvdCveInfo, ExecutorService processor, CveDB cveDB, Settings settings) throws UpdateException {
      -  63  2
               this.nvdCveInfo = nvdCveInfo;
      -  64  2
               this.processorService = processor;
      -  65  2
               this.cveDB = cveDB;
      -  66  2
               this.settings = settings;
      +  62  1
           public DownloadTask(NvdCveInfo nvdCveInfo, ExecutorService processor, CveDB cveDB, Settings settings) throws UpdateException {
      +  63  1
               this.nvdCveInfo = nvdCveInfo;
      +  64  1
               this.processorService = processor;
      +  65  1
               this.cveDB = cveDB;
      +  66  1
               this.settings = settings;
       67  
       
       68   @@ -152,16 +152,16 @@
       
       71  
               try {
      -  72  2
                   file1 = File.createTempFile("cve" + nvdCveInfo.getId() + '_', ".xml", Settings.getTempDirectory());
      -  73  2
                   file2 = File.createTempFile("cve_1_2_" + nvdCveInfo.getId() + '_', ".xml", Settings.getTempDirectory());
      +  72  1
                   file1 = File.createTempFile("cve" + nvdCveInfo.getId() + '_', ".xml", Settings.getTempDirectory());
      +  73  1
                   file2 = File.createTempFile("cve_1_2_" + nvdCveInfo.getId() + '_', ".xml", Settings.getTempDirectory());
       74  0
               } catch (IOException ex) {
       75  0
                   throw new UpdateException("Unable to create temporary files", ex);
      -  76  2
               }
      -  77  2
               this.first = file1;
      -  78  2
               this.second = file2;
      +  76  1
               }
      +  77  1
               this.first = file1;
      +  78  1
               this.second = file2;
       79  
       
      -  80  2
           }
      +  80  1
           }
       81  
           /**
       82   @@ -317,15 +317,15 @@
           public Future<ProcessTask> call() throws Exception {
       162  
               try {
      -  163  2
                   Settings.setInstance(settings);
      -  164  2
                   final URL url1 = new URL(nvdCveInfo.getUrl());
      -  165  2
                   final URL url2 = new URL(nvdCveInfo.getOldSchemaVersionUrl());
      -  166  2
                   LOGGER.info("Download Started for NVD CVE - {}", nvdCveInfo.getId());
      -  167  2
                   final long startDownload = System.currentTimeMillis();
      +  163  1
                   Settings.setInstance(settings);
      +  164  1
                   final URL url1 = new URL(nvdCveInfo.getUrl());
      +  165  1
                   final URL url2 = new URL(nvdCveInfo.getOldSchemaVersionUrl());
      +  166  1
                   LOGGER.info("Download Started for NVD CVE - {}", nvdCveInfo.getId());
      +  167  1
                   final long startDownload = System.currentTimeMillis();
       168  
                   try {
      -  169  2
                       Downloader.fetchFile(url1, first);
      -  170  2
                       Downloader.fetchFile(url2, second);
      +  169  1
                       Downloader.fetchFile(url1, first);
      +  170  1
                       Downloader.fetchFile(url2, second);
       171  0
                   } catch (DownloadFailedException ex) {
       172  0
                       LOGGER.warn("Download Failed for NVD CVE - {}\nSome CVEs may not be reported.", nvdCveInfo.getId());
       173  0
                       if (Settings.getString(Settings.KEYS.PROXY_SERVER) == null) {
      @@ -336,21 +336,21 @@
                       }
       177  0
                       LOGGER.debug("", ex);
       178  0
                       return null;
      -  179  2
                   }
      -  180  2
                   if (url1.toExternalForm().endsWith(".xml.gz") && !isXml(first)) {
      -  181  2
                       extractGzip(first);
      +  179  1
                   }
      +  180  1
                   if (url1.toExternalForm().endsWith(".xml.gz") && !isXml(first)) {
      +  181  1
                       extractGzip(first);
       182  
                   }
      -  183  2
                   if (url2.toExternalForm().endsWith(".xml.gz") && !isXml(second)) {
      -  184  2
                       extractGzip(second);
      +  183  1
                   if (url2.toExternalForm().endsWith(".xml.gz") && !isXml(second)) {
      +  184  1
                       extractGzip(second);
       185  
                   }
       186  
       
      -  187  4
                   LOGGER.info("Download Complete for NVD CVE - {}  ({} ms)", nvdCveInfo.getId(),
      -  188  2
                           System.currentTimeMillis() - startDownload);
      -  189  2
                   if (this.processorService == null) {
      -  190  4
                       return null;
      +  187  2
                   LOGGER.info("Download Complete for NVD CVE - {}  ({} ms)", nvdCveInfo.getId(),
      +  188  1
                           System.currentTimeMillis() - startDownload);
      +  189  1
                   if (this.processorService == null) {
      +  190  2
                       return null;
       191  
                   }
       192  0
                   final ProcessTask task = new ProcessTask(cveDB, this, settings);
      @@ -362,7 +362,7 @@  197  0
                   LOGGER.debug("Download Task Failed", ex);
       198  
               } finally {
      -  199  2
                   Settings.cleanup(false);
      +  199  1
                   Settings.cleanup(false);
       200  0
               }
       201  0
               return null;
       202   @@ -424,25 +424,25 @@
            */
       236  
           public static boolean isXml(File file) {
      -  237  8
               if (file == null || !file.isFile()) {
      +  237  4
               if (file == null || !file.isFile()) {
       238  0
                   return false;
       239  
               }
      -  240  8
               InputStream is = null;
      +  240  4
               InputStream is = null;
       241  
               try {
      -  242  8
                   is = new FileInputStream(file);
      +  242  4
                   is = new FileInputStream(file);
       243  
       
      -  244  8
                   final byte[] buf = new byte[5];
      -  245  8
                   int read = 0;
      +  244  4
                   final byte[] buf = new byte[5];
      +  245  4
                   int read = 0;
       246  
                   try {
      -  247  8
                       read = is.read(buf);
      +  247  4
                       read = is.read(buf);
       248  0
                   } catch (IOException ex) {
       249  0
                       return false;
      -  250  8
                   }
      -  251  16
                   return read == 5
      +  250  4
                   }
      +  251  8
                   return read == 5
       252  
                           && buf[0] == '<'
       253   @@ -457,13 +457,13 @@  258  0
                   return false;
       259  
               } finally {
      -  260  8
                   if (is != null) {
      +  260  4
                   if (is != null) {
       261  
                       try {
      -  262  8
                           is.close();
      +  262  4
                           is.close();
       263  0
                       } catch (IOException ex) {
       264  0
                           LOGGER.debug("Error closing stream", ex);
      -  265  8
                       }
      +  265  4
                       }
       266  
                   }
       267   @@ -488,67 +488,67 @@
            */
       277  
           private void extractGzip(File file) throws FileNotFoundException, IOException {
      -  278  4
               final String originalPath = file.getPath();
      -  279  4
               final File gzip = new File(originalPath + ".gz");
      -  280  4
               if (gzip.isFile() && !gzip.delete()) {
      +  278  2
               final String originalPath = file.getPath();
      +  279  2
               final File gzip = new File(originalPath + ".gz");
      +  280  2
               if (gzip.isFile() && !gzip.delete()) {
       281  0
                   gzip.deleteOnExit();
       282  
               }
      -  283  4
               if (!file.renameTo(gzip)) {
      +  283  2
               if (!file.renameTo(gzip)) {
       284  0
                   throw new IOException("Unable to rename '" + file.getPath() + "'");
       285  
               }
      -  286  4
               final File newfile = new File(originalPath);
      +  286  2
               final File newfile = new File(originalPath);
       287  
       
      -  288  4
               final byte[] buffer = new byte[4096];
      +  288  2
               final byte[] buffer = new byte[4096];
       289  
       
      -  290  4
               GZIPInputStream cin = null;
      -  291  4
               FileOutputStream out = null;
      +  290  2
               GZIPInputStream cin = null;
      +  291  2
               FileOutputStream out = null;
       292  
               try {
      -  293  4
                   cin = new GZIPInputStream(new FileInputStream(gzip));
      -  294  4
                   out = new FileOutputStream(newfile);
      +  293  2
                   cin = new GZIPInputStream(new FileInputStream(gzip));
      +  294  2
                   out = new FileOutputStream(newfile);
       295  
       
       296  
                   int len;
      -  297  3366
                   while ((len = cin.read(buffer)) > 0) {
      -  298  3362
                       out.write(buffer, 0, len);
      +  297  1060
                   while ((len = cin.read(buffer)) > 0) {
      +  298  1058
                       out.write(buffer, 0, len);
       299  
                   }
       300  
               } finally {
      -  301  4
                   if (cin != null) {
      +  301  2
                   if (cin != null) {
       302  
                       try {
      -  303  4
                           cin.close();
      +  303  2
                           cin.close();
       304  0
                       } catch (IOException ex) {
       305  0
                           LOGGER.trace("ignore", ex);
      -  306  4
                       }
      +  306  2
                       }
       307  
                   }
      -  308  4
                   if (out != null) {
      +  308  2
                   if (out != null) {
       309  
                       try {
      -  310  4
                           out.close();
      +  310  2
                           out.close();
       311  0
                       } catch (IOException ex) {
       312  0
                           LOGGER.trace("ignore", ex);
      -  313  4
                       }
      +  313  2
                       }
       314  
                   }
      -  315  4
                   if (gzip.isFile()) {
      -  316  4
                       FileUtils.deleteQuietly(gzip);
      +  315  2
                   if (gzip.isFile()) {
      +  316  2
                       FileUtils.deleteQuietly(gzip);
       317  
                   }
       318  
               }
      -  319  4
           }
      +  319  2
           }
       320  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.NvdCve12Handler.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.NvdCve12Handler.html index 013b34797..5ed3d4cec 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.NvdCve12Handler.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.NvdCve12Handler.html @@ -90,7 +90,7 @@
        * @author Jeremy Long
       36  
        */
      -  37  4
       public class NvdCve12Handler extends DefaultHandler {
      +  37  2
       public class NvdCve12Handler extends DefaultHandler {
       38  
       
       39   @@ -139,21 +139,21 @@
            * if the nvd cve should be skipped because it was rejected.
       61  
            */
      -  62  4
           private boolean skip = false;
      +  62  2
           private boolean skip = false;
       63  
           /**
       64  
            * flag indicating if there is a previous version.
       65  
            */
      -  66  4
           private boolean hasPreviousVersion = false;
      +  66  2
           private boolean hasPreviousVersion = false;
       67  
           /**
       68  
            * The current element.
       69  
            */
      -  70  4
           private final Element current = new Element();
      +  70  2
           private final Element current = new Element();
       71  
           /**
       72   @@ -176,7 +176,7 @@
            */
       81  
           public Map<String, List<VulnerableSoftware>> getVulnerabilities() {
      -  82  4
               return vulnerabilities;
      +  82  2
               return vulnerabilities;
       83  
           }
       84   @@ -185,31 +185,31 @@
           @Override
       86  
           public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
      -  87  2538
               current.setNode(qName);
      -  88  2538
               if (current.isEntryNode()) {
      -  89  56
                   vendor = null;
      -  90  56
                   product = null;
      -  91  56
                   hasPreviousVersion = false;
      -  92  56
                   final String reject = attributes.getValue("reject");
      -  93  56
                   skip = "1".equals(reject);
      -  94  56
                   if (!skip) {
      -  95  54
                       vulnerability = attributes.getValue("name");
      -  96  54
                       software = new ArrayList<VulnerableSoftware>();
      +  87  1269
               current.setNode(qName);
      +  88  1269
               if (current.isEntryNode()) {
      +  89  28
                   vendor = null;
      +  90  28
                   product = null;
      +  91  28
                   hasPreviousVersion = false;
      +  92  28
                   final String reject = attributes.getValue("reject");
      +  93  28
                   skip = "1".equals(reject);
      +  94  28
                   if (!skip) {
      +  95  27
                       vulnerability = attributes.getValue("name");
      +  96  27
                       software = new ArrayList<VulnerableSoftware>();
       97  
                   } else {
      -  98  2
                       vulnerability = null;
      -  99  2
                       software = null;
      +  98  1
                       vulnerability = null;
      +  99  1
                       software = null;
       100  
                   }
      -  101  56
               } else if (!skip && current.isProdNode()) {
      -  102  106
                   vendor = attributes.getValue("vendor");
      -  103  106
                   product = attributes.getValue("name");
      -  104  2376
               } else if (!skip && current.isVersNode()) {
      -  105  1584
                   final String prev = attributes.getValue("prev");
      -  106  1584
                   if (prev != null && "1".equals(prev)) {
      -  107  4
                       hasPreviousVersion = true;
      -  108  4
                       final String edition = attributes.getValue("edition");
      -  109  4
                       final String num = attributes.getValue("num");
      +  101  28
               } else if (!skip && current.isProdNode()) {
      +  102  53
                   vendor = attributes.getValue("vendor");
      +  103  53
                   product = attributes.getValue("name");
      +  104  1188
               } else if (!skip && current.isVersNode()) {
      +  105  792
                   final String prev = attributes.getValue("prev");
      +  106  792
                   if (prev != null && "1".equals(prev)) {
      +  107  2
                       hasPreviousVersion = true;
      +  108  2
                       final String edition = attributes.getValue("edition");
      +  109  2
                       final String num = attributes.getValue("num");
       110  
       
       111   @@ -218,52 +218,52 @@
                        purposes this is good enough as we won't use this if we don't find a corresponding "a"
       113  
                        in the nvd cve 2.0. */
      -  114  4
                       final int cpeLen = 8 + vendor.length() + product.length()
      -  115  4
                           + (null != num ? (1 + num.length()) : 0)
      +  114  2
                       final int cpeLen = 8 + vendor.length() + product.length()
      +  115  2
                           + (null != num ? (1 + num.length()) : 0)
       116  0
                           + (null != edition ? (1 + edition.length()) : 0);
      -  117  4
                       final StringBuilder cpe = new StringBuilder(cpeLen);
      -  118  4
                       cpe.append("cpe:/a:").append(vendor).append(':').append(product);
      -  119  4
                       if (num != null) {
      -  120  4
                           cpe.append(':').append(num);
      +  117  2
                       final StringBuilder cpe = new StringBuilder(cpeLen);
      +  118  2
                       cpe.append("cpe:/a:").append(vendor).append(':').append(product);
      +  119  2
                       if (num != null) {
      +  120  2
                           cpe.append(':').append(num);
       121  
                       }
      -  122  4
                       if (edition != null) {
      +  122  2
                       if (edition != null) {
       123  0
                           cpe.append(':').append(edition);
       124  
                       }
      -  125  4
                       final VulnerableSoftware vs = new VulnerableSoftware();
      -  126  4
                       vs.setCpe(cpe.toString());
      -  127  4
                       vs.setPreviousVersion(prev);
      -  128  4
                       software.add(vs);
      +  125  2
                       final VulnerableSoftware vs = new VulnerableSoftware();
      +  126  2
                       vs.setCpe(cpe.toString());
      +  127  2
                       vs.setPreviousVersion(prev);
      +  128  2
                       software.add(vs);
       129  
                   }
      -  130  1584
               } else if (current.isNVDNode()) {
      -  131  4
                   final String nvdVer = attributes.getValue("nvd_xml_version");
      -  132  4
                   if (!CURRENT_SCHEMA_VERSION.equals(nvdVer)) {
      +  130  792
               } else if (current.isNVDNode()) {
      +  131  2
                   final String nvdVer = attributes.getValue("nvd_xml_version");
      +  132  2
                   if (!CURRENT_SCHEMA_VERSION.equals(nvdVer)) {
       133  0
                       throw new SAXNotSupportedException("Schema version " + nvdVer + " is not supported");
       134  
                   }
      -  135  4
                   vulnerabilities = new HashMap<String, List<VulnerableSoftware>>();
      +  135  2
                   vulnerabilities = new HashMap<String, List<VulnerableSoftware>>();
       136  
               }
      -  137  2538
           }
      +  137  1269
           }
       138  
       
       139  
           @Override
       140  
           public void endElement(String uri, String localName, String qName) throws SAXException {
      -  141  2538
               current.setNode(qName);
      -  142  2538
               if (current.isEntryNode()) {
      -  143  56
                   if (!skip && hasPreviousVersion) {
      -  144  4
                       vulnerabilities.put(vulnerability, software);
      +  141  1269
               current.setNode(qName);
      +  142  1269
               if (current.isEntryNode()) {
      +  143  28
                   if (!skip && hasPreviousVersion) {
      +  144  2
                       vulnerabilities.put(vulnerability, software);
       145  
                   }
      -  146  56
                   vulnerability = null;
      -  147  56
                   software = null;
      +  146  28
                   vulnerability = null;
      +  147  28
                   software = null;
       148  
               }
      -  149  2538
           }
      +  149  1269
           }
       150  
       
       151   @@ -274,7 +274,7 @@
            * A simple class to maintain information about the current element while parsing the NVD CVE XML.
       154  
            */
      -  155  4
           protected static class Element {
      +  155  2
           protected static class Element {
       156  
       
       157   @@ -356,8 +356,8 @@
                */
       196  
               public void setNode(String node) {
      -  197  5076
                   this.node = node;
      -  198  5076
               }
      +  197  2538
                   this.node = node;
      +  198  2538
               }
       199  
       
       200   @@ -372,7 +372,7 @@
                */
       205  
               public boolean isNVDNode() {
      -  206  792
                   return NVD.equals(node);
      +  206  396
                   return NVD.equals(node);
       207  
               }
       208   @@ -389,7 +389,7 @@
                */
       214  
               public boolean isEntryNode() {
      -  215  5076
                   return ENTRY.equals(node);
      +  215  2538
                   return ENTRY.equals(node);
       216  
               }
       217   @@ -423,7 +423,7 @@
                */
       232  
               public boolean isProdNode() {
      -  233  2476
                   return PROD.equals(node);
      +  233  1238
                   return PROD.equals(node);
       234  
               }
       235   @@ -440,7 +440,7 @@
                */
       241  
               public boolean isVersNode() {
      -  242  2370
                   return VERS.equals(node);
      +  242  1185
                   return VERS.equals(node);
       243  
               }
       244   @@ -451,6 +451,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.NvdCve20Handler.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.NvdCve20Handler.html index 3e4086eae..b4e35dfb2 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.NvdCve20Handler.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.NvdCve20Handler.html @@ -98,7 +98,7 @@
        * @author Jeremy Long
       40  
        */
      -  41  4
       public class NvdCve20Handler extends DefaultHandler {
      +  41  2
       public class NvdCve20Handler extends DefaultHandler {
       42  
       
       43   @@ -107,7 +107,7 @@
            * The logger.
       45  
            */
      -  46  2
           private static final Logger LOGGER = LoggerFactory.getLogger(NvdCve20Handler.class);
      +  46  1
           private static final Logger LOGGER = LoggerFactory.getLogger(NvdCve20Handler.class);
       47  
           /**
       48   @@ -122,7 +122,7 @@
            * the current element.
       53  
            */
      -  54  4
           private final Element current = new Element();
      +  54  2
           private final Element current = new Element();
       55  
           /**
       56   @@ -153,7 +153,7 @@
            * flag indicating whether the application has a cpe.
       69  
            */
      -  70  4
           private boolean hasApplicationCpe = false;
      +  70  2
           private boolean hasApplicationCpe = false;
       71  
           /**
       72   @@ -176,7 +176,7 @@
            */
       81  
           public int getTotalNumberOfEntries() {
      -  82  2
               return totalNumberOfEntries;
      +  82  1
               return totalNumberOfEntries;
       83  
           }
       84   @@ -210,144 +210,144 @@
           @Override
       99  
           public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
      -  100  5020
               current.setNode(qName);
      -  101  5020
               if (current.isEntryNode()) {
      -  102  56
                   hasApplicationCpe = false;
      -  103  56
                   vulnerability = new Vulnerability();
      -  104  56
                   vulnerability.setName(attributes.getValue("id"));
      -  105  4964
               } else if (current.isVulnProductNode()) {
      -  106  1516
                   nodeText = new StringBuilder(100);
      -  107  3448
               } else if (current.isVulnReferencesNode()) {
      -  108  190
                   final String lang = attributes.getValue("xml:lang");
      -  109  190
                   if ("en".equals(lang)) {
      -  110  190
                       reference = new Reference();
      +  100  2510
               current.setNode(qName);
      +  101  2510
               if (current.isEntryNode()) {
      +  102  28
                   hasApplicationCpe = false;
      +  103  28
                   vulnerability = new Vulnerability();
      +  104  28
                   vulnerability.setName(attributes.getValue("id"));
      +  105  2482
               } else if (current.isVulnProductNode()) {
      +  106  758
                   nodeText = new StringBuilder(100);
      +  107  1724
               } else if (current.isVulnReferencesNode()) {
      +  108  95
                   final String lang = attributes.getValue("xml:lang");
      +  109  95
                   if ("en".equals(lang)) {
      +  110  95
                       reference = new Reference();
       111  
                   } else {
       112  0
                       reference = null;
       113  
                   }
      -  114  190
               } else if (reference != null && current.isVulnReferenceNode()) {
      -  115  190
                   reference.setUrl(attributes.getValue("href"));
      -  116  190
                   nodeText = new StringBuilder(130);
      -  117  3068
               } else if (reference != null && current.isVulnSourceNode()) {
      -  118  190
                   nodeText = new StringBuilder(30);
      -  119  2878
               } else if (current.isVulnSummaryNode()) {
      -  120  56
                   nodeText = new StringBuilder(500);
      -  121  2822
               } else if (current.isNVDNode()) {
      -  122  4
                   final String nvdVer = attributes.getValue("nvd_xml_version");
      -  123  4
                   if (!CURRENT_SCHEMA_VERSION.equals(nvdVer)) {
      +  114  95
               } else if (reference != null && current.isVulnReferenceNode()) {
      +  115  95
                   reference.setUrl(attributes.getValue("href"));
      +  116  95
                   nodeText = new StringBuilder(130);
      +  117  1534
               } else if (reference != null && current.isVulnSourceNode()) {
      +  118  95
                   nodeText = new StringBuilder(30);
      +  119  1439
               } else if (current.isVulnSummaryNode()) {
      +  120  28
                   nodeText = new StringBuilder(500);
      +  121  1411
               } else if (current.isNVDNode()) {
      +  122  2
                   final String nvdVer = attributes.getValue("nvd_xml_version");
      +  123  2
                   if (!CURRENT_SCHEMA_VERSION.equals(nvdVer)) {
       124  0
                       throw new SAXNotSupportedException("Schema version " + nvdVer + " is not supported");
       125  
                   }
      -  126  4
               } else if (current.isVulnCWENode()) {
      -  127  40
                   vulnerability.setCwe(attributes.getValue("id"));
      -  128  2778
               } else if (current.isCVSSScoreNode()) {
      -  129  54
                   nodeText = new StringBuilder(5);
      -  130  2724
               } else if (current.isCVSSAccessVectorNode()) {
      -  131  54
                   nodeText = new StringBuilder(20);
      -  132  2670
               } else if (current.isCVSSAccessComplexityNode()) {
      -  133  54
                   nodeText = new StringBuilder(20);
      -  134  2616
               } else if (current.isCVSSAuthenticationNode()) {
      -  135  54
                   nodeText = new StringBuilder(20);
      -  136  2562
               } else if (current.isCVSSAvailabilityImpactNode()) {
      -  137  54
                   nodeText = new StringBuilder(20);
      -  138  2508
               } else if (current.isCVSSConfidentialityImpactNode()) {
      -  139  54
                   nodeText = new StringBuilder(20);
      -  140  2454
               } else if (current.isCVSSIntegrityImpactNode()) {
      -  141  54
                   nodeText = new StringBuilder(20);
      +  126  2
               } else if (current.isVulnCWENode()) {
      +  127  20
                   vulnerability.setCwe(attributes.getValue("id"));
      +  128  1389
               } else if (current.isCVSSScoreNode()) {
      +  129  27
                   nodeText = new StringBuilder(5);
      +  130  1362
               } else if (current.isCVSSAccessVectorNode()) {
      +  131  27
                   nodeText = new StringBuilder(20);
      +  132  1335
               } else if (current.isCVSSAccessComplexityNode()) {
      +  133  27
                   nodeText = new StringBuilder(20);
      +  134  1308
               } else if (current.isCVSSAuthenticationNode()) {
      +  135  27
                   nodeText = new StringBuilder(20);
      +  136  1281
               } else if (current.isCVSSAvailabilityImpactNode()) {
      +  137  27
                   nodeText = new StringBuilder(20);
      +  138  1254
               } else if (current.isCVSSConfidentialityImpactNode()) {
      +  139  27
                   nodeText = new StringBuilder(20);
      +  140  1227
               } else if (current.isCVSSIntegrityImpactNode()) {
      +  141  27
                   nodeText = new StringBuilder(20);
       142  
               }
      -  143  5020
           }
      +  143  2510
           }
       144  
       
       145  
           @Override
       146  
           public void characters(char[] ch, int start, int length) throws SAXException {
      -  147  8310
               if (nodeText != null) {
      -  148  2384
                   nodeText.append(ch, start, length);
      +  147  4155
               if (nodeText != null) {
      +  148  1192
                   nodeText.append(ch, start, length);
       149  
               }
      -  150  8310
           }
      +  150  4155
           }
       151  
       
       152  
           @Override
       153  
           public void endElement(String uri, String localName, String qName) throws SAXException {
      -  154  5020
               current.setNode(qName);
      -  155  5020
               if (current.isEntryNode()) {
      -  156  56
                   totalNumberOfEntries += 1;
      -  157  56
                   if (hasApplicationCpe) {
      -  158  40
                       totalNumberOfApplicationEntries += 1;
      +  154  2510
               current.setNode(qName);
      +  155  2510
               if (current.isEntryNode()) {
      +  156  28
                   totalNumberOfEntries += 1;
      +  157  28
                   if (hasApplicationCpe) {
      +  158  20
                       totalNumberOfApplicationEntries += 1;
       159  
                       try {
      -  160  40
                           saveEntry(vulnerability);
      +  160  20
                           saveEntry(vulnerability);
       161  0
                       } catch (DatabaseException ex) {
       162  0
                           throw new SAXException(ex);
       163  0
                       } catch (CorruptIndexException ex) {
       164  0
                           throw new SAXException(ex);
       165  0
                       } catch (IOException ex) {
       166  0
                           throw new SAXException(ex);
      -  167  40
                       }
      +  167  20
                       }
       168  
                   }
      -  169  56
                   vulnerability = null;
      -  170  4964
               } else if (current.isCVSSScoreNode()) {
      +  169  28
                   vulnerability = null;
      +  170  2482
               } else if (current.isCVSSScoreNode()) {
       171  
                   try {
      -  172  54
                       final float score = Float.parseFloat(nodeText.toString());
      -  173  54
                       vulnerability.setCvssScore(score);
      +  172  27
                       final float score = Float.parseFloat(nodeText.toString());
      +  173  27
                       vulnerability.setCvssScore(score);
       174  0
                   } catch (NumberFormatException ex) {
       175  0
                       LOGGER.error("Error parsing CVSS Score.");
       176  0
                       LOGGER.debug("", ex);
      -  177  54
                   }
      -  178  54
                   nodeText = null;
      -  179  4910
               } else if (current.isCVSSAccessVectorNode()) {
      -  180  54
                   vulnerability.setCvssAccessVector(nodeText.toString());
      -  181  54
                   nodeText = null;
      -  182  4856
               } else if (current.isCVSSAccessComplexityNode()) {
      -  183  54
                   vulnerability.setCvssAccessComplexity(nodeText.toString());
      -  184  54
                   nodeText = null;
      -  185  4802
               } else if (current.isCVSSAuthenticationNode()) {
      -  186  54
                   vulnerability.setCvssAuthentication(nodeText.toString());
      -  187  54
                   nodeText = null;
      -  188  4748
               } else if (current.isCVSSAvailabilityImpactNode()) {
      -  189  54
                   vulnerability.setCvssAvailabilityImpact(nodeText.toString());
      -  190  54
                   nodeText = null;
      -  191  4694
               } else if (current.isCVSSConfidentialityImpactNode()) {
      -  192  54
                   vulnerability.setCvssConfidentialityImpact(nodeText.toString());
      -  193  54
                   nodeText = null;
      -  194  4640
               } else if (current.isCVSSIntegrityImpactNode()) {
      -  195  54
                   vulnerability.setCvssIntegrityImpact(nodeText.toString());
      -  196  54
                   nodeText = null;
      -  197  4586
               } else if (current.isVulnProductNode()) {
      -  198  1516
                   final String cpe = nodeText.toString();
      -  199  1516
                   if (cpe.startsWith("cpe:/a:")) {
      -  200  1290
                       hasApplicationCpe = true;
      -  201  1290
                       vulnerability.addVulnerableSoftware(cpe);
      +  177  27
                   }
      +  178  27
                   nodeText = null;
      +  179  2455
               } else if (current.isCVSSAccessVectorNode()) {
      +  180  27
                   vulnerability.setCvssAccessVector(nodeText.toString());
      +  181  27
                   nodeText = null;
      +  182  2428
               } else if (current.isCVSSAccessComplexityNode()) {
      +  183  27
                   vulnerability.setCvssAccessComplexity(nodeText.toString());
      +  184  27
                   nodeText = null;
      +  185  2401
               } else if (current.isCVSSAuthenticationNode()) {
      +  186  27
                   vulnerability.setCvssAuthentication(nodeText.toString());
      +  187  27
                   nodeText = null;
      +  188  2374
               } else if (current.isCVSSAvailabilityImpactNode()) {
      +  189  27
                   vulnerability.setCvssAvailabilityImpact(nodeText.toString());
      +  190  27
                   nodeText = null;
      +  191  2347
               } else if (current.isCVSSConfidentialityImpactNode()) {
      +  192  27
                   vulnerability.setCvssConfidentialityImpact(nodeText.toString());
      +  193  27
                   nodeText = null;
      +  194  2320
               } else if (current.isCVSSIntegrityImpactNode()) {
      +  195  27
                   vulnerability.setCvssIntegrityImpact(nodeText.toString());
      +  196  27
                   nodeText = null;
      +  197  2293
               } else if (current.isVulnProductNode()) {
      +  198  758
                   final String cpe = nodeText.toString();
      +  199  758
                   if (cpe.startsWith("cpe:/a:")) {
      +  200  645
                       hasApplicationCpe = true;
      +  201  645
                       vulnerability.addVulnerableSoftware(cpe);
       202  
                   }
      -  203  1516
                   nodeText = null;
      -  204  1516
               } else if (reference != null && current.isVulnReferencesNode()) {
      -  205  190
                   vulnerability.addReference(reference);
      -  206  190
                   reference = null;
      -  207  2880
               } else if (reference != null && current.isVulnReferenceNode()) {
      -  208  190
                   reference.setName(nodeText.toString());
      -  209  190
                   nodeText = null;
      -  210  2690
               } else if (reference != null && current.isVulnSourceNode()) {
      -  211  190
                   reference.setSource(nodeText.toString());
      -  212  190
                   nodeText = null;
      -  213  2500
               } else if (current.isVulnSummaryNode()) {
      -  214  56
                   vulnerability.setDescription(nodeText.toString());
      -  215  56
                   if (nodeText.indexOf("** REJECT **") >= 0) {
      -  216  2
                       hasApplicationCpe = true; //ensure we process this to delete the vuln
      +  203  758
                   nodeText = null;
      +  204  758
               } else if (reference != null && current.isVulnReferencesNode()) {
      +  205  95
                   vulnerability.addReference(reference);
      +  206  95
                   reference = null;
      +  207  1440
               } else if (reference != null && current.isVulnReferenceNode()) {
      +  208  95
                   reference.setName(nodeText.toString());
      +  209  95
                   nodeText = null;
      +  210  1345
               } else if (reference != null && current.isVulnSourceNode()) {
      +  211  95
                   reference.setSource(nodeText.toString());
      +  212  95
                   nodeText = null;
      +  213  1250
               } else if (current.isVulnSummaryNode()) {
      +  214  28
                   vulnerability.setDescription(nodeText.toString());
      +  215  28
                   if (nodeText.indexOf("** REJECT **") >= 0) {
      +  216  1
                       hasApplicationCpe = true; //ensure we process this to delete the vuln
       217  
                   }
      -  218  56
                   nodeText = null;
      +  218  28
                   nodeText = null;
       219  
               }
      -  220  5020
           }
      +  220  2510
           }
       221  
           /**
       222   @@ -394,8 +394,8 @@
            */
       244  
           public void setPrevVersionVulnMap(Map<String, List<VulnerableSoftware>> map) {
      -  245  2
               prevVersionVulnMap = map;
      -  246  2
           }
      +  245  1
               prevVersionVulnMap = map;
      +  246  1
           }
       247  
       
       248   @@ -416,19 +416,19 @@
            */
       256  
           private void saveEntry(Vulnerability vuln) throws DatabaseException, CorruptIndexException, IOException {
      -  257  40
               final String cveName = vuln.getName();
      -  258  40
               if (prevVersionVulnMap != null && prevVersionVulnMap.containsKey(cveName)) {
      -  259  2
                   final List<VulnerableSoftware> vulnSoftware = prevVersionVulnMap.get(cveName);
      -  260  2
                   for (VulnerableSoftware vs : vulnSoftware) {
      -  261  2
                       vuln.updateVulnerableSoftware(vs);
      -  262  2
                   }
      +  257  20
               final String cveName = vuln.getName();
      +  258  20
               if (prevVersionVulnMap != null && prevVersionVulnMap.containsKey(cveName)) {
      +  259  1
                   final List<VulnerableSoftware> vulnSoftware = prevVersionVulnMap.get(cveName);
      +  260  1
                   for (VulnerableSoftware vs : vulnSoftware) {
      +  261  1
                       vuln.updateVulnerableSoftware(vs);
      +  262  1
                   }
       263  
               }
      -  264  40
               if (cveDB != null) {
      +  264  20
               if (cveDB != null) {
       265  0
                   cveDB.updateVulnerability(vuln);
       266  
               }
      -  267  40
           }
      +  267  20
           }
       268  
       
       269   @@ -439,7 +439,7 @@
            * A simple class to maintain information about the current element while parsing the NVD CVE XML.
       272  
            */
      -  273  4
           protected static class Element {
      +  273  2
           protected static class Element {
       274  
       
       275   @@ -601,8 +601,8 @@
                */
       354  
               public void setNode(String node) {
      -  355  10040
                   this.node = node;
      -  356  10040
               }
      +  355  5020
                   this.node = node;
      +  356  5020
               }
       357  
       
       358   @@ -617,7 +617,7 @@
                */
       363  
               public boolean isNVDNode() {
      -  364  2822
                   return NVD.equals(node);
      +  364  1411
                   return NVD.equals(node);
       365  
               }
       366   @@ -634,7 +634,7 @@
                */
       372  
               public boolean isEntryNode() {
      -  373  10040
                   return ENTRY.equals(node);
      +  373  5020
                   return ENTRY.equals(node);
       374  
               }
       375   @@ -651,7 +651,7 @@
                */
       381  
               public boolean isVulnProductNode() {
      -  382  9550
                   return VULN_PRODUCT.equals(node);
      +  382  4775
                   return VULN_PRODUCT.equals(node);
       383  
               }
       384   @@ -668,7 +668,7 @@
                */
       390  
               public boolean isVulnReferencesNode() {
      -  391  4018
                   return VULN_REFERENCES.equals(node);
      +  391  2009
                   return VULN_REFERENCES.equals(node);
       392  
               }
       393   @@ -685,7 +685,7 @@
                */
       399  
               public boolean isVulnReferenceNode() {
      -  400  760
                   return VULN_REFERENCE.equals(node);
      +  400  380
                   return VULN_REFERENCE.equals(node);
       401  
               }
       402   @@ -702,7 +702,7 @@
                */
       408  
               public boolean isVulnSourceNode() {
      -  409  380
                   return VULN_SOURCE.equals(node);
      +  409  190
                   return VULN_SOURCE.equals(node);
       410  
               }
       411   @@ -719,7 +719,7 @@
                */
       417  
               public boolean isVulnSummaryNode() {
      -  418  5378
                   return VULN_SUMMARY.equals(node);
      +  418  2689
                   return VULN_SUMMARY.equals(node);
       419  
               }
       420   @@ -736,7 +736,7 @@
                */
       426  
               public boolean isVulnCWENode() {
      -  427  2818
                   return VULN_CWE.equals(node);
      +  427  1409
                   return VULN_CWE.equals(node);
       428  
               }
       429   @@ -753,7 +753,7 @@
                */
       435  
               public boolean isCVSSScoreNode() {
      -  436  7742
                   return CVSS_SCORE.equals(node);
      +  436  3871
                   return CVSS_SCORE.equals(node);
       437  
               }
       438   @@ -770,7 +770,7 @@
                */
       444  
               public boolean isCVSSAccessVectorNode() {
      -  445  7634
                   return CVSS_ACCESS_VECTOR.equals(node);
      +  445  3817
                   return CVSS_ACCESS_VECTOR.equals(node);
       446  
               }
       447   @@ -787,7 +787,7 @@
                */
       453  
               public boolean isCVSSAccessComplexityNode() {
      -  454  7526
                   return CVSS_ACCESS_COMPLEXITY.equals(node);
      +  454  3763
                   return CVSS_ACCESS_COMPLEXITY.equals(node);
       455  
               }
       456   @@ -804,7 +804,7 @@
                */
       462  
               public boolean isCVSSAuthenticationNode() {
      -  463  7418
                   return CVSS_AUTHENTICATION.equals(node);
      +  463  3709
                   return CVSS_AUTHENTICATION.equals(node);
       464  
               }
       465   @@ -821,7 +821,7 @@
                */
       471  
               public boolean isCVSSConfidentialityImpactNode() {
      -  472  7202
                   return CVSS_CONFIDENTIALITY_IMPACT.equals(node);
      +  472  3601
                   return CVSS_CONFIDENTIALITY_IMPACT.equals(node);
       473  
               }
       474   @@ -838,7 +838,7 @@
                */
       480  
               public boolean isCVSSIntegrityImpactNode() {
      -  481  7094
                   return CVSS_INTEGRITY_IMPACT.equals(node);
      +  481  3547
                   return CVSS_INTEGRITY_IMPACT.equals(node);
       482  
               }
       483   @@ -855,7 +855,7 @@
                */
       489  
               public boolean isCVSSAvailabilityImpactNode() {
      -  490  7310
                   return CVSS_AVAILABILITY_IMPACT.equals(node);
      +  490  3655
                   return CVSS_AVAILABILITY_IMPACT.equals(node);
       491  
               }
       492   @@ -866,6 +866,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.NvdCveInfo.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.NvdCveInfo.html index 21d437ce6..8fa8ca593 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.NvdCveInfo.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.NvdCveInfo.html @@ -65,7 +65,7 @@
        * @author Jeremy Long
       24  
        */
      -  25  30
       public class NvdCveInfo {
      +  25  15
       public class NvdCveInfo {
       26  
       
       27   @@ -90,7 +90,7 @@
            */
       37  
           public String getId() {
      -  38  20
               return id;
      +  38  10
               return id;
       39  
           }
       40   @@ -107,8 +107,8 @@
            */
       46  
           public void setId(String id) {
      -  47  22
               this.id = id;
      -  48  22
           }
      +  47  11
               this.id = id;
      +  48  11
           }
       49  
           /**
       50   @@ -131,7 +131,7 @@
            */
       59  
           public String getUrl() {
      -  60  8
               return url;
      +  60  4
               return url;
       61  
           }
       62   @@ -148,8 +148,8 @@
            */
       68  
           public void setUrl(String url) {
      -  69  22
               this.url = url;
      -  70  22
           }
      +  69  11
               this.url = url;
      +  70  11
           }
       71  
           /**
       72   @@ -172,7 +172,7 @@
            */
       81  
           public String getOldSchemaVersionUrl() {
      -  82  8
               return oldSchemaVersionUrl;
      +  82  4
               return oldSchemaVersionUrl;
       83  
           }
       84   @@ -189,8 +189,8 @@
            */
       90  
           public void setOldSchemaVersionUrl(String oldSchemaVersionUrl) {
      -  91  22
               this.oldSchemaVersionUrl = oldSchemaVersionUrl;
      -  92  22
           }
      +  91  11
               this.oldSchemaVersionUrl = oldSchemaVersionUrl;
      +  92  11
           }
       93  
           /**
       94   @@ -213,7 +213,7 @@
            */
       103  
           public long getTimestamp() {
      -  104  2
               return timestamp;
      +  104  1
               return timestamp;
       105  
           }
       106   @@ -230,15 +230,15 @@
            */
       112  
           public void setTimestamp(long timestamp) {
      -  113  20
               this.timestamp = timestamp;
      -  114  20
           }
      +  113  10
               this.timestamp = timestamp;
      +  114  10
           }
       115  
           /**
       116  
            * indicates whether or not this item should be updated.
       117  
            */
      -  118  30
           private boolean needsUpdate = true;
      +  118  15
           private boolean needsUpdate = true;
       119  
       
       120   @@ -253,7 +253,7 @@
            */
       125  
           public boolean getNeedsUpdate() {
      -  126  10
               return needsUpdate;
      +  126  5
               return needsUpdate;
       127  
           }
       128   @@ -270,12 +270,12 @@
            */
       134  
           public void setNeedsUpdate(boolean needsUpdate) {
      -  135  22
               this.needsUpdate = needsUpdate;
      -  136  22
           }
      +  135  11
               this.needsUpdate = needsUpdate;
      +  136  11
           }
       137  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.ProcessTask.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.ProcessTask.html index c688ebc44..d157fbadf 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.ProcessTask.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.ProcessTask.html @@ -336,6 +336,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.UpdateableNvdCve.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.UpdateableNvdCve.html index 799e72511..cb23ec4e4 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.UpdateableNvdCve.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.UpdateableNvdCve.html @@ -12,7 +12,7 @@
       
      - +
      Classes in this File Line Coverage Branch Coverage Complexity
      UpdateableNvdCve
      93%
      28/30
      100%
      4/4
      1.25
      UpdateableNvdCve
      93%
      30/32
      100%
      4/4
      1.25
       
      @@ -72,291 +72,303 @@  27  
       import org.owasp.dependencycheck.utils.Downloader;
       28   -
       
      +
       import org.slf4j.Logger;
       29   -
       /**
      +
       import org.slf4j.LoggerFactory;
       30   -
        * Contains a collection of updateable NvdCveInfo objects. This is used to determine which files need to be downloaded and
      +
       
       31   -
        * processed.
      +
       /**
       32   -
        *
      +
        * Contains a collection of updateable NvdCveInfo objects. This is used to determine which files need to be downloaded and
       33   -
        * @author Jeremy Long
      +
        * processed.
       34   -
        */
      -  35  24
       public class UpdateableNvdCve implements Iterable<NvdCveInfo>, Iterator<NvdCveInfo> {
      +
        *
      +  35   +
        * @author Jeremy Long
       36   -
       
      -  37   -
           /**
      +
        */
      +  37  12
       public class UpdateableNvdCve implements Iterable<NvdCveInfo>, Iterator<NvdCveInfo> {
       38   -
            * A collection of sources of data.
      +
       
       39   -
            */
      -  40  10
           private final Map<String, NvdCveInfo> collection = new TreeMap<String, NvdCveInfo>();
      +
           /**
      +  40   +
            * A reference to the logger.
       41   -
       
      -  42   -
           /**
      +
            */
      +  42  1
           private static final Logger LOGGER = LoggerFactory.getLogger(UpdateableNvdCve.class);
       43   -
            * Returns the collection of NvdCveInfo objects. This method is mainly used for testing.
      +
           /**
       44   -
            *
      +
            * A collection of sources of data.
       45   -
            * @return the collection of NvdCveInfo objects
      -  46  
            */
      +  46  5
           private final Map<String, NvdCveInfo> collection = new TreeMap<String, NvdCveInfo>();
       47   -
           protected Map<String, NvdCveInfo> getCollection() {
      -  48  6
               return collection;
      +
       
      +  48   +
           /**
       49   -
           }
      +
            * Returns the collection of NvdCveInfo objects. This method is mainly used for testing.
       50   -
       
      +
            *
       51   -
           /**
      +
            * @return the collection of NvdCveInfo objects
       52   -
            * Gets whether or not an update is needed.
      +
            */
       53   -
            *
      -  54   -
            * @return true or false depending on whether an update is needed
      +
           protected Map<String, NvdCveInfo> getCollection() {
      +  54  3
               return collection;
       55   -
            */
      -  56   -
           public boolean isUpdateNeeded() {
      -  57  6
               for (NvdCveInfo item : this) {
      -  58  8
                   if (item.getNeedsUpdate()) {
      -  59  2
                       return true;
      -  60   -
                   }
      -  61  6
               }
      -  62  4
               return false;
      -  63  
           }
      -  64   +  56  
       
      -  65   +  57  
           /**
      +  58   +
            * Gets whether or not an update is needed.
      +  59   +
            *
      +  60   +
            * @return true or false depending on whether an update is needed
      +  61   +
            */
      +  62   +
           public boolean isUpdateNeeded() {
      +  63  3
               for (NvdCveInfo item : this) {
      +  64  4
                   if (item.getNeedsUpdate()) {
      +  65  1
                       return true;
       66   -
            * Adds a new entry of updateable information to the contained collection.
      -  67   -
            *
      -  68   -
            * @param id the key for the item to be added
      +
                   }
      +  67  3
               }
      +  68  2
               return false;
       69   -
            * @param url the URL to download the item
      +
           }
       70   -
            * @param oldUrl the URL for the old version of the item (the NVD CVE old schema still contains useful data we need).
      +
       
       71   -
            * @throws MalformedURLException thrown if the URL provided is invalid
      +
           /**
       72   -
            * @throws DownloadFailedException thrown if the download fails.
      -  73   -
            */
      -  74   -
           public void add(String id, String url, String oldUrl) throws MalformedURLException, DownloadFailedException {
      -  75  2
               add(id, url, oldUrl, false);
      -  76  2
           }
      -  77   -
       
      -  78   -
           /**
      -  79  
            * Adds a new entry of updateable information to the contained collection.
      -  80   +  73  
            *
      -  81   +  74  
            * @param id the key for the item to be added
      -  82   +  75  
            * @param url the URL to download the item
      -  83   +  76  
            * @param oldUrl the URL for the old version of the item (the NVD CVE old schema still contains useful data we need).
      -  84   -
            * @param needsUpdate whether or not the data needs to be updated
      -  85   +  77  
            * @throws MalformedURLException thrown if the URL provided is invalid
      -  86   +  78  
            * @throws DownloadFailedException thrown if the download fails.
      -  87   +  79  
            */
      -  88   -
           public void add(String id, String url, String oldUrl, boolean needsUpdate) throws MalformedURLException, DownloadFailedException {
      -  89  18
               final NvdCveInfo item = new NvdCveInfo();
      -  90  18
               item.setNeedsUpdate(needsUpdate); //the others default to true, to make life easier later this should default to false.
      -  91  18
               item.setId(id);
      -  92  18
               item.setUrl(url);
      -  93  18
               item.setOldSchemaVersionUrl(oldUrl);
      -  94  18
               item.setTimestamp(Downloader.getLastModified(new URL(url)));
      -  95  18
               collection.put(id, item);
      -  96  18
           }
      -  97   +  80   +
           public void add(String id, String url, String oldUrl) throws MalformedURLException, DownloadFailedException {
      +  81  1
               add(id, url, oldUrl, false);
      +  82  1
           }
      +  83  
       
      -  98   +  84  
           /**
      -  99   -
            * Clears the contained collection of NvdCveInfo entries.
      -  100   +  85   +
            * Adds a new entry of updateable information to the contained collection.
      +  86   +
            *
      +  87   +
            * @param id the key for the item to be added
      +  88   +
            * @param url the URL to download the item
      +  89   +
            * @param oldUrl the URL for the old version of the item (the NVD CVE old schema still contains useful data we need).
      +  90   +
            * @param needsUpdate whether or not the data needs to be updated
      +  91   +
            * @throws MalformedURLException thrown if the URL provided is invalid
      +  92   +
            * @throws DownloadFailedException thrown if the download fails.
      +  93  
            */
      -  101   -
           public void clear() {
      -  102  2
               collection.clear();
      -  103  2
           }
      +  94   +
           public void add(String id, String url, String oldUrl, boolean needsUpdate) throws MalformedURLException, DownloadFailedException {
      +  95  9
               final NvdCveInfo item = new NvdCveInfo();
      +  96  9
               item.setNeedsUpdate(needsUpdate); //the others default to true, to make life easier later this should default to false.
      +  97  9
               item.setId(id);
      +  98  9
               item.setUrl(url);
      +  99  9
               item.setOldSchemaVersionUrl(oldUrl);
      +  100  9
               LOGGER.debug("Checking for updates from: {}", url);
      +  101  9
               item.setTimestamp(Downloader.getLastModified(new URL(url)));
      +  102  9
               collection.put(id, item);
      +  103  9
           }
       104  
       
       105  
           /**
       106   -
            * Returns the timestamp for the given entry.
      +
            * Clears the contained collection of NvdCveInfo entries.
       107   -
            *
      +
            */
       108   -
            * @param key the key to lookup in the collection of NvdCveInfo items
      -  109   -
            * @return the timestamp for the given entry
      -  110   -
            */
      +
           public void clear() {
      +  109  1
               collection.clear();
      +  110  1
           }
       111   -
           public long getTimeStamp(String key) {
      -  112  0
               return collection.get(key).getTimestamp();
      +
       
      +  112   +
           /**
       113   -
           }
      +
            * Returns the timestamp for the given entry.
       114   -
           /**
      +
            *
       115   -
            * An internal iterator used to implement iterable.
      +
            * @param key the key to lookup in the collection of NvdCveInfo items
       116   +
            * @return the timestamp for the given entry
      +  117  
            */
      -  117  10
           private Iterator<Entry<String, NvdCveInfo>> iterableContent = null;
       118   -
       
      -  119   -
           /**
      +
           public long getTimeStamp(String key) {
      +  119  0
               return collection.get(key).getTimestamp();
       120   -
            * <p>
      +
           }
       121   -
            * Returns an iterator for the NvdCveInfo contained.</p>
      +
           /**
       122   -
            * <p>
      +
            * An internal iterator used to implement iterable.
       123   -
            * <b>This method is not thread safe.</b></p>
      -  124   -
            *
      +
            */
      +  124  5
           private Iterator<Entry<String, NvdCveInfo>> iterableContent = null;
       125   -
            * @return an NvdCveInfo Iterator
      +
       
       126   -
            */
      +
           /**
       127   -
           @Override
      +
            * <p>
       128   -
           public Iterator<NvdCveInfo> iterator() {
      -  129  8
               iterableContent = collection.entrySet().iterator();
      -  130  8
               return this;
      +
            * Returns an iterator for the NvdCveInfo contained.</p>
      +  129   +
            * <p>
      +  130   +
            * <b>This method is not thread safe.</b></p>
       131   -
           }
      +
            *
       132   -
       
      +
            * @return an NvdCveInfo Iterator
       133   -
           /**
      +
            */
       134   -
            * <p>
      +
           @Override
       135   -
            * Returns whether or not there is another item in the collection.</p>
      -  136   -
            * <p>
      -  137   -
            * <b>This method is not thread safe.</b></p>
      +
           public Iterator<NvdCveInfo> iterator() {
      +  136  4
               iterableContent = collection.entrySet().iterator();
      +  137  4
               return this;
       138   -
            *
      +
           }
       139   -
            * @return true or false depending on whether or not another item exists in the collection
      +
       
       140   -
            */
      +
           /**
       141   -
           @Override
      +
            * <p>
       142   -
           public boolean hasNext() {
      -  143  20
               return iterableContent.hasNext();
      +
            * Returns whether or not there is another item in the collection.</p>
      +  143   +
            * <p>
       144   -
           }
      +
            * <b>This method is not thread safe.</b></p>
       145   -
       
      +
            *
       146   -
           /**
      +
            * @return true or false depending on whether or not another item exists in the collection
       147   -
            * <p>
      +
            */
       148   -
            * Returns the next item in the collection.</p>
      +
           @Override
       149   -
            * <p>
      -  150   -
            * <b>This method is not thread safe.</b></p>
      +
           public boolean hasNext() {
      +  150  10
               return iterableContent.hasNext();
       151   -
            *
      +
           }
       152   -
            * @return the next NvdCveInfo item in the collection
      +
       
       153   -
            */
      +
           /**
       154   -
           @Override
      +
            * <p>
       155   -
           public NvdCveInfo next() {
      -  156  14
               return iterableContent.next().getValue();
      +
            * Returns the next item in the collection.</p>
      +  156   +
            * <p>
       157   -
           }
      -  158   -
       
      -  159   -
           /**
      -  160   -
            * <p>
      -  161   -
            * Removes the current NvdCveInfo object from the collection.</p>
      -  162   -
            * <p>
      -  163  
            * <b>This method is not thread safe.</b></p>
      -  164   -
            */
      -  165   -
           @Override
      -  166   -
           public void remove() {
      -  167  2
               iterableContent.remove();
      -  168  2
           }
      -  169   -
       
      -  170   -
           /**
      -  171   -
            * Returns the specified item from the collection.
      -  172   +  158  
            *
      -  173   -
            * @param key the key to lookup the return value
      -  174   -
            * @return the NvdCveInfo object stored using the specified key
      -  175   +  159   +
            * @return the next NvdCveInfo item in the collection
      +  160  
            */
      -  176   -
           public NvdCveInfo get(String key) {
      -  177  4
               return collection.get(key);
      -  178   -
           }
      -  179   -
       
      -  180   +  161  
           @Override
      -  181   -
           public String toString() {
      -  182  0
               return "Updateable{" + "size=" + collection.size() + '}';
      -  183   +  162   +
           public NvdCveInfo next() {
      +  163  7
               return iterableContent.next().getValue();
      +  164  
           }
      -  184   +  165   +
       
      +  166   +
           /**
      +  167   +
            * <p>
      +  168   +
            * Removes the current NvdCveInfo object from the collection.</p>
      +  169   +
            * <p>
      +  170   +
            * <b>This method is not thread safe.</b></p>
      +  171   +
            */
      +  172   +
           @Override
      +  173   +
           public void remove() {
      +  174  1
               iterableContent.remove();
      +  175  1
           }
      +  176   +
       
      +  177   +
           /**
      +  178   +
            * Returns the specified item from the collection.
      +  179   +
            *
      +  180   +
            * @param key the key to lookup the return value
      +  181   +
            * @return the NvdCveInfo object stored using the specified key
      +  182   +
            */
      +  183   +
           public NvdCveInfo get(String key) {
      +  184  2
               return collection.get(key);
      +  185   +
           }
      +  186   +
       
      +  187   +
           @Override
      +  188   +
           public String toString() {
      +  189  0
               return "Updateable{" + "size=" + collection.size() + '}';
      +  190   +
           }
      +  191  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Confidence.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Confidence.html index 865487f3b..81b2530b6 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Confidence.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Confidence.html @@ -65,7 +65,7 @@
        * @author Jeremy Long
       24  
        */
      -  25  24
       public enum Confidence {
      +  25  85
       public enum Confidence {
       26  
       
       27   @@ -74,32 +74,32 @@
            * High confidence evidence.
       29  
            */
      -  30  2
           HIGHEST,
      +  30  1
           HIGHEST,
       31  
           /**
       32  
            * High confidence evidence.
       33  
            */
      -  34  2
           HIGH,
      +  34  1
           HIGH,
       35  
           /**
       36  
            * Medium confidence evidence.
       37  
            */
      -  38  2
           MEDIUM,
      +  38  1
           MEDIUM,
       39  
           /**
       40  
            * Low confidence evidence.
       41  
            */
      -  42  2
           LOW
      +  42  1
           LOW
       43  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Dependency.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Dependency.html index 9de33ead8..0c38f5eea 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Dependency.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Dependency.html @@ -107,7 +107,7 @@
        * @author Jeremy Long
       45  
        */
      -  46  4
       public class Dependency implements Serializable, Comparable<Dependency> {
      +  46  2
       public class Dependency implements Serializable, Comparable<Dependency> {
       47  
       
       48   @@ -124,7 +124,7 @@
            * The logger.
       54  
            */
      -  55  2
           private static final Logger LOGGER = LoggerFactory.getLogger(Dependency.class);
      +  55  1
           private static final Logger LOGGER = LoggerFactory.getLogger(Dependency.class);
       56  
           /**
       57   @@ -206,8 +206,8 @@
            */
       96  
           public void setPackagePath(String packagePath) {
      -  97  8
               this.packagePath = packagePath;
      -  98  8
           }
      +  97  4
               this.packagePath = packagePath;
      +  98  4
           }
       99  
       
       100   @@ -266,15 +266,15 @@
            * Constructs a new Dependency object.
       127  
            */
      -  128  184
           public Dependency() {
      -  129  184
               vendorEvidence = new EvidenceCollection();
      -  130  184
               productEvidence = new EvidenceCollection();
      -  131  184
               versionEvidence = new EvidenceCollection();
      -  132  184
               identifiers = new TreeSet<Identifier>();
      -  133  184
               vulnerabilities = new TreeSet<Vulnerability>(new VulnerabilityComparator());
      -  134  184
               suppressedIdentifiers = new TreeSet<Identifier>();
      -  135  184
               suppressedVulnerabilities = new TreeSet<Vulnerability>(new VulnerabilityComparator());
      -  136  184
           }
      +  128  92
           public Dependency() {
      +  129  92
               vendorEvidence = new EvidenceCollection();
      +  130  92
               productEvidence = new EvidenceCollection();
      +  131  92
               versionEvidence = new EvidenceCollection();
      +  132  92
               identifiers = new TreeSet<Identifier>();
      +  133  92
               vulnerabilities = new TreeSet<Vulnerability>(new VulnerabilityComparator());
      +  134  92
               suppressedIdentifiers = new TreeSet<Identifier>();
      +  135  92
               suppressedVulnerabilities = new TreeSet<Vulnerability>(new VulnerabilityComparator());
      +  136  92
           }
       137  
       
       138   @@ -289,13 +289,13 @@
            */
       143  
           public Dependency(File file) {
      -  144  142
               this();
      -  145  142
               this.actualFilePath = file.getAbsolutePath();
      -  146  142
               this.filePath = this.actualFilePath;
      -  147  142
               this.fileName = file.getName();
      -  148  142
               this.packagePath = filePath;
      -  149  142
               determineHashes(file);
      -  150  142
           }
      +  144  71
               this();
      +  145  71
               this.actualFilePath = file.getAbsolutePath();
      +  146  71
               this.filePath = this.actualFilePath;
      +  147  71
               this.fileName = file.getName();
      +  148  71
               this.packagePath = filePath;
      +  149  71
               determineHashes(file);
      +  150  71
           }
       151  
       
       152   @@ -310,7 +310,7 @@
            */
       157  
           public String getFileName() {
      -  158  98
               return this.fileName;
      +  158  50
               return this.fileName;
       159  
           }
       160   @@ -350,8 +350,8 @@
            */
       178  
           public void setFileName(String fileName) {
      -  179  14
               this.fileName = fileName;
      -  180  14
           }
      +  179  7
               this.fileName = fileName;
      +  180  7
           }
       181  
       
       182   @@ -366,13 +366,13 @@
            */
       187  
           public void setActualFilePath(String actualFilePath) {
      -  188  4
               this.actualFilePath = actualFilePath;
      -  189  4
               if (this.sha1sum == null) {
      +  188  2
               this.actualFilePath = actualFilePath;
      +  189  2
               if (this.sha1sum == null) {
       190  0
                   final File file = new File(this.actualFilePath);
       191  0
                   determineHashes(file);
       192  
               }
      -  193  4
           }
      +  193  2
           }
       194  
       
       195   @@ -387,7 +387,7 @@
            */
       200  
           public String getActualFilePath() {
      -  201  148
               return this.actualFilePath;
      +  201  72
               return this.actualFilePath;
       202  
           }
       203   @@ -404,7 +404,7 @@
            */
       209  
           public File getActualFile() {
      -  210  272
               return new File(this.actualFilePath);
      +  210  134
               return new File(this.actualFilePath);
       211  
           }
       212   @@ -421,12 +421,12 @@
            */
       218  
           public void setFilePath(String filePath) {
      -  219  74
               if (this.packagePath == null || this.packagePath.equals(this.filePath)) {
      -  220  74
                   this.packagePath = filePath;
      +  219  37
               if (this.packagePath == null || this.packagePath.equals(this.filePath)) {
      +  220  37
                   this.packagePath = filePath;
       221  
               }
      -  222  74
               this.filePath = filePath;
      -  223  74
           }
      +  222  37
               this.filePath = filePath;
      +  223  37
           }
       224  
       
       225   @@ -435,7 +435,7 @@
            * The file name to display in reports.
       227  
            */
      -  228  184
           private String displayName = null;
      +  228  92
           private String displayName = null;
       229  
       
       230   @@ -450,8 +450,8 @@
            */
       235  
           public void setDisplayFileName(String displayName) {
      -  236  94
               this.displayName = displayName;
      -  237  94
           }
      +  236  47
               this.displayName = displayName;
      +  237  47
           }
       238  
       
       239   @@ -468,11 +468,11 @@
            */
       245  
           public String getDisplayFileName() {
      -  246  80
               if (displayName == null) {
      -  247  60
                   return this.fileName;
      +  246  40
               if (displayName == null) {
      +  247  30
                   return this.fileName;
       248  
               }
      -  249  20
               return this.displayName;
      +  249  10
               return this.displayName;
       250  
           }
       251   @@ -499,7 +499,7 @@
            */
       262  
           public String getFilePath() {
      -  263  236
               return this.filePath;
      +  263  118
               return this.filePath;
       264  
           }
       265   @@ -516,7 +516,7 @@
            */
       271  
           public String getMd5sum() {
      -  272  4
               return this.md5sum;
      +  272  2
               return this.md5sum;
       273  
           }
       274   @@ -533,8 +533,8 @@
            */
       280  
           public void setMd5sum(String md5sum) {
      -  281  144
               this.md5sum = md5sum;
      -  282  144
           }
      +  281  72
               this.md5sum = md5sum;
      +  282  72
           }
       283  
       
       284   @@ -549,7 +549,7 @@
            */
       289  
           public String getSha1sum() {
      -  290  26
               return this.sha1sum;
      +  290  13
               return this.sha1sum;
       291  
           }
       292   @@ -566,8 +566,8 @@
            */
       298  
           public void setSha1sum(String sha1sum) {
      -  299  220
               this.sha1sum = sha1sum;
      -  300  220
           }
      +  299  110
               this.sha1sum = sha1sum;
      +  300  110
           }
       301  
       
       302   @@ -582,7 +582,7 @@
            */
       307  
           public Set<Identifier> getIdentifiers() {
      -  308  908
               return this.identifiers;
      +  308  460
               return this.identifiers;
       309  
           }
       310   @@ -599,8 +599,8 @@
            */
       316  
           public void setIdentifiers(Set<Identifier> identifiers) {
      -  317  2
               this.identifiers = identifiers;
      -  318  2
           }
      +  317  1
               this.identifiers = identifiers;
      +  318  1
           }
       319  
       
       320   @@ -621,9 +621,9 @@
            */
       328  
           public void addIdentifier(String type, String value, String url) {
      -  329  22
               final Identifier i = new Identifier(type, value, url);
      -  330  22
               this.identifiers.add(i);
      -  331  22
           }
      +  329  11
               final Identifier i = new Identifier(type, value, url);
      +  330  11
               this.identifiers.add(i);
      +  331  11
           }
       332  
       
       333   @@ -646,10 +646,10 @@
            */
       342  
           public void addIdentifier(String type, String value, String url, Confidence confidence) {
      -  343  6
               final Identifier i = new Identifier(type, value, url);
      -  344  6
               i.setConfidence(confidence);
      -  345  6
               this.identifiers.add(i);
      -  346  6
           }
      +  343  3
               final Identifier i = new Identifier(type, value, url);
      +  344  3
               i.setConfidence(confidence);
      +  345  3
               this.identifiers.add(i);
      +  346  3
           }
       347  
       
       348   @@ -668,21 +668,21 @@
            */
       355  
           public void addAsEvidence(String source, MavenArtifact mavenArtifact, Confidence confidence) {
      -  356  4
               if (mavenArtifact.getGroupId() != null && !mavenArtifact.getGroupId().isEmpty()) {
      -  357  2
                   this.getVendorEvidence().addEvidence(source, "groupid", mavenArtifact.getGroupId(), confidence);
      +  356  2
               if (mavenArtifact.getGroupId() != null && !mavenArtifact.getGroupId().isEmpty()) {
      +  357  1
                   this.getVendorEvidence().addEvidence(source, "groupid", mavenArtifact.getGroupId(), confidence);
       358  
               }
      -  359  4
               if (mavenArtifact.getArtifactId() != null && !mavenArtifact.getArtifactId().isEmpty()) {
      -  360  2
                   this.getProductEvidence().addEvidence(source, "artifactid", mavenArtifact.getArtifactId(), confidence);
      +  359  2
               if (mavenArtifact.getArtifactId() != null && !mavenArtifact.getArtifactId().isEmpty()) {
      +  360  1
                   this.getProductEvidence().addEvidence(source, "artifactid", mavenArtifact.getArtifactId(), confidence);
       361  
               }
      -  362  4
               if (mavenArtifact.getVersion() != null && !mavenArtifact.getVersion().isEmpty()) {
      -  363  2
                   this.getVersionEvidence().addEvidence(source, "version", mavenArtifact.getVersion(), confidence);
      +  362  2
               if (mavenArtifact.getVersion() != null && !mavenArtifact.getVersion().isEmpty()) {
      +  363  1
                   this.getVersionEvidence().addEvidence(source, "version", mavenArtifact.getVersion(), confidence);
       364  
               }
      -  365  4
               if (mavenArtifact.getArtifactUrl() != null && !mavenArtifact.getArtifactUrl().isEmpty()) {
      -  366  2
                   boolean found = false;
      -  367  2
                   for (Identifier i : this.getIdentifiers()) {
      +  365  2
               if (mavenArtifact.getArtifactUrl() != null && !mavenArtifact.getArtifactUrl().isEmpty()) {
      +  366  1
                   boolean found = false;
      +  367  1
                   for (Identifier i : this.getIdentifiers()) {
       368  0
                       if ("maven".equals(i.getType()) && i.getValue().equals(mavenArtifact.toString())) {
       369  0
                           found = true;
       370  0
                           i.setConfidence(Confidence.HIGHEST);
      @@ -695,14 +695,14 @@  376  
                       }
       377  0
                   }
      -  378  2
                   if (!found) {
      -  379  2
                       LOGGER.debug("Adding new maven identifier {}", mavenArtifact);
      -  380  2
                       this.addIdentifier("maven", mavenArtifact.toString(), mavenArtifact.getArtifactUrl(), Confidence.HIGHEST);
      +  378  1
                   if (!found) {
      +  379  1
                       LOGGER.debug("Adding new maven identifier {}", mavenArtifact);
      +  380  1
                       this.addIdentifier("maven", mavenArtifact.toString(), mavenArtifact.getArtifactUrl(), Confidence.HIGHEST);
       381  
                   }
       382  
               }
      -  383  4
           }
      +  383  2
           }
       384  
       
       385   @@ -719,8 +719,8 @@
            */
       391  
           public void addIdentifier(Identifier identifier) {
      -  392  6
               this.identifiers.add(identifier);
      -  393  6
           }
      +  392  3
               this.identifiers.add(identifier);
      +  393  3
           }
       394  
       
       395   @@ -745,7 +745,7 @@
            */
       405  
           public Set<Identifier> getSuppressedIdentifiers() {
      -  406  14
               return suppressedIdentifiers;
      +  406  7
               return suppressedIdentifiers;
       407  
           }
       408   @@ -778,8 +778,8 @@
            */
       423  
           public void addSuppressedIdentifier(Identifier identifier) {
      -  424  8
               this.suppressedIdentifiers.add(identifier);
      -  425  8
           }
      +  424  4
               this.suppressedIdentifiers.add(identifier);
      +  425  4
           }
       426  
       
       427   @@ -804,7 +804,7 @@
            */
       437  
           public SortedSet<Vulnerability> getSuppressedVulnerabilities() {
      -  438  6
               return suppressedVulnerabilities;
      +  438  3
               return suppressedVulnerabilities;
       439  
           }
       440   @@ -837,8 +837,8 @@
            */
       455  
           public void addSuppressedVulnerability(Vulnerability vulnerability) {
      -  456  6
               this.suppressedVulnerabilities.add(vulnerability);
      -  457  6
           }
      +  456  3
               this.suppressedVulnerabilities.add(vulnerability);
      +  457  3
           }
       458  
       
       459   @@ -853,7 +853,7 @@
            */
       464  
           public EvidenceCollection getEvidence() {
      -  465  22
               return EvidenceCollection.merge(this.productEvidence, this.vendorEvidence, this.versionEvidence);
      +  465  11
               return EvidenceCollection.merge(this.productEvidence, this.vendorEvidence, this.versionEvidence);
       466  
           }
       467   @@ -887,7 +887,7 @@
            */
       482  
           public EvidenceCollection getEvidenceUsed() {
      -  483  2
               return EvidenceCollection.mergeUsed(this.productEvidence, this.vendorEvidence, this.versionEvidence);
      +  483  1
               return EvidenceCollection.mergeUsed(this.productEvidence, this.vendorEvidence, this.versionEvidence);
       484  
           }
       485   @@ -904,7 +904,7 @@
            */
       491  
           public EvidenceCollection getVendorEvidence() {
      -  492  352
               return this.vendorEvidence;
      +  492  176
               return this.vendorEvidence;
       493  
           }
       494   @@ -921,7 +921,7 @@
            */
       500  
           public EvidenceCollection getProductEvidence() {
      -  501  430
               return this.productEvidence;
      +  501  240
               return this.productEvidence;
       502  
           }
       503   @@ -938,7 +938,7 @@
            */
       509  
           public EvidenceCollection getVersionEvidence() {
      -  510  226
               return this.versionEvidence;
      +  510  111
               return this.versionEvidence;
       511  
           }
       512   @@ -965,7 +965,7 @@
            */
       523  
           public String getDescription() {
      -  524  20
               return description;
      +  524  10
               return description;
       525  
           }
       526   @@ -982,8 +982,8 @@
            */
       532  
           public void setDescription(String description) {
      -  533  40
               this.description = description;
      -  534  40
           }
      +  533  20
               this.description = description;
      +  534  20
           }
       535  
       
       536   @@ -1008,7 +1008,7 @@
            */
       546  
           public String getLicense() {
      -  547  4
               return license;
      +  547  2
               return license;
       548  
           }
       549   @@ -1025,8 +1025,8 @@
            */
       555  
           public void setLicense(String license) {
      -  556  4
               this.license = license;
      -  557  4
           }
      +  556  2
               this.license = license;
      +  557  2
           }
       558  
       
       559   @@ -1051,7 +1051,7 @@
            */
       569  
           public SortedSet<Vulnerability> getVulnerabilities() {
      -  570  28
               return vulnerabilities;
      +  570  14
               return vulnerabilities;
       571  
           }
       572   @@ -1084,22 +1084,22 @@
            */
       587  
           private void determineHashes(File file) {
      -  588  142
               String md5 = null;
      -  589  142
               String sha1 = null;
      +  588  71
               String md5 = null;
      +  589  71
               String sha1 = null;
       590  
               try {
      -  591  142
                   md5 = Checksum.getMD5Checksum(file);
      -  592  140
                   sha1 = Checksum.getSHA1Checksum(file);
      -  593  2
               } catch (IOException ex) {
      -  594  2
                   LOGGER.warn("Unable to read '{}' to determine hashes.", file.getName());
      -  595  2
                   LOGGER.debug("", ex);
      +  591  71
                   md5 = Checksum.getMD5Checksum(file);
      +  592  70
                   sha1 = Checksum.getSHA1Checksum(file);
      +  593  1
               } catch (IOException ex) {
      +  594  1
                   LOGGER.warn("Unable to read '{}' to determine hashes.", file.getName());
      +  595  1
                   LOGGER.debug("", ex);
       596  0
               } catch (NoSuchAlgorithmException ex) {
       597  0
                   LOGGER.warn("Unable to use MD5 of SHA1 checksums.");
       598  0
                   LOGGER.debug("", ex);
      -  599  142
               }
      -  600  142
               this.setMd5sum(md5);
      -  601  142
               this.setSha1sum(sha1);
      -  602  142
           }
      +  599  71
               }
      +  600  71
               this.setMd5sum(md5);
      +  601  71
               this.setSha1sum(sha1);
      +  602  71
           }
       603  
       
       604   @@ -1114,8 +1114,8 @@
            */
       609  
           public void addVulnerability(Vulnerability vulnerability) {
      -  610  6
               this.vulnerabilities.add(vulnerability);
      -  611  6
           }
      +  610  3
               this.vulnerabilities.add(vulnerability);
      +  611  3
           }
       612  
       
       613   @@ -1124,7 +1124,7 @@
            * A collection of related dependencies.
       615  
            */
      -  616  184
           private Set<Dependency> relatedDependencies = new TreeSet<Dependency>();
      +  616  92
           private Set<Dependency> relatedDependencies = new TreeSet<Dependency>();
       617  
       
       618   @@ -1154,7 +1154,7 @@
            * A list of projects that reference this dependency.
       631  
            */
      -  632  184
           private Set<String> projectReferences = new HashSet<String>();
      +  632  92
           private Set<String> projectReferences = new HashSet<String>();
       633  
       
       634   @@ -1279,7 +1279,7 @@
            * A list of available versions.
       703  
            */
      -  704  184
           private List<String> availableVersions = new ArrayList<String>();
      +  704  92
           private List<String> availableVersions = new ArrayList<String>();
       705  
       
       706   @@ -1349,7 +1349,7 @@
           @Override
       741  
           public int compareTo(Dependency o) {
      -  742  4
               return this.getFilePath().compareToIgnoreCase(o.getFilePath());
      +  742  2
               return this.getFilePath().compareToIgnoreCase(o.getFilePath());
       743  
           }
       744   @@ -1413,24 +1413,24 @@
           @Override
       784  
           public int hashCode() {
      -  785  408
               return new HashCodeBuilder(MAGIC_HASH_INIT_VALUE, MAGIC_HASH_MULTIPLIER)
      -  786  204
                       .append(actualFilePath)
      -  787  204
                       .append(filePath)
      -  788  204
                       .append(fileName)
      -  789  204
                       .append(md5sum)
      -  790  204
                       .append(sha1sum)
      -  791  204
                       .append(identifiers)
      -  792  204
                       .append(vendorEvidence)
      -  793  204
                       .append(productEvidence)
      -  794  204
                       .append(versionEvidence)
      -  795  204
                       .append(description)
      -  796  204
                       .append(license)
      -  797  204
                       .append(vulnerabilities)
      +  785  200
               return new HashCodeBuilder(MAGIC_HASH_INIT_VALUE, MAGIC_HASH_MULTIPLIER)
      +  786  100
                       .append(actualFilePath)
      +  787  100
                       .append(filePath)
      +  788  100
                       .append(fileName)
      +  789  100
                       .append(md5sum)
      +  790  100
                       .append(sha1sum)
      +  791  100
                       .append(identifiers)
      +  792  100
                       .append(vendorEvidence)
      +  793  100
                       .append(productEvidence)
      +  794  100
                       .append(versionEvidence)
      +  795  100
                       .append(description)
      +  796  100
                       .append(license)
      +  797  100
                       .append(vulnerabilities)
       798  
                       //.append(relatedDependencies)
      -  799  204
                       .append(projectReferences)
      -  800  204
                       .append(availableVersions)
      -  801  204
                       .toHashCode();
      +  799  100
                       .append(projectReferences)
      +  800  100
                       .append(availableVersions)
      +  801  100
                       .toHashCode();
       802  
           }
       803   @@ -1451,7 +1451,7 @@
           @Override
       811  
           public String toString() {
      -  812  60
               return "Dependency{ fileName='" + fileName + "', actualFilePath='" + actualFilePath
      +  812  30
               return "Dependency{ fileName='" + fileName + "', actualFilePath='" + actualFilePath
       813  
                       + "', filePath='" + filePath + "', packagePath='" + packagePath + "'}";
       814   @@ -1460,6 +1460,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Evidence.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Evidence.html index 8e2ea17e0..90121200d 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Evidence.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Evidence.html @@ -77,7 +77,7 @@
        * @author Jeremy Long
       30  
        */
      -  31  1394
       public class Evidence implements Serializable, Comparable<Evidence> {
      +  31  691
       public class Evidence implements Serializable, Comparable<Evidence> {
       32  
       
       33   @@ -134,12 +134,12 @@
            * @param confidence the confidence of the evidence.
       60  
            */
      -  61  798
           public Evidence(String source, String name, String value, Confidence confidence) {
      -  62  798
               this.source = source;
      -  63  798
               this.name = name;
      -  64  798
               this.value = value;
      -  65  798
               this.confidence = confidence;
      -  66  798
           }
      +  61  428
           public Evidence(String source, String name, String value, Confidence confidence) {
      +  62  428
               this.source = source;
      +  63  428
               this.name = name;
      +  64  428
               this.value = value;
      +  65  428
               this.confidence = confidence;
      +  66  428
           }
       67  
       
       68   @@ -164,7 +164,7 @@
            */
       78  
           public String getName() {
      -  79  74
               return name;
      +  79  27
               return name;
       80  
           }
       81   @@ -207,7 +207,7 @@
            */
       101  
           public String getSource() {
      -  102  60
               return source;
      +  102  16
               return source;
       103  
           }
       104   @@ -250,8 +250,8 @@
            */
       124  
           public String getValue() {
      -  125  936
               used = true;
      -  126  936
               return value;
      +  125  446
               used = true;
      +  126  446
               return value;
       127  
           }
       128   @@ -270,8 +270,8 @@
            */
       135  
           public String getValue(Boolean setUsed) {
      -  136  100
               used = used || setUsed;
      -  137  100
               return value;
      +  136  50
               used = used || setUsed;
      +  137  50
               return value;
       138  
           }
       139   @@ -314,7 +314,7 @@
            */
       159  
           public boolean isUsed() {
      -  160  1248
               return used;
      +  160  651
               return used;
       161  
           }
       162   @@ -357,7 +357,7 @@
            */
       182  
           public Confidence getConfidence() {
      -  183  512
               return confidence;
      +  183  240
               return confidence;
       184  
           }
       185   @@ -392,12 +392,12 @@
           @Override
       201  
           public int hashCode() {
      -  202  32
               return new HashCodeBuilder(MAGIC_HASH_INIT_VALUE, MAGIC_HASH_MULTIPLIER)
      -  203  16
                   .append(StringUtils.lowerCase(name))
      -  204  16
                   .append(StringUtils.lowerCase(source))
      -  205  16
                   .append(StringUtils.lowerCase(value))
      -  206  16
                   .append(confidence)
      -  207  16
                   .toHashCode();
      +  202  16
               return new HashCodeBuilder(MAGIC_HASH_INIT_VALUE, MAGIC_HASH_MULTIPLIER)
      +  203  8
                   .append(StringUtils.lowerCase(name))
      +  204  8
                   .append(StringUtils.lowerCase(source))
      +  205  8
                   .append(StringUtils.lowerCase(value))
      +  206  8
                   .append(confidence)
      +  207  8
                   .toHashCode();
       208  
           }
       209   @@ -418,21 +418,21 @@
           @Override
       217  
           public boolean equals(Object that) {
      -  218  20
               if (this == that) {
      +  218  10
               if (this == that) {
       219  0
                   return true;
       220  
               }
      -  221  20
               if (!(that instanceof Evidence)) {
      +  221  10
               if (!(that instanceof Evidence)) {
       222  0
                   return false;
       223  
               }
      -  224  20
               final Evidence e = (Evidence) that;
      +  224  10
               final Evidence e = (Evidence) that;
       225  
       
      -  226  40
               return StringUtils.equalsIgnoreCase(name, e.name)
      -  227  4
                       && StringUtils.equalsIgnoreCase(source, e.source)
      -  228  4
                       && StringUtils.equalsIgnoreCase(value, e.value)
      -  229  4
                       && ObjectUtils.equals(confidence, e.confidence);
      +  226  20
               return StringUtils.equalsIgnoreCase(name, e.name)
      +  227  2
                       && StringUtils.equalsIgnoreCase(source, e.source)
      +  228  2
                       && StringUtils.equalsIgnoreCase(value, e.value)
      +  229  2
                       && ObjectUtils.equals(confidence, e.confidence);
       230  
           }
       231   @@ -453,33 +453,33 @@
           @Override
       239  
           public int compareTo(Evidence o) {
      -  240  1414
               if (o == null) {
      +  240  701
               if (o == null) {
       241  0
                   return 1;
       242  
               }
      -  243  1414
               if (StringUtils.equalsIgnoreCase(source, o.source)) {
      -  244  912
                   if (StringUtils.equalsIgnoreCase(name, o.name)) {
      -  245  500
                       if (StringUtils.equalsIgnoreCase(value, o.value)) {
      -  246  444
                           if (ObjectUtils.equals(confidence, o.confidence)) {
      -  247  440
                               return 0; //they are equal
      +  243  701
               if (StringUtils.equalsIgnoreCase(source, o.source)) {
      +  244  450
                   if (StringUtils.equalsIgnoreCase(name, o.name)) {
      +  245  244
                       if (StringUtils.equalsIgnoreCase(value, o.value)) {
      +  246  219
                           if (ObjectUtils.equals(confidence, o.confidence)) {
      +  247  217
                               return 0; //they are equal
       248  
                           } else {
      -  249  4
                               return ObjectUtils.compare(confidence, o.confidence);
      +  249  2
                               return ObjectUtils.compare(confidence, o.confidence);
       250  
                           }
       251  
                       } else {
      -  252  56
                           return compareToIgnoreCaseWithNullCheck(value, o.value);
      +  252  25
                           return compareToIgnoreCaseWithNullCheck(value, o.value);
       253  
                       }
       254  
                   } else {
      -  255  412
                       return compareToIgnoreCaseWithNullCheck(name, o.name);
      +  255  206
                       return compareToIgnoreCaseWithNullCheck(name, o.name);
       256  
                   }
       257  
               } else {
      -  258  502
                   return compareToIgnoreCaseWithNullCheck(source, o.source);
      +  258  251
                   return compareToIgnoreCaseWithNullCheck(source, o.source);
       259  
               }
       260   @@ -504,15 +504,15 @@
            */
       270  
           private int compareToIgnoreCaseWithNullCheck(String me, String other) {
      -  271  970
               if (me == null && other == null) {
      +  271  482
               if (me == null && other == null) {
       272  0
                   return 0;
      -  273  970
               } else if (me == null) {
      +  273  482
               } else if (me == null) {
       274  0
                   return -1; //the other string is greater then me
      -  275  970
               } else if (other == null) {
      +  275  482
               } else if (other == null) {
       276  0
                   return 1; //me is greater then the other string
       277  
               }
      -  278  970
               return me.compareToIgnoreCase(other);
      +  278  482
               return me.compareToIgnoreCase(other);
       279  
           }
       280   @@ -538,6 +538,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.EvidenceCollection.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.EvidenceCollection.html index 48ed478bd..9abbcb33c 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.EvidenceCollection.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.EvidenceCollection.html @@ -118,19 +118,19 @@
            * The logger.
       48  
            */
      -  49  2
           private static final Logger LOGGER = LoggerFactory.getLogger(EvidenceCollection.class);
      +  49  1
           private static final Logger LOGGER = LoggerFactory.getLogger(EvidenceCollection.class);
       50  
           /**
       51  
            * Used to iterate over highest confidence evidence contained in the collection.
       52  
            */
      -  53  44
           private static final Filter<Evidence> HIGHEST_CONFIDENCE = new Filter<Evidence>() {
      +  53  22
           private static final Filter<Evidence> HIGHEST_CONFIDENCE = new Filter<Evidence>() {
       54  
               @Override
       55  
               public boolean passes(Evidence evidence) {
      -  56  42
                   return evidence.getConfidence() == Confidence.HIGHEST;
      +  56  21
                   return evidence.getConfidence() == Confidence.HIGHEST;
       57  
               }
       58   @@ -141,12 +141,12 @@
            * Used to iterate over high confidence evidence contained in the collection.
       61  
            */
      -  62  124
           private static final Filter<Evidence> HIGH_CONFIDENCE = new Filter<Evidence>() {
      +  62  61
           private static final Filter<Evidence> HIGH_CONFIDENCE = new Filter<Evidence>() {
       63  
               @Override
       64  
               public boolean passes(Evidence evidence) {
      -  65  122
                   return evidence.getConfidence() == Confidence.HIGH;
      +  65  60
                   return evidence.getConfidence() == Confidence.HIGH;
       66  
               }
       67   @@ -157,12 +157,12 @@
            * Used to iterate over medium confidence evidence contained in the collection.
       70  
            */
      -  71  74
           private static final Filter<Evidence> MEDIUM_CONFIDENCE = new Filter<Evidence>() {
      +  71  37
           private static final Filter<Evidence> MEDIUM_CONFIDENCE = new Filter<Evidence>() {
       72  
               @Override
       73  
               public boolean passes(Evidence evidence) {
      -  74  72
                   return evidence.getConfidence() == Confidence.MEDIUM;
      +  74  36
                   return evidence.getConfidence() == Confidence.MEDIUM;
       75  
               }
       76   @@ -173,12 +173,12 @@
            * Used to iterate over low confidence evidence contained in the collection.
       79  
            */
      -  80  80
           private static final Filter<Evidence> LOW_CONFIDENCE = new Filter<Evidence>() {
      +  80  40
           private static final Filter<Evidence> LOW_CONFIDENCE = new Filter<Evidence>() {
       81  
               @Override
       82  
               public boolean passes(Evidence evidence) {
      -  83  78
                   return evidence.getConfidence() == Confidence.LOW;
      +  83  39
                   return evidence.getConfidence() == Confidence.LOW;
       84  
               }
       85   @@ -189,12 +189,12 @@
            * Used to iterate over evidence that has was used (aka read) from the collection.
       88  
            */
      -  89  1246
           private static final Filter<Evidence> EVIDENCE_USED = new Filter<Evidence>() {
      +  89  650
           private static final Filter<Evidence> EVIDENCE_USED = new Filter<Evidence>() {
       90  
               @Override
       91  
               public boolean passes(Evidence evidence) {
      -  92  1244
                   return evidence.isUsed();
      +  92  649
                   return evidence.isUsed();
       93  
               }
       94   @@ -215,15 +215,15 @@
            */
       102  
           public final Iterable<Evidence> iterator(Confidence confidence) {
      -  103  60
               if (confidence == Confidence.HIGHEST) {
      -  104  10
                   return EvidenceCollection.HIGHEST_CONFIDENCE.filter(this.list);
      -  105  50
               } else if (confidence == Confidence.HIGH) {
      -  106  24
                   return EvidenceCollection.HIGH_CONFIDENCE.filter(this.list);
      -  107  26
               } else if (confidence == Confidence.MEDIUM) {
      -  108  12
                   return EvidenceCollection.MEDIUM_CONFIDENCE.filter(this.list);
      +  103  30
               if (confidence == Confidence.HIGHEST) {
      +  104  5
                   return EvidenceCollection.HIGHEST_CONFIDENCE.filter(this.list);
      +  105  25
               } else if (confidence == Confidence.HIGH) {
      +  106  12
                   return EvidenceCollection.HIGH_CONFIDENCE.filter(this.list);
      +  107  13
               } else if (confidence == Confidence.MEDIUM) {
      +  108  6
                   return EvidenceCollection.MEDIUM_CONFIDENCE.filter(this.list);
       109  
               } else {
      -  110  14
                   return EvidenceCollection.LOW_CONFIDENCE.filter(this.list);
      +  110  7
                   return EvidenceCollection.LOW_CONFIDENCE.filter(this.list);
       111  
               }
       112   @@ -252,10 +252,10 @@
            * Creates a new EvidenceCollection.
       124  
            */
      -  125  576
           public EvidenceCollection() {
      -  126  576
               list = new TreeSet<Evidence>();
      -  127  576
               weightedStrings = new HashSet<String>();
      -  128  576
           }
      +  125  288
           public EvidenceCollection() {
      +  126  288
               list = new TreeSet<Evidence>();
      +  127  288
               weightedStrings = new HashSet<String>();
      +  128  288
           }
       129  
       
       130   @@ -270,8 +270,8 @@
            */
       135  
           public void addEvidence(Evidence e) {
      -  136  666
               list.add(e);
      -  137  666
           }
      +  136  330
               list.add(e);
      +  137  330
           }
       138  
       
       139   @@ -292,9 +292,9 @@
            */
       147  
           public void addEvidence(String source, String name, String value, Confidence confidence) {
      -  148  652
               final Evidence e = new Evidence(source, name, value, confidence);
      -  149  652
               addEvidence(e);
      -  150  652
           }
      +  148  319
               final Evidence e = new Evidence(source, name, value, confidence);
      +  149  319
               addEvidence(e);
      +  150  319
           }
       151  
       
       152   @@ -321,8 +321,8 @@
            */
       163  
           public void addWeighting(String str) {
      -  164  30
               weightedStrings.add(str);
      -  165  30
           }
      +  164  15
               weightedStrings.add(str);
      +  165  15
           }
       166  
       
       167   @@ -339,7 +339,7 @@
            */
       173  
           public Set<String> getWeighting() {
      -  174  46
               return weightedStrings;
      +  174  23
               return weightedStrings;
       175  
           }
       176   @@ -356,7 +356,7 @@
            */
       182  
           public Set<Evidence> getEvidence() {
      -  183  38
               return list;
      +  183  44
               return list;
       184  
           }
       185   @@ -375,18 +375,18 @@
            */
       192  
           public Set<Evidence> getEvidence(String source) {
      -  193  2
               if (source == null) {
      +  193  1
               if (source == null) {
       194  0
                   return null;
       195  
               }
      -  196  2
               final Set<Evidence> ret = new HashSet<Evidence>();
      -  197  2
               for (Evidence e : list) {
      -  198  10
                   if (source.equals(e.getSource())) {
      -  199  2
                       ret.add(e);
      +  196  1
               final Set<Evidence> ret = new HashSet<Evidence>();
      +  197  1
               for (Evidence e : list) {
      +  198  5
                   if (source.equals(e.getSource())) {
      +  199  1
                       ret.add(e);
       200  
                   }
      -  201  10
               }
      -  202  2
               return ret;
      +  201  5
               }
      +  202  1
               return ret;
       203  
           }
       204   @@ -407,18 +407,18 @@
            */
       212  
           public Set<Evidence> getEvidence(String source, String name) {
      -  213  16
               if (source == null || name == null) {
      +  213  8
               if (source == null || name == null) {
       214  0
                   return null;
       215  
               }
      -  216  16
               final Set<Evidence> ret = new HashSet<Evidence>();
      -  217  16
               for (Evidence e : list) {
      -  218  22
                   if (source.equals(e.getSource()) && name.equals(e.getName())) {
      -  219  10
                       ret.add(e);
      +  216  8
               final Set<Evidence> ret = new HashSet<Evidence>();
      +  217  8
               for (Evidence e : list) {
      +  218  11
                   if (source.equals(e.getSource()) && name.equals(e.getName())) {
      +  219  5
                       ret.add(e);
       220  
                   }
      -  221  22
               }
      -  222  16
               return ret;
      +  221  11
               }
      +  222  8
               return ret;
       223  
           }
       224   @@ -437,7 +437,7 @@
           @Override
       231  
           public Iterator<Evidence> iterator() {
      -  232  214
               return list.iterator();
      +  232  105
               return list.iterator();
       233  
           }
       234   @@ -456,23 +456,23 @@
            */
       241  
           public boolean containsUsedString(String text) {
      -  242  184
               if (text == null) {
      +  242  90
               if (text == null) {
       243  0
                   return false;
       244  
               }
      -  245  184
               final String textToTest = text.toLowerCase();
      +  245  90
               final String textToTest = text.toLowerCase();
       246  
       
      -  247  184
               for (Evidence e : EvidenceCollection.EVIDENCE_USED.filter(this)) {
      +  247  90
               for (Evidence e : EvidenceCollection.EVIDENCE_USED.filter(this)) {
       248  
                   //TODO consider changing the regex to only compare alpha-numeric (i.e. strip everything else)
      -  249  612
                   final String value = urlCorrection(e.getValue().toLowerCase()).replaceAll("[\\s_-]", "");
      -  250  612
                   if (value.contains(textToTest)) {
      -  251  48
                       return true;
      +  249  299
                   final String value = urlCorrection(e.getValue().toLowerCase()).replaceAll("[\\s_-]", "");
      +  250  299
                   if (value.contains(textToTest)) {
      +  251  27
                       return true;
       252  
                   }
      -  253  564
               }
      -  254  136
               return false;
      +  253  272
               }
      +  254  63
               return false;
       255  
           }
       256   @@ -523,13 +523,13 @@
            */
       283  
           public boolean contains(Confidence confidence) {
      -  284  60
               for (Evidence e : list) {
      -  285  170
                   if (e.getConfidence().equals(confidence)) {
      -  286  36
                       return true;
      +  284  30
               for (Evidence e : list) {
      +  285  84
                   if (e.getConfidence().equals(confidence)) {
      +  286  18
                       return true;
       287  
                   }
      -  288  134
               }
      -  289  24
               return false;
      +  288  66
               }
      +  289  12
               return false;
       290  
           }
       291   @@ -548,17 +548,17 @@
            */
       298  
           public static EvidenceCollection mergeUsed(EvidenceCollection... ec) {
      -  299  2
               final EvidenceCollection ret = new EvidenceCollection();
      -  300  8
               for (EvidenceCollection col : ec) {
      -  301  6
                   for (Evidence e : col.list) {
      -  302  4
                       if (e.isUsed()) {
      -  303  2
                           ret.addEvidence(e);
      +  299  1
               final EvidenceCollection ret = new EvidenceCollection();
      +  300  4
               for (EvidenceCollection col : ec) {
      +  301  3
                   for (Evidence e : col.list) {
      +  302  2
                       if (e.isUsed()) {
      +  303  1
                           ret.addEvidence(e);
       304  
                       }
      -  305  4
                   }
      +  305  2
                   }
       306  
               }
      -  307  2
               return ret;
      +  307  1
               return ret;
       308  
           }
       309   @@ -577,13 +577,13 @@
            */
       316  
           public static EvidenceCollection merge(EvidenceCollection... ec) {
      -  317  22
               final EvidenceCollection ret = new EvidenceCollection();
      -  318  88
               for (EvidenceCollection col : ec) {
      -  319  66
                   ret.list.addAll(col.list);
      -  320  66
                   ret.weightedStrings.addAll(col.weightedStrings);
      +  317  11
               final EvidenceCollection ret = new EvidenceCollection();
      +  318  44
               for (EvidenceCollection col : ec) {
      +  319  33
                   ret.list.addAll(col.list);
      +  320  33
                   ret.weightedStrings.addAll(col.weightedStrings);
       321  
               }
      -  322  22
               return ret;
      +  322  11
               return ret;
       323  
           }
       324   @@ -634,11 +634,11 @@
           @Override
       351  
           public String toString() {
      -  352  86
               final StringBuilder sb = new StringBuilder();
      -  353  86
               for (Evidence e : this.list) {
      -  354  170
                   sb.append(e.getValue()).append(' ');
      -  355  170
               }
      -  356  86
               return sb.toString();
      +  352  43
               final StringBuilder sb = new StringBuilder();
      +  353  43
               for (Evidence e : this.list) {
      +  354  85
                   sb.append(e.getValue()).append(' ');
      +  355  85
               }
      +  356  43
               return sb.toString();
       357  
           }
       358   @@ -655,7 +655,7 @@
            */
       364  
           public int size() {
      -  365  38
               return list.size();
      +  365  19
               return list.size();
       366  
           }
       367   @@ -698,22 +698,22 @@
            */
       386  
           private String urlCorrection(String value) {
      -  387  612
               if (value == null || !UrlStringUtils.containsUrl(value)) {
      -  388  574
                   return value;
      +  387  299
               if (value == null || !UrlStringUtils.containsUrl(value)) {
      +  388  280
                   return value;
       389  
               }
      -  390  38
               final StringBuilder sb = new StringBuilder(value.length());
      -  391  38
               final String[] parts = value.split("\\s");
      -  392  76
               for (String part : parts) {
      -  393  38
                   if (UrlStringUtils.isUrl(part)) {
      +  390  19
               final StringBuilder sb = new StringBuilder(value.length());
      +  391  19
               final String[] parts = value.split("\\s");
      +  392  38
               for (String part : parts) {
      +  393  19
                   if (UrlStringUtils.isUrl(part)) {
       394  
                       try {
      -  395  38
                           final List<String> data = UrlStringUtils.extractImportantUrlData(part);
      -  396  38
                           sb.append(' ').append(StringUtils.join(data, ' '));
      +  395  19
                           final List<String> data = UrlStringUtils.extractImportantUrlData(part);
      +  396  19
                           sb.append(' ').append(StringUtils.join(data, ' '));
       397  0
                       } catch (MalformedURLException ex) {
       398  0
                           LOGGER.debug("error parsing {}", part, ex);
       399  0
                           sb.append(' ').append(part);
      -  400  38
                       }
      +  400  19
                       }
       401  
                   } else {
       402  0
                       sb.append(' ').append(part);
      @@ -721,13 +721,13 @@
                   }
       404  
               }
      -  405  38
               return sb.toString().trim();
      +  405  19
               return sb.toString().trim();
       406  
           }
       407  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Identifier.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Identifier.html index 13bfca30d..2325941c7 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Identifier.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Identifier.html @@ -67,7 +67,7 @@
        * @author Jeremy Long
       25  
        */
      -  26  62
       public class Identifier implements Serializable, Comparable<Identifier> {
      +  26  31
       public class Identifier implements Serializable, Comparable<Identifier> {
       27  
       
       28   @@ -110,11 +110,11 @@
            * @param url the identifier url.
       48  
            */
      -  49  56
           public Identifier(String type, String value, String url) {
      -  50  56
               this.type = type;
      -  51  56
               this.value = value;
      -  52  56
               this.url = url;
      -  53  56
           }
      +  49  28
           public Identifier(String type, String value, String url) {
      +  50  28
               this.type = type;
      +  51  28
               this.value = value;
      +  52  28
               this.url = url;
      +  53  28
           }
       54  
       
       55   @@ -179,8 +179,8 @@
            */
       87  
           public void setConfidence(Confidence confidence) {
      -  88  12
               this.confidence = confidence;
      -  89  12
           }
      +  88  6
               this.confidence = confidence;
      +  89  6
           }
       90  
       
       91   @@ -205,7 +205,7 @@
            */
       101  
           public String getValue() {
      -  102  432
               return value;
      +  102  216
               return value;
       103  
           }
       104   @@ -287,7 +287,7 @@
            */
       145  
           public String getType() {
      -  146  744
               return type;
      +  146  378
               return type;
       147  
           }
       148   @@ -383,10 +383,10 @@
           @Override
       201  
           public int hashCode() {
      -  202  36
               int hash = 5;
      -  203  36
               hash = 53 * hash + (this.value != null ? this.value.hashCode() : 0);
      -  204  36
               hash = 53 * hash + (this.type != null ? this.type.hashCode() : 0);
      -  205  36
               return hash;
      +  202  18
               int hash = 5;
      +  203  18
               hash = 53 * hash + (this.value != null ? this.value.hashCode() : 0);
      +  204  18
               hash = 53 * hash + (this.type != null ? this.type.hashCode() : 0);
      +  205  18
               return hash;
       206  
           }
       207   @@ -426,17 +426,17 @@
           @Override
       225  
           public int compareTo(Identifier o) {
      -  226  66
               if (o == null) {
      +  226  33
               if (o == null) {
       227  0
                   return -1;
       228  
               }
      -  229  66
               return this.value.compareTo(o.value);
      +  229  33
               return this.value.compareTo(o.value);
       230  
           }
       231  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Reference.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Reference.html index 230e5e836..4684783ed 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Reference.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Reference.html @@ -71,7 +71,7 @@
        * @author Jeremy Long
       27  
        */
      -  28  1052
       public class Reference implements Serializable, Comparable<Reference> {
      +  28  526
       public class Reference implements Serializable, Comparable<Reference> {
       29  
       
       30   @@ -121,8 +121,8 @@
            */
       53  
           public void setName(String name) {
      -  54  326
               this.name = name;
      -  55  326
           }
      +  54  163
               this.name = name;
      +  55  163
           }
       56  
           /**
       57   @@ -162,8 +162,8 @@
            */
       75  
           public void setUrl(String url) {
      -  76  326
               this.url = url;
      -  77  326
           }
      +  76  163
               this.url = url;
      +  77  163
           }
       78  
           /**
       79   @@ -203,8 +203,8 @@
            */
       97  
           public void setSource(String source) {
      -  98  326
               this.source = source;
      -  99  326
           }
      +  98  163
               this.source = source;
      +  99  163
           }
       100  
       
       101   @@ -275,10 +275,10 @@
           @Override
       143  
           public int compareTo(Reference o) {
      -  144  726
               if (source.equals(o.source)) {
      -  145  210
                   if (name.equals(o.name)) {
      -  146  70
                       if (url.equals(o.url)) {
      -  147  70
                           return 0; //they are equal
      +  144  363
               if (source.equals(o.source)) {
      +  145  105
                   if (name.equals(o.name)) {
      +  146  35
                       if (url.equals(o.url)) {
      +  147  35
                           return 0; //they are equal
       148  
                       } else {
       149  0
                           return url.compareTo(o.url);
      @@ -286,12 +286,12 @@
                       }
       151  
                   } else {
      -  152  140
                       return name.compareTo(o.name);
      +  152  70
                       return name.compareTo(o.name);
       153  
                   }
       154  
               } else {
      -  155  516
                   return source.compareTo(o.source);
      +  155  258
                   return source.compareTo(o.source);
       156  
               }
       157   @@ -300,6 +300,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Vulnerability.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Vulnerability.html index 911a6bfdc..58c3ee7d7 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Vulnerability.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Vulnerability.html @@ -12,7 +12,7 @@
       
      - +
      Classes in this File Line Coverage Branch Coverage Complexity
      Vulnerability
      57%
      50/87
      22%
      5/22
      1.324
      Vulnerability
      56%
      50/89
      22%
      5/22
      1.324
       
      @@ -64,804 +64,800 @@  23  
       import java.util.TreeSet;
       24   -
       import java.util.Iterator;
      +
       
       25   -
       
      -  26  
       /**
      -  27   +  26  
        * Contains the information about a vulnerability.
      -  28   +  27  
        *
      -  29   +  28  
        * @author Jeremy Long
      -  30   +  29  
        */
      -  31  80
       public class Vulnerability implements Serializable, Comparable<Vulnerability> {
      +  30  40
       public class Vulnerability implements Serializable, Comparable<Vulnerability> {
      +  31   +
       
       32   -
       
      +
           /**
       33   -
           /**
      -  34  
            * The serial version uid.
      +  34   +
            */
       35   -
            */
      -  36  
           private static final long serialVersionUID = 307319490326651052L;
      +  36   +
       
       37   -
       
      +
           /**
       38   -
           /**
      -  39  
            * The name of the vulnerability.
      +  39   +
            */
       40   -
            */
      -  41  
           private String name;
      +  41   +
       
       42   -
       
      +
           /**
       43   -
           /**
      -  44  
            * Get the value of name.
      +  44   +
            *
       45   -
            *
      -  46  
            * @return the value of name
      +  46   +
            */
       47   -
            */
      -  48  
           public String getName() {
      -  49  146
               return name;
      +  48  73
               return name;
      +  49   +
           }
       50   -
           }
      +
       
       51   -
       
      +
           /**
       52   -
           /**
      -  53  
            * Set the value of name.
      +  53   +
            *
       54   -
            *
      -  55  
            * @param name new value of name
      +  55   +
            */
       56   -
            */
      -  57  
           public void setName(String name) {
      -  58  74
               this.name = name;
      -  59  74
           }
      +  57  37
               this.name = name;
      +  58  37
           }
      +  59   +
           /**
       60   -
           /**
      -  61  
            * the description of the vulnerability.
      +  61   +
            */
       62   -
            */
      -  63  
           private String description;
      +  63   +
       
       64   -
       
      +
           /**
       65   -
           /**
      -  66  
            * Get the value of description.
      +  66   +
            *
       67   -
            *
      -  68  
            * @return the value of description
      +  68   +
            */
       69   -
            */
      -  70  
           public String getDescription() {
      -  71  0
               return description;
      +  70  0
               return description;
      +  71   +
           }
       72   -
           }
      +
       
       73   -
       
      +
           /**
       74   -
           /**
      -  75  
            * Set the value of description.
      +  75   +
            *
       76   -
            *
      -  77  
            * @param description new value of description
      +  77   +
            */
       78   -
            */
      -  79  
           public void setDescription(String description) {
      -  80  72
               this.description = description;
      -  81  72
           }
      +  79  36
               this.description = description;
      +  80  36
           }
      +  81   +
           /**
       82   -
           /**
      -  83  
            * References for this vulnerability.
      -  84   +  83  
            */
      -  85  80
           private SortedSet<Reference> references = new TreeSet<Reference>();
      +  84  40
           private SortedSet<Reference> references = new TreeSet<Reference>();
      +  85   +
       
       86   -
       
      +
           /**
       87   -
           /**
      -  88  
            * Get the value of references.
      +  88   +
            *
       89   -
            *
      -  90  
            * @return the value of references
      +  90   +
            */
       91   -
            */
      -  92  
           public Set<Reference> getReferences() {
      -  93  0
               return references;
      +  92  0
               return references;
      +  93   +
           }
       94   -
           }
      +
       
       95   -
       
      +
           /**
       96   -
           /**
      -  97  
            * Set the value of references.
      +  97   +
            *
       98   -
            *
      -  99  
            * @param references new value of references
      +  99   +
            */
       100   -
            */
      -  101  
           public void setReferences(SortedSet<Reference> references) {
      -  102  0
               this.references = references;
      -  103  0
           }
      +  101  0
               this.references = references;
      +  102  0
           }
      +  103   +
       
       104   -
       
      +
           /**
       105   -
           /**
      -  106  
            * Adds a reference to the references collection.
      +  106   +
            *
       107   -
            *
      -  108  
            * @param ref a reference for the vulnerability
      +  108   +
            */
       109   -
            */
      -  110  
           public void addReference(Reference ref) {
      -  111  190
               this.references.add(ref);
      -  112  190
           }
      +  110  95
               this.references.add(ref);
      +  111  95
           }
      +  112   +
       
       113   -
       
      +
           /**
       114   -
           /**
      -  115  
            * Adds a reference.
      +  115   +
            *
       116   -
            *
      -  117  
            * @param referenceSource the source of the reference
      -  118   +  117  
            * @param referenceName the referenceName of the reference
      -  119   +  118  
            * @param referenceUrl the url of the reference
      +  119   +
            */
       120   -
            */
      -  121  
           public void addReference(String referenceSource, String referenceName, String referenceUrl) {
      -  122  136
               final Reference ref = new Reference();
      -  123  136
               ref.setSource(referenceSource);
      -  124  136
               ref.setName(referenceName);
      -  125  136
               ref.setUrl(referenceUrl);
      -  126  136
               this.references.add(ref);
      -  127  136
           }
      +  121  68
               final Reference ref = new Reference();
      +  122  68
               ref.setSource(referenceSource);
      +  123  68
               ref.setName(referenceName);
      +  124  68
               ref.setUrl(referenceUrl);
      +  125  68
               this.references.add(ref);
      +  126  68
           }
      +  127   +
           /**
       128   -
           /**
      -  129  
            * A set of vulnerable software.
      -  130   +  129  
            */
      -  131  80
           private SortedSet<VulnerableSoftware> vulnerableSoftware = new TreeSet<VulnerableSoftware>();
      +  130  40
           private SortedSet<VulnerableSoftware> vulnerableSoftware = new TreeSet<VulnerableSoftware>();
      +  131   +
       
       132   -
       
      +
           /**
       133   -
           /**
      -  134  
            * Get the value of vulnerableSoftware.
      +  134   +
            *
       135   -
            *
      -  136  
            * @return the value of vulnerableSoftware
      +  136   +
            */
       137   -
            */
      -  138  
           public Set<VulnerableSoftware> getVulnerableSoftware() {
      -  139  6
               return vulnerableSoftware;
      +  138  3
               return vulnerableSoftware;
      +  139   +
           }
       140   -
           }
      +
       
       141   -
       
      +
           /**
       142   -
           /**
      -  143  
            * Set the value of vulnerableSoftware.
      +  143   +
            *
       144   -
            *
      -  145  
            * @param vulnerableSoftware new value of vulnerableSoftware
      +  145   +
            */
       146   -
            */
      -  147  
           public void setVulnerableSoftware(SortedSet<VulnerableSoftware> vulnerableSoftware) {
      -  148  0
               this.vulnerableSoftware = vulnerableSoftware;
      -  149  0
           }
      +  147  0
               this.vulnerableSoftware = vulnerableSoftware;
      +  148  0
           }
      +  149   +
       
       150   -
       
      +
           /**
       151   -
           /**
      +
            * Adds an entry for vulnerable software.
       152   -
            * Adds an entry for vulnerable software.
      +
            *
       153   -
            *
      -  154  
            * @param cpe string representation of a CPE entry
      +  154   +
            * @return if the add succeeded
       155   -
            * @return if the add succeeded
      +
            */
       156   -
            */
      -  157  
           public boolean addVulnerableSoftware(String cpe) {
      -  158  1752
               return addVulnerableSoftware(cpe, null);
      +  157  876
               return addVulnerableSoftware(cpe, null);
      +  158   +
           }
       159   -
           }
      +
       
       160   -
       
      +
           /**
       161   -
           /**
      -  162  
            * Adds an entry for vulnerable software.
      +  162   +
            *
       163   -
            *
      -  164  
            * @param cpe string representation of a cpe
      -  165   +  164  
            * @param previousVersion the previous version (previousVersion - cpe would be considered vulnerable)
      -  166   +  165  
            * @return if the add succeeded
      +  166   +
            */
       167   -
            */
      -  168  
           public boolean addVulnerableSoftware(String cpe, String previousVersion) {
      -  169  1894
               final VulnerableSoftware vs = new VulnerableSoftware();
      -  170  1894
               vs.setCpe(cpe);
      -  171  1894
               if (previousVersion != null) {
      -  172  18
                   vs.setPreviousVersion(previousVersion);
      -  173   +  168  947
               final VulnerableSoftware vs = new VulnerableSoftware();
      +  169  947
               vs.setCpe(cpe);
      +  170  947
               if (previousVersion != null) {
      +  171  9
                   vs.setPreviousVersion(previousVersion);
      +  172  
               }
      -  174  1894
               return updateVulnerableSoftware(vs);
      +  173  947
               return updateVulnerableSoftware(vs);
      +  174   +
           }
       175   -
           }
      +
       
       176   -
       
      +
           /**
       177   -
           /**
      -  178  
            * Adds or updates a vulnerable software entry.
      +  178   +
            *
       179   -
            *
      -  180  
            * @param vulnSoftware the vulnerable software
      -  181   +  180  
            * @return if the update succeeded
      +  181   +
            */
       182   -
            */
      -  183  
           public boolean updateVulnerableSoftware(VulnerableSoftware vulnSoftware) {
      -  184  1896
               if (vulnerableSoftware.contains(vulnSoftware)) {
      -  185  6
                   vulnerableSoftware.remove(vulnSoftware);
      -  186   +  183  948
               if (vulnerableSoftware.contains(vulnSoftware)) {
      +  184  3
                   vulnerableSoftware.remove(vulnSoftware);
      +  185  
               }
      -  187  1896
               return vulnerableSoftware.add(vulnSoftware);
      +  186  948
               return vulnerableSoftware.add(vulnSoftware);
      +  187   +
           }
       188   -
           }
      +
           /**
       189   -
           /**
      -  190  
            * The CWE for the vulnerability.
      +  190   +
            */
       191   -
            */
      -  192  
           private String cwe;
      +  192   +
       
       193   -
       
      +
           /**
       194   -
           /**
      -  195  
            * Get the value of cwe.
      +  195   +
            *
       196   -
            *
      -  197  
            * @return the value of cwe
      +  197   +
            */
       198   -
            */
      -  199  
           public String getCwe() {
      -  200  4
               return cwe;
      +  199  2
               return cwe;
      +  200   +
           }
       201   -
           }
      +
       
       202   -
       
      +
           /**
       203   -
           /**
      -  204  
            * Set the value of cwe.
      +  204   +
            *
       205   -
            *
      -  206  
            * @param cwe new value of cwe
      +  206   +
            */
       207   -
            */
      -  208  
           public void setCwe(String cwe) {
      -  209  58
               this.cwe = cwe;
      -  210  58
           }
      +  208  29
               this.cwe = cwe;
      +  209  29
           }
      +  210   +
           /**
       211   -
           /**
      -  212  
            * CVSS Score.
      +  212   +
            */
       213   -
            */
      -  214  
           private float cvssScore;
      +  214   +
       
       215   -
       
      +
           /**
       216   -
           /**
      -  217  
            * Get the value of cvssScore.
      +  217   +
            *
       218   -
            *
      -  219  
            * @return the value of cvssScore
      +  219   +
            */
       220   -
            */
      -  221  
           public float getCvssScore() {
      -  222  6
               return cvssScore;
      +  221  3
               return cvssScore;
      +  222   +
           }
       223   -
           }
      +
       
       224   -
       
      +
           /**
       225   -
           /**
      -  226  
            * Set the value of cvssScore.
      +  226   +
            *
       227   -
            *
      -  228  
            * @param cvssScore new value of cvssScore
      +  228   +
            */
       229   -
            */
      -  230  
           public void setCvssScore(float cvssScore) {
      -  231  72
               this.cvssScore = cvssScore;
      -  232  72
           }
      +  230  36
               this.cvssScore = cvssScore;
      +  231  36
           }
      +  232   +
           /**
       233   -
           /**
      -  234  
            * CVSS Access Vector.
      +  234   +
            */
       235   -
            */
      -  236  
           private String cvssAccessVector;
      +  236   +
       
       237   -
       
      +
           /**
       238   -
           /**
      -  239  
            * Get the value of cvssAccessVector.
      +  239   +
            *
       240   -
            *
      -  241  
            * @return the value of cvssAccessVector
      +  241   +
            */
       242   -
            */
      -  243  
           public String getCvssAccessVector() {
      -  244  0
               return cvssAccessVector;
      +  243  0
               return cvssAccessVector;
      +  244   +
           }
       245   -
           }
      +
       
       246   -
       
      +
           /**
       247   -
           /**
      -  248  
            * Set the value of cvssAccessVector.
      +  248   +
            *
       249   -
            *
      -  250  
            * @param cvssAccessVector new value of cvssAccessVector
      +  250   +
            */
       251   -
            */
      -  252  
           public void setCvssAccessVector(String cvssAccessVector) {
      -  253  70
               this.cvssAccessVector = cvssAccessVector;
      -  254  70
           }
      +  252  35
               this.cvssAccessVector = cvssAccessVector;
      +  253  35
           }
      +  254   +
           /**
       255   -
           /**
      -  256  
            * CVSS Access Complexity.
      +  256   +
            */
       257   -
            */
      -  258  
           private String cvssAccessComplexity;
      +  258   +
       
       259   -
       
      +
           /**
       260   -
           /**
      -  261  
            * Get the value of cvssAccessComplexity.
      +  261   +
            *
       262   -
            *
      -  263  
            * @return the value of cvssAccessComplexity
      +  263   +
            */
       264   -
            */
      -  265  
           public String getCvssAccessComplexity() {
      -  266  0
               return cvssAccessComplexity;
      +  265  0
               return cvssAccessComplexity;
      +  266   +
           }
       267   -
           }
      +
       
       268   -
       
      +
           /**
       269   -
           /**
      -  270  
            * Set the value of cvssAccessComplexity.
      +  270   +
            *
       271   -
            *
      -  272  
            * @param cvssAccessComplexity new value of cvssAccessComplexity
      +  272   +
            */
       273   -
            */
      -  274  
           public void setCvssAccessComplexity(String cvssAccessComplexity) {
      -  275  70
               this.cvssAccessComplexity = cvssAccessComplexity;
      -  276  70
           }
      +  274  35
               this.cvssAccessComplexity = cvssAccessComplexity;
      +  275  35
           }
      +  276   +
           /**
       277   -
           /**
      -  278  
            * CVSS Authentication.
      +  278   +
            */
       279   -
            */
      -  280  
           private String cvssAuthentication;
      +  280   +
       
       281   -
       
      +
           /**
       282   -
           /**
      -  283  
            * Get the value of cvssAuthentication.
      +  283   +
            *
       284   -
            *
      -  285  
            * @return the value of cvssAuthentication
      +  285   +
            */
       286   -
            */
      -  287  
           public String getCvssAuthentication() {
      -  288  0
               return cvssAuthentication;
      +  287  0
               return cvssAuthentication;
      +  288   +
           }
       289   -
           }
      +
       
       290   -
       
      +
           /**
       291   -
           /**
      -  292  
            * Set the value of cvssAuthentication.
      +  292   +
            *
       293   -
            *
      -  294  
            * @param cvssAuthentication new value of cvssAuthentication
      +  294   +
            */
       295   -
            */
      -  296  
           public void setCvssAuthentication(String cvssAuthentication) {
      -  297  70
               this.cvssAuthentication = cvssAuthentication;
      -  298  70
           }
      +  296  35
               this.cvssAuthentication = cvssAuthentication;
      +  297  35
           }
      +  298   +
           /**
       299   -
           /**
      -  300  
            * CVSS Confidentiality Impact.
      +  300   +
            */
       301   -
            */
      -  302  
           private String cvssConfidentialityImpact;
      +  302   +
       
       303   -
       
      +
           /**
       304   -
           /**
      -  305  
            * Get the value of cvssConfidentialityImpact.
      +  305   +
            *
       306   -
            *
      -  307  
            * @return the value of cvssConfidentialityImpact
      +  307   +
            */
       308   -
            */
      -  309  
           public String getCvssConfidentialityImpact() {
      -  310  0
               return cvssConfidentialityImpact;
      +  309  0
               return cvssConfidentialityImpact;
      +  310   +
           }
       311   -
           }
      +
       
       312   -
       
      +
           /**
       313   -
           /**
      -  314  
            * Set the value of cvssConfidentialityImpact.
      +  314   +
            *
       315   -
            *
      -  316  
            * @param cvssConfidentialityImpact new value of cvssConfidentialityImpact
      +  316   +
            */
       317   -
            */
      -  318  
           public void setCvssConfidentialityImpact(String cvssConfidentialityImpact) {
      -  319  70
               this.cvssConfidentialityImpact = cvssConfidentialityImpact;
      -  320  70
           }
      +  318  35
               this.cvssConfidentialityImpact = cvssConfidentialityImpact;
      +  319  35
           }
      +  320   +
           /**
       321   -
           /**
      -  322  
            * CVSS Integrity Impact.
      +  322   +
            */
       323   -
            */
      -  324  
           private String cvssIntegrityImpact;
      +  324   +
       
       325   -
       
      +
           /**
       326   -
           /**
      -  327  
            * Get the value of cvssIntegrityImpact.
      +  327   +
            *
       328   -
            *
      -  329  
            * @return the value of cvssIntegrityImpact
      +  329   +
            */
       330   -
            */
      -  331  
           public String getCvssIntegrityImpact() {
      -  332  0
               return cvssIntegrityImpact;
      +  331  0
               return cvssIntegrityImpact;
      +  332   +
           }
       333   -
           }
      +
       
       334   -
       
      +
           /**
       335   -
           /**
      -  336  
            * Set the value of cvssIntegrityImpact.
      +  336   +
            *
       337   -
            *
      -  338  
            * @param cvssIntegrityImpact new value of cvssIntegrityImpact
      +  338   +
            */
       339   -
            */
      -  340  
           public void setCvssIntegrityImpact(String cvssIntegrityImpact) {
      -  341  70
               this.cvssIntegrityImpact = cvssIntegrityImpact;
      -  342  70
           }
      +  340  35
               this.cvssIntegrityImpact = cvssIntegrityImpact;
      +  341  35
           }
      +  342   +
           /**
       343   -
           /**
      -  344  
            * CVSS Availability Impact.
      +  344   +
            */
       345   -
            */
      -  346  
           private String cvssAvailabilityImpact;
      +  346   +
       
       347   -
       
      +
           /**
       348   -
           /**
      -  349  
            * Get the value of cvssAvailabilityImpact.
      +  349   +
            *
       350   -
            *
      -  351  
            * @return the value of cvssAvailabilityImpact
      +  351   +
            */
       352   -
            */
      -  353  
           public String getCvssAvailabilityImpact() {
      -  354  0
               return cvssAvailabilityImpact;
      +  353  0
               return cvssAvailabilityImpact;
      +  354   +
           }
       355   -
           }
      +
       
       356   -
       
      +
           /**
       357   -
           /**
      -  358  
            * Set the value of cvssAvailabilityImpact.
      +  358   +
            *
       359   -
            *
      -  360  
            * @param cvssAvailabilityImpact new value of cvssAvailabilityImpact
      +  360   +
            */
       361   -
            */
      -  362  
           public void setCvssAvailabilityImpact(String cvssAvailabilityImpact) {
      -  363  70
               this.cvssAvailabilityImpact = cvssAvailabilityImpact;
      -  364  70
           }
      +  362  35
               this.cvssAvailabilityImpact = cvssAvailabilityImpact;
      +  363  35
           }
      +  364   +
       
       365   -
       
      +
           @Override
       366   -
           @Override
      -  367  
           public boolean equals(Object obj) {
      -  368  0
               if (obj == null) {
      -  369  0
                   return false;
      -  370   +  367  0
               if (obj == null) {
      +  368  0
                   return false;
      +  369  
               }
      -  371  0
               if (getClass() != obj.getClass()) {
      -  372  0
                   return false;
      -  373   +  370  0
               if (getClass() != obj.getClass()) {
      +  371  0
                   return false;
      +  372  
               }
      -  374  0
               final Vulnerability other = (Vulnerability) obj;
      -  375  0
               if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
      -  376  0
                   return false;
      -  377   +  373  0
               final Vulnerability other = (Vulnerability) obj;
      +  374  0
               if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
      +  375  0
                   return false;
      +  376  
               }
      -  378  0
               return true;
      +  377  0
               return true;
      +  378   +
           }
       379   -
           }
      +
       
       380   -
       
      +
           @Override
       381   -
           @Override
      -  382  
           public int hashCode() {
      -  383  16
               int hash = 5;
      -  384  16
               hash = 41 * hash + (this.name != null ? this.name.hashCode() : 0);
      -  385  16
               return hash;
      +  382  8
               int hash = 5;
      +  383  8
               hash = 41 * hash + (this.name != null ? this.name.hashCode() : 0);
      +  384  8
               return hash;
      +  385   +
           }
       386   -
           }
      +
       
       387   -
       
      +
           @Override
       388   -
           @Override
      -  389  
           public String toString() {
      -  390  0
               final StringBuilder sb = new StringBuilder("Vulnerability ");
      -  391  0
               sb.append(this.name);
      -  392  0
               sb.append("\nReferences:\n");
      -  393  0
               for (Iterator i = this.references.iterator(); i.hasNext();) {
      -  394  0
                 sb.append("=> ");
      -  395  0
                 sb.append(i.next());
      -  396  0
                 sb.append("\n");
      -  397   -
               }
      -  398  0
               sb.append("\nSoftware:\n");
      -  399  0
               for (Iterator i = this.vulnerableSoftware.iterator(); i.hasNext();) {
      -  400  0
                 sb.append("=> ");
      -  401  0
                 sb.append(i.next());
      -  402  0
                 sb.append("\n");
      -  403   -
               }
      -  404  0
               return sb.toString();
      +  389  0
               final StringBuilder sb = new StringBuilder("Vulnerability ");
      +  390  0
               sb.append(this.name);
      +  391  0
               sb.append("\nReferences:\n");
      +  392  0
               for (Reference reference : this.references) {
      +  393  0
                 sb.append("=> ");
      +  394  0
                 sb.append(reference);
      +  395  0
                 sb.append("\n");
      +  396  0
               }
      +  397  0
               sb.append("\nSoftware:\n");
      +  398  0
               for (VulnerableSoftware software : this.vulnerableSoftware) {
      +  399  0
                 sb.append("=> ");
      +  400  0
                 sb.append(software);
      +  401  0
                 sb.append("\n");
      +  402  0
               }
      +  403  0
               return sb.toString();
      +  404   +
           }
       405   -
           }
      +
           /**
       406   -
           /**
      -  407  
            * Compares two vulnerabilities.
      +  407   +
            *
       408   -
            *
      -  409  
            * @param v a vulnerability to be compared
      -  410   +  409  
            * @return a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than
      -  411   +  410  
            * the specified vulnerability
      +  411   +
            */
       412   -
            */
      -  413  
           @Override
      -  414   +  413  
           public int compareTo(Vulnerability v) {
      -  415  0
               return v.getName().compareTo(this.getName());
      +  414  0
               return v.getName().compareTo(this.getName());
      +  415   +
           }
       416   -
           }
      +
       
       417   -
       
      +
           /**
       418   -
           /**
      -  419  
            * The CPE id that caused this vulnerability to be flagged.
      +  419   +
            */
       420   -
            */
      -  421  
           private String matchedCPE;
      +  421   +
           /**
       422   -
           /**
      -  423  
            * Whether or not all previous versions were affected.
      +  423   +
            */
       424   -
            */
      -  425  
           private String matchedAllPreviousCPE;
      +  425   +
       
       426   -
       
      +
           /**
       427   -
           /**
      -  428  
            * Sets the CPE that caused this vulnerability to be flagged.
      +  428   +
            *
       429   -
            *
      -  430  
            * @param cpeId a CPE identifier
      -  431   +  430  
            * @param previous a flag indicating whether or not all previous versions were affected (any non-null value is
      -  432   +  431  
            * considered true)
      +  432   +
            */
       433   -
            */
      -  434  
           public void setMatchedCPE(String cpeId, String previous) {
      -  435  16
               matchedCPE = cpeId;
      -  436  16
               matchedAllPreviousCPE = previous;
      -  437  16
           }
      +  434  8
               matchedCPE = cpeId;
      +  435  8
               matchedAllPreviousCPE = previous;
      +  436  8
           }
      +  437   +
       
       438   -
       
      +
           /**
       439   -
           /**
      -  440  
            * Get the value of matchedCPE.
      +  440   +
            *
       441   -
            *
      -  442  
            * @return the value of matchedCPE
      +  442   +
            */
       443   -
            */
      -  444  
           public String getMatchedCPE() {
      -  445  0
               return matchedCPE;
      +  444  0
               return matchedCPE;
      +  445   +
           }
       446   -
           }
      +
       
       447   -
       
      +
           /**
       448   -
           /**
      -  449  
            * Get the value of matchedAllPreviousCPE.
      +  449   +
            *
       450   -
            *
      -  451  
            * @return the value of matchedAllPreviousCPE
      +  451   +
            */
       452   -
            */
      -  453  
           public String getMatchedAllPreviousCPE() {
      -  454  0
               return matchedAllPreviousCPE;
      +  453  0
               return matchedAllPreviousCPE;
      +  454   +
           }
       455   -
           }
      -  456  
       
      -  457   +  456  
           /**
      -  458   +  457  
            * Determines whether or not matchedAllPreviousCPE has been set.
      -  459   +  458  
            *
      -  460   +  459  
            * @return true if matchedAllPreviousCPE is not null; otherwise false
      -  461   +  460  
            */
      -  462   +  461  
           public boolean hasMatchedAllPreviousCPE() {
      -  463  0
               return matchedAllPreviousCPE != null;
      -  464   +  462  0
               return matchedAllPreviousCPE != null;
      +  463  
           }
      -  465   +  464  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.VulnerabilityComparator.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.VulnerabilityComparator.html index 85c7cea2e..f6c736c2f 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.VulnerabilityComparator.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.VulnerabilityComparator.html @@ -71,7 +71,7 @@
        * @author Jeremy Long
       27  
        */
      -  28  418
       public class VulnerabilityComparator implements Comparator<Vulnerability>, Serializable {
      +  28  209
       public class VulnerabilityComparator implements Comparator<Vulnerability>, Serializable {
       29  
       
       30   @@ -102,13 +102,13 @@
           @Override
       43  
           public int compare(Vulnerability o1, Vulnerability o2) {
      -  44  50
               return o2.getName().compareTo(o1.getName());
      +  44  25
               return o2.getName().compareTo(o1.getName());
       45  
           }
       46  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.VulnerableSoftware.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.VulnerableSoftware.html index 800bf93a2..ee5b09c13 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.VulnerableSoftware.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.VulnerableSoftware.html @@ -79,7 +79,7 @@
        * @author Jeremy Long
       31  
        */
      -  32  24636
       public class VulnerableSoftware extends IndexEntry implements Serializable, Comparable<VulnerableSoftware> {
      +  32  12318
       public class VulnerableSoftware extends IndexEntry implements Serializable, Comparable<VulnerableSoftware> {
       33  
       
       34   @@ -88,7 +88,7 @@
            * The logger.
       36  
            */
      -  37  2
           private static final Logger LOGGER = LoggerFactory.getLogger(VulnerableSoftware.class);
      +  37  1
           private static final Logger LOGGER = LoggerFactory.getLogger(VulnerableSoftware.class);
       38  
           /**
       39   @@ -113,13 +113,13 @@
           public void setCpe(String cpe) {
       49  
               try {
      -  50  2164
                   parseName(cpe);
      +  50  1082
                   parseName(cpe);
       51  0
               } catch (UnsupportedEncodingException ex) {
       52  0
                   LOGGER.warn("Character encoding is unsupported for CPE '{}'.", cpe);
       53  0
                   LOGGER.debug("", ex);
       54  0
                   setName(cpe);
      -  55  2164
               }
      -  56  2164
           }
      +  55  1082
               }
      +  56  1082
           }
       57  
       
       58   @@ -154,32 +154,32 @@
           @Override
       73  
           public void parseName(String cpeName) throws UnsupportedEncodingException {
      -  74  3198
               this.name = cpeName;
      -  75  3198
               if (cpeName != null && cpeName.length() > 7) {
      -  76  3188
                   final String[] data = cpeName.substring(7).split(":");
      -  77  3188
                   if (data.length >= 1) {
      -  78  3188
                       this.setVendor(urlDecode(data[0]));
      +  74  1599
               this.name = cpeName;
      +  75  1599
               if (cpeName != null && cpeName.length() > 7) {
      +  76  1594
                   final String[] data = cpeName.substring(7).split(":");
      +  77  1594
                   if (data.length >= 1) {
      +  78  1594
                       this.setVendor(urlDecode(data[0]));
       79  
                   }
      -  80  3188
                   if (data.length >= 2) {
      -  81  3186
                       this.setProduct(urlDecode(data[1]));
      +  80  1594
                   if (data.length >= 2) {
      +  81  1593
                       this.setProduct(urlDecode(data[1]));
       82  
                   }
      -  83  3188
                   if (data.length >= 3) {
      -  84  3186
                       version = urlDecode(data[2]);
      +  83  1594
                   if (data.length >= 3) {
      +  84  1593
                       version = urlDecode(data[2]);
       85  
                   }
      -  86  3188
                   if (data.length >= 4) {
      -  87  464
                       update = urlDecode(data[3]);
      +  86  1594
                   if (data.length >= 4) {
      +  87  232
                       update = urlDecode(data[3]);
       88  
                   }
      -  89  3188
                   if (data.length >= 5) {
      +  89  1594
                   if (data.length >= 5) {
       90  0
                       edition = urlDecode(data[4]);
       91  
                   }
       92  
               }
      -  93  3198
           }
      +  93  1599
           }
       94  
           /**
       95   @@ -236,8 +236,8 @@
            */
       122  
           public void setPreviousVersion(String previousVersion) {
      -  123  28
               this.previousVersion = previousVersion;
      -  124  28
           }
      +  123  14
               this.previousVersion = previousVersion;
      +  124  14
           }
       125  
       
       126   @@ -256,20 +256,20 @@
           @Override
       133  
           public boolean equals(Object obj) {
      -  134  8
               if (obj == null) {
      +  134  4
               if (obj == null) {
       135  0
                   return false;
       136  
               }
      -  137  8
               if (getClass() != obj.getClass()) {
      +  137  4
               if (getClass() != obj.getClass()) {
       138  0
                   return false;
       139  
               }
      -  140  8
               final VulnerableSoftware other = (VulnerableSoftware) obj;
      -  141  8
               if ((this.name == null) ? (other.getName() != null) : !this.name.equals(other.getName())) {
      -  142  2
                   return false;
      +  140  4
               final VulnerableSoftware other = (VulnerableSoftware) obj;
      +  141  4
               if ((this.name == null) ? (other.getName() != null) : !this.name.equals(other.getName())) {
      +  142  1
                   return false;
       143  
               }
      -  144  6
               return true;
      +  144  3
               return true;
       145  
           }
       146   @@ -288,9 +288,9 @@
           @Override
       153  
           public int hashCode() {
      -  154  220
               int hash = 7;
      -  155  220
               hash = 83 * hash + (this.name != null ? this.name.hashCode() : 0);
      -  156  220
               return hash;
      +  154  110
               int hash = 7;
      +  155  110
               hash = 83 * hash + (this.name != null ? this.name.hashCode() : 0);
      +  156  110
               return hash;
       157  
           }
       158   @@ -330,21 +330,21 @@
           @Override
       176  
           public int compareTo(VulnerableSoftware vs) {
      -  177  21472
               int result = 0;
      -  178  21472
               final String[] left = this.name.split(":");
      -  179  21472
               final String[] right = vs.getName().split(":");
      -  180  21472
               final int max = (left.length <= right.length) ? left.length : right.length;
      -  181  21472
               if (max > 0) {
      -  182  129238
                   for (int i = 0; result == 0 && i < max; i++) {
      -  183  107766
                       final String[] subLeft = left[i].split("(\\.|-)");
      -  184  107766
                       final String[] subRight = right[i].split("(\\.|-)");
      -  185  107766
                       final int subMax = (subLeft.length <= subRight.length) ? subLeft.length : subRight.length;
      -  186  107766
                       if (subMax > 0) {
      -  187  246638
                           for (int x = 0; result == 0 && x < subMax; x++) {
      -  188  138890
                               if (isPositiveInteger(subLeft[x]) && isPositiveInteger(subRight[x])) {
      +  177  10736
               int result = 0;
      +  178  10736
               final String[] left = this.name.split(":");
      +  179  10736
               final String[] right = vs.getName().split(":");
      +  180  10736
               final int max = (left.length <= right.length) ? left.length : right.length;
      +  181  10736
               if (max > 0) {
      +  182  64619
                   for (int i = 0; result == 0 && i < max; i++) {
      +  183  53883
                       final String[] subLeft = left[i].split("(\\.|-)");
      +  184  53883
                       final String[] subRight = right[i].split("(\\.|-)");
      +  185  53883
                       final int subMax = (subLeft.length <= subRight.length) ? subLeft.length : subRight.length;
      +  186  53883
                       if (subMax > 0) {
      +  187  123319
                           for (int x = 0; result == 0 && x < subMax; x++) {
      +  188  69445
                               if (isPositiveInteger(subLeft[x]) && isPositiveInteger(subRight[x])) {
       189  
                                   try {
      -  190  51138
                                       result = Long.valueOf(subLeft[x]).compareTo(Long.valueOf(subRight[x]));
      +  190  25569
                                       result = Long.valueOf(subLeft[x]).compareTo(Long.valueOf(subRight[x]));
       191  0
                                   } catch (NumberFormatException ex) {
       192  
                                       //ignore the exception - they obviously aren't numbers
      @@ -352,39 +352,39 @@  194  0
                                           result = subLeft[x].compareToIgnoreCase(subRight[x]);
       195  
                                       }
      -  196  51138
                                   }
      +  196  25569
                                   }
       197  
                               } else {
      -  198  87752
                                   result = subLeft[x].compareToIgnoreCase(subRight[x]);
      +  198  43876
                                   result = subLeft[x].compareToIgnoreCase(subRight[x]);
       199  
                               }
       200  
                           }
      -  201  107748
                           if (result == 0) {
      -  202  86938
                               if (subLeft.length > subRight.length) {
      -  203  312
                                   result = 2;
      +  201  53874
                           if (result == 0) {
      +  202  43469
                               if (subLeft.length > subRight.length) {
      +  203  156
                                   result = 2;
       204  
                               }
      -  205  86938
                               if (subRight.length > subLeft.length) {
      -  206  106
                                   result = -2;
      +  205  43469
                               if (subRight.length > subLeft.length) {
      +  206  53
                                   result = -2;
       207  
                               }
       208  
                           }
       209  
                       } else {
      -  210  18
                           result = left[i].compareToIgnoreCase(right[i]);
      +  210  9
                           result = left[i].compareToIgnoreCase(right[i]);
       211  
                       }
       212  
                   }
      -  213  21472
                   if (result == 0) {
      -  214  232
                       if (left.length > right.length) {
      -  215  136
                           result = 2;
      +  213  10736
                   if (result == 0) {
      +  214  116
                       if (left.length > right.length) {
      +  215  68
                           result = 2;
       216  
                       }
      -  217  232
                       if (right.length > left.length) {
      -  218  20
                           result = -2;
      +  217  116
                       if (right.length > left.length) {
      +  218  10
                           result = -2;
       219  
                       }
       220   @@ -394,7 +394,7 @@  222  0
                   result = this.getName().compareToIgnoreCase(vs.getName());
       223  
               }
      -  224  21472
               return result;
      +  224  10736
               return result;
       225  
           }
       226   @@ -413,19 +413,19 @@
            */
       233  
           private static boolean isPositiveInteger(final String str) {
      -  234  190200
               if (str == null || str.isEmpty()) {
      -  235  28
                   return false;
      +  234  95100
               if (str == null || str.isEmpty()) {
      +  235  14
                   return false;
       236  
               }
      -  237  309718
               for (int i = 0; i < str.length(); i++) {
      -  238  207270
                   final char c = str.charAt(i);
      -  239  207270
                   if (c < '0' || c > '9') {
      -  240  87724
                       return false;
      +  237  154859
               for (int i = 0; i < str.length(); i++) {
      +  238  103635
                   final char c = str.charAt(i);
      +  239  103635
                   if (c < '0' || c > '9') {
      +  240  43862
                       return false;
       241  
                   }
       242  
               }
      -  243  102448
               return true;
      +  243  51224
               return true;
       244  
           }
       245   @@ -450,7 +450,7 @@
            */
       255  
           public String getName() {
      -  256  21574
               return name;
      +  256  10787
               return name;
       257  
           }
       258   @@ -491,7 +491,7 @@
            */
       277  
           public String getVersion() {
      -  278  3940
               return version;
      +  278  1970
               return version;
       279  
           }
       280   @@ -532,7 +532,7 @@
            */
       299  
           public String getUpdate() {
      -  300  2858
               return update;
      +  300  1429
               return update;
       301  
           }
       302   @@ -608,12 +608,12 @@
            */
       340  
           private String urlDecode(String string) {
      -  341  10024
               final String text = string.replace("+", "%2B");
      +  341  5012
               final String text = string.replace("+", "%2B");
       342  
               String result;
       343  
               try {
      -  344  10024
                   result = URLDecoder.decode(text, "UTF-8");
      +  344  5012
                   result = URLDecoder.decode(text, "UTF-8");
       345  0
               } catch (UnsupportedEncodingException ex) {
       346  
                   try {
      @@ -621,8 +621,8 @@  348  0
                   } catch (UnsupportedEncodingException ex1) {
       349  0
                       result = defaultUrlDecode(text);
       350  0
                   }
      -  351  10024
               }
      -  352  10024
               return result;
      +  351  5012
               }
      +  352  5012
               return result;
       353  
           }
       354   @@ -650,6 +650,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.exception.ExceptionCollection.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.exception.ExceptionCollection.html new file mode 100644 index 000000000..be3075c67 --- /dev/null +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.exception.ExceptionCollection.html @@ -0,0 +1,399 @@ + + + + +Coverage Report + + + + +
      Coverage Report - org.owasp.dependencycheck.exception.ExceptionCollection
      +
       
      + + + + +
      Classes in this File Line Coverage Branch Coverage Complexity
      ExceptionCollection
      7%
      4/53
      0%
      0/4
      1.133
      +
       
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
       1  
       /*
       2  
        * This file is part of dependency-check-core.
       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) 2016 Jeremy Long. All Rights Reserved.
       17  
        */
       18  
       package org.owasp.dependencycheck.exception;
       19  
       
       20  
       import java.io.PrintStream;
       21  
       import java.io.PrintWriter;
       22  
       import java.util.ArrayList;
       23  
       import java.util.List;
       24  
       
       25  
       /**
       26  
        * A collection of several exceptions.
       27  
        *
       28  
        * @author Jeremy Lomg
       29  
        */
       30  
       public class ExceptionCollection extends Exception {
       31  
       
       32  
           /**
       33  
            * Instantiates a new exception collection.
       34  
            *
       35  
            * @param exceptions a list of exceptions
       36  
            */
       37  
           public ExceptionCollection(List<Throwable> exceptions) {
       38  0
               super();
       39  0
               this.exceptions = exceptions;
       40  0
           }
       41  
       
       42  
           /**
       43  
            * Instantiates a new exception collection.
       44  
            *
       45  
            * @param msg the exception message
       46  
            * @param exceptions a list of exceptions
       47  
            */
       48  
           public ExceptionCollection(String msg, List<Throwable> exceptions) {
       49  1
               super(msg);
       50  1
               this.exceptions = exceptions;
       51  1
           }
       52  
       
       53  
           /**
       54  
            * Instantiates a new exception collection.
       55  
            *
       56  
            * @param exceptions a list of exceptions
       57  
            * @param fatal indicates if the exception that occurred is fatal - meaning
       58  
            * that no analysis was performed.
       59  
            */
       60  
           public ExceptionCollection(List<Throwable> exceptions, boolean fatal) {
       61  0
               super();
       62  0
               this.exceptions = exceptions;
       63  0
               this.fatal = fatal;
       64  0
           }
       65  
       
       66  
           /**
       67  
            * Instantiates a new exception collection.
       68  
            *
       69  
            * @param msg the exception message
       70  
            * @param exceptions a list of exceptions
       71  
            * @param fatal indicates if the exception that occurred is fatal - meaning
       72  
            * that no analysis was performed.
       73  
            */
       74  
           public ExceptionCollection(String msg, List<Throwable> exceptions, boolean fatal) {
       75  0
               super(msg);
       76  0
               this.exceptions = exceptions;
       77  0
               this.fatal = fatal;
       78  0
           }
       79  
       
       80  
           /**
       81  
            * Instantiates a new exception collection.
       82  
            *
       83  
            * @param exceptions a list of exceptions
       84  
            * @param fatal indicates if the exception that occurred is fatal - meaning
       85  
            * that no analysis was performed.
       86  
            */
       87  
           public ExceptionCollection(Throwable exceptions, boolean fatal) {
       88  0
               super();
       89  0
               this.exceptions = new ArrayList<Throwable>();
       90  0
               this.exceptions.add(exceptions);
       91  0
               this.fatal = fatal;
       92  0
           }
       93  
               /**
       94  
            * Instantiates a new exception collection.
       95  
            *
       96  
            * @param msg the exception message
       97  
            * @param exception a list of exceptions
       98  
            */
       99  
           public ExceptionCollection(String msg, Throwable exception) {
       100  0
               super(msg);
       101  0
               this.exceptions = new ArrayList<Throwable>();
       102  0
               this.exceptions.add(exception);
       103  0
               this.fatal = false;
       104  0
           }
       105  
       
       106  
           /**
       107  
            * Instantiates a new exception collection.
       108  
            */
       109  
           public ExceptionCollection() {
       110  0
               super();
       111  0
               this.exceptions = new ArrayList<Throwable>();
       112  0
           }
       113  
           /**
       114  
            * The serial version uid.
       115  
            */
       116  
           private static final long serialVersionUID = 1L;
       117  
       
       118  
           /**
       119  
            * A collection of exceptions.
       120  
            */
       121  
           private List<Throwable> exceptions;
       122  
       
       123  
           /**
       124  
            * Get the value of exceptions.
       125  
            *
       126  
            * @return the value of exceptions
       127  
            */
       128  
           public List<Throwable> getExceptions() {
       129  0
               return exceptions;
       130  
           }
       131  
       
       132  
           /**
       133  
            * Adds an exception to the collection.
       134  
            *
       135  
            * @param ex the exception to add
       136  
            */
       137  
           public void addException(Throwable ex) {
       138  0
               this.exceptions.add(ex);
       139  0
           }
       140  
       
       141  
           /**
       142  
            * Adds an exception to the collection.
       143  
            *
       144  
            * @param ex the exception to add
       145  
            * @param fatal flag indicating if this is a fatal error
       146  
            */
       147  
           public void addException(Throwable ex, boolean fatal) {
       148  0
               addException(ex);
       149  0
               this.fatal = fatal;
       150  0
           }
       151  
       
       152  
           /**
       153  
            * Flag indicating if a fatal exception occurred that would prevent the
       154  
            * attempt at completing the analysis even if exceptions occurred.
       155  
            */
       156  1
           private boolean fatal = false;
       157  
       
       158  
           /**
       159  
            * Get the value of fatal.
       160  
            *
       161  
            * @return the value of fatal
       162  
            */
       163  
           public boolean isFatal() {
       164  0
               return fatal;
       165  
           }
       166  
       
       167  
           /**
       168  
            * Set the value of fatal.
       169  
            *
       170  
            * @param fatal new value of fatal
       171  
            */
       172  
           public void setFatal(boolean fatal) {
       173  0
               this.fatal = fatal;
       174  0
           }
       175  
       
       176  
           /**
       177  
            * Prints the stack trace.
       178  
            *
       179  
            * @param s the writer to print to
       180  
            */
       181  
           @Override
       182  
           public void printStackTrace(PrintWriter s) {
       183  0
               s.println("Multiple Exceptions Occured");
       184  0
               super.printStackTrace(s);
       185  0
               for (Throwable t : this.exceptions) {
       186  0
                   s.println("Next Exception:");
       187  0
                   t.printStackTrace(s);
       188  0
               }
       189  0
           }
       190  
       
       191  
           /**
       192  
            * Prints the stack trace.
       193  
            *
       194  
            * @param s the stream to write the stack trace to
       195  
            */
       196  
           @Override
       197  
           public void printStackTrace(PrintStream s) {
       198  0
               s.println("Multiple Exceptions Occured");
       199  0
               super.printStackTrace(s);
       200  0
               for (Throwable t : this.exceptions) {
       201  0
                   s.println("Next Exception:");
       202  0
                   t.printStackTrace(s);
       203  0
               }
       204  0
           }
       205  
       
       206  
           /**
       207  
            * Prints the stack trace to standard error.
       208  
            */
       209  
           @Override
       210  
           public void printStackTrace() {
       211  0
               this.printStackTrace(System.err);
       212  0
           }
       213  
       
       214  
       }
      + + + + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.exception.InitializationException.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.exception.InitializationException.html new file mode 100644 index 000000000..b704a5364 --- /dev/null +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.exception.InitializationException.html @@ -0,0 +1,148 @@ + + + + +Coverage Report + + + + +
      Coverage Report - org.owasp.dependencycheck.exception.InitializationException
      +
       
      + + + + +
      Classes in this File Line Coverage Branch Coverage Complexity
      InitializationException
      25%
      2/8
      N/A
      1
      +
       
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
       1  
       /*
       2  
        * This file is part of dependency-check-core.
       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) 2016 Jeremy Long. All Rights Reserved.
       17  
        */
       18  
       package org.owasp.dependencycheck.exception;
       19  
       
       20  
       /**
       21  
        * An exception used when initializing analyzers.
       22  
        *
       23  
        * @author Jeremy Long
       24  
        */
       25  
       public class InitializationException extends Exception {
       26  
       
       27  
           /**
       28  
            * The serial version uid.
       29  
            */
       30  
           private static final long serialVersionUID = 1L;
       31  
       
       32  
           /**
       33  
            * Creates a new InitializationException.
       34  
            */
       35  
           public InitializationException() {
       36  0
               super();
       37  0
           }
       38  
       
       39  
           /**
       40  
            * Creates a new InitializationException.
       41  
            *
       42  
            * @param msg a message for the exception.
       43  
            */
       44  
           public InitializationException(String msg) {
       45  0
               super(msg);
       46  0
           }
       47  
       
       48  
           /**
       49  
            * Creates a new InitializationException.
       50  
            *
       51  
            * @param ex the cause of the exception.
       52  
            */
       53  
           public InitializationException(Throwable ex) {
       54  0
               super(ex);
       55  0
           }
       56  
       
       57  
           /**
       58  
            * Creates a new InitializationException.
       59  
            *
       60  
            * @param msg a message for the exception.
       61  
            * @param ex the cause of the exception.
       62  
            */
       63  
           public InitializationException(String msg, Throwable ex) {
       64  5
               super(msg, ex);
       65  5
           }
       66  
       }
      + + + + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.exception.NoDataException.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.exception.NoDataException.html index 749283805..d0033c10a 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.exception.NoDataException.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.exception.NoDataException.html @@ -147,6 +147,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.exception.ReportException.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.exception.ReportException.html new file mode 100644 index 000000000..454d8e2f5 --- /dev/null +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.exception.ReportException.html @@ -0,0 +1,148 @@ + + + + +Coverage Report + + + + +
      Coverage Report - org.owasp.dependencycheck.exception.ReportException
      +
       
      + + + + +
      Classes in this File Line Coverage Branch Coverage Complexity
      ReportException
      0%
      0/8
      N/A
      1
      +
       
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
       1  
       /*
       2  
        * This file is part of dependency-check-core.
       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) 2016 Jeremy Long. All Rights Reserved.
       17  
        */
       18  
       package org.owasp.dependencycheck.exception;
       19  
       
       20  
       /**
       21  
        * An exception used when generating reports.
       22  
        *
       23  
        * @author Jeremy Long
       24  
        */
       25  
       public class ReportException extends Exception {
       26  
       
       27  
           /**
       28  
            * The serial version uid.
       29  
            */
       30  
           private static final long serialVersionUID = 1L;
       31  
       
       32  
           /**
       33  
            * Creates a new ReportException.
       34  
            */
       35  
           public ReportException() {
       36  0
               super();
       37  0
           }
       38  
       
       39  
           /**
       40  
            * Creates a new ReportException.
       41  
            *
       42  
            * @param msg a message for the exception.
       43  
            */
       44  
           public ReportException(String msg) {
       45  0
               super(msg);
       46  0
           }
       47  
       
       48  
           /**
       49  
            * Creates a new ReportException.
       50  
            *
       51  
            * @param ex the cause of the exception.
       52  
            */
       53  
           public ReportException(Throwable ex) {
       54  0
               super(ex);
       55  0
           }
       56  
       
       57  
           /**
       58  
            * Creates a new ReportException.
       59  
            *
       60  
            * @param msg a message for the exception.
       61  
            * @param ex the cause of the exception.
       62  
            */
       63  
           public ReportException(String msg, Throwable ex) {
       64  0
               super(msg, ex);
       65  0
           }
       66  
       }
      + + + + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.exception.ScanAgentException.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.exception.ScanAgentException.html index 4f2a6546e..d391feccd 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.exception.ScanAgentException.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.exception.ScanAgentException.html @@ -147,6 +147,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.reporting.EscapeTool.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.reporting.EscapeTool.html index 753c1158d..38e85e2f8 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.reporting.EscapeTool.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.reporting.EscapeTool.html @@ -170,6 +170,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.reporting.ReportGenerator.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.reporting.ReportGenerator.html index 9387d20cd..0ec55e4aa 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.reporting.ReportGenerator.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.reporting.ReportGenerator.html @@ -12,8 +12,8 @@
       
      - - + +
      Classes in this File Line Coverage Branch Coverage Complexity
      ReportGenerator
      0%
      0/108
      0%
      0/64
      6
      ReportGenerator$Format
      0%
      0/5
      N/A
      6
      ReportGenerator
      0%
      0/114
      0%
      0/66
      7
      ReportGenerator$Format
      0%
      0/5
      N/A
      7
       
      @@ -75,474 +75,492 @@  28  
       import java.io.OutputStreamWriter;
       29   -
       import java.text.DateFormat;
      +
       import java.io.UnsupportedEncodingException;
       30   -
       import java.text.SimpleDateFormat;
      +
       import java.text.DateFormat;
       31   -
       import java.util.Date;
      +
       import java.text.SimpleDateFormat;
       32   -
       import java.util.List;
      +
       import java.util.Date;
       33   -
       import org.apache.velocity.VelocityContext;
      +
       import java.util.List;
       34   -
       import org.apache.velocity.app.VelocityEngine;
      +
       import org.apache.velocity.VelocityContext;
       35   -
       import org.apache.velocity.context.Context;
      +
       import org.apache.velocity.app.VelocityEngine;
       36   -
       import org.apache.velocity.runtime.RuntimeConstants;
      +
       import org.apache.velocity.context.Context;
       37   -
       import org.owasp.dependencycheck.analyzer.Analyzer;
      +
       import org.apache.velocity.runtime.RuntimeConstants;
       38   -
       import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties;
      +
       import org.owasp.dependencycheck.analyzer.Analyzer;
       39   -
       import org.owasp.dependencycheck.dependency.Dependency;
      +
       import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties;
       40   -
       import org.owasp.dependencycheck.utils.Settings;
      +
       import org.owasp.dependencycheck.dependency.Dependency;
       41   -
       import org.slf4j.Logger;
      +
       import org.owasp.dependencycheck.exception.ReportException;
       42   -
       import org.slf4j.LoggerFactory;
      +
       import org.owasp.dependencycheck.utils.Settings;
       43   -
       
      +
       import org.slf4j.Logger;
       44   -
       /**
      +
       import org.slf4j.LoggerFactory;
       45   -
        * The ReportGenerator is used to, as the name implies, generate reports. Internally the generator uses the Velocity
      +
       
       46   -
        * Templating Engine. The ReportGenerator exposes a list of Dependencies to the template when generating the report.
      +
       /**
       47   -
        *
      +
        * The ReportGenerator is used to, as the name implies, generate reports.
       48   -
        * @author Jeremy Long
      +
        * Internally the generator uses the Velocity Templating Engine. The
       49   -
        */
      +
        * ReportGenerator exposes a list of Dependencies to the template when
       50   -
       public class ReportGenerator {
      +
        * generating the report.
       51   -
       
      +
        *
       52   -
           /**
      +
        * @author Jeremy Long
       53   -
            * The logger.
      +
        */
       54   -
            */
      -  55  0
           private static final Logger LOGGER = LoggerFactory.getLogger(ReportGenerator.class);
      +
       public class ReportGenerator {
      +  55   +
       
       56   -
       
      -  57  
           /**
      +  57   +
            * The logger.
       58   -
            * An enumeration of the report formats.
      -  59  
            */
      -  60  0
           public enum Format {
      -  61   +  59  0
           private static final Logger LOGGER = LoggerFactory.getLogger(ReportGenerator.class);
      +  60  
       
      +  61   +
           /**
       62   -
               /**
      +
            * An enumeration of the report formats.
       63   -
                * Generate all reports.
      -  64   -
                */
      -  65  0
               ALL,
      +
            */
      +  64  0
           public enum Format {
      +  65   +
       
       66  
               /**
       67   -
                * Generate XML report.
      +
                * Generate all reports.
       68  
                */
      -  69  0
               XML,
      +  69  0
               ALL,
       70  
               /**
       71   -
                * Generate HTML report.
      +
                * Generate XML report.
       72  
                */
      -  73  0
               HTML,
      +  73  0
               XML,
       74  
               /**
       75   -
                * Generate HTML Vulnerability report.
      +
                * Generate HTML report.
       76  
                */
      -  77  0
               VULN
      +  77  0
               HTML,
       78   -
           }
      +
               /**
       79   -
           /**
      +
                * Generate HTML Vulnerability report.
       80   -
            * The Velocity Engine.
      -  81   -
            */
      +
                */
      +  81  0
               VULN
       82   -
           private final VelocityEngine engine;
      +
           }
       83  
           /**
       84   -
            * The Velocity Engine Context.
      +
            * The Velocity Engine.
       85  
            */
       86   -
           private final Context context;
      +
           private final VelocityEngine velocityEngine;
       87   -
       
      +
           /**
       88   -
           /**
      +
            * The Velocity Engine Context.
       89   -
            * Constructs a new ReportGenerator.
      +
            */
       90   -
            *
      +
           private final Context context;
       91   -
            * @param applicationName the application name being analyzed
      +
       
       92   -
            * @param dependencies the list of dependencies
      +
           /**
       93   -
            * @param analyzers the list of analyzers used
      +
            * Constructs a new ReportGenerator.
       94   -
            * @param properties the database properties (containing timestamps of the NVD CVE data)
      +
            *
       95   -
            */
      -  96  0
           public ReportGenerator(String applicationName, List<Dependency> dependencies, List<Analyzer> analyzers, DatabaseProperties properties) {
      -  97  0
               engine = createVelocityEngine();
      -  98  0
               context = createContext();
      +
            * @param applicationName the application name being analyzed
      +  96   +
            * @param dependencies the list of dependencies
      +  97   +
            * @param analyzers the list of analyzers used
      +  98   +
            * @param properties the database properties (containing timestamps of the
       99   +
            * NVD CVE data)
      +  100   +
            */
      +  101  0
           public ReportGenerator(String applicationName, List<Dependency> dependencies, List<Analyzer> analyzers, DatabaseProperties properties) {
      +  102  0
               velocityEngine = createVelocityEngine();
      +  103  0
               context = createContext();
      +  104  
       
      -  100  0
               engine.init();
      -  101   +  105  0
               velocityEngine.init();
      +  106  
       
      -  102  0
               final DateFormat dateFormat = new SimpleDateFormat("MMM d, yyyy 'at' HH:mm:ss z");
      -  103  0
               final DateFormat dateFormatXML = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
      -  104  0
               final Date d = new Date();
      -  105  0
               final String scanDate = dateFormat.format(d);
      -  106  0
               final String scanDateXML = dateFormatXML.format(d);
      -  107  0
               final EscapeTool enc = new EscapeTool();
      -  108   +  107  0
               final DateFormat dateFormat = new SimpleDateFormat("MMM d, yyyy 'at' HH:mm:ss z");
      +  108  0
               final DateFormat dateFormatXML = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
      +  109  0
               final Date d = new Date();
      +  110  0
               final String scanDate = dateFormat.format(d);
      +  111  0
               final String scanDateXML = dateFormatXML.format(d);
      +  112  0
               final EscapeTool enc = new EscapeTool();
      +  113  
       
      -  109  0
               context.put("applicationName", applicationName);
      -  110  0
               context.put("dependencies", dependencies);
      -  111  0
               context.put("analyzers", analyzers);
      -  112  0
               context.put("properties", properties);
      -  113  0
               context.put("scanDate", scanDate);
      -  114  0
               context.put("scanDateXML", scanDateXML);
      -  115  0
               context.put("enc", enc);
      -  116  0
               context.put("version", Settings.getString(Settings.KEYS.APPLICATION_VERSION, "Unknown"));
      -  117  0
           }
      -  118   -
       
      -  119   -
           /**
      -  120   -
            * Creates a new Velocity Engine.
      -  121   -
            *
      -  122   -
            * @return a velocity engine.
      +  114  0
               context.put("applicationName", applicationName);
      +  115  0
               context.put("dependencies", dependencies);
      +  116  0
               context.put("analyzers", analyzers);
      +  117  0
               context.put("properties", properties);
      +  118  0
               context.put("scanDate", scanDate);
      +  119  0
               context.put("scanDateXML", scanDateXML);
      +  120  0
               context.put("enc", enc);
      +  121  0
               context.put("version", Settings.getString(Settings.KEYS.APPLICATION_VERSION, "Unknown"));
      +  122  0
           }
       123   -
            */
      +
       
       124   -
           private VelocityEngine createVelocityEngine() {
      -  125  0
               final VelocityEngine engine = new VelocityEngine();
      +
           /**
      +  125   +
            * Creates a new Velocity Engine.
       126   -
               // Logging redirection for Velocity - Required by Jenkins and other server applications
      -  127  0
               engine.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, VelocityLoggerRedirect.class.getName());
      -  128  0
               return engine;
      +
            *
      +  127   +
            * @return a velocity engine
      +  128   +
            */
       129   -
           }
      -  130   -
       
      +
           private VelocityEngine createVelocityEngine() {
      +  130  0
               final VelocityEngine velocity = new VelocityEngine();
       131   -
           /**
      -  132   -
            * Creates a new Velocity Context.
      -  133   -
            *
      +
               // Logging redirection for Velocity - Required by Jenkins and other server applications
      +  132  0
               velocity.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, VelocityLoggerRedirect.class.getName());
      +  133  0
               return velocity;
       134   -
            * @return a Velocity Context.
      -  135   -
            */
      -  136   -
           private Context createContext() {
      -  137  0
               return new VelocityContext();
      -  138  
           }
      +  135   +
       
      +  136   +
           /**
      +  137   +
            * Creates a new Velocity Context.
      +  138   +
            *
       139   -
       
      +
            * @return a Velocity Context
       140   -
           /**
      +
            */
       141   -
            * Generates the Dependency Reports for the identified dependencies.
      -  142   -
            *
      +
           private Context createContext() {
      +  142  0
               return new VelocityContext();
       143   -
            * @param outputStream the OutputStream to send the generated report to
      +
           }
       144   -
            * @param format the format the report should be written in
      +
       
       145   -
            * @throws IOException is thrown when the template file does not exist
      +
           /**
       146   -
            * @throws Exception is thrown if there is an error writing out the reports.
      +
            * Generates the Dependency Reports for the identified dependencies.
       147   -
            */
      +
            *
       148   -
           public void generateReports(OutputStream outputStream, Format format) throws IOException, Exception {
      -  149  0
               if (format == Format.XML || format == Format.ALL) {
      -  150  0
                   generateReport("XmlReport", outputStream);
      -  151   -
               }
      -  152  0
               if (format == Format.HTML || format == Format.ALL) {
      -  153  0
                   generateReport("HtmlReport", outputStream);
      -  154   -
               }
      -  155  0
               if (format == Format.VULN || format == Format.ALL) {
      -  156  0
                   generateReport("VulnerabilityReport", outputStream);
      -  157   -
               }
      -  158  0
           }
      -  159   -
       
      -  160   -
           /**
      -  161   -
            * Generates the Dependency Reports for the identified dependencies.
      -  162   -
            *
      -  163   -
            * @param outputDir the path where the reports should be written
      -  164   +
            * @param outputStream the OutputStream to send the generated report to
      +  149  
            * @param format the format the report should be written in
      +  150   +
            * @throws IOException is thrown when the template file does not exist
      +  151   +
            * @throws Exception is thrown if there is an error writing out the reports
      +  152   +
            */
      +  153   +
           public void generateReports(OutputStream outputStream, Format format) throws IOException, Exception {
      +  154  0
               if (format == Format.XML || format == Format.ALL) {
      +  155  0
                   generateReport("XmlReport", outputStream);
      +  156   +
               }
      +  157  0
               if (format == Format.HTML || format == Format.ALL) {
      +  158  0
                   generateReport("HtmlReport", outputStream);
      +  159   +
               }
      +  160  0
               if (format == Format.VULN || format == Format.ALL) {
      +  161  0
                   generateReport("VulnerabilityReport", outputStream);
      +  162   +
               }
      +  163  0
           }
      +  164   +
       
       165   -
            * @throws IOException is thrown when the template file does not exist
      +
           /**
       166   -
            * @throws Exception is thrown if there is an error writing out the reports.
      -  167   -
            */
      -  168   -
           public void generateReports(String outputDir, Format format) throws IOException, Exception {
      -  169  0
               if (format == Format.XML || format == Format.ALL) {
      -  170  0
                   generateReport("XmlReport", outputDir + File.separator + "dependency-check-report.xml");
      -  171   -
               }
      -  172  0
               if (format == Format.HTML || format == Format.ALL) {
      -  173  0
                   generateReport("HtmlReport", outputDir + File.separator + "dependency-check-report.html");
      -  174   -
               }
      -  175  0
               if (format == Format.VULN || format == Format.ALL) {
      -  176  0
                   generateReport("VulnerabilityReport", outputDir + File.separator + "dependency-check-vulnerability.html");
      -  177   -
               }
      -  178  0
           }
      -  179   -
       
      -  180   -
           /**
      -  181  
            * Generates the Dependency Reports for the identified dependencies.
      -  182   +  167  
            *
      -  183   +  168  
            * @param outputDir the path where the reports should be written
      +  169   +
            * @param format the format the report should be written in
      +  170   +
            * @throws ReportException is thrown if there is an error writing out the reports
      +  171   +
            */
      +  172   +
           public void generateReports(String outputDir, Format format) throws ReportException {
      +  173  0
               if (format == Format.XML || format == Format.ALL) {
      +  174  0
                   generateReport("XmlReport", outputDir + File.separator + "dependency-check-report.xml");
      +  175   +
               }
      +  176  0
               if (format == Format.HTML || format == Format.ALL) {
      +  177  0
                   generateReport("HtmlReport", outputDir + File.separator + "dependency-check-report.html");
      +  178   +
               }
      +  179  0
               if (format == Format.VULN || format == Format.ALL) {
      +  180  0
                   generateReport("VulnerabilityReport", outputDir + File.separator + "dependency-check-vulnerability.html");
      +  181   +
               }
      +  182  0
           }
      +  183   +
       
       184   -
            * @param outputFormat the format the report should be written in (XML, HTML, ALL)
      +
           /**
       185   -
            * @throws IOException is thrown when the template file does not exist
      +
            * Generates the Dependency Reports for the identified dependencies.
       186   -
            * @throws Exception is thrown if there is an error writing out the reports.
      +
            *
       187   -
            */
      +
            * @param outputDir the path where the reports should be written
       188   -
           public void generateReports(String outputDir, String outputFormat) throws IOException, Exception {
      -  189  0
               final String format = outputFormat.toUpperCase();
      -  190  0
               final String pathToCheck = outputDir.toLowerCase();
      -  191  0
               if (format.matches("^(XML|HTML|VULN|ALL)$")) {
      -  192  0
                   if ("XML".equalsIgnoreCase(format)) {
      -  193  0
                       if (pathToCheck.endsWith(".xml")) {
      -  194  0
                           generateReport("XmlReport", outputDir);
      -  195   +
            * @param outputFormat the format the report should be written in (XML,
      +  189   +
            * HTML, ALL)
      +  190   +
            * @throws ReportException is thrown if there is an error creating out the
      +  191   +
            * reports
      +  192   +
            */
      +  193   +
           public void generateReports(String outputDir, String outputFormat) throws ReportException {
      +  194  0
               final String format = outputFormat.toUpperCase();
      +  195  0
               final String pathToCheck = outputDir.toLowerCase();
      +  196  0
               if (format.matches("^(XML|HTML|VULN|ALL)$")) {
      +  197  0
                   if ("XML".equalsIgnoreCase(format)) {
      +  198  0
                       if (pathToCheck.endsWith(".xml")) {
      +  199  0
                           generateReport("XmlReport", outputDir);
      +  200  
                       } else {
      -  196  0
                           generateReports(outputDir, Format.XML);
      -  197   -
                       }
      -  198   -
                   }
      -  199  0
                   if ("HTML".equalsIgnoreCase(format)) {
      -  200  0
                       if (pathToCheck.endsWith(".html") || pathToCheck.endsWith(".htm")) {
      -  201  0
                           generateReport("HtmlReport", outputDir);
      +  201  0
                           generateReports(outputDir, Format.XML);
       202   -
                       } else {
      -  203  0
                           generateReports(outputDir, Format.HTML);
      -  204  
                       }
      -  205   +  203  
                   }
      -  206  0
                   if ("VULN".equalsIgnoreCase(format)) {
      -  207  0
                       if (pathToCheck.endsWith(".html") || pathToCheck.endsWith(".htm")) {
      -  208  0
                           generateReport("VulnReport", outputDir);
      +  204  0
                   if ("HTML".equalsIgnoreCase(format)) {
      +  205  0
                       if (pathToCheck.endsWith(".html") || pathToCheck.endsWith(".htm")) {
      +  206  0
                           generateReport("HtmlReport", outputDir);
      +  207   +
                       } else {
      +  208  0
                           generateReports(outputDir, Format.HTML);
       209   -
                       } else {
      -  210  0
                           generateReports(outputDir, Format.VULN);
      -  211  
                       }
      -  212   -
                   }
      -  213  0
                   if ("ALL".equalsIgnoreCase(format)) {
      -  214  0
                       generateReports(outputDir, Format.ALL);
      -  215   +  210  
                   }
      +  211  0
                   if ("VULN".equalsIgnoreCase(format)) {
      +  212  0
                       if (pathToCheck.endsWith(".html") || pathToCheck.endsWith(".htm")) {
      +  213  0
                           generateReport("VulnReport", outputDir);
      +  214   +
                       } else {
      +  215  0
                           generateReports(outputDir, Format.VULN);
       216   -
               }
      -  217  0
           }
      -  218   -
       
      -  219   -
           /**
      +
                       }
      +  217   +
                   }
      +  218  0
                   if ("ALL".equalsIgnoreCase(format)) {
      +  219  0
                       generateReports(outputDir, Format.ALL);
       220   -
            * Generates a report from a given Velocity Template. The template name provided can be the name of a template
      +
                   }
       221   -
            * contained in the jar file, such as 'XmlReport' or 'HtmlReport', or the template name can be the path to a
      -  222   -
            * template file.
      +
               }
      +  222  0
           }
       223   -
            *
      +
       
       224   -
            * @param templateName the name of the template to load.
      -  225   -
            * @param outputStream the OutputStream to write the report to.
      -  226   -
            * @throws IOException is thrown when the template file does not exist.
      -  227   -
            * @throws Exception is thrown when an exception occurs.
      -  228   -
            */
      -  229   -
           protected void generateReport(String templateName, OutputStream outputStream) throws IOException, Exception {
      -  230  0
               InputStream input = null;
      -  231  0
               String templatePath = null;
      -  232  0
               final File f = new File(templateName);
      -  233  0
               if (f.exists() && f.isFile()) {
      -  234   -
                   try {
      -  235  0
                       templatePath = templateName;
      -  236  0
                       input = new FileInputStream(f);
      -  237  0
                   } catch (FileNotFoundException ex) {
      -  238  0
                       LOGGER.error("Unable to generate the report, the report template file could not be found.");
      -  239  0
                       LOGGER.debug("", ex);
      -  240  0
                   }
      -  241   -
               } else {
      -  242  0
                   templatePath = "templates/" + templateName + ".vsl";
      -  243  0
                   input = this.getClass().getClassLoader().getResourceAsStream(templatePath);
      -  244   -
               }
      -  245  0
               if (input == null) {
      -  246  0
                   throw new IOException("Template file doesn't exist");
      -  247   -
               }
      -  248   -
       
      -  249  0
               final InputStreamReader reader = new InputStreamReader(input, "UTF-8");
      -  250  0
               OutputStreamWriter writer = null;
      -  251   -
       
      -  252   -
               try {
      -  253  0
                   writer = new OutputStreamWriter(outputStream, "UTF-8");
      -  254   -
       
      -  255  0
                   if (!engine.evaluate(context, writer, templatePath, reader)) {
      -  256  0
                       throw new Exception("Failed to convert the template into html.");
      -  257   -
                   }
      -  258  0
                   writer.flush();
      -  259   -
               } finally {
      -  260  0
                   if (writer != null) {
      -  261   -
                       try {
      -  262  0
                           writer.close();
      -  263  0
                       } catch (IOException ex) {
      -  264  0
                           LOGGER.trace("", ex);
      -  265  0
                       }
      -  266   -
                   }
      -  267  0
                   if (outputStream != null) {
      -  268   -
                       try {
      -  269  0
                           outputStream.close();
      -  270  0
                       } catch (IOException ex) {
      -  271  0
                           LOGGER.trace("", ex);
      -  272  0
                       }
      -  273   -
                   }
      -  274   -
                   try {
      -  275  0
                       reader.close();
      -  276  0
                   } catch (IOException ex) {
      -  277  0
                       LOGGER.trace("", ex);
      -  278  0
                   }
      -  279  0
               }
      -  280  0
           }
      -  281   -
       
      -  282  
           /**
      -  283   -
            * Generates a report from a given Velocity Template. The template name provided can be the name of a template
      -  284   -
            * contained in the jar file, such as 'XmlReport' or 'HtmlReport', or the template name can be the path to a
      -  285   +  225   +
            * Generates a report from a given Velocity Template. The template name
      +  226   +
            * provided can be the name of a template contained in the jar file, such as
      +  227   +
            * 'XmlReport' or 'HtmlReport', or the template name can be the path to a
      +  228  
            * template file.
      -  286   +  229  
            *
      -  287   -
            * @param templateName the name of the template to load.
      -  288   -
            * @param outFileName the filename and path to write the report to.
      -  289   -
            * @throws IOException is thrown when the template file does not exist.
      -  290   -
            * @throws Exception is thrown when an exception occurs.
      -  291   +  230   +
            * @param templateName the name of the template to load
      +  231   +
            * @param outputStream the OutputStream to write the report to
      +  232   +
            * @throws ReportException is thrown when an exception occurs
      +  233  
            */
      -  292   -
           protected void generateReport(String templateName, String outFileName) throws Exception {
      -  293  0
               File outFile = new File(outFileName);
      -  294  0
               if (outFile.getParentFile() == null) {
      -  295  0
                   outFile = new File(".", outFileName);
      -  296   +  234   +
           protected void generateReport(String templateName, OutputStream outputStream) throws ReportException {
      +  235  0
               InputStream input = null;
      +  236  0
               String templatePath = null;
      +  237  0
               final File f = new File(templateName);
      +  238  0
               if (f.exists() && f.isFile()) {
      +  239   +
                   try {
      +  240  0
                       templatePath = templateName;
      +  241  0
                       input = new FileInputStream(f);
      +  242  0
                   } catch (FileNotFoundException ex) {
      +  243  0
                       throw new ReportException("Unable to locate template file: " + templateName, ex);
      +  244  0
                   }
      +  245   +
               } else {
      +  246  0
                   templatePath = "templates/" + templateName + ".vsl";
      +  247  0
                   input = this.getClass().getClassLoader().getResourceAsStream(templatePath);
      +  248  
               }
      -  297  0
               if (!outFile.getParentFile().exists()) {
      -  298  0
                   final boolean created = outFile.getParentFile().mkdirs();
      -  299  0
                   if (!created) {
      -  300  0
                       throw new Exception("Unable to create directory '" + outFile.getParentFile().getAbsolutePath() + "'.");
      -  301   -
                   }
      -  302   +  249  0
               if (input == null) {
      +  250  0
                   throw new ReportException("Template file doesn't exist: " + templatePath);
      +  251  
               }
      -  303   +  252  
       
      -  304  0
               OutputStream outputSteam = null;
      -  305   +  253  0
               InputStreamReader reader = null;
      +  254  0
               OutputStreamWriter writer = null;
      +  255   +
       
      +  256  
               try {
      -  306  0
                   outputSteam = new FileOutputStream(outFile);
      -  307  0
                   generateReport(templateName, outputSteam);
      -  308   -
               } finally {
      -  309  0
                   if (outputSteam != null) {
      -  310   -
                       try {
      -  311  0
                           outputSteam.close();
      -  312  0
                       } catch (IOException ex) {
      -  313  0
                           LOGGER.trace("ignore", ex);
      -  314  0
                       }
      -  315   +  257  0
                   reader = new InputStreamReader(input, "UTF-8");
      +  258  0
                   writer = new OutputStreamWriter(outputStream, "UTF-8");
      +  259  0
                   if (!velocityEngine.evaluate(context, writer, templatePath, reader)) {
      +  260  0
                       throw new ReportException("Failed to convert the template into html.");
      +  261  
                   }
      -  316   +  262  0
                   writer.flush();
      +  263  0
               } catch (UnsupportedEncodingException ex) {
      +  264  0
                   throw new ReportException("Unable to generate the report using UTF-8", ex);
      +  265  0
               } catch (IOException ex) {
      +  266  0
                   throw new ReportException("Unable to write the report", ex);
      +  267   +
               } finally {
      +  268  0
                   if (writer != null) {
      +  269   +
                       try {
      +  270  0
                           writer.close();
      +  271  0
                       } catch (IOException ex) {
      +  272  0
                           LOGGER.trace("", ex);
      +  273  0
                       }
      +  274   +
                   }
      +  275  0
                   if (outputStream != null) {
      +  276   +
                       try {
      +  277  0
                           outputStream.close();
      +  278  0
                       } catch (IOException ex) {
      +  279  0
                           LOGGER.trace("", ex);
      +  280  0
                       }
      +  281   +
                   }
      +  282  0
                   if (reader != null) {
      +  283   +
                       try {
      +  284  0
                           reader.close();
      +  285  0
                       } catch (IOException ex) {
      +  286  0
                           LOGGER.trace("", ex);
      +  287  0
                       }
      +  288   +
                   }
      +  289  
               }
      -  317  0
           }
      -  318   +  290  0
           }
      +  291   +
       
      +  292   +
           /**
      +  293   +
            * Generates a report from a given Velocity Template. The template name
      +  294   +
            * provided can be the name of a template contained in the jar file, such as
      +  295   +
            * 'XmlReport' or 'HtmlReport', or the template name can be the path to a
      +  296   +
            * template file.
      +  297   +
            *
      +  298   +
            * @param templateName the name of the template to load
      +  299   +
            * @param outFileName the filename and path to write the report to
      +  300   +
            * @throws ReportException is thrown when the report cannot be generated
      +  301   +
            */
      +  302   +
           protected void generateReport(String templateName, String outFileName) throws ReportException {
      +  303  0
               File outFile = new File(outFileName);
      +  304  0
               if (outFile.getParentFile() == null) {
      +  305  0
                   outFile = new File(".", outFileName);
      +  306   +
               }
      +  307  0
               if (!outFile.getParentFile().exists()) {
      +  308  0
                   final boolean created = outFile.getParentFile().mkdirs();
      +  309  0
                   if (!created) {
      +  310  0
                       throw new ReportException("Unable to create directory '" + outFile.getParentFile().getAbsolutePath() + "'.");
      +  311   +
                   }
      +  312   +
               }
      +  313   +
       
      +  314  0
               OutputStream outputSteam = null;
      +  315   +
               try {
      +  316  0
                   outputSteam = new FileOutputStream(outFile);
      +  317  0
                   generateReport(templateName, outputSteam);
      +  318  0
               } catch (FileNotFoundException ex) {
      +  319  0
                   throw new ReportException("Unable to write to file: " + outFile, ex);
      +  320   +
               } finally {
      +  321  0
                   if (outputSteam != null) {
      +  322   +
                       try {
      +  323  0
                           outputSteam.close();
      +  324  0
                       } catch (IOException ex) {
      +  325  0
                           LOGGER.trace("ignore", ex);
      +  326  0
                       }
      +  327   +
                   }
      +  328   +
               }
      +  329  0
           }
      +  330  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.reporting.VelocityLoggerRedirect.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.reporting.VelocityLoggerRedirect.html index ce1edeaed..4c0b43ca7 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.reporting.VelocityLoggerRedirect.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.reporting.VelocityLoggerRedirect.html @@ -235,6 +235,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.DBUtils.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.DBUtils.html index 8cecb0d61..251297ff4 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.DBUtils.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.DBUtils.html @@ -89,7 +89,7 @@
            * The logger.
       36  
            */
      -  37  2
           private static final Logger LOGGER = LoggerFactory.getLogger(DBUtils.class);
      +  37  1
           private static final Logger LOGGER = LoggerFactory.getLogger(DBUtils.class);
       38  
       
       39   @@ -151,16 +151,16 @@
            */
       74  
           public static void closeStatement(Statement statement) {
      -  75  98
               if (statement != null) {
      +  75  49
               if (statement != null) {
       76  
                   try {
      -  77  98
                       statement.close();
      +  77  49
                       statement.close();
       78  0
                   } catch (SQLException ex) {
       79  0
                       LOGGER.trace(statement.toString(), ex);
      -  80  98
                   }
      +  80  49
                   }
       81  
               }
      -  82  98
           }
      +  82  49
           }
       83  
       
       84   @@ -175,20 +175,20 @@
            */
       89  
           public static void closeResultSet(ResultSet rs) {
      -  90  98
               if (rs != null) {
      +  90  49
               if (rs != null) {
       91  
                   try {
      -  92  98
                       rs.close();
      +  92  49
                       rs.close();
       93  0
                   } catch (SQLException ex) {
       94  0
                       LOGGER.trace(rs.toString(), ex);
      -  95  98
                   }
      +  95  49
                   }
       96  
               }
      -  97  98
           }
      +  97  49
           }
       98  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.DateUtil.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.DateUtil.html index 2077721e4..a9752d1b6 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.DateUtil.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.DateUtil.html @@ -101,14 +101,14 @@
           public static boolean withinDateRange(long date, long compareTo, int dayRange) {
       43  
               // ms = dayRange x 24 hours/day x 60 min/hour x 60 sec/min x 1000 ms/sec
      -  44  18
               final long msRange = dayRange * 24L * 60L * 60L * 1000L;
      -  45  18
               return (compareTo - date) < msRange;
      +  44  9
               final long msRange = dayRange * 24L * 60L * 60L * 1000L;
      +  45  9
               return (compareTo - date) < msRange;
       46  
           }
       47  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.DependencyVersion.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.DependencyVersion.html index 2930e159e..5b280f1ff 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.DependencyVersion.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.DependencyVersion.html @@ -95,7 +95,7 @@
        * @author Jeremy Long
       39  
        */
      -  40  28
       public class DependencyVersion implements Iterable<String>, Comparable<DependencyVersion> {
      +  40  14
       public class DependencyVersion implements Iterable<String>, Comparable<DependencyVersion> {
       41  
       
       42   @@ -104,8 +104,8 @@
            * Constructor for a empty DependencyVersion.
       44  
            */
      -  45  8
           public DependencyVersion() {
      -  46  8
           }
      +  45  4
           public DependencyVersion() {
      +  46  4
           }
       47  
       
       48   @@ -122,9 +122,9 @@
            * @param version the well formatted version number to parse
       54  
            */
      -  55  2076
           public DependencyVersion(String version) {
      -  56  2076
               parseVersion(version);
      -  57  2076
           }
      +  55  1038
           public DependencyVersion(String version) {
      +  56  1038
               parseVersion(version);
      +  57  1038
           }
       58  
       
       59   @@ -141,21 +141,21 @@
            */
       65  
           public final void parseVersion(String version) {
      -  66  2080
               versionParts = new ArrayList<String>();
      -  67  2080
               if (version != null) {
      -  68  2080
                   final Pattern rx = Pattern.compile("(\\d+[a-z]{1,3}$|[a-z]+\\d+|\\d+|(release|beta|alpha)$)");
      -  69  2080
                   final Matcher matcher = rx.matcher(version.toLowerCase());
      -  70  8650
                   while (matcher.find()) {
      -  71  6570
                       versionParts.add(matcher.group());
      +  66  1040
               versionParts = new ArrayList<String>();
      +  67  1040
               if (version != null) {
      +  68  1040
                   final Pattern rx = Pattern.compile("(\\d+[a-z]{1,3}$|[a-z]+\\d+|\\d+|(release|beta|alpha)$)");
      +  69  1040
                   final Matcher matcher = rx.matcher(version.toLowerCase());
      +  70  4325
                   while (matcher.find()) {
      +  71  3285
                       versionParts.add(matcher.group());
       72  
                   }
      -  73  2080
                   if (versionParts.isEmpty()) {
      -  74  12
                       versionParts.add(version);
      +  73  1040
                   if (versionParts.isEmpty()) {
      +  74  6
                       versionParts.add(version);
       75  
                   }
       76  
               }
      -  77  2080
           }
      +  77  1040
           }
       78  
           /**
       79   @@ -178,7 +178,7 @@
            */
       88  
           public List<String> getVersionParts() {
      -  89  3630
               return versionParts;
      +  89  1815
               return versionParts;
       90  
           }
       91   @@ -195,8 +195,8 @@
            */
       97  
           public void setVersionParts(List<String> versionParts) {
      -  98  6
               this.versionParts = versionParts;
      -  99  6
           }
      +  98  3
               this.versionParts = versionParts;
      +  99  3
           }
       100  
       
       101   @@ -213,7 +213,7 @@
           @Override
       107  
           public Iterator<String> iterator() {
      -  108  2
               return versionParts.iterator();
      +  108  1
               return versionParts.iterator();
       109  
           }
       110   @@ -232,7 +232,7 @@
           @Override
       117  
           public String toString() {
      -  118  636
               return StringUtils.join(versionParts, '.');
      +  118  318
               return StringUtils.join(versionParts, '.');
       119  
           }
       120   @@ -253,29 +253,29 @@
           @Override
       128  
           public boolean equals(Object obj) {
      -  129  1332
               if (obj == null) {
      +  129  666
               if (obj == null) {
       130  0
                   return false;
       131  
               }
      -  132  1332
               if (getClass() != obj.getClass()) {
      +  132  666
               if (getClass() != obj.getClass()) {
       133  0
                   return false;
       134  
               }
      -  135  1332
               final DependencyVersion other = (DependencyVersion) obj;
      -  136  1332
               final int max = (this.versionParts.size() < other.versionParts.size())
      -  137  254
                       ? this.versionParts.size() : other.versionParts.size();
      +  135  666
               final DependencyVersion other = (DependencyVersion) obj;
      +  136  666
               final int max = (this.versionParts.size() < other.versionParts.size())
      +  137  127
                       ? this.versionParts.size() : other.versionParts.size();
       138  
               //TODO steal better version of code from compareTo
      -  139  2900
               for (int i = 0; i < max; i++) {
      -  140  2666
                   final String thisPart = this.versionParts.get(i);
      -  141  2666
                   final String otherPart = other.versionParts.get(i);
      -  142  2666
                   if (!thisPart.equals(otherPart)) {
      -  143  1098
                       return false;
      +  139  1450
               for (int i = 0; i < max; i++) {
      +  140  1333
                   final String thisPart = this.versionParts.get(i);
      +  141  1333
                   final String otherPart = other.versionParts.get(i);
      +  142  1333
                   if (!thisPart.equals(otherPart)) {
      +  143  549
                       return false;
       144  
                   }
       145  
               }
      -  146  234
               if (this.versionParts.size() > max) {
      +  146  117
               if (this.versionParts.size() > max) {
       147  0
                   for (int i = max; i < this.versionParts.size(); i++) {
       148  0
                       if (!"0".equals(this.versionParts.get(i))) {
       149  0
                           return false;
      @@ -287,10 +287,10 @@
               }
       153  
       
      -  154  234
               if (other.versionParts.size() > max) {
      -  155  186
                   for (int i = max; i < other.versionParts.size(); i++) {
      -  156  186
                       if (!"0".equals(other.versionParts.get(i))) {
      -  157  186
                           return false;
      +  154  117
               if (other.versionParts.size() > max) {
      +  155  93
                   for (int i = max; i < other.versionParts.size(); i++) {
      +  156  93
                       if (!"0".equals(other.versionParts.get(i))) {
      +  157  93
                           return false;
       158  
                       }
       159   @@ -309,7 +309,7 @@
                *  }
       166  
                */
      -  167  48
               return true;
      +  167  24
               return true;
       168  
           }
       169   @@ -328,9 +328,9 @@
           @Override
       176  
           public int hashCode() {
      -  177  2
               int hash = 5;
      -  178  2
               hash = 71 * hash + (this.versionParts != null ? this.versionParts.hashCode() : 0);
      -  179  2
               return hash;
      +  177  1
               int hash = 5;
      +  178  1
               hash = 71 * hash + (this.versionParts != null ? this.versionParts.hashCode() : 0);
      +  179  1
               return hash;
       180  
           }
       181   @@ -351,40 +351,40 @@
            */
       189  
           public boolean matchesAtLeastThreeLevels(DependencyVersion version) {
      -  190  848
               if (version == null) {
      +  190  424
               if (version == null) {
       191  0
                   return false;
       192  
               }
      -  193  848
               if (Math.abs(this.versionParts.size() - version.versionParts.size()) >= 3) {
      -  194  2
                   return false;
      +  193  424
               if (Math.abs(this.versionParts.size() - version.versionParts.size()) >= 3) {
      +  194  1
                   return false;
       195  
               }
       196  
       
      -  197  846
               final int max = (this.versionParts.size() < version.versionParts.size())
      -  198  176
                       ? this.versionParts.size() : version.versionParts.size();
      +  197  423
               final int max = (this.versionParts.size() < version.versionParts.size())
      +  198  88
                       ? this.versionParts.size() : version.versionParts.size();
       199  
       
      -  200  846
               boolean ret = true;
      -  201  1744
               for (int i = 0; i < max; i++) {
      -  202  1612
                   final String thisVersion = this.versionParts.get(i);
      -  203  1612
                   final String otherVersion = version.getVersionParts().get(i);
      -  204  1612
                   if (i >= 3) {
      -  205  4
                       if (thisVersion.compareToIgnoreCase(otherVersion) >= 0) {
      -  206  2
                           ret = false;
      -  207  2
                           break;
      +  200  423
               boolean ret = true;
      +  201  872
               for (int i = 0; i < max; i++) {
      +  202  806
                   final String thisVersion = this.versionParts.get(i);
      +  203  806
                   final String otherVersion = version.getVersionParts().get(i);
      +  204  806
                   if (i >= 3) {
      +  205  2
                       if (thisVersion.compareToIgnoreCase(otherVersion) >= 0) {
      +  206  1
                           ret = false;
      +  207  1
                           break;
       208  
                       }
      -  209  1608
                   } else if (!thisVersion.equals(otherVersion)) {
      -  210  712
                       ret = false;
      -  211  712
                       break;
      +  209  804
                   } else if (!thisVersion.equals(otherVersion)) {
      +  210  356
                       ret = false;
      +  211  356
                       break;
       212  
                   }
       213  
               }
       214  
       
      -  215  846
               return ret;
      +  215  423
               return ret;
       216  
           }
       217   @@ -393,50 +393,50 @@
           @Override
       219  
           public int compareTo(DependencyVersion version) {
      -  220  64
               if (version == null) {
      +  220  32
               if (version == null) {
       221  0
                   return 1;
       222  
               }
      -  223  64
               final List<String> left = this.getVersionParts();
      -  224  64
               final List<String> right = version.getVersionParts();
      -  225  64
               final int max = left.size() < right.size() ? left.size() : right.size();
      +  223  32
               final List<String> left = this.getVersionParts();
      +  224  32
               final List<String> right = version.getVersionParts();
      +  225  32
               final int max = left.size() < right.size() ? left.size() : right.size();
       226  
       
      -  227  164
               for (int i = 0; i < max; i++) {
      -  228  140
                   final String lStr = left.get(i);
      -  229  140
                   final String rStr = right.get(i);
      -  230  140
                   if (lStr.equals(rStr)) {
      -  231  100
                       continue;
      +  227  82
               for (int i = 0; i < max; i++) {
      +  228  70
                   final String lStr = left.get(i);
      +  229  70
                   final String rStr = right.get(i);
      +  230  70
                   if (lStr.equals(rStr)) {
      +  231  50
                       continue;
       232  
                   }
       233  
                   try {
      -  234  40
                       final int l = Integer.parseInt(lStr);
      -  235  26
                       final int r = Integer.parseInt(rStr);
      -  236  24
                       if (l < r) {
      -  237  18
                           return -1;
      -  238  6
                       } else if (l > r) {
      -  239  6
                           return 1;
      +  234  20
                       final int l = Integer.parseInt(lStr);
      +  235  13
                       final int r = Integer.parseInt(rStr);
      +  236  12
                       if (l < r) {
      +  237  9
                           return -1;
      +  238  3
                       } else if (l > r) {
      +  239  3
                           return 1;
       240  
                       }
      -  241  16
                   } catch (NumberFormatException ex) {
      -  242  16
                       final int comp = left.get(i).compareTo(right.get(i));
      -  243  16
                       if (comp < 0) {
      -  244  12
                           return -1;
      -  245  4
                       } else if (comp > 0) {
      -  246  4
                           return 1;
      +  241  8
                   } catch (NumberFormatException ex) {
      +  242  8
                       final int comp = left.get(i).compareTo(right.get(i));
      +  243  8
                       if (comp < 0) {
      +  244  6
                           return -1;
      +  245  2
                       } else if (comp > 0) {
      +  246  2
                           return 1;
       247  
                       }
       248  0
                   }
       249  
               }
      -  250  24
               if (left.size() < right.size()) {
      -  251  6
                   return -1;
      -  252  18
               } else if (left.size() > right.size()) {
      -  253  6
                   return 1;
      +  250  12
               if (left.size() < right.size()) {
      +  251  3
                   return -1;
      +  252  9
               } else if (left.size() > right.size()) {
      +  253  3
                   return 1;
       254  
               } else {
      -  255  12
                   return 0;
      +  255  6
                   return 0;
       256  
               }
       257   @@ -445,6 +445,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.DependencyVersionUtil.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.DependencyVersionUtil.html index aad346724..a1cf4e230 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.DependencyVersionUtil.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.DependencyVersionUtil.html @@ -87,7 +87,7 @@
            * Regular expression to extract version numbers from file names.
       35  
            */
      -  36  2
           private static final Pattern RX_VERSION = Pattern.compile("\\d+(\\.\\d{1,6})+(\\.?([_-](release|beta|alpha|\\d+)|[a-zA-Z_-]{1,3}\\d{0,8}))?");
      +  36  1
           private static final Pattern RX_VERSION = Pattern.compile("\\d+(\\.\\d{1,6})+(\\.?([_-](release|beta|alpha|\\d+)|[a-zA-Z_-]{1,3}\\d{0,8}))?");
       37  
           /**
       38   @@ -96,7 +96,7 @@
            * are missing a version number using the previous regex.
       40  
            */
      -  41  2
           private static final Pattern RX_SINGLE_VERSION = Pattern.compile("\\d+(\\.?([_-](release|beta|alpha)|[a-zA-Z_-]{1,3}\\d{1,8}))?");
      +  41  1
           private static final Pattern RX_SINGLE_VERSION = Pattern.compile("\\d+(\\.?([_-](release|beta|alpha)|[a-zA-Z_-]{1,3}\\d{1,8}))?");
       42  
       
       43   @@ -133,60 +133,60 @@
            */
       60  
           public static DependencyVersion parseVersion(String text) {
      -  61  1978
               if (text == null) {
      +  61  989
               if (text == null) {
       62  0
                   return null;
       63  
               }
       64  
               //'-' is a special case used within the CVE entries, just include it as the version.
      -  65  1978
               if ("-".equals(text)) {
      -  66  2
                   final DependencyVersion dv = new DependencyVersion();
      -  67  2
                   final List<String> list = new ArrayList<String>();
      -  68  2
                   list.add(text);
      -  69  2
                   dv.setVersionParts(list);
      -  70  2
                   return dv;
      +  65  989
               if ("-".equals(text)) {
      +  66  1
                   final DependencyVersion dv = new DependencyVersion();
      +  67  1
                   final List<String> list = new ArrayList<String>();
      +  68  1
                   list.add(text);
      +  69  1
                   dv.setVersionParts(list);
      +  70  1
                   return dv;
       71  
               }
      -  72  1976
               String version = null;
      -  73  1976
               Matcher matcher = RX_VERSION.matcher(text);
      -  74  1976
               if (matcher.find()) {
      -  75  1966
                   version = matcher.group();
      +  72  988
               String version = null;
      +  73  988
               Matcher matcher = RX_VERSION.matcher(text);
      +  74  988
               if (matcher.find()) {
      +  75  983
                   version = matcher.group();
       76  
               }
       77  
               //throw away the results if there are two things that look like version numbers
      -  78  1976
               if (matcher.find()) {
      -  79  4
                   return null;
      +  78  988
               if (matcher.find()) {
      +  79  2
                   return null;
       80  
               }
      -  81  1972
               if (version == null) {
      -  82  10
                   matcher = RX_SINGLE_VERSION.matcher(text);
      -  83  10
                   if (matcher.find()) {
      -  84  4
                       version = matcher.group();
      +  81  986
               if (version == null) {
      +  82  5
                   matcher = RX_SINGLE_VERSION.matcher(text);
      +  83  5
                   if (matcher.find()) {
      +  84  2
                       version = matcher.group();
       85  
                   } else {
      -  86  6
                       return null;
      +  86  3
                       return null;
       87  
                   }
       88  
                   //throw away the results if there are two things that look like version numbers
      -  89  4
                   if (matcher.find()) {
      -  90  2
                       return null;
      +  89  2
                   if (matcher.find()) {
      +  90  1
                       return null;
       91  
                   }
       92  
               }
      -  93  1964
               if (version != null && version.endsWith("-py2") && version.length() > 4) {
      -  94  2
                   version = version.substring(0, version.length() - 4);
      +  93  982
               if (version != null && version.endsWith("-py2") && version.length() > 4) {
      +  94  1
                   version = version.substring(0, version.length() - 4);
       95  
               }
      -  96  1964
               return new DependencyVersion(version);
      +  96  982
               return new DependencyVersion(version);
       97  
           }
       98  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.ExtractionUtil.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.ExtractionUtil.html index d8a47f75d..e03552ae6 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.ExtractionUtil.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.ExtractionUtil.html @@ -117,7 +117,7 @@
            * The logger.
       50  
            */
      -  51  2
           private static final Logger LOGGER = LoggerFactory.getLogger(ExtractionUtil.class);
      +  51  1
           private static final Logger LOGGER = LoggerFactory.getLogger(ExtractionUtil.class);
       52  
       
       53   @@ -256,23 +256,23 @@
           public static void extractFilesUsingFilter(File archive, File destination,
       142  
                   FilenameFilter filter) throws ExtractionException {
      -  143  6
               if (archive == null || destination == null) {
      +  143  3
               if (archive == null || destination == null) {
       144  0
                   return;
       145  
               }
       146  
       
      -  147  6
               FileInputStream fis = null;
      +  147  3
               FileInputStream fis = null;
       148  
               try {
      -  149  6
                   fis = new FileInputStream(archive);
      +  149  3
                   fis = new FileInputStream(archive);
       150  0
               } catch (FileNotFoundException ex) {
       151  0
                   LOGGER.debug("", ex);
       152  0
                   throw new ExtractionException("Archive file was not found.", ex);
      -  153  6
               }
      +  153  3
               }
       154  
               try {
      -  155  6
                   extractArchive(new ZipArchiveInputStream(new BufferedInputStream(
      +  155  3
                   extractArchive(new ZipArchiveInputStream(new BufferedInputStream(
       156  
                           fis)), destination, filter);
       157  0
               } catch (ArchiveExtractionException ex) {
      @@ -281,12 +281,12 @@  160  
               } finally {
       161  0
                   try {
      -  162  6
                       fis.close();
      +  162  3
                       fis.close();
       163  0
                   } catch (IOException ex) {
       164  0
                       LOGGER.debug("", ex);
      -  165  6
                   }
      +  165  3
                   }
       166  0
               }
      -  167  6
           }
      +  167  3
           }
       168  
       
       169   @@ -315,8 +315,8 @@
               ArchiveEntry entry;
       181  
               try {
      -  182  72
                   while ((entry = input.getNextEntry()) != null) {
      -  183  66
                       if (entry.isDirectory()) {
      +  182  36
                   while ((entry = input.getNextEntry()) != null) {
      +  183  33
                       if (entry.isDirectory()) {
       184  0
                           final File dir = new File(destination, entry.getName());
       185  0
                           if (!dir.exists() && !dir.mkdirs()) {
       186  0
                               final String msg = String.format(
      @@ -327,7 +327,7 @@  190  
                           }
       191  0
                       } else {
      -  192  66
                           extractFile(input, destination, filter, entry);
      +  192  33
                           extractFile(input, destination, filter, entry);
       193  
                       }
       194   @@ -338,9 +338,9 @@  198  0
                   throw new ArchiveExtractionException(ex);
       199  
               } finally {
      -  200  6
                   closeStream(input);
      -  201  6
               }
      -  202  6
           }
      +  200  3
                   closeStream(input);
      +  201  3
               }
      +  202  3
           }
       203  
       
       204   @@ -365,16 +365,16 @@
           private static void extractFile(ArchiveInputStream input, File destination,
       214  
                   FilenameFilter filter, ArchiveEntry entry) throws ExtractionException {
      -  215  66
               final File file = new File(destination, entry.getName());
      -  216  66
               if (filter.accept(file.getParentFile(), file.getName())) {
      -  217  12
                   LOGGER.debug("Extracting '{}'",
      -  218  6
                           file.getPath());
      -  219  6
                   FileOutputStream fos = null;
      +  215  33
               final File file = new File(destination, entry.getName());
      +  216  33
               if (filter.accept(file.getParentFile(), file.getName())) {
      +  217  6
                   LOGGER.debug("Extracting '{}'",
      +  218  3
                           file.getPath());
      +  219  3
                   FileOutputStream fos = null;
       220  
                   try {
      -  221  6
                       createParentFile(file);
      -  222  6
                       fos = new FileOutputStream(file);
      -  223  6
                       IOUtils.copy(input, fos);
      +  221  3
                       createParentFile(file);
      +  222  3
                       fos = new FileOutputStream(file);
      +  223  3
                       IOUtils.copy(input, fos);
       224  0
                   } catch (FileNotFoundException ex) {
       225  0
                       LOGGER.debug("", ex);
       226  0
                       final String msg = String.format("Unable to find file '%s'.",
      @@ -388,11 +388,11 @@  234  0
                       throw new ExtractionException(msg, ex);
       235  
                   } finally {
      -  236  6
                       closeStream(fos);
      -  237  6
                   }
      +  236  3
                       closeStream(fos);
      +  237  3
                   }
       238  
               }
      -  239  66
           }
      +  239  33
           }
       240  
       
       241   @@ -407,16 +407,16 @@
            */
       246  
           private static void closeStream(Closeable stream) {
      -  247  12
               if (stream != null) {
      +  247  6
               if (stream != null) {
       248  
                   try {
      -  249  12
                       stream.close();
      +  249  6
                       stream.close();
       250  0
                   } catch (IOException ex) {
       251  0
                       LOGGER.trace("", ex);
      -  252  12
                   }
      +  252  6
                   }
       253  
               }
      -  254  12
           }
      +  254  6
           }
       255  
       
       256   @@ -435,8 +435,8 @@
           private static void createParentFile(final File file)
       263  
                   throws ExtractionException {
      -  264  6
               final File parent = file.getParentFile();
      -  265  6
               if (!parent.isDirectory() && !parent.mkdirs()) {
      +  264  3
               final File parent = file.getParentFile();
      +  265  3
               if (!parent.isDirectory() && !parent.mkdirs()) {
       266  0
                   final String msg = String.format(
       267  
                           "Unable to build directory '%s'.",
      @@ -444,11 +444,11 @@  269  0
                   throw new ExtractionException(msg);
       270  
               }
      -  271  6
           }
      +  271  3
           }
       272  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.FileFilterBuilder.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.FileFilterBuilder.html index 94774f548..14b49c2f2 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.FileFilterBuilder.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.FileFilterBuilder.html @@ -107,7 +107,7 @@
        * @see <a href="https://en.wikipedia.org/wiki/Builder_pattern">Builder pattern</a>
       45  
        */
      -  46  40
       public class FileFilterBuilder {
      +  46  20
       public class FileFilterBuilder {
       47  
       
       48   @@ -116,21 +116,21 @@
            * A set of filenames to filter.
       50  
            */
      -  51  40
           private final Set<String> filenames = new HashSet<String>();
      +  51  20
           private final Set<String> filenames = new HashSet<String>();
       52  
           /**
       53  
            * A set of extensions to filter.
       54  
            */
      -  55  40
           private final Set<String> extensions = new HashSet<String>();
      +  55  20
           private final Set<String> extensions = new HashSet<String>();
       56  
           /**
       57  
            * An array list of file filters.
       58  
            */
      -  59  40
           private final List<IOFileFilter> fileFilters = new ArrayList<IOFileFilter>();
      +  59  20
           private final List<IOFileFilter> fileFilters = new ArrayList<IOFileFilter>();
       60  
       
       61   @@ -145,7 +145,7 @@
            */
       66  
           public static FileFilterBuilder newInstance() {
      -  67  40
               return new FileFilterBuilder();
      +  67  20
               return new FileFilterBuilder();
       68  
           }
       69   @@ -164,8 +164,8 @@
            */
       76  
           public FileFilterBuilder addFilenames(String... names) {
      -  77  12
               filenames.addAll(Arrays.asList(names));
      -  78  12
               return this;
      +  77  6
               filenames.addAll(Arrays.asList(names));
      +  78  6
               return this;
       79  
           }
       80   @@ -184,7 +184,7 @@
            */
       87  
           public FileFilterBuilder addExtensions(String... extensions) {
      -  88  30
               return this.addExtensions(Arrays.asList(extensions));
      +  88  15
               return this.addExtensions(Arrays.asList(extensions));
       89  
           }
       90   @@ -203,12 +203,12 @@
            */
       97  
           public FileFilterBuilder addExtensions(Iterable<String> extensions) {
      -  98  32
               for (String extension : extensions) {
      +  98  16
               for (String extension : extensions) {
       99  
                   // Ultimately, SuffixFileFilter will be used, and the "." needs to be explicit.
      -  100  78
                   this.extensions.add(extension.startsWith(".") ? extension : "." + extension);
      -  101  78
               }
      -  102  32
               return this;
      +  100  39
                   this.extensions.add(extension.startsWith(".") ? extension : "." + extension);
      +  101  39
               }
      +  102  16
               return this;
       103  
           }
       104   @@ -227,8 +227,8 @@
            */
       111  
           public FileFilterBuilder addFileFilters(IOFileFilter... filters) {
      -  112  2
               fileFilters.addAll(Arrays.asList(filters));
      -  113  2
               return this;
      +  112  1
               fileFilters.addAll(Arrays.asList(filters));
      +  113  1
               return this;
       114  
           }
       115   @@ -247,29 +247,29 @@
            */
       122  
           public FileFilter build() {
      -  123  40
               if (filenames.isEmpty() && extensions.isEmpty() && fileFilters.isEmpty()) {
      +  123  20
               if (filenames.isEmpty() && extensions.isEmpty() && fileFilters.isEmpty()) {
       124  0
                   throw new IllegalStateException("May only be invoked after at least one add... method has been invoked.");
       125  
               }
      -  126  40
               final OrFileFilter filter = new OrFileFilter();
      -  127  40
               if (!filenames.isEmpty()) {
      -  128  12
                   filter.addFileFilter(new NameFileFilter(new ArrayList<String>(filenames)));
      +  126  20
               final OrFileFilter filter = new OrFileFilter();
      +  127  20
               if (!filenames.isEmpty()) {
      +  128  6
                   filter.addFileFilter(new NameFileFilter(new ArrayList<String>(filenames)));
       129  
               }
      -  130  40
               if (!extensions.isEmpty()) {
      -  131  32
                   filter.addFileFilter(new SuffixFileFilter(new ArrayList<String>(extensions), IOCase.INSENSITIVE));
      +  130  20
               if (!extensions.isEmpty()) {
      +  131  16
                   filter.addFileFilter(new SuffixFileFilter(new ArrayList<String>(extensions), IOCase.INSENSITIVE));
       132  
               }
      -  133  40
               for (IOFileFilter iof : fileFilters) {
      -  134  4
                   filter.addFileFilter(iof);
      -  135  4
               }
      -  136  40
               return filter;
      +  133  20
               for (IOFileFilter iof : fileFilters) {
      +  134  2
                   filter.addFileFilter(iof);
      +  135  2
               }
      +  136  20
               return filter;
       137  
           }
       138  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.Filter.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.Filter.html index 0f42d2ae1..7babda0a3 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.Filter.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.Filter.html @@ -47,7 +47,7 @@
        * https://plus.google.com/115403795880834599019/?rel=author
       14  
        */
      -  15  12
       public abstract class Filter<T> {
      +  15  6
       public abstract class Filter<T> {
       16  
       
       17   @@ -56,21 +56,21 @@
       
       19  
           public Iterator<T> filter(Iterator<T> iterator) {
      -  20  246
               return new FilterIterator(iterator);
      +  20  121
               return new FilterIterator(iterator);
       21  
           }
       22  
       
       23  
           public Iterable<T> filter(final Iterable<T> iterable) {
      -  24  246
               return new Iterable<T>() {
      +  24  121
               return new Iterable<T>() {
       25  
       
       26  
                   @Override
       27  
                   public Iterator<T> iterator() {
      -  28  246
                       return filter(iterable.iterator());
      +  28  121
                       return filter(iterable.iterator());
       29  
                   }
       30   @@ -79,7 +79,7 @@
           }
       32  
       
      -  33  246
           private class FilterIterator implements Iterator<T> {
      +  33  121
           private class FilterIterator implements Iterator<T> {
       34  
       
       35   @@ -88,17 +88,17 @@
               private T next;
       37  
       
      -  38  246
               private FilterIterator(Iterator<T> iterator) {
      -  39  246
                   this.iterator = iterator;
      -  40  246
                   toNext();
      -  41  246
               }
      +  38  121
               private FilterIterator(Iterator<T> iterator) {
      +  39  121
                   this.iterator = iterator;
      +  40  121
                   toNext();
      +  41  121
               }
       42  
       
       43  
               @Override
       44  
               public boolean hasNext() {
      -  45  914
                   return next != null;
      +  45  444
                   return next != null;
       46  
               }
       47   @@ -107,13 +107,13 @@
               @Override
       49  
               public T next() {
      -  50  716
                   if (next == null) {
      +  50  350
                   if (next == null) {
       51  0
                       throw new NoSuchElementException();
       52  
                   }
      -  53  716
                   final T returnValue = next;
      -  54  716
                   toNext();
      -  55  716
                   return returnValue;
      +  53  350
                   final T returnValue = next;
      +  54  350
                   toNext();
      +  55  350
                   return returnValue;
       56  
               }
       57   @@ -129,22 +129,22 @@
       
       63  
               private void toNext() {
      -  64  962
                   next = null;
      -  65  1766
                   while (iterator.hasNext()) {
      -  66  1564
                       final T item = iterator.next();
      -  67  1564
                       if (item != null && passes(item)) {
      -  68  760
                           next = item;
      -  69  760
                           break;
      +  64  471
                   next = null;
      +  65  904
                   while (iterator.hasNext()) {
      +  66  808
                       final T item = iterator.next();
      +  67  808
                       if (item != null && passes(item)) {
      +  68  375
                           next = item;
      +  69  375
                           break;
       70  
                       }
      -  71  804
                   }
      -  72  962
               }
      +  71  433
                   }
      +  72  471
               }
       73  
           }
       74  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.Pair.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.Pair.html index 995685a2b..dfe044e1f 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.Pair.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.Pair.html @@ -97,17 +97,17 @@
            * @param right the value for the right pair
       41  
            */
      -  42  103668
           public Pair(L left, R right) {
      -  43  103668
               this.left = left;
      -  44  103668
               this.right = right;
      -  45  103668
           }
      +  42  52138
           public Pair(L left, R right) {
      +  43  52138
               this.left = left;
      +  44  52138
               this.right = right;
      +  45  52138
           }
       46  
           /**
       47  
            * The left element of the pair.
       48  
            */
      -  49  103668
           private L left = null;
      +  49  52138
           private L left = null;
       50  
       
       51   @@ -122,7 +122,7 @@
            */
       56  
           public L getLeft() {
      -  57  103668
               return left;
      +  57  52138
               return left;
       58  
           }
       59   @@ -147,7 +147,7 @@
            * The right element of the pair.
       70  
            */
      -  71  103668
           private R right = null;
      +  71  52138
           private R right = null;
       72  
       
       73   @@ -162,7 +162,7 @@
            */
       78  
           public R getRight() {
      -  79  103668
               return right;
      +  79  52138
               return right;
       80  
           }
       81   @@ -197,10 +197,10 @@
           @Override
       97  
           public int hashCode() {
      -  98  103668
               int hash = 3;
      -  99  103668
               hash = 53 * hash + (this.left != null ? this.left.hashCode() : 0);
      -  100  103668
               hash = 53 * hash + (this.right != null ? this.right.hashCode() : 0);
      -  101  103668
               return hash;
      +  98  52138
               int hash = 3;
      +  99  52138
               hash = 53 * hash + (this.left != null ? this.left.hashCode() : 0);
      +  100  52138
               hash = 53 * hash + (this.right != null ? this.right.hashCode() : 0);
      +  101  52138
               return hash;
       102  
           }
       103   @@ -245,6 +245,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.UrlStringUtils.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.UrlStringUtils.html index 6a1a58943..c272b0567 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.UrlStringUtils.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.UrlStringUtils.html @@ -99,14 +99,14 @@
            * A regular expression to test if a string contains a URL.
       42  
            */
      -  43  2
           private static final Pattern CONTAINS_URL_TEST = Pattern.compile("^.*(ht|f)tps?://.*$", Pattern.MULTILINE | Pattern.CASE_INSENSITIVE);
      +  43  1
           private static final Pattern CONTAINS_URL_TEST = Pattern.compile("^.*(ht|f)tps?://.*$", Pattern.MULTILINE | Pattern.CASE_INSENSITIVE);
       44  
           /**
       45  
            * A regular expression to test if a string is a URL.
       46  
            */
      -  47  2
           private static final Pattern IS_URL_TEST = Pattern.compile("^(ht|f)tps?://.*", Pattern.CASE_INSENSITIVE);
      +  47  1
           private static final Pattern IS_URL_TEST = Pattern.compile("^(ht|f)tps?://.*", Pattern.CASE_INSENSITIVE);
       48  
       
       49   @@ -125,7 +125,7 @@
            */
       56  
           public static boolean containsUrl(String text) {
      -  57  40463
               return CONTAINS_URL_TEST.matcher(text).matches();
      +  57  210313
               return CONTAINS_URL_TEST.matcher(text).matches();
       58  
           }
       59   @@ -144,7 +144,7 @@
            */
       66  
           public static boolean isUrl(String text) {
      -  67  66
               return IS_URL_TEST.matcher(text).matches();
      +  67  33
               return IS_URL_TEST.matcher(text).matches();
       68  
           }
       69   @@ -153,8 +153,8 @@
            * A listing of domain parts that should not be used as evidence. Yes, this is an incomplete list.
       71  
            */
      -  72  4
           private static final Set<String> IGNORE_LIST = new HashSet<String>(
      -  73  2
                   Arrays.asList("www", "com", "org", "gov", "info", "name", "net", "pro", "tel", "mobi", "xxx"));
      +  72  2
           private static final Set<String> IGNORE_LIST = new HashSet<String>(
      +  73  1
                   Arrays.asList("www", "com", "org", "gov", "info", "name", "net", "pro", "tel", "mobi", "xxx"));
       74  
       
       75   @@ -187,40 +187,40 @@
            */
       89  
           public static List<String> extractImportantUrlData(String text) throws MalformedURLException {
      -  90  50
               final List<String> importantParts = new ArrayList<String>();
      -  91  50
               final URL url = new URL(text);
      -  92  50
               final String[] domain = url.getHost().split("\\.");
      +  90  25
               final List<String> importantParts = new ArrayList<String>();
      +  91  25
               final URL url = new URL(text);
      +  92  25
               final String[] domain = url.getHost().split("\\.");
       93  
               //add the domain except www and the tld.
      -  94  144
               for (int i = 0; i < domain.length - 1; i++) {
      -  95  94
                   final String sub = domain[i];
      -  96  94
                   if (!IGNORE_LIST.contains(sub.toLowerCase())) {
      -  97  88
                       importantParts.add(sub);
      +  94  72
               for (int i = 0; i < domain.length - 1; i++) {
      +  95  47
                   final String sub = domain[i];
      +  96  47
                   if (!IGNORE_LIST.contains(sub.toLowerCase())) {
      +  97  44
                       importantParts.add(sub);
       98  
                   }
       99  
               }
      -  100  50
               final String document = url.getPath();
      -  101  50
               final String[] pathParts = document.split("[\\//]");
      -  102  88
               for (int i = 0; i < pathParts.length - 2; i++) {
      -  103  38
                   if (!pathParts[i].isEmpty()) {
      +  100  25
               final String document = url.getPath();
      +  101  25
               final String[] pathParts = document.split("[\\//]");
      +  102  44
               for (int i = 0; i < pathParts.length - 2; i++) {
      +  103  19
                   if (!pathParts[i].isEmpty()) {
       104  0
                       importantParts.add(pathParts[i]);
       105  
                   }
       106  
               }
      -  107  50
               if (pathParts.length > 0 && !pathParts[pathParts.length - 1].isEmpty()) {
      -  108  44
                   final String fileNameNoExt = pathParts[pathParts.length - 1].replaceAll("\\..*{0,5}$", "");
      -  109  44
                   importantParts.add(fileNameNoExt);
      +  107  25
               if (pathParts.length > 0 && !pathParts[pathParts.length - 1].isEmpty()) {
      +  108  22
                   final String fileNameNoExt = pathParts[pathParts.length - 1].replaceAll("\\..*{0,5}$", "");
      +  109  22
                   importantParts.add(fileNameNoExt);
       110  
               }
      -  111  50
               return importantParts;
      +  111  25
               return importantParts;
       112  
           }
       113  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.hints.HintErrorHandler.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.hints.HintErrorHandler.html new file mode 100644 index 000000000..2df1e8b72 --- /dev/null +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.hints.HintErrorHandler.html @@ -0,0 +1,201 @@ + + + + +Coverage Report + + + + +
      Coverage Report - org.owasp.dependencycheck.xml.hints.HintErrorHandler
      +
       
      + + + + +
      Classes in this File Line Coverage Branch Coverage Complexity
      HintErrorHandler
      11%
      2/17
      0%
      0/8
      2.5
      +
       
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
       1  
       /*
       2  
        * This file is part of dependency-check-core.
       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) 2016 Jeremy Long. All Rights Reserved.
       17  
        */
       18  
       package org.owasp.dependencycheck.xml.hints;
       19  
       
       20  
       import org.slf4j.Logger;
       21  
       import org.slf4j.LoggerFactory;
       22  
       import org.xml.sax.ErrorHandler;
       23  
       import org.xml.sax.SAXException;
       24  
       import org.xml.sax.SAXParseException;
       25  
       
       26  
       /**
       27  
        * An XML parsing error handler.
       28  
        *
       29  
        * @author Jeremy Long
       30  
        */
       31  5
       public class HintErrorHandler implements ErrorHandler {
       32  
       
       33  
           /**
       34  
            * The logger.
       35  
            */
       36  1
           private static final Logger LOGGER = LoggerFactory.getLogger(HintErrorHandler.class);
       37  
       
       38  
           /**
       39  
            * Builds a prettier exception message.
       40  
            *
       41  
            * @param ex the SAXParseException
       42  
            * @return an easier to read exception message
       43  
            */
       44  
           private String getPrettyParseExceptionInfo(SAXParseException ex) {
       45  
       
       46  0
               final StringBuilder sb = new StringBuilder();
       47  
       
       48  0
               if (ex.getSystemId() != null) {
       49  0
                   sb.append("systemId=").append(ex.getSystemId()).append(", ");
       50  
               }
       51  0
               if (ex.getPublicId() != null) {
       52  0
                   sb.append("publicId=").append(ex.getPublicId()).append(", ");
       53  
               }
       54  0
               if (ex.getLineNumber() > 0) {
       55  0
                   sb.append("Line=").append(ex.getLineNumber());
       56  
               }
       57  0
               if (ex.getColumnNumber() > 0) {
       58  0
                   sb.append(", Column=").append(ex.getColumnNumber());
       59  
               }
       60  0
               sb.append(": ").append(ex.getMessage());
       61  
       
       62  0
               return sb.toString();
       63  
           }
       64  
       
       65  
           /**
       66  
            * Logs warnings.
       67  
            *
       68  
            * @param ex the warning to log
       69  
            * @throws SAXException is never thrown
       70  
            */
       71  
           @Override
       72  
           public void warning(SAXParseException ex) throws SAXException {
       73  0
               LOGGER.debug("", ex);
       74  0
           }
       75  
       
       76  
           /**
       77  
            * Handles errors.
       78  
            *
       79  
            * @param ex the error to handle
       80  
            * @throws SAXException is always thrown
       81  
            */
       82  
           @Override
       83  
           public void error(SAXParseException ex) throws SAXException {
       84  0
               throw new SAXException(getPrettyParseExceptionInfo(ex));
       85  
           }
       86  
       
       87  
           /**
       88  
            * Handles fatal exceptions.
       89  
            *
       90  
            * @param ex a fatal exception
       91  
            * @throws SAXException is always
       92  
            */
       93  
           @Override
       94  
           public void fatalError(SAXParseException ex) throws SAXException {
       95  0
               throw new SAXException(getPrettyParseExceptionInfo(ex));
       96  
           }
       97  
       }
      + + + + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.hints.HintHandler.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.hints.HintHandler.html new file mode 100644 index 000000000..a0f5c9296 --- /dev/null +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.hints.HintHandler.html @@ -0,0 +1,407 @@ + + + + +Coverage Report + + + + +
      Coverage Report - org.owasp.dependencycheck.xml.hints.HintHandler
      +
       
      + + + + +
      Classes in this File Line Coverage Branch Coverage Complexity
      HintHandler
      100%
      51/51
      85%
      24/28
      4.5
      +
       
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
       1  
       /*
       2  
        * This file is part of dependency-check-core.
       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) 2016 Jeremy Long. All Rights Reserved.
       17  
        */
       18  
       package org.owasp.dependencycheck.xml.hints;
       19  
       
       20  
       import java.util.ArrayList;
       21  
       import java.util.List;
       22  
       import org.owasp.dependencycheck.dependency.Confidence;
       23  
       import org.owasp.dependencycheck.xml.suppression.PropertyType;
       24  
       import org.xml.sax.Attributes;
       25  
       import org.xml.sax.SAXException;
       26  
       import org.xml.sax.helpers.DefaultHandler;
       27  
       
       28  
       /**
       29  
        * A handler to load hint rules.
       30  
        *
       31  
        * @author Jeremy Long
       32  
        */
       33  5
       public class HintHandler extends DefaultHandler {
       34  
       
       35  
           //<editor-fold defaultstate="collapsed" desc="Element and attribute names">
       36  
           /**
       37  
            * Element name.
       38  
            */
       39  
           private static final String HINT = "hint";
       40  
           /**
       41  
            * Element name.
       42  
            */
       43  
           private static final String GIVEN = "given";
       44  
           /**
       45  
            * Element name.
       46  
            */
       47  
           private static final String ADD = "add";
       48  
           /**
       49  
            * Element name.
       50  
            */
       51  
           private static final String EVIDENCE = "evidence";
       52  
           /**
       53  
            * Element name.
       54  
            */
       55  
           private static final String FILE_NAME = "fileName";
       56  
           /**
       57  
            * Element name.
       58  
            */
       59  
           private static final String VENDOR_DUPLICATING_RULE = "vendorDuplicatingHint";
       60  
           /**
       61  
            * Attribute name.
       62  
            */
       63  
           private static final String DUPLICATE = "duplicate";
       64  
           /**
       65  
            * Attribute name.
       66  
            */
       67  
           private static final String VENDOR = "vendor";
       68  
           /**
       69  
            * Attribute name.
       70  
            */
       71  
           private static final String CONFIDENCE = "confidence";
       72  
           /**
       73  
            * Attribute name.
       74  
            */
       75  
           private static final String VALUE = "value";
       76  
           /**
       77  
            * Attribute name.
       78  
            */
       79  
           private static final String NAME = "name";
       80  
           /**
       81  
            * Attribute name.
       82  
            */
       83  
           private static final String SOURCE = "source";
       84  
           /**
       85  
            * Attribute name.
       86  
            */
       87  
           private static final String TYPE = "type";
       88  
           /**
       89  
            * Attribute name.
       90  
            */
       91  
           private static final String CASE_SENSITIVE = "caseSensitive";
       92  
           /**
       93  
            * Attribute name.
       94  
            */
       95  
           private static final String REGEX = "regex";
       96  
           /**
       97  
            * Attribute name.
       98  
            */
       99  
           private static final String CONTAINS = "contains";
       100  
           //</editor-fold>
       101  
       
       102  
           /**
       103  
            * The list of hint rules.
       104  
            */
       105  5
           private final List<HintRule> hintRules = new ArrayList<HintRule>();
       106  
       
       107  
           /**
       108  
            * Returns the list of hint rules.
       109  
            *
       110  
            * @return the value of hintRules
       111  
            */
       112  
           public List<HintRule> getHintRules() {
       113  5
               return hintRules;
       114  
           }
       115  
       
       116  
           /**
       117  
            * The list of vendor duplicating hint rules.
       118  
            */
       119  5
           private final List<VendorDuplicatingHintRule> vendorDuplicatingHintRules = new ArrayList<VendorDuplicatingHintRule>();
       120  
       
       121  
           /**
       122  
            * Returns the list of vendor duplicating hint rules.
       123  
            *
       124  
            * @return the list of vendor duplicating hint rules
       125  
            */
       126  
           public List<VendorDuplicatingHintRule> getVendorDuplicatingHintRules() {
       127  4
               return vendorDuplicatingHintRules;
       128  
           }
       129  
       
       130  
           /**
       131  
            * The current rule being read.
       132  
            */
       133  
           private HintRule rule;
       134  
           /**
       135  
            * The current state of the parent node (to differentiate between 'add' and
       136  
            * 'given').
       137  
            */
       138  5
           private boolean inAddNode = false;
       139  
       
       140  
           /**
       141  
            * Handles the start element event.
       142  
            *
       143  
            * @param uri the uri of the element being processed
       144  
            * @param localName the local name of the element being processed
       145  
            * @param qName the qName of the element being processed
       146  
            * @param attr the attributes of the element being processed
       147  
            * @throws SAXException thrown if there is an exception processing
       148  
            */
       149  
           @Override
       150  
           public void startElement(String uri, String localName, String qName, Attributes attr) throws SAXException {
       151  155
               if (HINT.equals(qName)) {
       152  20
                   rule = new HintRule();
       153  135
               } else if (ADD.equals(qName)) {
       154  20
                   inAddNode = true;
       155  115
               } else if (GIVEN.equals(qName)) {
       156  20
                   inAddNode = false;
       157  95
               } else if (EVIDENCE.equals(qName)) {
       158  72
                   final String hintType = attr.getValue(TYPE);
       159  72
                   if (VENDOR.equals(hintType)) {
       160  39
                       if (inAddNode) {
       161  64
                           rule.addAddVendor(attr.getValue(SOURCE),
       162  32
                                   attr.getValue(NAME),
       163  32
                                   attr.getValue(VALUE),
       164  32
                                   Confidence.valueOf(attr.getValue(CONFIDENCE)));
       165  
                       } else {
       166  14
                           rule.addGivenVendor(attr.getValue(SOURCE),
       167  7
                                   attr.getValue(NAME),
       168  7
                                   attr.getValue(VALUE),
       169  7
                                   Confidence.valueOf(attr.getValue(CONFIDENCE)));
       170  
                       }
       171  33
                   } else if (inAddNode) {
       172  28
                       rule.addAddProduct(attr.getValue(SOURCE),
       173  14
                               attr.getValue(NAME),
       174  14
                               attr.getValue(VALUE),
       175  14
                               Confidence.valueOf(attr.getValue(CONFIDENCE)));
       176  
                   } else {
       177  38
                       rule.addGivenProduct(attr.getValue(SOURCE),
       178  19
                               attr.getValue(NAME),
       179  19
                               attr.getValue(VALUE),
       180  19
                               Confidence.valueOf(attr.getValue(CONFIDENCE)));
       181  
                   }
       182  72
               } else if (FILE_NAME.equals(qName)) {
       183  8
                   final PropertyType pt = new PropertyType();
       184  8
                   pt.setValue(attr.getValue(CONTAINS));
       185  8
                   if (attr.getLength() > 0) {
       186  8
                       final String regex = attr.getValue(REGEX);
       187  8
                       if (regex != null) {
       188  8
                           pt.setRegex(Boolean.parseBoolean(regex));
       189  
                       }
       190  8
                       final String caseSensitive = attr.getValue(CASE_SENSITIVE);
       191  8
                       if (caseSensitive != null) {
       192  8
                           pt.setCaseSensitive(Boolean.parseBoolean(caseSensitive));
       193  
                       }
       194  
                   }
       195  8
                   rule.addFilename(pt);
       196  8
               } else if (VENDOR_DUPLICATING_RULE.equals(qName)) {
       197  10
                   vendorDuplicatingHintRules.add(new VendorDuplicatingHintRule(attr.getValue(VALUE), attr.getValue(DUPLICATE)));
       198  
               }
       199  155
           }
       200  
       
       201  
           /**
       202  
            * Handles the end element event.
       203  
            *
       204  
            * @param uri the element's URI
       205  
            * @param localName the local name
       206  
            * @param qName the qualified name
       207  
            * @throws SAXException thrown if there is an exception processing the
       208  
            * element
       209  
            */
       210  
           @Override
       211  
           public void endElement(String uri, String localName, String qName) throws SAXException {
       212  155
               if (HINT.equals(qName) && rule != null) {
       213  20
                   hintRules.add(rule);
       214  20
                   rule = null;
       215  
               }
       216  155
           }
       217  
       }
      + + + + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.hints.HintParseException.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.hints.HintParseException.html new file mode 100644 index 000000000..2ade01c6c --- /dev/null +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.hints.HintParseException.html @@ -0,0 +1,152 @@ + + + + +Coverage Report + + + + +
      Coverage Report - org.owasp.dependencycheck.xml.hints.HintParseException
      +
       
      + + + + +
      Classes in this File Line Coverage Branch Coverage Complexity
      HintParseException
      0%
      0/8
      N/A
      1
      +
       
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
       1  
       /*
       2  
        * This file is part of dependency-check-core.
       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) 2016 Jeremy Long. All Rights Reserved.
       17  
        */
       18  
       package org.owasp.dependencycheck.xml.hints;
       19  
       
       20  
       import java.io.IOException;
       21  
       
       22  
       /**
       23  
        * An exception used when parsing a suppression rule file fails.
       24  
        *
       25  
        * @author Jeremy Long
       26  
        */
       27  
       public class HintParseException extends IOException {
       28  
       
       29  
           /**
       30  
            * The serial version UID for serialization.
       31  
            */
       32  
           private static final long serialVersionUID = 1L;
       33  
       
       34  
           /**
       35  
            * Creates a new SuppressionParseException.
       36  
            */
       37  
           public HintParseException() {
       38  0
               super();
       39  0
           }
       40  
       
       41  
           /**
       42  
            * Creates a new SuppressionParseException.
       43  
            *
       44  
            * @param msg a message for the exception.
       45  
            */
       46  
           public HintParseException(String msg) {
       47  0
               super(msg);
       48  0
           }
       49  
       
       50  
           /**
       51  
            * Creates a new SuppressionParseException.
       52  
            *
       53  
            * @param ex the cause of the parse exception
       54  
            */
       55  
           public HintParseException(Throwable ex) {
       56  0
               super(ex);
       57  0
           }
       58  
       
       59  
           /**
       60  
            * Creates a new SuppressionParseException.
       61  
            *
       62  
            * @param msg a message for the exception.
       63  
            * @param ex the cause of the parse exception
       64  
            */
       65  
           public HintParseException(String msg, Throwable ex) {
       66  0
               super(msg, ex);
       67  0
           }
       68  
       }
      + + + + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.hints.HintParser.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.hints.HintParser.html new file mode 100644 index 000000000..5acce48ad --- /dev/null +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.hints.HintParser.html @@ -0,0 +1,269 @@ + + + + +Coverage Report + + + + +
      Coverage Report - org.owasp.dependencycheck.xml.hints.HintParser
      +
       
      + + + + +
      Classes in this File Line Coverage Branch Coverage Complexity
      HintParser
      55%
      26/47
      25%
      1/4
      10
      +
       
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
       1  
       /*
       2  
        * This file is part of dependency-check-core.
       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) 2016 Jeremy Long. All Rights Reserved.
       17  
        */
       18  
       package org.owasp.dependencycheck.xml.hints;
       19  
       
       20  
       import java.io.File;
       21  
       import java.io.FileInputStream;
       22  
       import java.io.FileNotFoundException;
       23  
       import java.io.IOException;
       24  
       import java.io.InputStream;
       25  
       import java.io.InputStreamReader;
       26  
       import java.io.Reader;
       27  
       import javax.xml.parsers.ParserConfigurationException;
       28  
       import javax.xml.parsers.SAXParser;
       29  
       import javax.xml.parsers.SAXParserFactory;
       30  
       
       31  
       import org.slf4j.Logger;
       32  
       import org.slf4j.LoggerFactory;
       33  
       import org.xml.sax.InputSource;
       34  
       import org.xml.sax.SAXException;
       35  
       import org.xml.sax.XMLReader;
       36  
       
       37  
       /**
       38  
        * A simple validating parser for XML Hint Rules.
       39  
        *
       40  
        * @author Jeremy Long
       41  
        */
       42  4
       public class HintParser {
       43  
       
       44  
           /**
       45  
            * The logger.
       46  
            */
       47  1
           private static final Logger LOGGER = LoggerFactory.getLogger(HintParser.class);
       48  
           /**
       49  
            * JAXP Schema Language. Source:
       50  
            * http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html
       51  
            */
       52  
           public static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
       53  
           /**
       54  
            * W3C XML Schema. Source:
       55  
            * http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html
       56  
            */
       57  
           public static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";
       58  
           /**
       59  
            * JAXP Schema Source. Source:
       60  
            * http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html
       61  
            */
       62  
           public static final String JAXP_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource";
       63  
       
       64  
           /**
       65  
            * The schema for the hint XML files.
       66  
            */
       67  
           private static final String HINT_SCHEMA = "schema/dependency-hint.1.0.xsd";
       68  
       
       69  
           /**
       70  
            * Parses the given XML file and returns a list of the hints contained.
       71  
            *
       72  
            * @param file an XML file containing hints
       73  
            * @return a list of hint rules
       74  
            * @throws HintParseException thrown if the XML file cannot be parsed
       75  
            */
       76  
           public Hints parseHints(File file) throws HintParseException {
       77  1
               FileInputStream fis = null;
       78  
               try {
       79  1
                   fis = new FileInputStream(file);
       80  2
                   return parseHints(fis);
       81  0
               } catch (IOException ex) {
       82  0
                   LOGGER.debug("", ex);
       83  0
                   throw new HintParseException(ex);
       84  0
               } catch (SAXException ex) {
       85  0
                   throw new HintParseException(ex);
       86  
               } finally {
       87  1
                   if (fis != null) {
       88  
                       try {
       89  1
                           fis.close();
       90  0
                       } catch (IOException ex) {
       91  0
                           LOGGER.debug("Unable to close stream", ex);
       92  1
                       }
       93  
                   }
       94  
               }
       95  
           }
       96  
       
       97  
           /**
       98  
            * Parses the given XML stream and returns a list of the hint rules
       99  
            * contained.
       100  
            *
       101  
            * @param inputStream an InputStream containing hint rules
       102  
            * @return a list of hint rules
       103  
            * @throws HintParseException thrown if the XML cannot be parsed
       104  
            * @throws SAXException thrown if the XML cannot be parsed
       105  
            */
       106  
           public Hints parseHints(InputStream inputStream) throws HintParseException, SAXException {
       107  
               try {
       108  4
                   final InputStream schemaStream = this.getClass().getClassLoader().getResourceAsStream(HINT_SCHEMA);
       109  4
                   final HintHandler handler = new HintHandler();
       110  4
                   final SAXParserFactory factory = SAXParserFactory.newInstance();
       111  4
                   factory.setNamespaceAware(true);
       112  4
                   factory.setValidating(true);
       113  4
                   final SAXParser saxParser = factory.newSAXParser();
       114  4
                   saxParser.setProperty(HintParser.JAXP_SCHEMA_LANGUAGE, HintParser.W3C_XML_SCHEMA);
       115  4
                   saxParser.setProperty(HintParser.JAXP_SCHEMA_SOURCE, new InputSource(schemaStream));
       116  4
                   final XMLReader xmlReader = saxParser.getXMLReader();
       117  4
                   xmlReader.setErrorHandler(new HintErrorHandler());
       118  4
                   xmlReader.setContentHandler(handler);
       119  
       
       120  4
                   final Reader reader = new InputStreamReader(inputStream, "UTF-8");
       121  4
                   final InputSource in = new InputSource(reader);
       122  
       
       123  4
                   xmlReader.parse(in);
       124  4
                   final Hints hints = new Hints();
       125  4
                   hints.setHintRules(handler.getHintRules());
       126  4
                   hints.setVendorDuplicatingHintRules(handler.getVendorDuplicatingHintRules());
       127  4
                   return hints;
       128  0
               } catch (ParserConfigurationException ex) {
       129  0
                   LOGGER.debug("", ex);
       130  0
                   throw new HintParseException(ex);
       131  0
               } catch (SAXException ex) {
       132  0
                   if (ex.getMessage().contains("Cannot find the declaration of element 'hints'.")) {
       133  0
                       throw ex;
       134  
                   } else {
       135  0
                       LOGGER.debug("", ex);
       136  0
                       throw new HintParseException(ex);
       137  
                   }
       138  0
               } catch (FileNotFoundException ex) {
       139  0
                   LOGGER.debug("", ex);
       140  0
                   throw new HintParseException(ex);
       141  0
               } catch (IOException ex) {
       142  0
                   LOGGER.debug("", ex);
       143  0
                   throw new HintParseException(ex);
       144  
               }
       145  
           }
       146  
       }
      + + + + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.hints.HintRule.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.hints.HintRule.html new file mode 100644 index 000000000..5479c7cad --- /dev/null +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.hints.HintRule.html @@ -0,0 +1,323 @@ + + + + +Coverage Report + + + + +
      Coverage Report - org.owasp.dependencycheck.xml.hints.HintRule
      +
       
      + + + + +
      Classes in this File Line Coverage Branch Coverage Complexity
      HintRule
      100%
      21/21
      N/A
      1
      +
       
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
       1  
       /*
       2  
        * This file is part of dependency-check-core.
       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) 2016 Jeremy Long. All Rights Reserved.
       17  
        */
       18  
       package org.owasp.dependencycheck.xml.hints;
       19  
       
       20  
       import java.util.ArrayList;
       21  
       import java.util.List;
       22  
       import org.owasp.dependencycheck.dependency.Confidence;
       23  
       import org.owasp.dependencycheck.dependency.Evidence;
       24  
       import org.owasp.dependencycheck.xml.suppression.PropertyType;
       25  
       
       26  
       /**
       27  
        * A collection of product and vendor evidence to match; if any evidence is
       28  
        * matched the addVendor and addProduct evidence should be added to the
       29  
        * dependency.
       30  
        *
       31  
        * @author Jeremy Long
       32  
        */
       33  20
       public class HintRule {
       34  
       
       35  
           /**
       36  
            * The list of file names to match.
       37  
            */
       38  20
           private final List<PropertyType> filenames = new ArrayList<PropertyType>();
       39  
       
       40  
           /**
       41  
            * Adds the filename evidence to the collection.
       42  
            *
       43  
            * @param filename the filename to add
       44  
            */
       45  
           public void addFilename(PropertyType filename) {
       46  8
               this.filenames.add(filename);
       47  8
           }
       48  
       
       49  
           /**
       50  
            * Returns the list of filename evidence to match against.
       51  
            *
       52  
            * @return the list of filename evidence to match against
       53  
            */
       54  
           public List<PropertyType> getFilenames() {
       55  33
               return filenames;
       56  
           }
       57  
           /**
       58  
            * The list of product evidence that is being matched.
       59  
            */
       60  20
           private final List<Evidence> givenProduct = new ArrayList<Evidence>();
       61  
       
       62  
           /**
       63  
            * Adds a given product to the list of evidence to matched.
       64  
            *
       65  
            * @param source the source of the evidence
       66  
            * @param name the name of the evidence
       67  
            * @param value the value of the evidence
       68  
            * @param confidence the confidence of the evidence
       69  
            */
       70  
           public void addGivenProduct(String source, String name, String value, Confidence confidence) {
       71  19
               givenProduct.add(new Evidence(source, name, value, confidence));
       72  19
           }
       73  
       
       74  
           /**
       75  
            * Get the value of givenProduct.
       76  
            *
       77  
            * @return the value of givenProduct
       78  
            */
       79  
           public List<Evidence> getGivenProduct() {
       80  29
               return givenProduct;
       81  
           }
       82  
       
       83  
           /**
       84  
            * The list of vendor evidence that is being matched.
       85  
            */
       86  20
           private final List<Evidence> givenVendor = new ArrayList<Evidence>();
       87  
       
       88  
           /**
       89  
            * Adds a given vendors to the list of evidence to matched.
       90  
            *
       91  
            * @param source the source of the evidence
       92  
            * @param name the name of the evidence
       93  
            * @param value the value of the evidence
       94  
            * @param confidence the confidence of the evidence
       95  
            */
       96  
           public void addGivenVendor(String source, String name, String value, Confidence confidence) {
       97  7
               givenVendor.add(new Evidence(source, name, value, confidence));
       98  7
           }
       99  
       
       100  
           /**
       101  
            * Get the value of givenVendor.
       102  
            *
       103  
            * @return the value of givenVendor
       104  
            */
       105  
           public List<Evidence> getGivenVendor() {
       106  29
               return givenVendor;
       107  
           }
       108  
       
       109  
           /**
       110  
            * The list of product evidence to add.
       111  
            */
       112  20
           private final List<Evidence> addProduct = new ArrayList<Evidence>();
       113  
       
       114  
           /**
       115  
            * Adds a given product to the list of evidence to add when matched.
       116  
            *
       117  
            * @param source the source of the evidence
       118  
            * @param name the name of the evidence
       119  
            * @param value the value of the evidence
       120  
            * @param confidence the confidence of the evidence
       121  
            */
       122  
           public void addAddProduct(String source, String name, String value, Confidence confidence) {
       123  14
               addProduct.add(new Evidence(source, name, value, confidence));
       124  14
           }
       125  
       
       126  
           /**
       127  
            * Get the value of addProduct.
       128  
            *
       129  
            * @return the value of addProduct
       130  
            */
       131  
           public List<Evidence> getAddProduct() {
       132  3
               return addProduct;
       133  
           }
       134  
       
       135  
           /**
       136  
            * The list of vendor hints to add.
       137  
            */
       138  20
           private final List<Evidence> addVendor = new ArrayList<Evidence>();
       139  
       
       140  
           /**
       141  
            * Adds a given vendor to the list of evidence to add when matched.
       142  
            *
       143  
            * @param source the source of the evidence
       144  
            * @param name the name of the evidence
       145  
            * @param value the value of the evidence
       146  
            * @param confidence the confidence of the evidence
       147  
            */
       148  
           public void addAddVendor(String source, String name, String value, Confidence confidence) {
       149  32
               addVendor.add(new Evidence(source, name, value, confidence));
       150  32
           }
       151  
       
       152  
           /**
       153  
            * Get the value of addVendor.
       154  
            *
       155  
            * @return the value of addVendor
       156  
            */
       157  
           public List<Evidence> getAddVendor() {
       158  3
               return addVendor;
       159  
           }
       160  
       }
      + + + + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.hints.Hints.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.hints.Hints.html new file mode 100644 index 000000000..9b3d1a386 --- /dev/null +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.hints.Hints.html @@ -0,0 +1,165 @@ + + + + +Coverage Report + + + + +
      Coverage Report - org.owasp.dependencycheck.xml.hints.Hints
      +
       
      + + + + +
      Classes in this File Line Coverage Branch Coverage Complexity
      Hints
      100%
      7/7
      N/A
      1
      +
       
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
       1  
       /*
       2  
        * This file is part of dependency-check-core.
       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) 2016 Jeremy Long. All Rights Reserved.
       17  
        */
       18  
       package org.owasp.dependencycheck.xml.hints;
       19  
       
       20  
       import java.util.List;
       21  
       
       22  
       /**
       23  
        * A collection of hint rules.
       24  
        *
       25  
        * @author Jeremy Long
       26  
        */
       27  4
       public class Hints {
       28  
       
       29  
           /**
       30  
            * The list of hint rules.
       31  
            */
       32  
           private List<HintRule> hintRules;
       33  
       
       34  
           /**
       35  
            * Get the value of hintRules.
       36  
            *
       37  
            * @return the value of hintRules
       38  
            */
       39  
           public List<HintRule> getHintRules() {
       40  18
               return hintRules;
       41  
           }
       42  
       
       43  
           /**
       44  
            * Set the value of hintRules.
       45  
            *
       46  
            * @param hintRules new value of hintRules
       47  
            */
       48  
           public void setHintRules(List<HintRule> hintRules) {
       49  4
               this.hintRules = hintRules;
       50  4
           }
       51  
       
       52  
           /**
       53  
            * The duplicating hint rules.
       54  
            */
       55  
           private List<VendorDuplicatingHintRule> vendorDuplicatingHintRules;
       56  
       
       57  
           /**
       58  
            * Get the value of vendorDuplicatingHintRules.
       59  
            *
       60  
            * @return the value of vendorDuplicatingHintRules
       61  
            */
       62  
           public List<VendorDuplicatingHintRule> getVendorDuplicatingHintRules() {
       63  29
               return vendorDuplicatingHintRules;
       64  
           }
       65  
       
       66  
           /**
       67  
            * Set the value of vendorDuplicatingHintRules.
       68  
            *
       69  
            * @param vendorDuplicatingHintRules new value of vendorDuplicatingHintRules
       70  
            */
       71  
           public void setVendorDuplicatingHintRules(List<VendorDuplicatingHintRule> vendorDuplicatingHintRules) {
       72  4
               this.vendorDuplicatingHintRules = vendorDuplicatingHintRules;
       73  4
           }
       74  
       }
      + + + + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.hints.VendorDuplicatingHintRule.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.hints.VendorDuplicatingHintRule.html new file mode 100644 index 000000000..2fa74c4fe --- /dev/null +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.hints.VendorDuplicatingHintRule.html @@ -0,0 +1,184 @@ + + + + +Coverage Report + + + + +
      Coverage Report - org.owasp.dependencycheck.xml.hints.VendorDuplicatingHintRule
      +
       
      + + + + +
      Classes in this File Line Coverage Branch Coverage Complexity
      VendorDuplicatingHintRule
      60%
      6/10
      N/A
      1
      +
       
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
       1  
       /*
       2  
        * This file is part of dependency-check-core.
       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) 2016 Jeremy Long. All Rights Reserved.
       17  
        */
       18  
       package org.owasp.dependencycheck.xml.hints;
       19  
       
       20  
       /**
       21  
        * Used to duplicate vendor evidence within a collection. The intent is if any evidence
       22  
        * is found in a collection that matches the value given the evidence will be
       23  
        * duplicated and the value replaced with the value indicated.
       24  
        *
       25  
        * @author Jeremy Long
       26  
        */
       27  
       public class VendorDuplicatingHintRule {
       28  
       
       29  
           /**
       30  
            * Constructs a new duplicating rule.
       31  
            *
       32  
            * @param value the value to duplicate the evidence if found
       33  
            * @param duplicate the value to replace within the duplicated evidence
       34  
            */
       35  10
           public VendorDuplicatingHintRule(String value, String duplicate) {
       36  10
               this.value = value;
       37  10
               this.duplicate = duplicate;
       38  10
           }
       39  
       
       40  
           /**
       41  
            * The evidence value to duplicate if found.
       42  
            */
       43  
           private String value;
       44  
       
       45  
           /**
       46  
            * Get the value of value.
       47  
            *
       48  
            * @return the value of value
       49  
            */
       50  
           public String getValue() {
       51  51
               return value;
       52  
           }
       53  
       
       54  
           /**
       55  
            * Set the value of value.
       56  
            *
       57  
            * @param value new value of value
       58  
            */
       59  
           public void setValue(String value) {
       60  0
               this.value = value;
       61  0
           }
       62  
       
       63  
           /**
       64  
            * The value to replace when duplicating the evidence.
       65  
            */
       66  
           private String duplicate;
       67  
       
       68  
           /**
       69  
            * Get the value of duplicate.
       70  
            *
       71  
            * @return the value of duplicate
       72  
            */
       73  
           public String getDuplicate() {
       74  1
               return duplicate;
       75  
           }
       76  
       
       77  
           /**
       78  
            * Set the value of duplicate.
       79  
            *
       80  
            * @param duplicate new value of duplicate
       81  
            */
       82  
           public void setDuplicate(String duplicate) {
       83  0
               this.duplicate = duplicate;
       84  0
           }
       85  
       }
      + + + + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.License.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.License.html index 272f90d1f..a1a6d0f4d 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.License.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.License.html @@ -89,12 +89,12 @@
            * @param url the license url
       37  
            */
      -  38  6
           public License(String name, String url) {
      -  39  6
               this.url = url;
      -  40  6
               this.name = name;
      +  38  3
           public License(String name, String url) {
      +  39  3
               this.url = url;
      +  40  3
               this.name = name;
       41  
       
      -  42  6
           }
      +  42  3
           }
       43  
       
       44   @@ -221,24 +221,24 @@
           @Override
       110  
           public boolean equals(Object obj) {
      -  111  2
               if (obj == null) {
      +  111  1
               if (obj == null) {
       112  0
                   return false;
       113  
               }
      -  114  2
               if (getClass() != obj.getClass()) {
      +  114  1
               if (getClass() != obj.getClass()) {
       115  0
                   return false;
       116  
               }
      -  117  2
               final License other = (License) obj;
      -  118  2
               if ((this.url == null) ? (other.url != null) : !this.url.equals(other.url)) {
      +  117  1
               final License other = (License) obj;
      +  118  1
               if ((this.url == null) ? (other.url != null) : !this.url.equals(other.url)) {
       119  0
                   return false;
       120  
               }
      -  121  2
               if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
      +  121  1
               if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
       122  0
                   return false;
       123  
               }
      -  124  2
               return true;
      +  124  1
               return true;
       125  
           }
       126   @@ -266,6 +266,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.Model.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.Model.html index 2d4052f1c..6e41b5f61 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.Model.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.Model.html @@ -80,7 +80,7 @@
        * @author jeremy
       31  
        */
      -  32  48
       public class Model {
      +  32  24
       public class Model {
       33  
       
       34   @@ -105,7 +105,7 @@
            */
       44  
           public String getName() {
      -  45  10
               return name;
      +  45  5
               return name;
       46  
           }
       47   @@ -122,8 +122,8 @@
            */
       53  
           public void setName(String name) {
      -  54  12
               this.name = name;
      -  55  12
           }
      +  54  6
               this.name = name;
      +  55  6
           }
       56  
       
       57   @@ -148,7 +148,7 @@
            */
       67  
           public String getOrganization() {
      -  68  6
               return organization;
      +  68  3
               return organization;
       69  
           }
       70   @@ -165,8 +165,8 @@
            */
       76  
           public void setOrganization(String organization) {
      -  77  4
               this.organization = organization;
      -  78  4
           }
      +  77  2
               this.organization = organization;
      +  78  2
           }
       79  
       
       80   @@ -191,7 +191,7 @@
            */
       90  
           public String getDescription() {
      -  91  6
               return description;
      +  91  3
               return description;
       92  
           }
       93   @@ -208,8 +208,8 @@
            */
       99  
           public void setDescription(String description) {
      -  100  8
               this.description = description;
      -  101  8
           }
      +  100  4
               this.description = description;
      +  101  4
           }
       102  
       
       103   @@ -234,7 +234,7 @@
            */
       113  
           public String getGroupId() {
      -  114  6
               return groupId;
      +  114  3
               return groupId;
       115  
           }
       116   @@ -251,8 +251,8 @@
            */
       122  
           public void setGroupId(String groupId) {
      -  123  10
               this.groupId = groupId;
      -  124  10
           }
      +  123  5
               this.groupId = groupId;
      +  124  5
           }
       125  
       
       126   @@ -277,7 +277,7 @@
            */
       136  
           public String getArtifactId() {
      -  137  6
               return artifactId;
      +  137  3
               return artifactId;
       138  
           }
       139   @@ -294,8 +294,8 @@
            */
       145  
           public void setArtifactId(String artifactId) {
      -  146  10
               this.artifactId = artifactId;
      -  147  10
           }
      +  146  5
               this.artifactId = artifactId;
      +  147  5
           }
       148  
       
       149   @@ -320,7 +320,7 @@
            */
       159  
           public String getVersion() {
      -  160  6
               return version;
      +  160  3
               return version;
       161  
           }
       162   @@ -337,8 +337,8 @@
            */
       168  
           public void setVersion(String version) {
      -  169  8
               this.version = version;
      -  170  8
           }
      +  169  4
               this.version = version;
      +  170  4
           }
       171  
       
       172   @@ -363,7 +363,7 @@
            */
       182  
           public String getParentGroupId() {
      -  183  6
               return parentGroupId;
      +  183  3
               return parentGroupId;
       184  
           }
       185   @@ -380,8 +380,8 @@
            */
       191  
           public void setParentGroupId(String parentGroupId) {
      -  192  6
               this.parentGroupId = parentGroupId;
      -  193  6
           }
      +  192  3
               this.parentGroupId = parentGroupId;
      +  193  3
           }
       194  
       
       195   @@ -406,7 +406,7 @@
            */
       205  
           public String getParentArtifactId() {
      -  206  6
               return parentArtifactId;
      +  206  3
               return parentArtifactId;
       207  
           }
       208   @@ -423,8 +423,8 @@
            */
       214  
           public void setParentArtifactId(String parentArtifactId) {
      -  215  6
               this.parentArtifactId = parentArtifactId;
      -  216  6
           }
      +  215  3
               this.parentArtifactId = parentArtifactId;
      +  216  3
           }
       217  
       
       218   @@ -449,7 +449,7 @@
            */
       228  
           public String getParentVersion() {
      -  229  6
               return parentVersion;
      +  229  3
               return parentVersion;
       230  
           }
       231   @@ -466,8 +466,8 @@
            */
       237  
           public void setParentVersion(String parentVersion) {
      -  238  6
               this.parentVersion = parentVersion;
      -  239  6
           }
      +  238  3
               this.parentVersion = parentVersion;
      +  239  3
           }
       240  
       
       241   @@ -476,7 +476,7 @@
            * The list of licenses.
       243  
            */
      -  244  48
           private final List<License> licenses = new ArrayList<License>();
      +  244  24
           private final List<License> licenses = new ArrayList<License>();
       245  
       
       246   @@ -491,7 +491,7 @@
            */
       251  
           public List<License> getLicenses() {
      -  252  16
               return licenses;
      +  252  8
               return licenses;
       253  
           }
       254   @@ -508,8 +508,8 @@
            */
       260  
           public void addLicense(License license) {
      -  261  4
               licenses.add(license);
      -  262  4
           }
      +  261  2
               licenses.add(license);
      +  262  2
           }
       263  
       
       264   @@ -534,7 +534,7 @@
            */
       274  
           public String getProjectURL() {
      -  275  4
               return projectURL;
      +  275  2
               return projectURL;
       276  
           }
       277   @@ -551,8 +551,8 @@
            */
       283  
           public void setProjectURL(String projectURL) {
      -  284  4
               this.projectURL = projectURL;
      -  285  4
           }
      +  284  2
               this.projectURL = projectURL;
      +  285  2
           }
       286  
       
       287   @@ -567,21 +567,21 @@
            */
       292  
           public void processProperties(Properties properties) {
      -  293  6
               this.groupId = interpolateString(this.groupId, properties);
      -  294  6
               this.artifactId = interpolateString(this.artifactId, properties);
      -  295  6
               this.version = interpolateString(this.version, properties);
      -  296  6
               this.description = interpolateString(this.description, properties);
      -  297  6
               for (License l : this.getLicenses()) {
      +  293  3
               this.groupId = interpolateString(this.groupId, properties);
      +  294  3
               this.artifactId = interpolateString(this.artifactId, properties);
      +  295  3
               this.version = interpolateString(this.version, properties);
      +  296  3
               this.description = interpolateString(this.description, properties);
      +  297  3
               for (License l : this.getLicenses()) {
       298  0
                   l.setName(interpolateString(l.getName(), properties));
       299  0
                   l.setUrl(interpolateString(l.getUrl(), properties));
       300  0
               }
      -  301  6
               this.name = interpolateString(this.name, properties);
      -  302  6
               this.projectURL = interpolateString(this.projectURL, properties);
      -  303  6
               this.organization = interpolateString(this.organization, properties);
      -  304  6
               this.parentGroupId = interpolateString(this.parentGroupId, properties);
      -  305  6
               this.parentArtifactId = interpolateString(this.parentArtifactId, properties);
      -  306  6
               this.parentVersion = interpolateString(this.parentVersion, properties);
      -  307  6
           }
      +  301  3
               this.name = interpolateString(this.name, properties);
      +  302  3
               this.projectURL = interpolateString(this.projectURL, properties);
      +  303  3
               this.organization = interpolateString(this.organization, properties);
      +  304  3
               this.parentGroupId = interpolateString(this.parentGroupId, properties);
      +  305  3
               this.parentArtifactId = interpolateString(this.parentArtifactId, properties);
      +  306  3
               this.parentVersion = interpolateString(this.parentVersion, properties);
      +  307  3
           }
       308  
       
       309   @@ -646,12 +646,12 @@
            */
       339  
           public static String interpolateString(String text, Properties properties) {
      -  340  62
               if (null == text || null == properties) {
      -  341  58
                   return text;
      +  340  31
               if (null == text || null == properties) {
      +  341  29
                   return text;
       342  
               }
      -  343  4
               final StrSubstitutor substitutor = new StrSubstitutor(new PropertyLookup(properties));
      -  344  4
               return substitutor.replace(text);
      +  343  2
               final StrSubstitutor substitutor = new StrSubstitutor(new PropertyLookup(properties));
      +  344  2
               return substitutor.replace(text);
       345  
           }
       346   @@ -688,9 +688,9 @@
                * @param props the properties to wrap.
       362  
                */
      -  363  4
               PropertyLookup(Properties props) {
      -  364  4
                   this.props = props;
      -  365  4
               }
      +  363  2
               PropertyLookup(Properties props) {
      +  364  2
                   this.props = props;
      +  365  2
               }
       366  
       
       367   @@ -709,7 +709,7 @@
               @Override
       374  
               public String lookup(String key) {
      -  375  12
                   return props.getProperty(key);
      +  375  6
                   return props.getProperty(key);
       376  
               }
       377   @@ -718,6 +718,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.PomHandler.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.PomHandler.html index 44f464d97..a9a418e77 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.PomHandler.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.PomHandler.html @@ -77,7 +77,7 @@
        * @author Jeremy Long
       30  
        */
      -  31  6
       public class PomHandler extends DefaultHandler {
      +  31  3
       public class PomHandler extends DefaultHandler {
       32  
       
       33   @@ -176,7 +176,7 @@
            * The pom model.
       80  
            */
      -  81  6
           private final Model model = new Model();
      +  81  3
           private final Model model = new Model();
       82  
       
       83   @@ -191,7 +191,7 @@
            */
       88  
           public Model getModel() {
      -  89  6
               return model;
      +  89  3
               return model;
       90  
           }
       91   @@ -200,14 +200,14 @@
            * The stack of elements processed; used to determine the parent node.
       93  
            */
      -  94  6
           private final Deque<String> stack = new ArrayDeque<String>();
      +  94  3
           private final Deque<String> stack = new ArrayDeque<String>();
       95  
           /**
       96  
            * The license object.
       97  
            */
      -  98  6
           private License license = null;
      +  98  3
           private License license = null;
       99  
       
       100   @@ -242,13 +242,13 @@
           @Override
       115  
           public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
      -  116  1378
               currentText = new StringBuilder();
      -  117  1378
               stack.push(qName);
      -  118  1378
               if (LICENSE.equals(qName)) {
      +  116  689
               currentText = new StringBuilder();
      +  117  689
               stack.push(qName);
      +  118  689
               if (LICENSE.equals(qName)) {
       119  0
                   license = new License();
       120  
               }
      -  121  1378
           }
      +  121  689
           }
       122  
       
       123   @@ -271,35 +271,35 @@
           @Override
       132  
           public void endElement(String uri, String localName, String qName) throws SAXException {
      -  133  1378
               stack.pop();
      -  134  1378
               final String parentNode = stack.peek();
      -  135  1378
               if (PROJECT.equals(parentNode)) {
      -  136  94
                   if (GROUPID.equals(qName)) {
      -  137  6
                       model.setGroupId(currentText.toString());
      -  138  88
                   } else if (ARTIFACTID.equals(qName)) {
      -  139  6
                       model.setArtifactId(currentText.toString());
      -  140  82
                   } else if (VERSION.equals(qName)) {
      -  141  4
                       model.setVersion(currentText.toString());
      -  142  78
                   } else if (NAME.equals(qName)) {
      -  143  6
                       model.setName(currentText.toString());
      -  144  72
                   } else if (ORGANIZATION.equals(qName)) {
      +  133  689
               stack.pop();
      +  134  689
               final String parentNode = stack.peek();
      +  135  689
               if (PROJECT.equals(parentNode)) {
      +  136  47
                   if (GROUPID.equals(qName)) {
      +  137  3
                       model.setGroupId(currentText.toString());
      +  138  44
                   } else if (ARTIFACTID.equals(qName)) {
      +  139  3
                       model.setArtifactId(currentText.toString());
      +  140  41
                   } else if (VERSION.equals(qName)) {
      +  141  2
                       model.setVersion(currentText.toString());
      +  142  39
                   } else if (NAME.equals(qName)) {
      +  143  3
                       model.setName(currentText.toString());
      +  144  36
                   } else if (ORGANIZATION.equals(qName)) {
       145  0
                       model.setOrganization(currentText.toString());
      -  146  72
                   } else if (DESCRIPTION.equals(qName)) {
      -  147  4
                       model.setDescription(currentText.toString());
      -  148  68
                   } else if (URL.equals(qName)) {
      -  149  4
                       model.setProjectURL(currentText.toString());
      +  146  36
                   } else if (DESCRIPTION.equals(qName)) {
      +  147  2
                       model.setDescription(currentText.toString());
      +  148  34
                   } else if (URL.equals(qName)) {
      +  149  2
                       model.setProjectURL(currentText.toString());
       150  
                   }
      -  151  1284
               } else if (PARENT.equals(parentNode)) {
      -  152  6
                   if (GROUPID.equals(qName)) {
      -  153  2
                       model.setParentGroupId(currentText.toString());
      -  154  4
                   } else if (ARTIFACTID.equals(qName)) {
      -  155  2
                       model.setParentArtifactId(currentText.toString());
      -  156  2
                   } else if (VERSION.equals(qName)) {
      -  157  2
                       model.setParentVersion(currentText.toString());
      +  151  642
               } else if (PARENT.equals(parentNode)) {
      +  152  3
                   if (GROUPID.equals(qName)) {
      +  153  1
                       model.setParentGroupId(currentText.toString());
      +  154  2
                   } else if (ARTIFACTID.equals(qName)) {
      +  155  1
                       model.setParentArtifactId(currentText.toString());
      +  156  1
                   } else if (VERSION.equals(qName)) {
      +  157  1
                       model.setParentVersion(currentText.toString());
       158  
                   }
      -  159  1278
               } else if (LICENSE.equals(parentNode)) {
      +  159  639
               } else if (LICENSE.equals(parentNode)) {
       160  0
                   if (license != null) {
       161  0
                       if (NAME.equals(qName)) {
       162  0
                           license.setName(currentText.toString());
      @@ -313,7 +313,7 @@
                       //TODO add error logging
       168  
                   }
      -  169  1278
               } else if (LICENSES.equals(parentNode)) {
      +  169  639
               } else if (LICENSES.equals(parentNode)) {
       170  0
                   if (LICENSE.equals(qName)) {
       171  0
                       if (license != null) {
       172  0
                           model.addLicense(license);
      @@ -327,7 +327,7 @@
                   }
       177  
               }
      -  178  1378
           }
      +  178  689
           }
       179  
       
       180   @@ -350,12 +350,12 @@
           @Override
       189  
           public void characters(char[] ch, int start, int length) throws SAXException {
      -  190  2760
               currentText.append(ch, start, length);
      -  191  2760
           }
      +  190  1380
               currentText.append(ch, start, length);
      +  191  1380
           }
       192  
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.PomParseException.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.PomParseException.html index c7dcda264..152665fa6 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.PomParseException.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.PomParseException.html @@ -147,6 +147,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.PomParser.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.PomParser.html index b1199fdf0..937c4151b 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.PomParser.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.PomParser.html @@ -99,7 +99,7 @@
        * @author Jeremy Long
       41  
        */
      -  42  6
       public class PomParser {
      +  42  3
       public class PomParser {
       43  
       
       44   @@ -108,7 +108,7 @@
            * The logger.
       46  
            */
      -  47  2
           private static final Logger LOGGER = LoggerFactory.getLogger(PomParser.class);
      +  47  1
           private static final Logger LOGGER = LoggerFactory.getLogger(PomParser.class);
       48  
       
       49   @@ -127,23 +127,23 @@
            */
       56  
           public Model parse(File file) throws PomParseException {
      -  57  2
               FileInputStream fis = null;
      +  57  1
               FileInputStream fis = null;
       58  
               try {
      -  59  2
                   fis = new FileInputStream(file);
      -  60  4
                   return parse(fis);
      +  59  1
                   fis = new FileInputStream(file);
      +  60  2
                   return parse(fis);
       61  0
               } catch (IOException ex) {
       62  0
                   LOGGER.debug("", ex);
       63  0
                   throw new PomParseException(ex);
       64  
               } finally {
      -  65  2
                   if (fis != null) {
      +  65  1
                   if (fis != null) {
       66  
                       try {
      -  67  2
                           fis.close();
      +  67  1
                           fis.close();
       68  0
                       } catch (IOException ex) {
       69  0
                           LOGGER.debug("Unable to close stream", ex);
      -  70  2
                       }
      +  70  1
                       }
       71  
                   }
       72   @@ -170,27 +170,27 @@
           public Model parse(InputStream inputStream) throws PomParseException {
       83  
               try {
      -  84  6
                   final PomHandler handler = new PomHandler();
      -  85  6
                   final SAXParserFactory factory = SAXParserFactory.newInstance();
      +  84  3
                   final PomHandler handler = new PomHandler();
      +  85  3
                   final SAXParserFactory factory = SAXParserFactory.newInstance();
       86  
       //            factory.setNamespaceAware(true);
       87  
       //            factory.setValidating(true);
      -  88  6
                   final SAXParser saxParser = factory.newSAXParser();
      -  89  6
                   final XMLReader xmlReader = saxParser.getXMLReader();
      -  90  6
                   xmlReader.setContentHandler(handler);
      +  88  3
                   final SAXParser saxParser = factory.newSAXParser();
      +  89  3
                   final XMLReader xmlReader = saxParser.getXMLReader();
      +  90  3
                   xmlReader.setContentHandler(handler);
       91  
       
      -  92  6
                   final Reader reader = new InputStreamReader(inputStream, "UTF-8");
      -  93  6
                   final InputSource in = new InputSource(reader);
      +  92  3
                   final Reader reader = new InputStreamReader(inputStream, "UTF-8");
      +  93  3
                   final InputSource in = new InputSource(reader);
       94  
                   //in.setEncoding("UTF-8");
       95  
       
      -  96  6
                   xmlReader.parse(in);
      +  96  3
                   xmlReader.parse(in);
       97  
       
      -  98  6
                   return handler.getModel();
      +  98  3
                   return handler.getModel();
       99  0
               } catch (ParserConfigurationException ex) {
       100  0
                   LOGGER.debug("", ex);
       101  0
                   throw new PomParseException(ex);
      @@ -211,6 +211,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.PomUtils.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.PomUtils.html index 124c47014..0b350eb62 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.PomUtils.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.pom.PomUtils.html @@ -101,7 +101,7 @@
            * The logger.
       43  
            */
      -  44  2
           private static final Logger LOGGER = LoggerFactory.getLogger(PomUtils.class);
      +  44  1
           private static final Logger LOGGER = LoggerFactory.getLogger(PomUtils.class);
       45  
       
       46   @@ -120,11 +120,11 @@
            */
       53  
           public static Model readPom(File file) throws AnalysisException {
      -  54  2
               Model model = null;
      +  54  1
               Model model = null;
       55  
               try {
      -  56  2
                   final PomParser parser = new PomParser();
      -  57  2
                   model = parser.parse(file);
      +  56  1
                   final PomParser parser = new PomParser();
      +  57  1
                   model = parser.parse(file);
       58  0
               } catch (PomParseException ex) {
       59  0
                   LOGGER.warn("Unable to parse pom '{}'", file.getPath());
       60  0
                   LOGGER.debug("", ex);
      @@ -137,8 +137,8 @@  67  0
                   LOGGER.warn("Unexpected error during parsing of the pom '{}'", file.getPath());
       68  0
                   LOGGER.debug("", ex);
       69  0
                   throw new AnalysisException(ex);
      -  70  2
               }
      -  71  2
               return model;
      +  70  1
               }
      +  71  1
               return model;
       72  
           }
       73   @@ -161,14 +161,14 @@
            */
       82  
           public static Model readPom(String path, JarFile jar) throws AnalysisException {
      -  83  4
               final ZipEntry entry = jar.getEntry(path);
      -  84  4
               Model model = null;
      -  85  4
               if (entry != null) { //should never be null
      +  83  2
               final ZipEntry entry = jar.getEntry(path);
      +  84  2
               Model model = null;
      +  85  2
               if (entry != null) { //should never be null
       86  
                   try {
      -  87  4
                       final PomParser parser = new PomParser();
      -  88  4
                       model = parser.parse(jar.getInputStream(entry));
      -  89  4
                       LOGGER.debug("Read POM {}", path);
      +  87  2
                       final PomParser parser = new PomParser();
      +  88  2
                       model = parser.parse(jar.getInputStream(entry));
      +  89  2
                       LOGGER.debug("Read POM {}", path);
       90  0
                   } catch (SecurityException ex) {
       91  0
                       LOGGER.warn("Unable to parse pom '{}' in jar '{}'; invalid signature", path, jar.getName());
       92  0
                       LOGGER.debug("", ex);
      @@ -181,10 +181,10 @@  99  0
                       LOGGER.warn("Unexpected error during parsing of the pom '{}' in jar '{}'", path, jar.getName());
       100  0
                       LOGGER.debug("", ex);
       101  0
                       throw new AnalysisException(ex);
      -  102  4
                   }
      +  102  2
                   }
       103  
               }
      -  104  4
               return model;
      +  104  2
               return model;
       105  
           }
       106   @@ -212,6 +212,6 @@
       }
      - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.suppression.PropertyType.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.suppression.PropertyType.html new file mode 100644 index 000000000..5fa2ac730 --- /dev/null +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.suppression.PropertyType.html @@ -0,0 +1,350 @@ + + + + +Coverage Report + + + + +
      Coverage Report - org.owasp.dependencycheck.xml.suppression.PropertyType
      +
       
      + + + + +
      Classes in this File Line Coverage Branch Coverage Complexity
      PropertyType
      70%
      28/40
      46%
      13/28
      3.1
      +
       
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
       1  
       /*
       2  
        * This file is part of dependency-check-core.
       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) 2013 Jeremy Long. All Rights Reserved.
       17  
        */
       18  
       package org.owasp.dependencycheck.xml.suppression;
       19  
       
       20  
       import java.util.regex.Pattern;
       21  
       
       22  
       /**
       23  
        * A simple PropertyType used to represent a string value that could be used as a regular expression or could be case
       24  
        * insensitive. The equals method has been over-ridden so that the object will correctly compare to strings.
       25  
        *
       26  
        * @author Jeremy Long
       27  
        */
       28  1010
       public class PropertyType {
       29  
       
       30  
           //<editor-fold defaultstate="collapsed" desc="properties">
       31  
           /**
       32  
            * The value.
       33  
            */
       34  
           private String value;
       35  
       
       36  
           /**
       37  
            * Gets the value of the value property.
       38  
            *
       39  
            * @return the value of the value property
       40  
            *
       41  
            */
       42  
           public String getValue() {
       43  119
               return value;
       44  
           }
       45  
       
       46  
           /**
       47  
            * Sets the value of the value property.
       48  
            *
       49  
            * @param value the value of the value property
       50  
            */
       51  
           public void setValue(String value) {
       52  1019
               this.value = value;
       53  1019
           }
       54  
           /**
       55  
            * Whether or not the expression is a regex.
       56  
            */
       57  1010
           private boolean regex = false;
       58  
       
       59  
           /**
       60  
            * Returns whether or not the value is a regex.
       61  
            *
       62  
            * @return true if the value is a regex, otherwise false
       63  
            *
       64  
            */
       65  
           public boolean isRegex() {
       66  69
               return regex;
       67  
           }
       68  
       
       69  
           /**
       70  
            * Sets whether the value property is a regex.
       71  
            *
       72  
            * @param value true if the value is a regex, otherwise false
       73  
            *
       74  
            */
       75  
           public void setRegex(boolean value) {
       76  1003
               this.regex = value;
       77  1003
           }
       78  
           /**
       79  
            * Indicates case sensitivity.
       80  
            */
       81  1010
           private boolean caseSensitive = false;
       82  
       
       83  
           /**
       84  
            * Gets the value of the caseSensitive property.
       85  
            *
       86  
            * @return true if the value is case sensitive
       87  
            *
       88  
            */
       89  
           public boolean isCaseSensitive() {
       90  59
               return caseSensitive;
       91  
           }
       92  
       
       93  
           /**
       94  
            * Sets the value of the caseSensitive property.
       95  
            *
       96  
            * @param value whether the value is case sensitive
       97  
            *
       98  
            */
       99  
           public void setCaseSensitive(boolean value) {
       100  1004
               this.caseSensitive = value;
       101  1004
           }
       102  
           //</editor-fold>
       103  
       
       104  
           /**
       105  
            * Uses the object's properties to determine if the supplied string matches the value of this property.
       106  
            *
       107  
            * @param text the String to validate
       108  
            * @return whether the text supplied is matched by the value of the property
       109  
            */
       110  
           public boolean matches(String text) {
       111  148
               if (text == null) {
       112  0
                   return false;
       113  
               }
       114  148
               if (this.regex) {
       115  
                   Pattern rx;
       116  80
                   if (this.caseSensitive) {
       117  2
                       rx = Pattern.compile(this.value);
       118  
                   } else {
       119  78
                       rx = Pattern.compile(this.value, Pattern.CASE_INSENSITIVE);
       120  
                   }
       121  80
                   return rx.matcher(text).matches();
       122  
               } else {
       123  68
                   if (this.caseSensitive) {
       124  2
                       return value.equals(text);
       125  
                   } else {
       126  66
                       return value.equalsIgnoreCase(text);
       127  
                   }
       128  
               }
       129  
           }
       130  
       
       131  
           //<editor-fold defaultstate="collapsed" desc="standard implementations of hashCode, equals, and toString">
       132  
           /**
       133  
            * Default implementation of hashCode.
       134  
            *
       135  
            * @return the hash code
       136  
            */
       137  
           @Override
       138  
           public int hashCode() {
       139  0
               int hash = 3;
       140  0
               hash = 59 * hash + (this.value != null ? this.value.hashCode() : 0);
       141  0
               hash = 59 * hash + (this.regex ? 1 : 0);
       142  0
               hash = 59 * hash + (this.caseSensitive ? 1 : 0);
       143  0
               return hash;
       144  
           }
       145  
       
       146  
           /**
       147  
            * Default implementation of equals.
       148  
            *
       149  
            * @param obj the object to compare
       150  
            * @return whether the objects are equivalent
       151  
            */
       152  
           @Override
       153  
           public boolean equals(Object obj) {
       154  1
               if (obj == null) {
       155  0
                   return false;
       156  
               }
       157  1
               if (getClass() != obj.getClass()) {
       158  0
                   return false;
       159  
               }
       160  1
               final PropertyType other = (PropertyType) obj;
       161  1
               if ((this.value == null) ? (other.value != null) : !this.value.equals(other.value)) {
       162  0
                   return false;
       163  
               }
       164  1
               if (this.regex != other.regex) {
       165  0
                   return false;
       166  
               }
       167  1
               if (this.caseSensitive != other.caseSensitive) {
       168  0
                   return false;
       169  
               }
       170  1
               return true;
       171  
           }
       172  
       
       173  
           /**
       174  
            * Default implementation of toString().
       175  
            *
       176  
            * @return the string representation of the object
       177  
            */
       178  
           @Override
       179  
           public String toString() {
       180  0
               return "PropertyType{" + "value=" + value + ", regex=" + regex + ", caseSensitive=" + caseSensitive + '}';
       181  
           }
       182  
           //</editor-fold>
       183  
       }
      + + + + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.suppression.SuppressionErrorHandler.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.suppression.SuppressionErrorHandler.html new file mode 100644 index 000000000..81d2397a8 --- /dev/null +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.suppression.SuppressionErrorHandler.html @@ -0,0 +1,202 @@ + + + + +Coverage Report + + + + +
      Coverage Report - org.owasp.dependencycheck.xml.suppression.SuppressionErrorHandler
      +
       
      + + + + +
      Classes in this File Line Coverage Branch Coverage Complexity
      SuppressionErrorHandler
      81%
      13/16
      50%
      4/8
      2.5
      +
       
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
       1  
       /*
       2  
        * This file is part of dependency-check-core.
       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) 2013 Jeremy Long. All Rights Reserved.
       17  
        */
       18  
       package org.owasp.dependencycheck.xml.suppression;
       19  
       
       20  
       import org.slf4j.Logger;
       21  
       import org.slf4j.LoggerFactory;
       22  
       import org.xml.sax.ErrorHandler;
       23  
       import org.xml.sax.SAXException;
       24  
       import org.xml.sax.SAXParseException;
       25  
       
       26  
       /**
       27  
        * An XML parsing error handler.
       28  
        *
       29  
        * @author Jeremy Long
       30  
        */
       31  14
       public class SuppressionErrorHandler implements ErrorHandler {
       32  
       
       33  
           /**
       34  
            * The logger.
       35  
            */
       36  1
           private static final Logger LOGGER = LoggerFactory.getLogger(SuppressionErrorHandler.class);
       37  
       
       38  
           /**
       39  
            * Builds a prettier exception message.
       40  
            *
       41  
            * @param ex the SAXParseException
       42  
            * @return an easier to read exception message
       43  
            */
       44  
           private String getPrettyParseExceptionInfo(SAXParseException ex) {
       45  
       
       46  3
               final StringBuilder sb = new StringBuilder();
       47  
       
       48  3
               if (ex.getSystemId() != null) {
       49  0
                   sb.append("systemId=").append(ex.getSystemId()).append(", ");
       50  
               }
       51  3
               if (ex.getPublicId() != null) {
       52  0
                   sb.append("publicId=").append(ex.getPublicId()).append(", ");
       53  
               }
       54  3
               if (ex.getLineNumber() > 0) {
       55  3
                   sb.append("Line=").append(ex.getLineNumber());
       56  
               }
       57  3
               if (ex.getColumnNumber() > 0) {
       58  3
                   sb.append(", Column=").append(ex.getColumnNumber());
       59  
               }
       60  3
               sb.append(": ").append(ex.getMessage());
       61  
       
       62  3
               return sb.toString();
       63  
           }
       64  
       
       65  
           /**
       66  
            * Logs warnings.
       67  
            *
       68  
            * @param ex the warning to log
       69  
            * @throws SAXException is never thrown
       70  
            */
       71  
           @Override
       72  
           public void warning(SAXParseException ex) throws SAXException {
       73  
               //LOGGER.debug("", ex);
       74  3
           }
       75  
       
       76  
           /**
       77  
            * Handles errors.
       78  
            *
       79  
            * @param ex the error to handle
       80  
            * @throws SAXException is always thrown
       81  
            */
       82  
           @Override
       83  
           public void error(SAXParseException ex) throws SAXException {
       84  3
               throw new SAXException(getPrettyParseExceptionInfo(ex));
       85  
           }
       86  
       
       87  
           /**
       88  
            * Handles fatal exceptions.
       89  
            *
       90  
            * @param ex a fatal exception
       91  
            * @throws SAXException is always
       92  
            */
       93  
           @Override
       94  
           public void fatalError(SAXParseException ex) throws SAXException {
       95  0
               throw new SAXException(getPrettyParseExceptionInfo(ex));
       96  
           }
       97  
       }
      + + + + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.suppression.SuppressionHandler.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.suppression.SuppressionHandler.html new file mode 100644 index 000000000..3d8aeaac5 --- /dev/null +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.suppression.SuppressionHandler.html @@ -0,0 +1,344 @@ + + + + +Coverage Report + + + + +
      Coverage Report - org.owasp.dependencycheck.xml.suppression.SuppressionHandler
      +
       
      + + + + +
      Classes in this File Line Coverage Branch Coverage Complexity
      SuppressionHandler
      95%
      44/46
      78%
      22/28
      3.8
      +
       
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
       1  
       /*
       2  
        * This file is part of dependency-check-core.
       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) 2013 Jeremy Long. All Rights Reserved.
       17  
        */
       18  
       package org.owasp.dependencycheck.xml.suppression;
       19  
       
       20  
       import java.util.ArrayList;
       21  
       import java.util.List;
       22  
       import org.xml.sax.Attributes;
       23  
       import org.xml.sax.SAXException;
       24  
       import org.xml.sax.helpers.DefaultHandler;
       25  
       
       26  
       /**
       27  
        * A handler to load suppression rules.
       28  
        *
       29  
        * @author Jeremy Long
       30  
        */
       31  14
       public class SuppressionHandler extends DefaultHandler {
       32  
       
       33  
           /**
       34  
            * The suppress node, indicates the start of a new rule.
       35  
            */
       36  
           public static final String SUPPRESS = "suppress";
       37  
           /**
       38  
            * The file path element name.
       39  
            */
       40  
           public static final String FILE_PATH = "filePath";
       41  
           /**
       42  
            * The sha1 hash element name.
       43  
            */
       44  
           public static final String SHA1 = "sha1";
       45  
           /**
       46  
            * The CVE element name.
       47  
            */
       48  
           public static final String CVE = "cve";
       49  
           /**
       50  
            * The CPE element name.
       51  
            */
       52  
           public static final String CPE = "cpe";
       53  
           /**
       54  
            * The CWE element name.
       55  
            */
       56  
           public static final String CWE = "cwe";
       57  
           /**
       58  
            * The GAV element name.
       59  
            */
       60  
           public static final String GAV = "gav";
       61  
           /**
       62  
            * The cvssBelow element name.
       63  
            */
       64  
           public static final String CVSS_BELOW = "cvssBelow";
       65  
           /**
       66  
            * A list of suppression rules.
       67  
            */
       68  14
           private final List<SuppressionRule> suppressionRules = new ArrayList<SuppressionRule>();
       69  
       
       70  
           /**
       71  
            * Get the value of suppressionRules.
       72  
            *
       73  
            * @return the value of suppressionRules
       74  
            */
       75  
           public List<SuppressionRule> getSuppressionRules() {
       76  11
               return suppressionRules;
       77  
           }
       78  
           /**
       79  
            * The current rule being read.
       80  
            */
       81  
           private SuppressionRule rule;
       82  
           /**
       83  
            * The attributes of the node being read.
       84  
            */
       85  
           private Attributes currentAttributes;
       86  
           /**
       87  
            * The current node text being extracted from the element.
       88  
            */
       89  
           private StringBuilder currentText;
       90  
       
       91  
           /**
       92  
            * Handles the start element event.
       93  
            *
       94  
            * @param uri the uri of the element being processed
       95  
            * @param localName the local name of the element being processed
       96  
            * @param qName the qName of the element being processed
       97  
            * @param attributes the attributes of the element being processed
       98  
            * @throws SAXException thrown if there is an exception processing
       99  
            */
       100  
           @Override
       101  
           public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
       102  1837
               currentAttributes = attributes;
       103  1837
               currentText = new StringBuilder();
       104  1837
               if (SUPPRESS.equals(qName)) {
       105  412
                   rule = new SuppressionRule();
       106  412
                   final String base = currentAttributes.getValue("base");
       107  412
                   if (base != null) {
       108  412
                       rule.setBase(Boolean.parseBoolean(base));
       109  
                   } else {
       110  0
                       rule.setBase(false);
       111  
                   }
       112  
               }
       113  1837
           }
       114  
       
       115  
           /**
       116  
            * Handles the end element event.
       117  
            *
       118  
            * @param uri the URI of the element
       119  
            * @param localName the local name of the element
       120  
            * @param qName the qName of the element
       121  
            * @throws SAXException thrown if there is an exception processing
       122  
            */
       123  
           @Override
       124  
           public void endElement(String uri, String localName, String qName) throws SAXException {
       125  1837
               if (SUPPRESS.equals(qName)) {
       126  412
                   suppressionRules.add(rule);
       127  412
                   rule = null;
       128  1425
               } else if (FILE_PATH.equals(qName)) {
       129  75
                   final PropertyType pt = processPropertyType();
       130  75
                   rule.setFilePath(pt);
       131  75
               } else if (SHA1.equals(qName)) {
       132  4
                   rule.setSha1(currentText.toString());
       133  1346
               } else if (GAV.equals(qName)) {
       134  329
                   final PropertyType pt = processPropertyType();
       135  329
                   rule.setGav(pt);
       136  329
               } else if (CPE.equals(qName)) {
       137  582
                   final PropertyType pt = processPropertyType();
       138  582
                   rule.addCpe(pt);
       139  582
               } else if (CWE.equals(qName)) {
       140  0
                   rule.addCwe(currentText.toString());
       141  435
               } else if (CVE.equals(qName)) {
       142  8
                   rule.addCve(currentText.toString());
       143  427
               } else if (CVSS_BELOW.equals(qName)) {
       144  4
                   final float cvss = Float.parseFloat(currentText.toString());
       145  4
                   rule.addCvssBelow(cvss);
       146  
               }
       147  1837
           }
       148  
       
       149  
           /**
       150  
            * Collects the body text of the node being processed.
       151  
            *
       152  
            * @param ch the char array of text
       153  
            * @param start the start position to copy text from in the char array
       154  
            * @param length the number of characters to copy from the char array
       155  
            * @throws SAXException thrown if there is a parsing exception
       156  
            */
       157  
           @Override
       158  
           public void characters(char[] ch, int start, int length) throws SAXException {
       159  4159
               currentText.append(ch, start, length);
       160  4159
           }
       161  
       
       162  
           /**
       163  
            * Processes field members that have been collected during the characters and startElement method to construct a
       164  
            * PropertyType object.
       165  
            *
       166  
            * @return a PropertyType object
       167  
            */
       168  
           private PropertyType processPropertyType() {
       169  986
               final PropertyType pt = new PropertyType();
       170  986
               pt.setValue(currentText.toString());
       171  986
               if (currentAttributes != null && currentAttributes.getLength() > 0) {
       172  986
                   final String regex = currentAttributes.getValue("regex");
       173  986
                   if (regex != null) {
       174  986
                       pt.setRegex(Boolean.parseBoolean(regex));
       175  
                   }
       176  986
                   final String caseSensitive = currentAttributes.getValue("caseSensitive");
       177  986
                   if (caseSensitive != null) {
       178  986
                       pt.setCaseSensitive(Boolean.parseBoolean(caseSensitive));
       179  
                   }
       180  
               }
       181  986
               return pt;
       182  
           }
       183  
       }
      + + + + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.suppression.SuppressionParseException.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.suppression.SuppressionParseException.html new file mode 100644 index 000000000..c20133581 --- /dev/null +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.suppression.SuppressionParseException.html @@ -0,0 +1,152 @@ + + + + +Coverage Report + + + + +
      Coverage Report - org.owasp.dependencycheck.xml.suppression.SuppressionParseException
      +
       
      + + + + +
      Classes in this File Line Coverage Branch Coverage Complexity
      SuppressionParseException
      50%
      4/8
      N/A
      1
      +
       
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
       1  
       /*
       2  
        * This file is part of dependency-check-core.
       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) 2013 Jeremy Long. All Rights Reserved.
       17  
        */
       18  
       package org.owasp.dependencycheck.xml.suppression;
       19  
       
       20  
       import java.io.IOException;
       21  
       
       22  
       /**
       23  
        * An exception used when parsing a suppression rule file fails.
       24  
        *
       25  
        * @author Jeremy Long
       26  
        */
       27  
       public class SuppressionParseException extends IOException {
       28  
       
       29  
           /**
       30  
            * The serial version UID for serialization.
       31  
            */
       32  
           private static final long serialVersionUID = 1L;
       33  
       
       34  
           /**
       35  
            * Creates a new SuppressionParseException.
       36  
            */
       37  
           public SuppressionParseException() {
       38  0
               super();
       39  0
           }
       40  
       
       41  
           /**
       42  
            * Creates a new SuppressionParseException.
       43  
            *
       44  
            * @param msg a message for the exception.
       45  
            */
       46  
           public SuppressionParseException(String msg) {
       47  0
               super(msg);
       48  0
           }
       49  
       
       50  
           /**
       51  
            * Creates a new SuppressionParseException.
       52  
            *
       53  
            * @param ex the cause of the parse exception
       54  
            */
       55  
           public SuppressionParseException(Throwable ex) {
       56  1
               super(ex);
       57  1
           }
       58  
       
       59  
           /**
       60  
            * Creates a new SuppressionParseException.
       61  
            *
       62  
            * @param msg a message for the exception.
       63  
            * @param ex the cause of the parse exception
       64  
            */
       65  
           public SuppressionParseException(String msg, Throwable ex) {
       66  1
               super(msg, ex);
       67  1
           }
       68  
       }
      + + + + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.suppression.SuppressionParser.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.suppression.SuppressionParser.html new file mode 100644 index 000000000..68eb64991 --- /dev/null +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.suppression.SuppressionParser.html @@ -0,0 +1,354 @@ + + + + +Coverage Report + + + + +
      Coverage Report - org.owasp.dependencycheck.xml.suppression.SuppressionParser
      +
       
      + + + + +
      Classes in this File Line Coverage Branch Coverage Complexity
      SuppressionParser
      63%
      51/80
      50%
      3/6
      11.333
      +
       
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
       1  
       /*
       2  
        * This file is part of dependency-check-core.
       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) 2013 Jeremy Long. All Rights Reserved.
       17  
        */
       18  
       package org.owasp.dependencycheck.xml.suppression;
       19  
       
       20  
       import java.io.File;
       21  
       import java.io.FileInputStream;
       22  
       import java.io.FileNotFoundException;
       23  
       import java.io.IOException;
       24  
       import java.io.InputStream;
       25  
       import java.io.InputStreamReader;
       26  
       import java.io.Reader;
       27  
       import java.util.List;
       28  
       import javax.xml.parsers.ParserConfigurationException;
       29  
       import javax.xml.parsers.SAXParser;
       30  
       import javax.xml.parsers.SAXParserFactory;
       31  
       
       32  
       import org.slf4j.Logger;
       33  
       import org.slf4j.LoggerFactory;
       34  
       import org.xml.sax.InputSource;
       35  
       import org.xml.sax.SAXException;
       36  
       import org.xml.sax.XMLReader;
       37  
       
       38  
       /**
       39  
        * A simple validating parser for XML Suppression Rules.
       40  
        *
       41  
        * @author Jeremy Long
       42  
        */
       43  8
       public class SuppressionParser {
       44  
       
       45  
           /**
       46  
            * The logger.
       47  
            */
       48  1
           private static final Logger LOGGER = LoggerFactory.getLogger(SuppressionParser.class);
       49  
           /**
       50  
            * JAXP Schema Language. Source:
       51  
            * http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html
       52  
            */
       53  
           public static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
       54  
           /**
       55  
            * W3C XML Schema. Source:
       56  
            * http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html
       57  
            */
       58  
           public static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";
       59  
           /**
       60  
            * JAXP Schema Source. Source:
       61  
            * http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html
       62  
            */
       63  
           public static final String JAXP_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource";
       64  
           /**
       65  
            * The suppression schema file location.
       66  
            */
       67  
           private static final String SUPPRESSION_SCHEMA = "schema/dependency-suppression.1.1.xsd";
       68  
           /**
       69  
            * The old suppression schema file location.
       70  
            */
       71  
           private static final String OLD_SUPPRESSION_SCHEMA = "schema/suppression.xsd";
       72  
       
       73  
           /**
       74  
            * Parses the given XML file and returns a list of the suppression rules
       75  
            * contained.
       76  
            *
       77  
            * @param file an XML file containing suppression rules
       78  
            * @return a list of suppression rules
       79  
            * @throws SuppressionParseException thrown if the XML file cannot be parsed
       80  
            */
       81  
           public List<SuppressionRule> parseSuppressionRules(File file) throws SuppressionParseException {
       82  4
               FileInputStream fis = null;
       83  
               try {
       84  4
                   fis = new FileInputStream(file);
       85  3
                   return parseSuppressionRules(fis);
       86  1
               } catch (IOException ex) {
       87  1
                   LOGGER.debug("", ex);
       88  1
                   throw new SuppressionParseException(ex);
       89  3
               } catch (SAXException ex) {
       90  
                   try {
       91  3
                       if (fis != null) {
       92  
                           try {
       93  3
                               fis.close();
       94  0
                           } catch (IOException ex1) {
       95  0
                               LOGGER.debug("Unable to close stream", ex1);
       96  3
                           }
       97  
                       }
       98  3
                       fis = new FileInputStream(file);
       99  0
                   } catch (FileNotFoundException ex1) {
       100  0
                       throw new SuppressionParseException(ex);
       101  3
                   }
       102  6
                   return parseOldSuppressionRules(fis);
       103  
               } finally {
       104  4
                   if (fis != null) {
       105  
                       try {
       106  3
                           fis.close();
       107  0
                       } catch (IOException ex) {
       108  0
                           LOGGER.debug("Unable to close stream", ex);
       109  4
                       }
       110  
                   }
       111  
               }
       112  
           }
       113  
       
       114  
           /**
       115  
            * Parses the given XML stream and returns a list of the suppression rules
       116  
            * contained.
       117  
            *
       118  
            * @param inputStream an InputStream containing suppression rules
       119  
            * @return a list of suppression rules
       120  
            * @throws SuppressionParseException thrown if the XML cannot be parsed
       121  
            * @throws SAXException thrown if the XML cannot be parsed
       122  
            */
       123  
           public List<SuppressionRule> parseSuppressionRules(InputStream inputStream) throws SuppressionParseException, SAXException {
       124  
               try {
       125  10
                   final InputStream schemaStream = this.getClass().getClassLoader().getResourceAsStream(SUPPRESSION_SCHEMA);
       126  10
                   final SuppressionHandler handler = new SuppressionHandler();
       127  10
                   final SAXParserFactory factory = SAXParserFactory.newInstance();
       128  10
                   factory.setNamespaceAware(true);
       129  10
                   factory.setValidating(true);
       130  10
                   final SAXParser saxParser = factory.newSAXParser();
       131  10
                   saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_LANGUAGE, SuppressionParser.W3C_XML_SCHEMA);
       132  10
                   saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_SOURCE, new InputSource(schemaStream));
       133  10
                   final XMLReader xmlReader = saxParser.getXMLReader();
       134  10
                   xmlReader.setErrorHandler(new SuppressionErrorHandler());
       135  10
                   xmlReader.setContentHandler(handler);
       136  
       
       137  10
                   final Reader reader = new InputStreamReader(inputStream, "UTF-8");
       138  10
                   final InputSource in = new InputSource(reader);
       139  
                   //in.setEncoding("UTF-8");
       140  
       
       141  10
                   xmlReader.parse(in);
       142  
       
       143  7
                   return handler.getSuppressionRules();
       144  0
               } catch (ParserConfigurationException ex) {
       145  0
                   LOGGER.debug("", ex);
       146  0
                   throw new SuppressionParseException(ex);
       147  3
               } catch (SAXException ex) {
       148  3
                   if (ex.getMessage().contains("Cannot find the declaration of element 'suppressions'.")) {
       149  3
                       throw ex;
       150  
                   } else {
       151  0
                       LOGGER.debug("", ex);
       152  0
                       throw new SuppressionParseException(ex);
       153  
                   }
       154  0
               } catch (FileNotFoundException ex) {
       155  0
                   LOGGER.debug("", ex);
       156  0
                   throw new SuppressionParseException(ex);
       157  0
               } catch (IOException ex) {
       158  0
                   LOGGER.debug("", ex);
       159  0
                   throw new SuppressionParseException(ex);
       160  
               }
       161  
           }
       162  
       
       163  
           /**
       164  
            * Parses the given XML stream and returns a list of the suppression rules
       165  
            * contained.
       166  
            *
       167  
            * @param inputStream an InputStream containing suppression rues
       168  
            * @return a list of suppression rules
       169  
            * @throws SuppressionParseException if the XML cannot be parsed
       170  
            */
       171  
           private List<SuppressionRule> parseOldSuppressionRules(InputStream inputStream) throws SuppressionParseException {
       172  
               try {
       173  3
                   final InputStream schemaStream = this.getClass().getClassLoader().getResourceAsStream(OLD_SUPPRESSION_SCHEMA);
       174  3
                   final SuppressionHandler handler = new SuppressionHandler();
       175  3
                   final SAXParserFactory factory = SAXParserFactory.newInstance();
       176  3
                   factory.setNamespaceAware(true);
       177  3
                   factory.setValidating(true);
       178  3
                   final SAXParser saxParser = factory.newSAXParser();
       179  3
                   saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_LANGUAGE, SuppressionParser.W3C_XML_SCHEMA);
       180  3
                   saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_SOURCE, new InputSource(schemaStream));
       181  3
                   final XMLReader xmlReader = saxParser.getXMLReader();
       182  3
                   xmlReader.setErrorHandler(new SuppressionErrorHandler());
       183  3
                   xmlReader.setContentHandler(handler);
       184  
       
       185  3
                   final Reader reader = new InputStreamReader(inputStream, "UTF-8");
       186  3
                   final InputSource in = new InputSource(reader);
       187  
       
       188  3
                   xmlReader.parse(in);
       189  
       
       190  3
                   return handler.getSuppressionRules();
       191  0
               } catch (ParserConfigurationException ex) {
       192  0
                   LOGGER.debug("", ex);
       193  0
                   throw new SuppressionParseException(ex);
       194  0
               } catch (SAXException ex) {
       195  0
                   LOGGER.debug("", ex);
       196  0
                   throw new SuppressionParseException(ex);
       197  0
               } catch (FileNotFoundException ex) {
       198  0
                   LOGGER.debug("", ex);
       199  0
                   throw new SuppressionParseException(ex);
       200  0
               } catch (IOException ex) {
       201  0
                   LOGGER.debug("", ex);
       202  0
                   throw new SuppressionParseException(ex);
       203  
               }
       204  
           }
       205  
       }
      + + + + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.suppression.SuppressionRule.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.suppression.SuppressionRule.html new file mode 100644 index 000000000..1e16404cf --- /dev/null +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.xml.suppression.SuppressionRule.html @@ -0,0 +1,828 @@ + + + + +Coverage Report + + + + +
      Coverage Report - org.owasp.dependencycheck.xml.suppression.SuppressionRule
      +
       
      + + + + +
      Classes in this File Line Coverage Branch Coverage Complexity
      SuppressionRule
      75%
      114/152
      67%
      76/112
      2.867
      +
       
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
       1  
       /*
       2  
        * This file is part of dependency-check-core.
       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) 2013 Jeremy Long. All Rights Reserved.
       17  
        */
       18  
       package org.owasp.dependencycheck.xml.suppression;
       19  
       
       20  
       import java.util.ArrayList;
       21  
       import java.util.Iterator;
       22  
       import java.util.List;
       23  
       import org.owasp.dependencycheck.dependency.Dependency;
       24  
       import org.owasp.dependencycheck.dependency.Identifier;
       25  
       import org.owasp.dependencycheck.dependency.Vulnerability;
       26  
       
       27  
       /**
       28  
        *
       29  
        * @author Jeremy Long
       30  
        */
       31  427
       public class SuppressionRule {
       32  
       
       33  
           /**
       34  
            * The file path for the suppression.
       35  
            */
       36  
           private PropertyType filePath;
       37  
       
       38  
           /**
       39  
            * Get the value of filePath.
       40  
            *
       41  
            * @return the value of filePath
       42  
            */
       43  
           public PropertyType getFilePath() {
       44  1
               return filePath;
       45  
           }
       46  
       
       47  
           /**
       48  
            * Set the value of filePath.
       49  
            *
       50  
            * @param filePath new value of filePath
       51  
            */
       52  
           public void setFilePath(PropertyType filePath) {
       53  77
               this.filePath = filePath;
       54  77
           }
       55  
           /**
       56  
            * The sha1 hash.
       57  
            */
       58  
           private String sha1;
       59  
       
       60  
           /**
       61  
            * Get the value of sha1.
       62  
            *
       63  
            * @return the value of sha1
       64  
            */
       65  
           public String getSha1() {
       66  1
               return sha1;
       67  
           }
       68  
       
       69  
           /**
       70  
            * Set the value of sha1.
       71  
            *
       72  
            * @param sha1 new value of sha1
       73  
            */
       74  
           public void setSha1(String sha1) {
       75  6
               this.sha1 = sha1;
       76  6
           }
       77  
           /**
       78  
            * A list of CPEs to suppression
       79  
            */
       80  427
           private List<PropertyType> cpe = new ArrayList<PropertyType>();
       81  
       
       82  
           /**
       83  
            * Get the value of cpe.
       84  
            *
       85  
            * @return the value of cpe
       86  
            */
       87  
           public List<PropertyType> getCpe() {
       88  1
               return cpe;
       89  
           }
       90  
       
       91  
           /**
       92  
            * Set the value of cpe.
       93  
            *
       94  
            * @param cpe new value of cpe
       95  
            */
       96  
           public void setCpe(List<PropertyType> cpe) {
       97  1
               this.cpe = cpe;
       98  1
           }
       99  
       
       100  
           /**
       101  
            * Adds the cpe to the cpe list.
       102  
            *
       103  
            * @param cpe the cpe to add
       104  
            */
       105  
           public void addCpe(PropertyType cpe) {
       106  589
               this.cpe.add(cpe);
       107  589
           }
       108  
       
       109  
           /**
       110  
            * Returns whether or not this suppression rule as CPE entries.
       111  
            *
       112  
            * @return whether or not this suppression rule as CPE entries
       113  
            */
       114  
           public boolean hasCpe() {
       115  35
               return !cpe.isEmpty();
       116  
           }
       117  
           /**
       118  
            * The list of cvssBelow scores.
       119  
            */
       120  427
           private List<Float> cvssBelow = new ArrayList<Float>();
       121  
       
       122  
           /**
       123  
            * Get the value of cvssBelow.
       124  
            *
       125  
            * @return the value of cvssBelow
       126  
            */
       127  
           public List<Float> getCvssBelow() {
       128  1
               return cvssBelow;
       129  
           }
       130  
       
       131  
           /**
       132  
            * Set the value of cvssBelow.
       133  
            *
       134  
            * @param cvssBelow new value of cvssBelow
       135  
            */
       136  
           public void setCvssBelow(List<Float> cvssBelow) {
       137  1
               this.cvssBelow = cvssBelow;
       138  1
           }
       139  
       
       140  
           /**
       141  
            * Adds the cvss to the cvssBelow list.
       142  
            *
       143  
            * @param cvss the cvss to add
       144  
            */
       145  
           public void addCvssBelow(Float cvss) {
       146  7
               this.cvssBelow.add(cvss);
       147  7
           }
       148  
       
       149  
           /**
       150  
            * Returns whether or not this suppression rule has cvss suppressions.
       151  
            *
       152  
            * @return whether or not this suppression rule has cvss suppressions
       153  
            */
       154  
           public boolean hasCvssBelow() {
       155  32
               return !cvssBelow.isEmpty();
       156  
           }
       157  
           /**
       158  
            * The list of cwe entries to suppress.
       159  
            */
       160  427
           private List<String> cwe = new ArrayList<String>();
       161  
       
       162  
           /**
       163  
            * Get the value of cwe.
       164  
            *
       165  
            * @return the value of cwe
       166  
            */
       167  
           public List<String> getCwe() {
       168  1
               return cwe;
       169  
           }
       170  
       
       171  
           /**
       172  
            * Set the value of cwe.
       173  
            *
       174  
            * @param cwe new value of cwe
       175  
            */
       176  
           public void setCwe(List<String> cwe) {
       177  1
               this.cwe = cwe;
       178  1
           }
       179  
       
       180  
           /**
       181  
            * Adds the cwe to the cwe list.
       182  
            *
       183  
            * @param cwe the cwe to add
       184  
            */
       185  
           public void addCwe(String cwe) {
       186  2
               this.cwe.add(cwe);
       187  2
           }
       188  
       
       189  
           /**
       190  
            * Returns whether this suppression rule has CWE entries.
       191  
            *
       192  
            * @return whether this suppression rule has CWE entries
       193  
            */
       194  
           public boolean hasCwe() {
       195  33
               return !cwe.isEmpty();
       196  
           }
       197  
           /**
       198  
            * The list of cve entries to suppress.
       199  
            */
       200  427
           private List<String> cve = new ArrayList<String>();
       201  
       
       202  
           /**
       203  
            * Get the value of cve.
       204  
            *
       205  
            * @return the value of cve
       206  
            */
       207  
           public List<String> getCve() {
       208  1
               return cve;
       209  
           }
       210  
       
       211  
           /**
       212  
            * Set the value of cve.
       213  
            *
       214  
            * @param cve new value of cve
       215  
            */
       216  
           public void setCve(List<String> cve) {
       217  1
               this.cve = cve;
       218  1
           }
       219  
       
       220  
           /**
       221  
            * Adds the cve to the cve list.
       222  
            *
       223  
            * @param cve the cve to add
       224  
            */
       225  
           public void addCve(String cve) {
       226  11
               this.cve.add(cve);
       227  11
           }
       228  
       
       229  
           /**
       230  
            * Returns whether this suppression rule has CVE entries.
       231  
            *
       232  
            * @return whether this suppression rule has CVE entries
       233  
            */
       234  
           public boolean hasCve() {
       235  35
               return !cve.isEmpty();
       236  
           }
       237  
           /**
       238  
            * A Maven GAV to suppression.
       239  
            */
       240  427
           private PropertyType gav = null;
       241  
       
       242  
           /**
       243  
            * Get the value of Maven GAV.
       244  
            *
       245  
            * @return the value of gav
       246  
            */
       247  
           public PropertyType getGav() {
       248  0
               return gav;
       249  
           }
       250  
       
       251  
           /**
       252  
            * Set the value of Maven GAV.
       253  
            *
       254  
            * @param gav new value of Maven gav
       255  
            */
       256  
           public void setGav(PropertyType gav) {
       257  330
               this.gav = gav;
       258  330
           }
       259  
       
       260  
           /**
       261  
            * Returns whether or not this suppression rule as GAV entries.
       262  
            *
       263  
            * @return whether or not this suppression rule as GAV entries
       264  
            */
       265  
           public boolean hasGav() {
       266  0
               return gav != null;
       267  
           }
       268  
       
       269  
           /**
       270  
            * A flag indicating whether or not the suppression rule is a core/base rule that should not be included in the resulting
       271  
            * report in the "suppressed" section.
       272  
            */
       273  
           private boolean base;
       274  
       
       275  
           /**
       276  
            * Get the value of base.
       277  
            *
       278  
            * @return the value of base
       279  
            */
       280  
           public boolean isBase() {
       281  17
               return base;
       282  
           }
       283  
       
       284  
           /**
       285  
            * Set the value of base.
       286  
            *
       287  
            * @param base new value of base
       288  
            */
       289  
           public void setBase(boolean base) {
       290  414
               this.base = base;
       291  414
           }
       292  
       
       293  
           /**
       294  
            * Processes a given dependency to determine if any CPE, CVE, CWE, or CVSS scores should be suppressed. If any should be, they
       295  
            * are removed from the dependency.
       296  
            *
       297  
            * @param dependency a project dependency to analyze
       298  
            */
       299  
           public void process(Dependency dependency) {
       300  458
               if (filePath != null && !filePath.matches(dependency.getFilePath())) {
       301  48
                   return;
       302  
               }
       303  410
               if (sha1 != null && !sha1.equalsIgnoreCase(dependency.getSha1sum())) {
       304  1
                   return;
       305  
               }
       306  409
               if (gav != null) {
       307  377
                   final Iterator<Identifier> itr = dependency.getIdentifiers().iterator();
       308  377
                   boolean gavFound = false;
       309  663
                   while (itr.hasNext()) {
       310  287
                       final Identifier i = itr.next();
       311  287
                       if (identifierMatches("maven", this.gav, i)) {
       312  1
                           gavFound = true;
       313  1
                           break;
       314  
                       }
       315  286
                   }
       316  377
                   if (!gavFound) {
       317  376
                       return;
       318  
                   }
       319  
               }
       320  
       
       321  33
               if (this.hasCpe()) {
       322  28
                   final Iterator<Identifier> itr = dependency.getIdentifiers().iterator();
       323  74
                   while (itr.hasNext()) {
       324  46
                       final Identifier i = itr.next();
       325  46
                       for (PropertyType c : this.cpe) {
       326  60
                           if (identifierMatches("cpe", c, i)) {
       327  7
                               if (!isBase()) {
       328  4
                                   dependency.addSuppressedIdentifier(i);
       329  
                               }
       330  7
                               itr.remove();
       331  7
                               break;
       332  
                           }
       333  53
                       }
       334  46
                   }
       335  
               }
       336  33
               if (hasCve() || hasCwe() || hasCvssBelow()) {
       337  5
                   final Iterator<Vulnerability> itr = dependency.getVulnerabilities().iterator();
       338  10
                   while (itr.hasNext()) {
       339  5
                       boolean remove = false;
       340  5
                       final Vulnerability v = itr.next();
       341  5
                       for (String entry : this.cve) {
       342  3
                           if (entry.equalsIgnoreCase(v.getName())) {
       343  1
                               remove = true;
       344  1
                               break;
       345  
                           }
       346  2
                       }
       347  5
                       if (!remove) {
       348  4
                           for (String entry : this.cwe) {
       349  1
                               if (v.getCwe() != null) {
       350  1
                                   final String toMatch = String.format("CWE-%s ", entry);
       351  1
                                   final String toTest = v.getCwe().substring(0, toMatch.length()).toUpperCase();
       352  1
                                   if (toTest.equals(toMatch)) {
       353  1
                                       remove = true;
       354  1
                                       break;
       355  
                                   }
       356  
                               }
       357  0
                           }
       358  
                       }
       359  5
                       if (!remove) {
       360  3
                           for (float cvss : this.cvssBelow) {
       361  3
                               if (v.getCvssScore() < cvss) {
       362  1
                                   remove = true;
       363  1
                                   break;
       364  
                               }
       365  2
                           }
       366  
                       }
       367  5
                       if (remove) {
       368  3
                           if (!isBase()) {
       369  3
                               dependency.addSuppressedVulnerability(v);
       370  
                           }
       371  3
                           itr.remove();
       372  
                       }
       373  5
                   }
       374  
               }
       375  33
           }
       376  
       
       377  
           /**
       378  
            * Identifies if the cpe specified by the cpe suppression rule does not specify a version.
       379  
            *
       380  
            * @param c a suppression rule identifier
       381  
            * @return true if the property type does not specify a version; otherwise false
       382  
            */
       383  
           boolean cpeHasNoVersion(PropertyType c) {
       384  64
               return !c.isRegex() && countCharacter(c.getValue(), ':') <= 3;
       385  
           }
       386  
       
       387  
           /**
       388  
            * Counts the number of occurrences of the character found within the string.
       389  
            *
       390  
            * @param str the string to check
       391  
            * @param c the character to count
       392  
            * @return the number of times the character is found in the string
       393  
            */
       394  
           int countCharacter(String str, char c) {
       395  62
               int count = 0;
       396  62
               int pos = str.indexOf(c) + 1;
       397  254
               while (pos > 0) {
       398  192
                   count += 1;
       399  192
                   pos = str.indexOf(c, pos) + 1;
       400  
               }
       401  62
               return count;
       402  
           }
       403  
       
       404  
           /**
       405  
            * Determines if the cpeEntry specified as a PropertyType matches the given Identifier.
       406  
            *
       407  
            * @param identifierType the type of identifier ("cpe", "maven", etc.)
       408  
            * @param suppressionEntry a suppression rule entry
       409  
            * @param identifier a CPE identifier to check
       410  
            * @return true if the entry matches; otherwise false
       411  
            */
       412  
           boolean identifierMatches(String identifierType, PropertyType suppressionEntry, Identifier identifier) {
       413  356
               if (identifierType.equals(identifier.getType())) {
       414  67
                   if (suppressionEntry.matches(identifier.getValue())) {
       415  5
                       return true;
       416  62
                   } else if ("cpe".equals(identifierType) && cpeHasNoVersion(suppressionEntry)) {
       417  55
                       if (suppressionEntry.isCaseSensitive()) {
       418  0
                           return identifier.getValue().startsWith(suppressionEntry.getValue());
       419  
                       } else {
       420  55
                           final String id = identifier.getValue().toLowerCase();
       421  55
                           final String check = suppressionEntry.getValue().toLowerCase();
       422  55
                           return id.startsWith(check);
       423  
                       }
       424  
                   }
       425  
               }
       426  296
               return false;
       427  
           }
       428  
       
       429  
           /**
       430  
            * Standard toString implementation.
       431  
            *
       432  
            * @return a string representation of this object
       433  
            */
       434  
           @Override
       435  
           public String toString() {
       436  0
               final StringBuilder sb = new StringBuilder(64);
       437  0
               sb.append("SuppressionRule{");
       438  0
               if (filePath != null) {
       439  0
                   sb.append("filePath=").append(filePath).append(',');
       440  
               }
       441  0
               if (sha1 != null) {
       442  0
                   sb.append("sha1=").append(sha1).append(',');
       443  
               }
       444  0
               if (gav != null) {
       445  0
                   sb.append("gav=").append(gav).append(',');
       446  
               }
       447  0
               if (cpe != null && !cpe.isEmpty()) {
       448  0
                   sb.append("cpe={");
       449  0
                   for (PropertyType pt : cpe) {
       450  0
                       sb.append(pt).append(',');
       451  0
                   }
       452  0
                   sb.append('}');
       453  
               }
       454  0
               if (cwe != null && !cwe.isEmpty()) {
       455  0
                   sb.append("cwe={");
       456  0
                   for (String s : cwe) {
       457  0
                       sb.append(s).append(',');
       458  0
                   }
       459  0
                   sb.append('}');
       460  
               }
       461  0
               if (cve != null && !cve.isEmpty()) {
       462  0
                   sb.append("cve={");
       463  0
                   for (String s : cve) {
       464  0
                       sb.append(s).append(',');
       465  0
                   }
       466  0
                   sb.append('}');
       467  
               }
       468  0
               if (cvssBelow != null && !cvssBelow.isEmpty()) {
       469  0
                   sb.append("cvssBelow={");
       470  0
                   for (Float s : cvssBelow) {
       471  0
                       sb.append(s).append(',');
       472  0
                   }
       473  0
                   sb.append('}');
       474  
               }
       475  0
               sb.append('}');
       476  0
               return sb.toString();
       477  
           }
       478  
       }
      + + + + diff --git a/dependency-check-core/cpd.html b/dependency-check-core/cpd.html index 9b2b7724c..5c39a07ff 100644 --- a/dependency-check-core/cpd.html +++ b/dependency-check-core/cpd.html @@ -1,13 +1,13 @@ - + dependency-check-core – CPD Results @@ -52,7 +52,7 @@ @@ -312,14 +312,63 @@ File Line -org\owasp\dependencycheck\suppression\SuppressionParser.java -117 +org\owasp\dependencycheck\xml\hints\HintErrorHandler.java +36 -org\owasp\dependencycheck\suppression\SuppressionParser.java -165 +org\owasp\dependencycheck\xml\suppression\SuppressionErrorHandler.java +36
      -
                  final InputStream schemaStream = this.getClass().getClassLoader().getResourceAsStream("schema/dependency-suppression.1.1.xsd");
      +
          private static final Logger LOGGER = LoggerFactory.getLogger(HintErrorHandler.class);
      +
      +    /**
      +     * Builds a prettier exception message.
      +     *
      +     * @param ex the SAXParseException
      +     * @return an easier to read exception message
      +     */
      +    private String getPrettyParseExceptionInfo(SAXParseException ex) {
      +
      +        final StringBuilder sb = new StringBuilder();
      +
      +        if (ex.getSystemId() != null) {
      +            sb.append("systemId=").append(ex.getSystemId()).append(", ");
      +        }
      +        if (ex.getPublicId() != null) {
      +            sb.append("publicId=").append(ex.getPublicId()).append(", ");
      +        }
      +        if (ex.getLineNumber() > 0) {
      +            sb.append("Line=").append(ex.getLineNumber());
      +        }
      +        if (ex.getColumnNumber() > 0) {
      +            sb.append(", Column=").append(ex.getColumnNumber());
      +        }
      +        sb.append(": ").append(ex.getMessage());
      +
      +        return sb.toString();
      +    }
      +
      +    /**
      +     * Logs warnings.
      +     *
      +     * @param ex the warning to log
      +     * @throws SAXException is never thrown
      +     */
      +    @Override
      +    public void warning(SAXParseException ex) throws SAXException {
      + + + + + + + + + + + - - + + - +
      FileLine
      org\owasp\dependencycheck\xml\suppression\SuppressionParser.java125
      org\owasp\dependencycheck\xml\suppression\SuppressionParser.java173
      +
      +
                  final InputStream schemaStream = this.getClass().getClassLoader().getResourceAsStream(SUPPRESSION_SCHEMA);
                   final SuppressionHandler handler = new SuppressionHandler();
                   final SAXParserFactory factory = SAXParserFactory.newInstance();
                   factory.setNamespaceAware(true);
      @@ -347,112 +396,39 @@
       
      File Line
      org\owasp\dependencycheck\analyzer\JarAnalyzer.java910
      org\owasp\dependencycheck\analyzer\ArchiveAnalyzer.java182
      org\owasp\dependencycheck\analyzer\PythonDistributionAnalyzer.java236
      244
      -
          public void initializeFileTypeAnalyzer() throws Exception {
      -        final File baseDir = Settings.getTempDirectory();
      -        tempFileLocation = File.createTempFile("check", "tmp", baseDir);
      -        if (!tempFileLocation.delete()) {
      -            final String msg = String.format("Unable to delete temporary file '%s'.", tempFileLocation.getAbsolutePath());
      -            throw new AnalysisException(msg);
      -        }
      -        if (!tempFileLocation.mkdirs()) {
      -            final String msg = String.format("Unable to create directory '%s'.", tempFileLocation.getAbsolutePath());
      -            throw new AnalysisException(msg);
      -        }
      -    }
      -
      -    /**
      -     * Deletes any files extracted from the JAR during analysis.
      -     */
      -    @Override
      -    public void close() {
      -        if (tempFileLocation != null && tempFileLocation.exists()) {
      -            LOGGER.debug("Attempting to delete temporary files");
      -            final boolean success = FileUtils.delete(tempFileLocation);
      -            if (!success) {
      -                LOGGER.warn("Failed to delete some temporary files, see the log for more details");
      +
          public void initializeFileTypeAnalyzer() throws InitializationException {
      +        try {
      +            final File baseDir = Settings.getTempDirectory();
      +            tempFileLocation = File.createTempFile("check", "tmp", baseDir);
      +            if (!tempFileLocation.delete()) {
      +                setEnabled(false);
      +                final String msg = String.format("Unable to delete temporary file '%s'.", tempFileLocation.getAbsolutePath());
      +                throw new InitializationException(msg);
                   }
      +            if (!tempFileLocation.mkdirs()) {
      +                setEnabled(false);
      +                final String msg = String.format("Unable to create directory '%s'.", tempFileLocation.getAbsolutePath());
      +                throw new InitializationException(msg);
      +            }
      +        } catch (IOException ex) {
      +            setEnabled(false);
      +            throw new InitializationException("Unable to create a temporary file", ex);
               }
           }
       
           /**
      -     * Determines if the key value pair from the manifest is for an "import"
      -     * type entry for package names.
      +     * The close method deletes any temporary files and directories created
      +     * during analysis.
            *
      -     * @param key the key from the manifest
      -     * @param value the value from the manifest
      -     * @return true or false depending on if it is believed the entry is an
      -     * "import" entry
      -     */
      -    private boolean isImportPackage(String key, String value) {
      - - - - - - - - - - -
      FileLine
      org\owasp\dependencycheck\analyzer\ArchiveAnalyzer.java174
      org\owasp\dependencycheck\analyzer\JarAnalyzer.java909
      -
      -
          @Override
      -    public void initializeFileTypeAnalyzer() throws Exception {
      -        final File baseDir = Settings.getTempDirectory();
      -        tempFileLocation = File.createTempFile("check", "tmp", baseDir);
      -        if (!tempFileLocation.delete()) {
      -            final String msg = String.format("Unable to delete temporary file '%s'.", tempFileLocation.getAbsolutePath());
      -            throw new AnalysisException(msg);
      -        }
      -        if (!tempFileLocation.mkdirs()) {
      -            final String msg = String.format("Unable to create directory '%s'.", tempFileLocation.getAbsolutePath());
      -            throw new AnalysisException(msg);
      -        }
      -    }
      -
      -    /**
      -     * The close method deletes any temporary files and directories created during analysis.
      -     *
      -     * @throws Exception thrown if there is an exception deleting temporary files
      -     */
      -    @Override
      -    public void close() throws Exception {
      - - - - - - - - - - -
      FileLine
      org\owasp\dependencycheck\analyzer\ArchiveAnalyzer.java175
      org\owasp\dependencycheck\analyzer\PythonDistributionAnalyzer.java236
      -
      -
          public void initializeFileTypeAnalyzer() throws Exception {
      -        final File baseDir = Settings.getTempDirectory();
      -        tempFileLocation = File.createTempFile("check", "tmp", baseDir);
      -        if (!tempFileLocation.delete()) {
      -            final String msg = String.format("Unable to delete temporary file '%s'.", tempFileLocation.getAbsolutePath());
      -            throw new AnalysisException(msg);
      -        }
      -        if (!tempFileLocation.mkdirs()) {
      -            final String msg = String.format("Unable to create directory '%s'.", tempFileLocation.getAbsolutePath());
      -            throw new AnalysisException(msg);
      -        }
      -    }
      -
      -    /**
      -     * The close method deletes any temporary files and directories created during analysis.
      -     *
      -     * @throws Exception thrown if there is an exception deleting temporary files
      +     * @throws Exception thrown if there is an exception deleting temporary
      +     * files
            */
           @Override
           public void close() throws Exception {
      diff --git a/dependency-check-core/dependency-analysis.html b/dependency-check-core/dependency-analysis.html index e340a25d0..fbbca43a3 100644 --- a/dependency-check-core/dependency-analysis.html +++ b/dependency-check-core/dependency-analysis.html @@ -1,13 +1,13 @@ - + dependency-check-core – Dependencies Report @@ -52,7 +52,7 @@ @@ -268,7 +268,7 @@ org.owasp dependency-check-utils -1.4.0 +1.4.2 compile jar @@ -284,7 +284,7 @@ org.jmockit jmockit -1.22 +1.24 test jar @@ -292,7 +292,7 @@ org.apache.commons commons-compress -1.11 +1.12 compile jar @@ -356,7 +356,7 @@ org.jsoup jsoup -1.9.1 +1.9.2 compile jar @@ -566,6 +566,14 @@ test jar + + +com.thoughtworks.xstream +xstream +1.4.8 +test + +jar
      diff --git a/dependency-check-core/dependency-updates-report.html b/dependency-check-core/dependency-updates-report.html index 7550d79ec..97a7e306d 100644 --- a/dependency-check-core/dependency-updates-report.html +++ b/dependency-check-core/dependency-updates-report.html @@ -1,13 +1,13 @@ - + dependency-check-core – Dependency Updates Report @@ -52,7 +52,7 @@ @@ -243,7 +243,7 @@ # of dependencies using the latest version available -25 +26 # of dependencies where the next version available is smaller than an incremental version update @@ -411,7 +411,7 @@ org.apache.commons commons-compress -1.11 +1.12 jar @@ -591,24 +591,24 @@ org.jmockit jmockit -1.22 +1.24 test jar -1.23 +1.25 - + org.jsoup jsoup -1.9.1 +1.9.2 jar -1.9.2 + @@ -685,7 +685,7 @@ 4.0-beta -4.0 + com.hazelcast @@ -700,6 +700,18 @@ 3.0 +com.thoughtworks.xstream +xstream +1.4.8 +test + +jar + +1.4.9 + + + + net.sf.ehcache ehcache-core 2.2.0 @@ -710,7 +722,7 @@ 2.3.0 - + org.apache.axis2 axis2-adb @@ -722,7 +734,7 @@ 1.5 - + org.apache.axis2 axis2-spring @@ -734,7 +746,7 @@ 1.5 - + org.apache.geronimo.daytrader daytrader-ear @@ -746,7 +758,7 @@ - + org.apache.maven.scm maven-scm-provider-cvsexe @@ -758,7 +770,7 @@ 1.9 - + org.apache.openjpa openjpa @@ -770,7 +782,7 @@ 2.1.0 - + org.apache.struts struts2-core @@ -782,7 +794,7 @@ 2.1.6 2.2.1 - + org.dojotoolkit dojo-war @@ -794,7 +806,7 @@ 1.11.1 - + org.glassfish.main.admingui war @@ -806,7 +818,7 @@ 4.1 - + org.mortbay.jetty jetty @@ -818,11 +830,11 @@ 6.1.17 - + org.owasp dependency-check-utils -1.4.0 +1.4.2 compile jar @@ -830,7 +842,7 @@ - + org.springframework spring-webmvc @@ -842,7 +854,7 @@ 2.5.6 3.0.0.RELEASE - + org.springframework.retry spring-retry @@ -854,7 +866,7 @@ 1.1.1.RELEASE - + org.springframework.security spring-security-web @@ -866,7 +878,7 @@ 3.0.1.RELEASE 3.1.0.RELEASE 4.0.0.RELEASE - + uk.ltd.getahead dwr @@ -878,7 +890,7 @@ - + xalan xalan @@ -890,7 +902,7 @@ 2.7.2 - + Status Group Id Artifact Id @@ -908,25 +920,25 @@

      ch.qos.logback:logback-classic

      - + - + - + - + - + - + - +
      Status  No newer versions available.
      Group Id ch.qos.logback
      Artifact Id logback-classic
      Current Version 1.1.7
      Scope
      Classifier
      Type jar
      @@ -1003,7 +1015,7 @@ jar Newer versions -4.0-beta Next Minor
      4.0-beta4
      4.0-beta5 Latest Minor
      4.0 Next Major
      +4.0-beta Next Minor
      4.0-beta4
      4.0-beta5 Latest Minor

      com.h2database:h2

      @@ -1057,7 +1069,7 @@ -
      jar
      Newer versions2.5.1 Next Incremental
      2.6 Next Minor
      2.6.1
      2.6.2
      2.6.3
      2.6.4
      2.6.5
      2.6.6
      2.6.7
      2.6.8
      2.6.9
      3.0-RC1
      3.0-RC2 Latest Minor
      3.0 Next Major
      3.0.1
      3.0.2
      3.0.3
      3.1
      3.1.1
      3.1.2
      3.1.3
      3.1.4
      3.1.5
      3.1.6
      3.1.7
      3.1.8
      3.2-RC1
      3.2-RC2
      3.2
      3.2.1
      3.2.2
      3.2.3
      3.2.4
      3.2.5
      3.2.6
      3.3-RC1
      3.3-RC2
      3.3-RC3
      3.3
      3.3-EA
      3.3-EA2
      3.3.1
      3.3.2
      3.3.3
      3.3.4
      3.3.5
      3.4
      3.4-EA
      3.4.1
      3.4.2
      3.4.5
      3.4.6
      3.4.7
      3.4.8
      3.5-EA
      3.5.1
      3.5.2
      3.5.3
      3.5.4
      3.5.5
      3.6-RC1
      3.6
      3.6-EA
      3.6-EA2
      3.6-EA3
      3.6.1
      3.6.2
      3.6.3
      3.7-EA Latest Major
      +2.5.1 Next Incremental
      2.6 Next Minor
      2.6.1
      2.6.2
      2.6.3
      2.6.4
      2.6.5
      2.6.6
      2.6.7
      2.6.8
      2.6.9
      3.0-RC1
      3.0-RC2 Latest Minor
      3.0 Next Major
      3.0.1
      3.0.2
      3.0.3
      3.1
      3.1.1
      3.1.2
      3.1.3
      3.1.4
      3.1.5
      3.1.6
      3.1.7
      3.1.8
      3.2-RC1
      3.2-RC2
      3.2
      3.2.1
      3.2.2
      3.2.3
      3.2.4
      3.2.5
      3.2.6
      3.3-RC1
      3.3-RC2
      3.3-RC3
      3.3
      3.3-EA
      3.3-EA2
      3.3.1
      3.3.2
      3.3.3
      3.3.4
      3.3.5
      3.4
      3.4-EA
      3.4.1
      3.4.2
      3.4.5
      3.4.6
      3.4.7
      3.4.8
      3.5-EA
      3.5.1
      3.5.2
      3.5.3
      3.5.4
      3.5.5
      3.6-RC1
      3.6
      3.6-EA
      3.6-EA2
      3.6-EA3
      3.6.1
      3.6.2
      3.6.3
      3.6.4
      3.7-EA Latest Major

      com.sun.mail:mailapi

      @@ -1083,6 +1095,33 @@
      Type jar
      +

      com.thoughtworks.xstream:xstream

      + + + + + + + + + + + + + + + + + + + + + + + + +
      Status There is at least one newer incremental version available. Incremental updates are typically passive.
      Group Idcom.thoughtworks.xstream
      Artifact Idxstream
      Current Version1.4.8
      Scopetest
      Classifier
      Typejar
      Newer versions1.4.9 Next Incremental
      +

      commons-cli:commons-cli

      @@ -1324,7 +1363,7 @@ - + @@ -1411,7 +1450,7 @@ -
      commons-compress
      Current Version1.11
      1.12
      Scope
      jar
      Newer versions4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      6.0.0
      6.0.1 Latest Major
      +4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      5.5.2
      6.0.0
      6.0.1
      6.1.0 Latest Major

      org.apache.lucene:lucene-core

      @@ -1438,7 +1477,7 @@ -
      jar
      Newer versions4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      6.0.0
      6.0.1 Latest Major
      +4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      5.5.2
      6.0.0
      6.0.1
      6.1.0 Latest Major

      org.apache.lucene:lucene-queryparser

      @@ -1465,7 +1504,7 @@ -
      jar
      Newer versions4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      6.0.0
      6.0.1 Latest Major
      +4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      5.5.2
      6.0.0
      6.0.1
      6.1.0 Latest Major

      org.apache.lucene:lucene-test-framework

      @@ -1492,7 +1531,7 @@ -
      jar
      Newer versions4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      6.0.0
      6.0.1 Latest Major
      +4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      5.5.2
      6.0.0
      6.0.1
      6.1.0 Latest Major

      org.apache.maven:maven-core

      @@ -1663,7 +1702,7 @@ -
      jar
      Newer versions1.9 Next Minor
      1.9.1
      1.9.2
      1.9.4 Latest Minor
      +1.9 Next Minor
      1.9.1
      1.9.2
      1.9.4
      1.9.5 Latest Minor

      org.apache.openjpa:openjpa

      @@ -1717,7 +1756,7 @@ -
      jar
      Newer versions2.1.6 Next Incremental
      2.1.8
      2.1.8.1 Latest Incremental
      2.2.1 Next Minor
      2.2.1.1
      2.2.3
      2.2.3.1
      2.3.1
      2.3.1.1
      2.3.1.2
      2.3.3
      2.3.4
      2.3.4.1
      2.3.7
      2.3.8
      2.3.12
      2.3.14
      2.3.14.1
      2.3.14.2
      2.3.14.3
      2.3.15
      2.3.15.1
      2.3.15.2
      2.3.15.3
      2.3.16
      2.3.16.1
      2.3.16.2
      2.3.16.3
      2.3.20
      2.3.20.1
      2.3.20.3
      2.3.24
      2.3.24.1
      2.3.24.3
      2.3.28
      2.3.28.1
      2.5-BETA1
      2.5-BETA2
      2.5-BETA3
      2.5 Latest Minor
      +2.1.6 Next Incremental
      2.1.8
      2.1.8.1 Latest Incremental
      2.2.1 Next Minor
      2.2.1.1
      2.2.3
      2.2.3.1
      2.3.1
      2.3.1.1
      2.3.1.2
      2.3.3
      2.3.4
      2.3.4.1
      2.3.7
      2.3.8
      2.3.12
      2.3.14
      2.3.14.1
      2.3.14.2
      2.3.14.3
      2.3.15
      2.3.15.1
      2.3.15.2
      2.3.15.3
      2.3.16
      2.3.16.1
      2.3.16.2
      2.3.16.3
      2.3.20
      2.3.20.1
      2.3.20.3
      2.3.24
      2.3.24.1
      2.3.24.3
      2.3.28
      2.3.28.1
      2.3.29
      2.3.30
      2.5-BETA1
      2.5-BETA2
      2.5-BETA3
      2.5
      2.5.1
      2.5.2 Latest Minor

      org.apache.velocity:velocity

      @@ -1768,7 +1807,7 @@ -
      war
      Newer versions1.11.1 Next Minor
      +1.11.1 Next Minor
      1.11.2 Latest Minor

      org.glassfish:javax.json

      @@ -1858,7 +1897,7 @@ - + @@ -1870,13 +1909,13 @@ -
      jmockit
      Current Version1.22
      1.24
      Scope test
      jar
      Newer versions1.23 Next Minor
      1.24 Latest Minor
      +1.25 Next Minor

      org.jsoup:jsoup

      - + @@ -1885,7 +1924,7 @@ - + @@ -1894,10 +1933,7 @@ - - - -
      Status There is at least one newer incremental version available. Incremental updates are typically passive.
       No newer versions available.
      Group Id org.jsoup
      jsoup
      Current Version1.9.1
      1.9.2
      Scope
      Typejar
      Newer versions1.9.2 Next Incremental
      +jar

      org.mortbay.jetty:jetty

      @@ -1939,7 +1975,7 @@ - + @@ -2047,7 +2083,7 @@ -
      dependency-check-utils
      Current Version1.4.0
      1.4.2
      Scope compile
      jar
      Newer versions2.5.6 Next Incremental
      2.5.6.SEC01
      2.5.6.SEC02
      2.5.6.SEC03 Latest Incremental
      3.0.0.RELEASE Next Major
      3.0.1.RELEASE
      3.0.2.RELEASE
      3.0.3.RELEASE
      3.0.4.RELEASE
      3.0.5.RELEASE
      3.0.6.RELEASE
      3.0.7.RELEASE
      3.1.0.RELEASE
      3.1.1.RELEASE
      3.1.2.RELEASE
      3.2.0.RELEASE
      3.2.1.RELEASE
      3.2.2.RELEASE
      3.2.3.RELEASE
      3.2.4.RELEASE
      3.2.5.RELEASE
      3.2.6.RELEASE
      3.2.7.RELEASE
      3.2.8.RELEASE
      3.2.9.RELEASE
      3.2.10.RELEASE
      3.2.11.RELEASE
      3.2.12.RELEASE
      3.2.13.RELEASE
      3.2.14.RELEASE
      3.2.15.RELEASE
      3.2.16.RELEASE
      3.2.17.RELEASE
      4.0.0.RELEASE
      4.0.1.RELEASE
      4.0.2.RELEASE
      4.0.3.RELEASE
      4.0.4.RELEASE
      4.0.5.RELEASE
      4.0.6.RELEASE
      4.0.7.RELEASE
      4.0.8.RELEASE
      4.0.9.RELEASE
      4.1.0.RELEASE
      4.1.1.RELEASE
      4.1.2.RELEASE
      4.1.3.RELEASE
      4.1.4.RELEASE
      4.1.5.RELEASE
      4.1.6.RELEASE
      4.1.7.RELEASE
      4.1.8.RELEASE
      4.1.9.RELEASE
      4.2.0.RELEASE
      4.2.1.RELEASE
      4.2.2.RELEASE
      4.2.3.RELEASE
      4.2.4.RELEASE
      4.2.5.RELEASE
      4.2.6.RELEASE
      4.3.0.RELEASE Latest Major
      +2.5.6 Next Incremental
      2.5.6.SEC01
      2.5.6.SEC02
      2.5.6.SEC03 Latest Incremental
      3.0.0.RELEASE Next Major
      3.0.1.RELEASE
      3.0.2.RELEASE
      3.0.3.RELEASE
      3.0.4.RELEASE
      3.0.5.RELEASE
      3.0.6.RELEASE
      3.0.7.RELEASE
      3.1.0.RELEASE
      3.1.1.RELEASE
      3.1.2.RELEASE
      3.2.0.RELEASE
      3.2.1.RELEASE
      3.2.2.RELEASE
      3.2.3.RELEASE
      3.2.4.RELEASE
      3.2.5.RELEASE
      3.2.6.RELEASE
      3.2.7.RELEASE
      3.2.8.RELEASE
      3.2.9.RELEASE
      3.2.10.RELEASE
      3.2.11.RELEASE
      3.2.12.RELEASE
      3.2.13.RELEASE
      3.2.14.RELEASE
      3.2.15.RELEASE
      3.2.16.RELEASE
      3.2.17.RELEASE
      4.0.0.RELEASE
      4.0.1.RELEASE
      4.0.2.RELEASE
      4.0.3.RELEASE
      4.0.4.RELEASE
      4.0.5.RELEASE
      4.0.6.RELEASE
      4.0.7.RELEASE
      4.0.8.RELEASE
      4.0.9.RELEASE
      4.1.0.RELEASE
      4.1.1.RELEASE
      4.1.2.RELEASE
      4.1.3.RELEASE
      4.1.4.RELEASE
      4.1.5.RELEASE
      4.1.6.RELEASE
      4.1.7.RELEASE
      4.1.8.RELEASE
      4.1.9.RELEASE
      4.2.0.RELEASE
      4.2.1.RELEASE
      4.2.2.RELEASE
      4.2.3.RELEASE
      4.2.4.RELEASE
      4.2.5.RELEASE
      4.2.6.RELEASE
      4.2.7.RELEASE
      4.3.0.RELEASE
      4.3.1.RELEASE
      4.3.2.RELEASE Latest Major

      org.springframework.retry:spring-retry

      @@ -2074,7 +2110,7 @@ -
      jar
      Newer versions1.1.1.RELEASE Next Incremental
      1.1.2.RELEASE Latest Incremental
      +1.1.1.RELEASE Next Incremental
      1.1.2.RELEASE
      1.1.3.RELEASE Latest Incremental

      org.springframework.security:spring-security-web

      @@ -2101,7 +2137,7 @@ -
      jar
      Newer versions3.0.1.RELEASE Next Incremental
      3.0.2.RELEASE
      3.0.3.RELEASE
      3.0.4.RELEASE
      3.0.5.RELEASE
      3.0.6.RELEASE
      3.0.7.RELEASE
      3.0.8.RELEASE Latest Incremental
      3.1.0.RELEASE Next Minor
      3.1.1.RELEASE
      3.1.2.RELEASE
      3.1.3.RELEASE
      3.1.4.RELEASE
      3.1.5.RELEASE
      3.1.6.RELEASE
      3.1.7.RELEASE
      3.2.0.RELEASE
      3.2.1.RELEASE
      3.2.2.RELEASE
      3.2.3.RELEASE
      3.2.4.RELEASE
      3.2.5.RELEASE
      3.2.6.RELEASE
      3.2.7.RELEASE
      3.2.8.RELEASE
      3.2.9.RELEASE Latest Minor
      4.0.0.RELEASE Next Major
      4.0.1.RELEASE
      4.0.2.RELEASE
      4.0.3.RELEASE
      4.0.4.RELEASE
      4.1.0.RELEASE Latest Major
      +3.0.1.RELEASE Next Incremental
      3.0.2.RELEASE
      3.0.3.RELEASE
      3.0.4.RELEASE
      3.0.5.RELEASE
      3.0.6.RELEASE
      3.0.7.RELEASE
      3.0.8.RELEASE Latest Incremental
      3.1.0.RELEASE Next Minor
      3.1.1.RELEASE
      3.1.2.RELEASE
      3.1.3.RELEASE
      3.1.4.RELEASE
      3.1.5.RELEASE
      3.1.6.RELEASE
      3.1.7.RELEASE
      3.2.0.RELEASE
      3.2.1.RELEASE
      3.2.2.RELEASE
      3.2.3.RELEASE
      3.2.4.RELEASE
      3.2.5.RELEASE
      3.2.6.RELEASE
      3.2.7.RELEASE
      3.2.8.RELEASE
      3.2.9.RELEASE Latest Minor
      4.0.0.RELEASE Next Major
      4.0.1.RELEASE
      4.0.2.RELEASE
      4.0.3.RELEASE
      4.0.4.RELEASE
      4.1.0.RELEASE
      4.1.1.RELEASE Latest Major

      uk.ltd.getahead:dwr

      diff --git a/dependency-check-core/failsafe-report.html b/dependency-check-core/failsafe-report.html index 0dcbb56a2..66c25ebc4 100644 --- a/dependency-check-core/failsafe-report.html +++ b/dependency-check-core/failsafe-report.html @@ -1,13 +1,13 @@ - + dependency-check-core – Surefire Report @@ -52,7 +52,7 @@ @@ -267,12 +267,12 @@ function toggleDisplay(elementId) { - + -
      Success Rate Time
      3738 0 0 0 100%179.157

      +127.255

      Note: failures are anticipated and checked for with assertions while errors are unanticipated.


      Package List

      @@ -293,7 +293,7 @@ function toggleDisplay(elementId) { 0 0 100% -0.68 +1.11 org.owasp.dependencycheck.reporting 2 @@ -301,7 +301,7 @@ function toggleDisplay(elementId) { 0 0 100% -7.052 +7.627 org.owasp.dependencycheck.data.update.nvd 1 @@ -309,7 +309,7 @@ function toggleDisplay(elementId) { 0 0 100% -36.765 +2.642 org.owasp.dependencycheck.data.nvdcve 10 @@ -317,7 +317,7 @@ function toggleDisplay(elementId) { 0 0 100% -6.288 +6.628 org.owasp.dependencycheck 1 @@ -325,15 +325,15 @@ function toggleDisplay(elementId) { 0 0 100% -96.448 +46.583 org.owasp.dependencycheck.analyzer -21 +22 0 0 0 100% -31.924
      +62.665

      Note: package statistics are not computed recursively, they only sum up all of its testsuites numbers.

      org.owasp.dependencycheck.data.update

      @@ -355,7 +355,7 @@ function toggleDisplay(elementId) { 0 0 100% -0.005 +0.021 NvdCveUpdaterIntegrationTest @@ -364,7 +364,7 @@ function toggleDisplay(elementId) { 0 0 100% -0.675
      +1.089

      org.owasp.dependencycheck.reporting

      @@ -385,7 +385,7 @@ function toggleDisplay(elementId) { -
      0 0 100%7.052
      +7.627

      org.owasp.dependencycheck.data.update.nvd

      @@ -406,7 +406,7 @@ function toggleDisplay(elementId) { -
      0 0 100%36.765
      +2.642

      org.owasp.dependencycheck.data.nvdcve

      @@ -427,7 +427,7 @@ function toggleDisplay(elementId) { - + @@ -436,7 +436,7 @@ function toggleDisplay(elementId) { -
      0 0 100%3.18
      3.513
      DatabasePropertiesIntegrationTest0 0 100%3.108
      +3.115

      org.owasp.dependencycheck

      @@ -457,7 +457,7 @@ function toggleDisplay(elementId) { -
      0 0 100%96.448
      +46.583

      org.owasp.dependencycheck.analyzer

      @@ -473,12 +473,12 @@ function toggleDisplay(elementId) { - + - + @@ -487,7 +487,7 @@ function toggleDisplay(elementId) { - + @@ -496,7 +496,7 @@ function toggleDisplay(elementId) { - + @@ -505,7 +505,7 @@ function toggleDisplay(elementId) { -
      ArchiveAnalyzerIntegrationTest1213 0 0 0 100%23.483
      19.052
      CPEAnalyzerIntegrationTest0 0 100%6.175
      41.103
      DependencyBundlingAnalyzerIntegrationTest0 0 100%0.003
      0
      VulnerabilitySuppressionAnalyzerIntegrationTest0 0 100%2.263

      +2.51

      Test Cases

      [Summary] [Package List] [Test Cases]

      @@ -514,49 +514,53 @@ function toggleDisplay(elementId) { - - + + + + + + - - - - - + - - + + + + + + - + - + - - + + - - - - - - + + + + + + - +
      testAnalyzeTar3.301
      testAnalyzeExecutableJar1.079
      testAnalyzeTar1.418
      testAnalyzeTgz5.892
      testAnalyzeTarBz24.492
      4.873
      testAnalyze1.985
      testAnalyzeTarBz23.642
      testAnalyze0.818
      testGetAnalysisPhase 0
      testGetName 0
      testAnalyze_badZip0.558
      0.521
      testInitialize 0
      testAnalyzeTbz23.19
      testAnalyzeTarGz3.403
      testAnalyzeTbz23.137
      testAnalyzeTarGz2.96
      testSupportsExtension 0
      testSupportsExtensions 0
      @@ -566,19 +570,19 @@ function toggleDisplay(elementId) { testSearchCPE -1.722 +1.768 testDetermineCPE -1.505 +1.156 testDetermineIdentifiers -1.205 +0.908 testDetermineCPE_full -1.734 +37.271 testBuildSearch @@ -596,7 +600,7 @@ function toggleDisplay(elementId) { testAnalyze -2.256 +2.495 testGetAnalysisPhase @@ -604,53 +608,53 @@ function toggleDisplay(elementId) { testGetName -0 +0.015

      CveDBIntegrationTest

      - + - + - + - + -
      testOpen0.97
      1.073
      testGetCPEs0.485
      0.528
      testGetVulnerabilities0.715
      0.815
      testGetMatchingSoftware0.495
      0.552
      testgetVulnerability0.513
      +0.529

      DatabasePropertiesIntegrationTest

      - + - + - + - + -
      testSave1.11
      1.024
      testGetProperty_String_String0.499
      0.515
      testGetProperties0.495
      0.541
      testGetProperty_String0.491
      0.513
      testIsEmpty0.508
      +0.522

      CpeUpdaterIntegrationTest

      @@ -664,32 +668,32 @@ function toggleDisplay(elementId) { -
      testUpdate36.759
      +2.642

      NvdCveUpdaterIntegrationTest

      -
      testUpdatesNeeded0.671
      +1.089

      EngineIntegrationTest

      -
      testEngine96.445
      +46.567

      ReportGeneratorIntegrationTest

      - + -
      testGenerateXMLReport7.047
      7.624
      testGenerateReport0.001

      +0
      diff --git a/dependency-check-core/findbugs.html b/dependency-check-core/findbugs.html index 5be51fca5..88d4afb0b 100644 --- a/dependency-check-core/findbugs.html +++ b/dependency-check-core/findbugs.html @@ -1,13 +1,13 @@ - + dependency-check-core – FindBugs Bug Detector Report @@ -52,7 +52,7 @@ @@ -251,8 +251,8 @@ Errors Missing Classes -137 -5 +147 +6 0 0
      @@ -262,48 +262,66 @@ Class Bugs +org.owasp.dependencycheck.analyzer.ArchiveAnalyzer +1 + org.owasp.dependencycheck.analyzer.CMakeAnalyzer 1 - + org.owasp.dependencycheck.analyzer.FalsePositiveAnalyzer 2 - + org.owasp.dependencycheck.analyzer.RubyBundleAuditAnalyzer 1 - -org.owasp.dependencycheck.analyzer.RubyGemspecAnalyzer -1
      -
      -

      org.owasp.dependencycheck.analyzer.CMakeAnalyzer

      - + +
      org.owasp.dependencycheck.analyzer.RubyGemspecAnalyzer1
      +
      +

      org.owasp.dependencycheck.analyzer.ArchiveAnalyzer

      + + + + + + + +
      Bug Category Details Line Priority
      org.owasp.dependencycheck.analyzer.ArchiveAnalyzer.ensureReadableJar(String, BufferedInputStream) ignores result of java.io.BufferedInputStream.read(byte[])BAD_PRACTICERR_NOT_CHECKED417Medium
      +
      +

      org.owasp.dependencycheck.analyzer.CMakeAnalyzer

      + + + + + + + - +
      BugCategoryDetailsLinePriority
      Found reliance on default encoding in org.owasp.dependencycheck.analyzer.CMakeAnalyzer.analyzeSetVersionCommand(Dependency, Engine, String): String.getBytes() I18N DM_DEFAULT_ENCODING221227 High

      org.owasp.dependencycheck.analyzer.FalsePositiveAnalyzer

      - + - + - + @@ -312,32 +330,32 @@

      org.owasp.dependencycheck.analyzer.RubyBundleAuditAnalyzer

      Bug Category Details Line Priority
      Possible null pointer dereference of currentVersion on branch that might be infeasible in org.owasp.dependencycheck.analyzer.FalsePositiveAnalyzer.removeSpuriousCPE(Dependency) STYLE NP_NULL_ON_SOME_PATH_MIGHT_BE_INFEASIBLE 188 Medium
      Possible null pointer dereference of nextVersion on branch that might be infeasible in org.owasp.dependencycheck.analyzer.FalsePositiveAnalyzer.removeSpuriousCPE(Dependency) STYLE NP_NULL_ON_SOME_PATH_MIGHT_BE_INFEASIBLE
      - + - + - +
      Bug Category Details Line Priority
      Exceptional return value of java.io.File.createNewFile() ignored in org.owasp.dependencycheck.analyzer.RubyBundleAuditAnalyzer.createDependencyForGem(Engine, String, String, String, String) BAD_PRACTICE RV_RETURN_VALUE_IGNORED_BAD_PRACTICE459485 Medium

      org.owasp.dependencycheck.analyzer.RubyGemspecAnalyzer

      - + - + - +
      Bug Category Details Line Priority
      Possible null pointer dereference in org.owasp.dependencycheck.analyzer.RubyGemspecAnalyzer.addEvidenceFromVersionFile(File, EvidenceCollection) due to return value of called method STYLE NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE218220 Medium
      diff --git a/dependency-check-core/index.html b/dependency-check-core/index.html index 0c191f85b..968d06a9c 100644 --- a/dependency-check-core/index.html +++ b/dependency-check-core/index.html @@ -1,13 +1,13 @@ - + dependency-check-core – About @@ -52,7 +52,7 @@ diff --git a/dependency-check-core/integration.html b/dependency-check-core/integration.html index 183bc6cf2..eeb717174 100644 --- a/dependency-check-core/integration.html +++ b/dependency-check-core/integration.html @@ -1,13 +1,13 @@ - + dependency-check-core – CI Management @@ -52,7 +52,7 @@ diff --git a/dependency-check-core/issue-tracking.html b/dependency-check-core/issue-tracking.html index 82582c82b..2a8585ec8 100644 --- a/dependency-check-core/issue-tracking.html +++ b/dependency-check-core/issue-tracking.html @@ -1,13 +1,13 @@ - + dependency-check-core – Issue Management @@ -52,7 +52,7 @@ diff --git a/dependency-check-core/license.html b/dependency-check-core/license.html index f32803dd1..2ed5544bb 100644 --- a/dependency-check-core/license.html +++ b/dependency-check-core/license.html @@ -1,13 +1,13 @@ - + dependency-check-core – Project Licenses @@ -52,7 +52,7 @@ diff --git a/dependency-check-core/mail-lists.html b/dependency-check-core/mail-lists.html index 8c48d0130..c4ec30abf 100644 --- a/dependency-check-core/mail-lists.html +++ b/dependency-check-core/mail-lists.html @@ -1,13 +1,13 @@ - + dependency-check-core – Project Mailing Lists @@ -52,7 +52,7 @@ diff --git a/dependency-check-core/nbproject/project.properties b/dependency-check-core/nbproject/project.properties new file mode 100644 index 000000000..e69de29bb diff --git a/dependency-check-core/plugin-updates-report.html b/dependency-check-core/plugin-updates-report.html index 77c18b95d..22d24734f 100644 --- a/dependency-check-core/plugin-updates-report.html +++ b/dependency-check-core/plugin-updates-report.html @@ -1,13 +1,13 @@ - + dependency-check-core – Plugin Updates Report @@ -52,7 +52,7 @@ @@ -243,7 +243,7 @@ # of plugins using the latest version available -18 +19 # of plugins where the next version available is smaller than an incremental version update @@ -259,7 +259,7 @@ # of plugins where the next version available is a major version update -1 +0 # of plugins where a dependencies section containes a dependency with an updated version @@ -381,7 +381,7 @@ org.apache.maven.plugins maven-jar-plugin -3.0.0 +3.0.2 @@ -391,7 +391,7 @@ org.apache.maven.plugins maven-javadoc-plugin -2.10.3 +2.10.4 @@ -428,14 +428,14 @@ - + org.apache.maven.plugins maven-source-plugin -2.4 +3.0.1 + -3.0.0 @@ -647,7 +647,7 @@ maven-jar-plugin Current Version -3.0.0 +3.0.2

      Plugin org.apache.maven.plugins:maven-javadoc-plugin

      @@ -662,7 +662,7 @@ -
      maven-javadoc-plugin
      Current Version2.10.3
      +2.10.4

      Plugin org.apache.maven.plugins:maven-release-plugin

      @@ -713,7 +713,7 @@
      - + @@ -722,10 +722,7 @@ - - - -
      Status There is at least one newer major version available. Major updates are rarely passive.
       No newer versions available.
      Group Id org.apache.maven.plugins
      maven-source-plugin
      Current Version2.4
      Newer versions3.0.0 Next Major
      +3.0.1

      Plugin org.apache.maven.plugins:maven-surefire-plugin

      diff --git a/dependency-check-core/pmd.html b/dependency-check-core/pmd.html index 2fbd00f91..2df97c251 100644 --- a/dependency-check-core/pmd.html +++ b/dependency-check-core/pmd.html @@ -1,13 +1,13 @@ - + dependency-check-core – PMD Results @@ -52,7 +52,7 @@ @@ -242,248 +242,266 @@

      Files

      -

      org/owasp/dependencycheck/analyzer/CPEAnalyzer.java

      +

      org/owasp/dependencycheck/analyzer/ArchiveAnalyzer.java

      - + - + -
      Violation Line
      These nested if statements could be combined570575
      431440
      These nested if statements could be combined571574
      432439
      These nested if statements could be combined579582
      +433438 + +These nested if statements could be combined +434437 +
      +

      org/owasp/dependencycheck/analyzer/CPEAnalyzer.java

      + + + + + + + + + + + + +
      ViolationLine
      These nested if statements could be combined581586
      These nested if statements could be combined582585
      These nested if statements could be combined590593

      org/owasp/dependencycheck/analyzer/FalsePositiveAnalyzer.java

      - + - + - +
      Violation Line
      These nested if statements could be combined 115121
      These nested if statements could be combined 177197
      -

      org/owasp/dependencycheck/analyzer/HintAnalyzer.java

      - - - - - - -
      ViolationLine
      Useless parentheses.127
      -

      org/owasp/dependencycheck/analyzer/JarAnalyzer.java

      - + - + -
      Violation Line
      Useless parentheses.385
      +386

      org/owasp/dependencycheck/analyzer/OpenSSLAnalyzer.java

      - + - + -
      Violation Line
      Useless parentheses.111
      +112

      org/owasp/dependencycheck/analyzer/PythonDistributionAnalyzer.java

      - + - + -
      Violation Line
      These nested if statements could be combined284287
      +299302

      org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java

      - + - + - + + + + - - - -
      Violation Line
      These nested if statements could be combined337339
      363365
      Useless parentheses.379
      Useless parentheses.353
      Useless parentheses.371
      +397

      org/owasp/dependencycheck/data/cpe/IndexEntry.java

      - + - + - +
      Violation Line
      Useless parentheses. 172
      Useless parentheses. 175

      org/owasp/dependencycheck/data/lucene/TokenPairConcatenatingFilter.java

      - + - +
      Violation Line
      Useless parentheses. 156

      org/owasp/dependencycheck/data/nvdcve/ConnectionFactory.java

      - + - +
      Violation Line
      Avoid empty if statements 332334

      org/owasp/dependencycheck/data/nvdcve/CveDB.java

      - + - - - -
      Violation Line
      These nested if statements could be combined648650
      These nested if statements could be combined760762
      +646648 + +These nested if statements could be combined +758760

      org/owasp/dependencycheck/data/nvdcve/DriverShim.java

      - + - +
      Violation Line
      Useless parentheses. 193

      org/owasp/dependencycheck/data/update/NvdCveUpdater.java

      - + - + -
      Violation Line
      Useless parentheses.181
      +177

      org/owasp/dependencycheck/data/update/nvd/DownloadTask.java

      - + - +
      Violation Line
      Useless parentheses. 253

      org/owasp/dependencycheck/dependency/Identifier.java

      - + - + - +
      Violation Line
      Useless parentheses. 191
      Useless parentheses. 194

      org/owasp/dependencycheck/dependency/Reference.java

      - + - - - - + + + +
      Violation Line
      Useless parentheses.115
      Useless parentheses.118
      115
      Useless parentheses.118
      Useless parentheses. 121

      org/owasp/dependencycheck/dependency/Vulnerability.java

      - + - + -
      Violation Line
      Useless parentheses.375
      +374

      org/owasp/dependencycheck/dependency/VulnerableSoftware.java

      - + - - - - + + + +
      Violation Line
      Useless parentheses.141
      Useless parentheses.180
      141
      Useless parentheses.180
      Useless parentheses. 185
      -

      org/owasp/dependencycheck/suppression/PropertyType.java

      - - - - - - -
      ViolationLine
      Useless parentheses.161
      -

      org/owasp/dependencycheck/utils/DependencyVersion.java

      - + - + - +
      Violation Line
      Useless parentheses. 136
      Useless parentheses. 197

      org/owasp/dependencycheck/xml/pom/License.java

      - + - + - +
      Violation Line
      Useless parentheses. 118
      Useless parentheses. 121

      org/owasp/dependencycheck/xml/pom/PomHandler.java

      + + + + + + + + +
      ViolationLine
      These nested if statements could be combined170176
      These nested if statements could be combined171175
      +
      +

      org/owasp/dependencycheck/xml/suppression/PropertyType.java

      + - - + +
      Violation Line
      These nested if statements could be combined170176
      Useless parentheses.161
      +
      +

      org/owasp/dependencycheck/xml/suppression/SuppressionErrorHandler.java

      + - -
      These nested if statements could be combined171175
      +Violation +Line + +Avoid unused private fields such as 'LOGGER'. +36 diff --git a/dependency-check-core/project-info.html b/dependency-check-core/project-info.html index f283b1204..e159da074 100644 --- a/dependency-check-core/project-info.html +++ b/dependency-check-core/project-info.html @@ -1,13 +1,13 @@ - + dependency-check-core – Project Information @@ -52,7 +52,7 @@ diff --git a/dependency-check-core/project-reports.html b/dependency-check-core/project-reports.html index 4d0ac2656..f431d0eb0 100644 --- a/dependency-check-core/project-reports.html +++ b/dependency-check-core/project-reports.html @@ -1,13 +1,13 @@ - + dependency-check-core – Generated Reports @@ -52,7 +52,7 @@ diff --git a/dependency-check-core/project-summary.html b/dependency-check-core/project-summary.html index c7b0b3272..d3e91d6d9 100644 --- a/dependency-check-core/project-summary.html +++ b/dependency-check-core/project-summary.html @@ -1,13 +1,13 @@ - + dependency-check-core – Project Summary @@ -52,7 +52,7 @@ @@ -230,7 +230,7 @@ dependency-check-core Version -1.4.0 +1.4.2 Type jar diff --git a/dependency-check-core/source-repository.html b/dependency-check-core/source-repository.html index ff0ee2254..262975588 100644 --- a/dependency-check-core/source-repository.html +++ b/dependency-check-core/source-repository.html @@ -1,13 +1,13 @@ - + dependency-check-core – Source Code Management @@ -52,7 +52,7 @@ diff --git a/dependency-check-core/surefire-report.html b/dependency-check-core/surefire-report.html index 9e9b9240f..e73d6af29 100644 --- a/dependency-check-core/surefire-report.html +++ b/dependency-check-core/surefire-report.html @@ -1,13 +1,13 @@ - + dependency-check-core – Surefire Report @@ -52,7 +52,7 @@ @@ -267,12 +267,12 @@ function toggleDisplay(elementId) { Success Rate Time -242 +245 0 0 -8 -96.694% -29.888
      +9 +96.327% +21.366

      Note: failures are anticipated and checked for with assertions while errors are unanticipated.


      Package List

      @@ -293,7 +293,7 @@ function toggleDisplay(elementId) { 0 0 100% -2.394 +2.413 org.owasp.dependencycheck.dependency 34 @@ -301,7 +301,7 @@ function toggleDisplay(elementId) { 0 0 100% -0.016 +0.015 org.owasp.dependencycheck.data.nexus 4 @@ -309,7 +309,7 @@ function toggleDisplay(elementId) { 0 4 0% -0.019 +0.002 org.owasp.dependencycheck.data.composer 4 @@ -317,23 +317,23 @@ function toggleDisplay(elementId) { 0 0 100% -0.05 +0.016 -org.owasp.dependencycheck.suppression -36 -0 -0 -0 -100% -0.037 - org.owasp.dependencycheck.data.nuget 3 0 0 0 100% -0.003 +0.006 + +org.owasp.dependencycheck.xml.hints +3 +0 +0 +0 +100% +0 org.owasp.dependencycheck.utils 13 @@ -341,15 +341,15 @@ function toggleDisplay(elementId) { 0 0 100% -0.042 +0.012 org.owasp.dependencycheck.analyzer 80 0 0 -4 -95% -24.286 +5 +93.75% +16.582 org.owasp.dependencycheck.data.cpe 1 @@ -357,7 +357,7 @@ function toggleDisplay(elementId) { 0 0 100% -0.013 +0.016 org.owasp.dependencycheck.data.lucene 10 @@ -365,7 +365,7 @@ function toggleDisplay(elementId) { 0 0 100% -0.573 +0.466 org.owasp.dependencycheck.data.cwe 1 @@ -373,7 +373,7 @@ function toggleDisplay(elementId) { 0 0 100% -0.002 +0 org.owasp.dependencycheck.data.update.nvd 15 @@ -381,7 +381,7 @@ function toggleDisplay(elementId) { 0 0 100% -1.197 +0.978 org.owasp.dependencycheck.xml.pom 23 @@ -389,7 +389,7 @@ function toggleDisplay(elementId) { 0 0 100% -0.017 +0 org.owasp.dependencycheck.data.nvdcve 7 @@ -397,15 +397,23 @@ function toggleDisplay(elementId) { 0 0 100% -1.236 +0.547 +org.owasp.dependencycheck.xml.suppression +36 +0 +0 +0 +100% +0.016 + org.owasp.dependencycheck.data.central 5 0 0 0 100% -0.003
      +0.297

      Note: package statistics are not computed recursively, they only sum up all of its testsuites numbers.

      org.owasp.dependencycheck.data.update

      @@ -427,7 +435,7 @@ function toggleDisplay(elementId) { 0 0 100% -2.123 +2.171 EngineVersionCheckTest @@ -436,7 +444,7 @@ function toggleDisplay(elementId) { 0 0 100% -0.271
      +0.242

      org.owasp.dependencycheck.dependency

      @@ -457,7 +465,7 @@ function toggleDisplay(elementId) { - + @@ -466,7 +474,7 @@ function toggleDisplay(elementId) { - + @@ -484,7 +492,7 @@ function toggleDisplay(elementId) { -
      0 0 100%0.003
      0.007
      EvidenceTest0 0 100%0.005
      0.002
      VulnerabilityTest0 0 100%0.005
      +0.003

      org.owasp.dependencycheck.data.nexus

      @@ -505,7 +513,7 @@ function toggleDisplay(elementId) { -
      0 4 0%0.019
      +0.002

      org.owasp.dependencycheck.data.composer

      @@ -526,54 +534,6 @@ function toggleDisplay(elementId) { -
      0 0 100%0.05
      -
      -

      org.owasp.dependencycheck.suppression

      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      ClassTestsErrors FailuresSkippedSuccess RateTime
      PropertyTypeTest4000100%0.003
      SuppressionHandlerTest1000100%0.003
      SuppressionParserTest1000100%0.015
      SuppressionRuleTest30000100% 0.016

      org.owasp.dependencycheck.data.nuget

      @@ -595,7 +555,37 @@ function toggleDisplay(elementId) { 0 0 100% -0.003
      +0.006 +
      +

      org.owasp.dependencycheck.xml.hints

      + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      ClassTestsErrors FailuresSkippedSuccess RateTime
      HintHandlerTest1000100%0
      HintParserTest2000100%0

      org.owasp.dependencycheck.utils

      @@ -616,7 +606,7 @@ function toggleDisplay(elementId) { - + @@ -625,7 +615,7 @@ function toggleDisplay(elementId) { - + @@ -664,7 +654,7 @@ function toggleDisplay(elementId) { - + @@ -673,7 +663,7 @@ function toggleDisplay(elementId) { - + @@ -682,7 +672,7 @@ function toggleDisplay(elementId) { - + @@ -691,7 +681,7 @@ function toggleDisplay(elementId) { - + @@ -700,7 +690,7 @@ function toggleDisplay(elementId) { - + @@ -709,7 +699,7 @@ function toggleDisplay(elementId) { - + @@ -718,7 +708,7 @@ function toggleDisplay(elementId) { - + @@ -727,7 +717,7 @@ function toggleDisplay(elementId) { - + @@ -736,7 +726,7 @@ function toggleDisplay(elementId) { - + @@ -754,7 +744,7 @@ function toggleDisplay(elementId) { - + @@ -763,7 +753,7 @@ function toggleDisplay(elementId) { - + @@ -772,7 +762,7 @@ function toggleDisplay(elementId) { - + @@ -781,7 +771,7 @@ function toggleDisplay(elementId) { - + @@ -790,7 +780,7 @@ function toggleDisplay(elementId) { - + @@ -799,7 +789,7 @@ function toggleDisplay(elementId) { - + @@ -808,7 +798,7 @@ function toggleDisplay(elementId) { - + @@ -817,16 +807,16 @@ function toggleDisplay(elementId) { - + - - - + + + @@ -835,7 +825,7 @@ function toggleDisplay(elementId) { - + @@ -844,7 +834,7 @@ function toggleDisplay(elementId) { -
      0 0 100%0.015
      0.004
      DependencyVersionTest0 0 100%0.022
      0.003
      DependencyVersionUtilTest0 0 100%1.665
      0.569
      AbstractSuppressionAnalyzerTest0 0 100%1.012
      0.394
      AnalyzerServiceTest0 0 100%0.09
      0.064
      ArchiveAnalyzerTest0 1 0%0.043
      0.002
      AssemblyAnalyzerTest0 1 80%1.674
      0.667
      AutoconfAnalyzerTest0 0 100%0.165
      0.031
      CMakeAnalyzerTest0 0 100%1.092
      0.837
      ComposerLockAnalyzerTest0 0 100%1.39
      1.071
      DependencyBundlingAnalyzerTest0 0 100%0.003
      0
      FalsePositiveAnalyzerTest0 0 100%0.002
      0
      HintAnalyzerTest0 0 100%5.993
      3.262
      JarAnalyzerTest0 0 100%0.383
      0.14
      NodePackageAnalyzerTest0 0 100%0.004
      0.008
      NuspecAnalyzerTest0 0 100%0.004
      0.003
      OpenSSLAnalyzerTest0 0 100%0.005
      0.002
      PythonDistributionAnalyzerTest0 0 100%2.025
      2.052
      PythonPackageAnalyzerTest0 0 100%2.019
      1.975
      RubyBundleAuditAnalyzerTest 6 0 0266.667%6.697
      350%5.503
      RubyBundlerAnalyzerTest0 0 100%0.013
      0
      RubyGemspecAnalyzerTest0 0 100%0.005
      +0

      org.owasp.dependencycheck.data.cpe

      @@ -865,7 +855,7 @@ function toggleDisplay(elementId) { -
      0 0 100%0.013
      +0.016

      org.owasp.dependencycheck.data.lucene

      @@ -886,7 +876,7 @@ function toggleDisplay(elementId) { - + @@ -895,7 +885,7 @@ function toggleDisplay(elementId) { - + @@ -904,7 +894,7 @@ function toggleDisplay(elementId) { - + @@ -913,7 +903,7 @@ function toggleDisplay(elementId) { -
      0 0 100%0.003
      0
      LuceneUtilsTest0 0 100%0.01
      0
      TokenPairConcatenatingFilterTest0 0 100%0.055
      0.116
      UrlTokenizingFilterTest0 0 100%0.505
      +0.35

      org.owasp.dependencycheck.data.cwe

      @@ -934,7 +924,7 @@ function toggleDisplay(elementId) { -
      0 0 100%0.002
      +0

      org.owasp.dependencycheck.data.update.nvd

      @@ -955,7 +945,7 @@ function toggleDisplay(elementId) { - + @@ -964,7 +954,7 @@ function toggleDisplay(elementId) { - + @@ -982,7 +972,7 @@ function toggleDisplay(elementId) { - + @@ -991,7 +981,7 @@ function toggleDisplay(elementId) { -
      0 0 100%0.946
      0.86
      NvdCveInfoTest0 0 100%0.004
      0.025
      NvdCve_1_2_HandlerTest0 0 100%0.238
      0.087
      UpdateableNvdCveTest0 0 100%0.006
      +0.003

      org.owasp.dependencycheck.xml.pom

      @@ -1012,7 +1002,7 @@ function toggleDisplay(elementId) { - + @@ -1021,7 +1011,7 @@ function toggleDisplay(elementId) { -
      0 0 100%0.002
      0
      PomUtilsTest0 0 100%0.015
      +0

      org.owasp.dependencycheck.data.nvdcve

      @@ -1042,7 +1032,7 @@ function toggleDisplay(elementId) { - + @@ -1051,7 +1041,55 @@ function toggleDisplay(elementId) { -
      0 0 100%0.922
      0.497
      DriverLoaderTest0 0 100%0.314
      +0.05 +
      +

      org.owasp.dependencycheck.xml.suppression

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      ClassTestsErrors FailuresSkippedSuccess RateTime
      PropertyTypeTest4000100%0
      SuppressionHandlerTest1000100%0
      SuppressionParserTest1000100%0.016
      SuppressionRuleTest30000100%0

      org.owasp.dependencycheck.data.central

      @@ -1072,7 +1110,7 @@ function toggleDisplay(elementId) { -
      0 0 100%0.003

      +0.297

      Test Cases

      [Summary] [Package List] [Test Cases]

      @@ -1082,37 +1120,37 @@ function toggleDisplay(elementId) { testNewHashSet -0.029
      +0.02

      AbstractSuppressionAnalyzerTest

      - + - + - + -
      testFailureToLocateSuppressionFileAnywhere0.581
      0.199
      testGetRulesFromSuppressionFileFromURL0.356
      0.17
      testGetRulesFromSuppressionFileInClasspath0.068
      0.022
      testGetSupportedExtensions0.002
      +0

      AnalyzerServiceTest

      - + -
      testGetAnalyzers0.08
      0.047
      testGetExperimentalAnalyzers0.007
      +0.017

      ArchiveAnalyzerTest

      @@ -1131,11 +1169,11 @@ function toggleDisplay(elementId) { - + - + - + -
      testGetName0.545
      0.253
      testAnalysis0.296
      0.128
      testWithSettingMono @@ -1148,18 +1186,18 @@ function toggleDisplay(elementId) {
      testNonexistent0.212
      0.099
      testLog4Net0.463
      +0.138

      AutoconfAnalyzerTest

      - + @@ -1171,15 +1209,15 @@ function toggleDisplay(elementId) { - + - + -
      testAnalyzeReadableConfigureScript0.067
      0
      testGetName
      testAnalyzeConfigureScript0.073
      0.031
      testAnalyzeConfigureAC10.011
      0
      testAnalyzeConfigureAC20.01
      +0

      CMakeAnalyzerTest

      @@ -1198,7 +1236,7 @@ function toggleDisplay(elementId) { - + @@ -1213,7 +1251,7 @@ function toggleDisplay(elementId) { - + @@ -1285,26 +1323,26 @@ function toggleDisplay(elementId) { - + - + -
      testAnalyzeCMakeListsOpenCV3rdParty1.048
      0.837
      testAccept
      testAnalyzePackageJson1.384
      1.071
      testSupportsFiles
      testAnalyze5.985
      3.246
      testGetAnalysisPhase0.001
      0
      testGetName0
      +0.016

      JarAnalyzerTest

      - + - + @@ -1312,14 +1350,14 @@ function toggleDisplay(elementId) { -
      testAnalyze0.315
      0.096
      testGetName0.001
      0
      testAcceptSupportedExtensions
      testParseManifest0.063
      +0.027

      NodePackageAnalyzerTest

      - + @@ -1380,23 +1418,23 @@ function toggleDisplay(elementId) { - + - + - + - + -
      testGetName0.001
      0
      testAnalyzePackageJson
      testAnalyzeEggArchiveNamedZip0
      0.002
      testAnalyzeWheel0.005
      0.02
      testAnalyzeEggInfoFolder0
      0.002
      testAnalyzeSitePackage0.007
      0.004
      testSupportsFiles0.003
      +0.004

      PythonPackageAnalyzerTest

      @@ -1418,7 +1456,7 @@ function toggleDisplay(elementId) { - + @@ -1433,19 +1471,24 @@ function toggleDisplay(elementId) { - - - + + + + + + + - + - +
      testMissingBundleAudit0.617
      0.713
      testGetNameskipped
      testDependenciesPath4.831
      testDependenciesPath +0
      skipped
      testAddCriticalityToVulnerability 0
      skipped
      testSupportsFiles 0
      @@ -1485,7 +1528,7 @@ function toggleDisplay(elementId) { testMultipleReturns -0 +0.181 testNullSha1 @@ -1497,30 +1540,30 @@ function toggleDisplay(elementId) { testValidSha1 -0 +0.069 testMissingSha1 -0 +0.047

      ComposerLockParserTest

      - + - + - + -
      testNotPackagesArray0.003
      0
      testValidComposerLock0.017
      0
      testNotComposer0.005
      0
      testNotJSON0.022
      +0.016

      IndexEntryTest

      @@ -1566,27 +1609,27 @@ function toggleDisplay(elementId) {
      - - + + - -
      testExamples0.037
      testClear0.038
      testClear0.008
      +testExamples +0

      UrlTokenizingFilterTest

      - - + + - - + + - -
      testEmptyTerm0
      testRandomStrings0.325
      testExamples0.038
      testEmptyTerm0.003
      testRandomStrings0.445
      +testExamples +0.005

      NexusSearchTest

      @@ -1647,7 +1690,7 @@ function toggleDisplay(elementId) { -
      testInitialize0.916
      +0.493

      DriverLoaderTest

      @@ -1670,11 +1713,11 @@ function toggleDisplay(elementId) { - + -
      testLoad_String_String0.041
      0.016
      testLoad_String_String_multiple_paths0.254
      +0.018

      BaseUpdaterTest

      @@ -1685,37 +1728,37 @@ function toggleDisplay(elementId) { - + - + -
      testOpenDataStores0.997
      1.048
      testGetProperties0.573
      0.547
      testCloseDataStores0.549
      +0.56

      EngineVersionCheckTest

      - + -
      testShouldUpdate0.234
      0.205
      testGetCurrentReleaseVersion0.026
      +0.037

      DownloadTaskTest

      - + -
      testIsXML0.013
      0
      testCall0.93
      +0.857

      NvdCveInfoTest

      @@ -1756,7 +1799,7 @@ function toggleDisplay(elementId) { -
      testParse0.235
      +0.084

      UpdateableNvdCveTest

      @@ -1850,7 +1893,7 @@ function toggleDisplay(elementId) { - + @@ -1929,162 +1972,6 @@ function toggleDisplay(elementId) {
      testGetEvidence0.001
      0
      testSetIdentifierstestParseCPE 0
      -

      PropertyTypeTest

      - - - - - - - - - - - - - - - - -
      testSetGetValue0
      testMatches0
      testIsRegex0
      testIsCaseSensitive0
      -
      -

      SuppressionHandlerTest

      - - - - -
      testHandler0
      -
      -

      SuppressionParserTest

      - - - - -
      testParseSuppressionRules0
      -
      -

      SuppressionRuleTest

      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      testCpeHasNoVersion0
      testCpe0
      testCve0
      testCwe0
      testBase0
      testSha10
      testCpeMatches0
      testHasCvssBelow0
      testProcess0
      testGetSha10
      testProcessGAV0
      testAddCvssBelow0
      testFilePath0
      testGetCvssBelow0
      testSetFilePath0
      testGetFilePath0
      testAddCpe0
      testAddCve0
      testAddCwe0
      testGetCpe0
      testGetCve0
      testGetCwe0
      testHasCpe0
      testHasCve0
      testHasCwe0
      testSetCvssBelow0
      testSetSha10
      testSetCpe0
      testSetCve0
      testSetCwe0
      -

      DateUtilTest

      @@ -2149,6 +2036,24 @@ function toggleDisplay(elementId) {
      testPasses 0
      +

      HintHandlerTest

      + + + + +
      testHandler0
      +
      +

      HintParserTest

      + + + + + + + + +
      testParseHints_File0
      testParseHints_InputStream0
      +

      ModelTest

      @@ -2245,6 +2150,162 @@ function toggleDisplay(elementId) { +
      testReadPom_File0
      +
      +

      PropertyTypeTest

      + + + + + + + + + + + + + + + + +
      testSetGetValue0
      testMatches0
      testIsRegex0
      testIsCaseSensitive0
      +
      +

      SuppressionHandlerTest

      + + + + +
      testHandler0
      +
      +

      SuppressionParserTest

      + + + + +
      testParseSuppressionRules0
      +
      +

      SuppressionRuleTest

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      testCpeHasNoVersion0
      testCpe0
      testCve0
      testCwe0
      testBase0
      testSha10
      testCpeMatches0
      testHasCvssBelow0
      testProcess0
      testGetSha10
      testProcessGAV0
      testAddCvssBelow0
      testFilePath0
      testGetCvssBelow0
      testSetFilePath0
      testGetFilePath0
      testAddCpe0
      testAddCve0
      testAddCwe0
      testGetCpe0
      testGetCve0
      testGetCwe0
      testHasCpe0
      testHasCve0
      testHasCwe0
      testSetCvssBelow0
      testSetSha10
      testSetCpe0
      testSetCve0
      testSetCwe 0

      Failure Details

      @@ -2270,6 +2331,12 @@ function toggleDisplay(elementId) { skipped: skipped +testDependenciesPath + + +skipped: skipped + + testAddCriticalityToVulnerability diff --git a/dependency-check-core/taglist.html b/dependency-check-core/taglist.html index 81efb0e37..0d8e9d463 100644 --- a/dependency-check-core/taglist.html +++ b/dependency-check-core/taglist.html @@ -1,13 +1,13 @@ - + dependency-check-core – Tag List report @@ -52,7 +52,7 @@ @@ -258,31 +258,31 @@ Line - can we get more evidence from the parent? EAR contains module name, etc. analyze the dependency (i.e. extract files) if it is a supported type. -235 +252 org.owasp.dependencycheck.analyzer.CMakeAnalyzer Line - refactor so we do not assign to the parameter (checkstyle) -211 +217 org.owasp.dependencycheck.analyzer.CPEAnalyzer Line test dojo-war against this. we shold get dojo-toolkit:dojo-toolkit AND dojo-toolkit:toolkit -188 +198 - does this nullify some of the fuzzy matching that happens in the lucene search? for instance CPE some-component and in the evidence we have SomeComponent. -439 +449 - likely need to change the split... not sure if this will work for CPE with special chars -457 +467 the following algorithm incorrectly identifies things as a lower version if there lower confidence evidence when the current (highest) version number is newer then anything in the NVD. -542 +552 the following isn't quite right is it? need to think about this guessing game a bit more. -567 +578 org.owasp.dependencycheck.analyzer.DependencyBundlingAnalyzerTest Line @@ -309,19 +309,19 @@ Line remove weighting -613 +614 change this to a regex? -728 +726 org.owasp.dependencycheck.analyzer.RubyGemspecAnalyzer Line support Rakefile = FileFilterBuilder.newInstance().addExtensions(GEMSPEC).addFilenames("Rakefile").build(); -74 +75 other checking? -221 +223 org.owasp.dependencycheck.analyzer.RubyGemspecAnalyzerTest Line diff --git a/dependency-check-core/team-list.html b/dependency-check-core/team-list.html index 37ffcf49e..a6ad0ec64 100644 --- a/dependency-check-core/team-list.html +++ b/dependency-check-core/team-list.html @@ -1,13 +1,13 @@ - + dependency-check-core – Project Team @@ -52,7 +52,7 @@ diff --git a/dependency-check-core/xref-test/allclasses-frame.html b/dependency-check-core/xref-test/allclasses-frame.html index 79ce705c5..fb24b4ccb 100644 --- a/dependency-check-core/xref-test/allclasses-frame.html +++ b/dependency-check-core/xref-test/allclasses-frame.html @@ -127,6 +127,12 @@
    188. HintAnalyzerTest +
    189. +
    190. + HintHandlerTest +
    191. +
    192. + HintParserTest
    193. IndexEntryTest @@ -153,7 +159,7 @@ NvdCveInfoTest
    194. - NvdCveUpdaterIntegrationTest + NvdCveUpdaterIntegrationTest
    195. NvdCve_1_2_HandlerTest @@ -168,7 +174,7 @@ PomUtilsTest
    196. - PropertyTypeTest + PropertyTypeTest
    197. PythonDistributionAnalyzerTest @@ -189,13 +195,13 @@ RubyGemspecAnalyzerTest
    198. - SuppressionHandlerTest + SuppressionHandlerTest
    199. - SuppressionParserTest + SuppressionParserTest
    200. - SuppressionRuleTest + SuppressionRuleTest
    201. TokenPairConcatenatingFilterTest diff --git a/dependency-check-core/xref-test/index.html b/dependency-check-core/xref-test/index.html index e71e8ba73..49f52c91f 100644 --- a/dependency-check-core/xref-test/index.html +++ b/dependency-check-core/xref-test/index.html @@ -4,7 +4,7 @@ - Dependency-Check Core 1.4.0 Reference + Dependency-Check Core 1.4.2 Reference diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/EngineIntegrationTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/EngineIntegrationTest.html index eac332370..d8dd77140 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/EngineIntegrationTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/EngineIntegrationTest.html @@ -25,45 +25,71 @@ 17 */ 18 package org.owasp.dependencycheck; 19 -20 import org.junit.After; -21 import static org.junit.Assert.assertTrue; -22 import org.junit.Before; -23 import org.junit.Test; -24 import org.owasp.dependencycheck.data.nvdcve.CveDB; -25 import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties; -26 import org.owasp.dependencycheck.reporting.ReportGenerator; -27 import org.owasp.dependencycheck.utils.Settings; -28 -29 /** -30 * -31 * @author Jeremy Long -32 */ -33 public class EngineIntegrationTest extends BaseDBTestCase { +20 import java.io.IOException; +21 import java.util.logging.Level; +22 import java.util.logging.Logger; +23 import static org.junit.Assert.assertTrue; +24 +25 import org.junit.Test; +26 import org.owasp.dependencycheck.data.nvdcve.CveDB; +27 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; +28 import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties; +29 import org.owasp.dependencycheck.exception.ExceptionCollection; +30 import org.owasp.dependencycheck.exception.ReportException; +31 import org.owasp.dependencycheck.reporting.ReportGenerator; +32 import org.owasp.dependencycheck.utils.InvalidSettingException; +33 import org.owasp.dependencycheck.utils.Settings; 34 -35 /** -36 * Test running the entire engine. -37 * -38 * @throws Exception is thrown when an exception occurs. -39 */ -40 @Test -41 public void testEngine() throws Exception { -42 String testClasses = "target/test-classes"; -43 boolean autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE); -44 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); -45 Engine instance = new Engine(); -46 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate); -47 instance.scan(testClasses); -48 assertTrue(instance.getDependencies().size() > 0); -49 instance.analyzeDependencies(); -50 CveDB cveDB = new CveDB(); -51 cveDB.open(); -52 DatabaseProperties dbProp = cveDB.getDatabaseProperties(); -53 cveDB.close(); -54 ReportGenerator rg = new ReportGenerator("DependencyCheck", instance.getDependencies(), instance.getAnalyzers(), dbProp); -55 rg.generateReports("./target/", "ALL"); -56 instance.cleanup(); -57 } -58 } +35 /** +36 * +37 * @author Jeremy Long +38 */ +39 public class EngineIntegrationTest extends BaseDBTestCase { +40 +41 /** +42 * Test running the entire engine. +43 * +44 * @throws java.io.IOException +45 * @throws org.owasp.dependencycheck.utils.InvalidSettingException +46 * @throws org.owasp.dependencycheck.data.nvdcve.DatabaseException +47 * @throws org.owasp.dependencycheck.exception.ReportException +48 * @throws org.owasp.dependencycheck.exception.ExceptionCollection +49 */ +50 @Test +51 public void testEngine() throws IOException, InvalidSettingException, DatabaseException, ReportException, ExceptionCollection { +52 String testClasses = "target/test-classes"; +53 boolean autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE); +54 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); +55 Engine instance = new Engine(); +56 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate); +57 instance.scan(testClasses); +58 assertTrue(instance.getDependencies().size() > 0); +59 try { +60 instance.analyzeDependencies(); +61 } catch (ExceptionCollection ex) { +62 if (ex.getExceptions().size()==1 && +63 (ex.getExceptions().get(0).getMessage().contains("bundle-audit") || +64 ex.getExceptions().get(0).getMessage().contains("AssemblyAnalyzer"))) { +65 //this is fine to ignore +66 } else if (ex.getExceptions().size()==2 && +67 ((ex.getExceptions().get(0).getMessage().contains("bundle-audit") && +68 ex.getExceptions().get(1).getMessage().contains("AssemblyAnalyzer")) || +69 (ex.getExceptions().get(1).getMessage().contains("bundle-audit") && +70 ex.getExceptions().get(0).getMessage().contains("AssemblyAnalyzer")))) { +71 //this is fine to ignore +72 } else { +73 throw ex; +74 } +75 } +76 CveDB cveDB = new CveDB(); +77 cveDB.open(); +78 DatabaseProperties dbProp = cveDB.getDatabaseProperties(); +79 cveDB.close(); +80 ReportGenerator rg = new ReportGenerator("DependencyCheck", instance.getDependencies(), instance.getAnalyzers(), dbProp); +81 rg.generateReports("./target/", "ALL"); +82 instance.cleanup(); +83 } +84 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzerTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzerTest.html index b19c56d9a..af40bbb41 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzerTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzerTest.html @@ -31,18 +31,18 @@ 23 import org.owasp.dependencycheck.Engine; 24 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; 25 import org.owasp.dependencycheck.dependency.Dependency; -26 import org.owasp.dependencycheck.suppression.SuppressionParseException; -27 import org.owasp.dependencycheck.suppression.SuppressionRule; -28 import org.owasp.dependencycheck.utils.Settings; -29 import org.slf4j.LoggerFactory; -30 -31 import java.net.MalformedURLException; -32 import java.net.URISyntaxException; -33 import java.util.List; -34 import java.util.Set; -35 -36 import static org.junit.Assert.assertNull; -37 import static org.junit.Assert.assertTrue; +26 import org.owasp.dependencycheck.xml.suppression.SuppressionRule; +27 import org.owasp.dependencycheck.utils.Settings; +28 import org.slf4j.LoggerFactory; +29 +30 import java.net.MalformedURLException; +31 import java.net.URISyntaxException; +32 import java.util.List; +33 import java.util.Set; +34 +35 import static org.junit.Assert.assertNull; +36 import static org.junit.Assert.assertTrue; +37 import org.owasp.dependencycheck.exception.InitializationException; 38 39 /** 40 * @author Jeremy Long @@ -57,74 +57,77 @@ 49 } 50 51 /** -52 * Test of getSupportedExtensions method, of class AbstractSuppressionAnalyzer. -53 */ -54 @Test -55 public void testGetSupportedExtensions() { -56 Set<String> result = instance.getSupportedExtensions(); -57 assertNull(result); -58 } -59 -60 /** -61 * Test of getRules method, of class AbstractSuppressionAnalyzer for suppression file declared as URL. -62 */ -63 @Test -64 public void testGetRulesFromSuppressionFileFromURL() throws Exception { -65 setSupressionFileFromURL(); -66 instance.initialize(); -67 int expCount = 5; -68 List<SuppressionRule> result = instance.getRules(); -69 assertTrue(expCount <= result.size()); -70 } -71 -72 /** -73 * Test of getRules method, of class AbstractSuppressionAnalyzer for suppression file declared as URL. -74 */ -75 @Test -76 public void testGetRulesFromSuppressionFileInClasspath() throws Exception { -77 Settings.setString(Settings.KEYS.SUPPRESSION_FILE, "suppressions.xml"); -78 instance.initialize(); -79 int expCount = 5; -80 int currentSize = instance.getRules().size(); -81 assertTrue(expCount <= currentSize); -82 } -83 -84 @Test(expected = SuppressionParseException.class) -85 public void testFailureToLocateSuppressionFileAnywhere() throws Exception { -86 Settings.setString(Settings.KEYS.SUPPRESSION_FILE, "doesnotexist.xml"); -87 instance.initialize(); -88 } -89 -90 private void setSupressionFileFromURL() throws Exception { -91 try { -92 final String uri = this.getClass().getClassLoader().getResource("suppressions.xml").toURI().toURL().toString(); -93 Settings.setString(Settings.KEYS.SUPPRESSION_FILE, uri); -94 } catch (URISyntaxException ex) { -95 LoggerFactory.getLogger(AbstractSuppressionAnalyzerTest.class).error("", ex); -96 } catch (MalformedURLException ex) { -97 LoggerFactory.getLogger(AbstractSuppressionAnalyzerTest.class).error("", ex); -98 } -99 } -100 -101 public class AbstractSuppressionAnalyzerImpl extends AbstractSuppressionAnalyzer { -102 -103 @Override -104 public void analyze(Dependency dependency, Engine engine) throws AnalysisException { -105 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. -106 } -107 -108 @Override -109 public String getName() { -110 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. -111 } -112 -113 @Override -114 public AnalysisPhase getAnalysisPhase() { -115 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. -116 } -117 } -118 -119 } +52 * Test of getSupportedExtensions method, of class +53 * AbstractSuppressionAnalyzer. +54 */ +55 @Test +56 public void testGetSupportedExtensions() { +57 Set<String> result = instance.getSupportedExtensions(); +58 assertNull(result); +59 } +60 +61 /** +62 * Test of getRules method, of class AbstractSuppressionAnalyzer for +63 * suppression file declared as URL. +64 */ +65 @Test +66 public void testGetRulesFromSuppressionFileFromURL() throws Exception { +67 setSupressionFileFromURL(); +68 instance.initialize(); +69 int expCount = 5; +70 List<SuppressionRule> result = instance.getRules(); +71 assertTrue(expCount <= result.size()); +72 } +73 +74 /** +75 * Test of getRules method, of class AbstractSuppressionAnalyzer for +76 * suppression file declared as URL. +77 */ +78 @Test +79 public void testGetRulesFromSuppressionFileInClasspath() throws Exception { +80 Settings.setString(Settings.KEYS.SUPPRESSION_FILE, "suppressions.xml"); +81 instance.initialize(); +82 int expCount = 5; +83 int currentSize = instance.getRules().size(); +84 assertTrue(expCount <= currentSize); +85 } +86 +87 @Test(expected = InitializationException.class) +88 public void testFailureToLocateSuppressionFileAnywhere() throws Exception { +89 Settings.setString(Settings.KEYS.SUPPRESSION_FILE, "doesnotexist.xml"); +90 instance.initialize(); +91 } +92 +93 private void setSupressionFileFromURL() throws Exception { +94 try { +95 final String uri = this.getClass().getClassLoader().getResource("suppressions.xml").toURI().toURL().toString(); +96 Settings.setString(Settings.KEYS.SUPPRESSION_FILE, uri); +97 } catch (URISyntaxException ex) { +98 LoggerFactory.getLogger(AbstractSuppressionAnalyzerTest.class).error("", ex); +99 } catch (MalformedURLException ex) { +100 LoggerFactory.getLogger(AbstractSuppressionAnalyzerTest.class).error("", ex); +101 } +102 } +103 +104 public class AbstractSuppressionAnalyzerImpl extends AbstractSuppressionAnalyzer { +105 +106 @Override +107 public void analyze(Dependency dependency, Engine engine) throws AnalysisException { +108 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. +109 } +110 +111 @Override +112 public String getName() { +113 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. +114 } +115 +116 @Override +117 public AnalysisPhase getAnalysisPhase() { +118 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. +119 } +120 } +121 +122 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/AnalyzerServiceTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/AnalyzerServiceTest.html index 678736ff6..6646fbc59 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/AnalyzerServiceTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/AnalyzerServiceTest.html @@ -25,65 +25,64 @@ 17 */ 18 package org.owasp.dependencycheck.analyzer; 19 -20 import java.util.Iterator; -21 import java.util.List; -22 import static org.junit.Assert.assertFalse; -23 import static org.junit.Assert.assertTrue; -24 import org.junit.Test; -25 import org.owasp.dependencycheck.BaseDBTestCase; -26 import org.owasp.dependencycheck.utils.Settings; -27 -28 /** -29 * -30 * @author Jeremy Long -31 */ -32 public class AnalyzerServiceTest extends BaseDBTestCase { -33 -34 /** -35 * Test of getAnalyzers method, of class AnalyzerService. -36 */ -37 @Test -38 public void testGetAnalyzers() { -39 AnalyzerService instance = new AnalyzerService(Thread.currentThread().getContextClassLoader()); -40 List<Analyzer> result = instance.getAnalyzers(); -41 -42 boolean found = false; -43 for (Analyzer a : result) { -44 if ("Jar Analyzer".equals(a.getName())) { -45 found = true; -46 } -47 } -48 assertTrue("JarAnalyzer loaded", found); -49 } -50 -51 /** -52 * Test of getAnalyzers method, of class AnalyzerService. -53 */ -54 @Test -55 public void testGetExperimentalAnalyzers() { -56 Settings.setBoolean(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, false); -57 AnalyzerService instance = new AnalyzerService(Thread.currentThread().getContextClassLoader()); -58 List<Analyzer> result = instance.getAnalyzers(); -59 String experimental = "CMake Analyzer"; -60 boolean found = false; -61 for (Analyzer a : result) { -62 if (experimental.equals(a.getName())) { -63 found = true; -64 } -65 } -66 assertFalse("Experimental analyzer loaded when set to false", found); -67 -68 Settings.setBoolean(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, true); -69 result = instance.getAnalyzers(); -70 found = false; -71 for (Analyzer a : result) { -72 if (experimental.equals(a.getName())) { -73 found = true; -74 } -75 } -76 assertTrue("Experimental analyzer not loaded when set to true", found); -77 } -78 } +20 import java.util.List; +21 import static org.junit.Assert.assertFalse; +22 import static org.junit.Assert.assertTrue; +23 import org.junit.Test; +24 import org.owasp.dependencycheck.BaseDBTestCase; +25 import org.owasp.dependencycheck.utils.Settings; +26 +27 /** +28 * +29 * @author Jeremy Long +30 */ +31 public class AnalyzerServiceTest extends BaseDBTestCase { +32 +33 /** +34 * Test of getAnalyzers method, of class AnalyzerService. +35 */ +36 @Test +37 public void testGetAnalyzers() { +38 AnalyzerService instance = new AnalyzerService(Thread.currentThread().getContextClassLoader()); +39 List<Analyzer> result = instance.getAnalyzers(); +40 +41 boolean found = false; +42 for (Analyzer a : result) { +43 if ("Jar Analyzer".equals(a.getName())) { +44 found = true; +45 } +46 } +47 assertTrue("JarAnalyzer loaded", found); +48 } +49 +50 /** +51 * Test of getAnalyzers method, of class AnalyzerService. +52 */ +53 @Test +54 public void testGetExperimentalAnalyzers() { +55 Settings.setBoolean(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, false); +56 AnalyzerService instance = new AnalyzerService(Thread.currentThread().getContextClassLoader()); +57 List<Analyzer> result = instance.getAnalyzers(); +58 String experimental = "CMake Analyzer"; +59 boolean found = false; +60 for (Analyzer a : result) { +61 if (experimental.equals(a.getName())) { +62 found = true; +63 } +64 } +65 assertFalse("Experimental analyzer loaded when set to false", found); +66 +67 Settings.setBoolean(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, true); +68 result = instance.getAnalyzers(); +69 found = false; +70 for (Analyzer a : result) { +71 if (experimental.equals(a.getName())) { +72 found = true; +73 } +74 } +75 assertTrue("Experimental analyzer not loaded when set to true", found); +76 } +77 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/ArchiveAnalyzerIntegrationTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/ArchiveAnalyzerIntegrationTest.html index e8270d3de..76195119d 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/ArchiveAnalyzerIntegrationTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/ArchiveAnalyzerIntegrationTest.html @@ -124,138 +124,138 @@ 116 try { 117 instance.initialize(); 118 File file = BaseTest.getResourceAsFile(this, "daytrader-ear-2.1.7.ear"); -119 //File file = new File(this.getClass().getClassLoader().getResource("daytrader-ear-2.1.7.ear").getPath()); -120 Dependency dependency = new Dependency(file); -121 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); -122 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); -123 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); -124 Engine engine = new Engine(); -125 -126 int initial_size = engine.getDependencies().size(); -127 instance.analyze(dependency, engine); -128 int ending_size = engine.getDependencies().size(); -129 -130 engine.cleanup(); -131 -132 assertTrue(initial_size < ending_size); -133 -134 } finally { -135 instance.close(); -136 } -137 } -138 -139 /** -140 * Test of analyze method, of class ArchiveAnalyzer. -141 */ -142 @Test -143 public void testAnalyzeTar() throws Exception { -144 ArchiveAnalyzer instance = new ArchiveAnalyzer(); -145 //trick the analyzer into thinking it is active so that it will initialize -146 instance.accept(new File("test.tar")); -147 try { -148 instance.initialize(); -149 -150 //File file = new File(this.getClass().getClassLoader().getResource("file.tar").getPath()); -151 //File file = new File(this.getClass().getClassLoader().getResource("stagedhttp-modified.tar").getPath()); -152 File file = BaseTest.getResourceAsFile(this, "stagedhttp-modified.tar"); -153 Dependency dependency = new Dependency(file); -154 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); -155 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); -156 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); -157 Engine engine = new Engine(); +119 Dependency dependency = new Dependency(file); +120 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); +121 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); +122 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); +123 Engine engine = new Engine(); +124 +125 int initial_size = engine.getDependencies().size(); +126 instance.analyze(dependency, engine); +127 int ending_size = engine.getDependencies().size(); +128 +129 engine.cleanup(); +130 +131 assertTrue(initial_size < ending_size); +132 +133 } finally { +134 instance.close(); +135 } +136 } +137 +138 /** +139 * Test of analyze method, of class ArchiveAnalyzer, with an executable jar. +140 */ +141 @Test +142 public void testAnalyzeExecutableJar() throws Exception { +143 ArchiveAnalyzer instance = new ArchiveAnalyzer(); +144 //trick the analyzer into thinking it is active. +145 instance.accept(new File("test.ear")); +146 try { +147 instance.initialize(); +148 File file = BaseTest.getResourceAsFile(this, "bootable-0.1.0.jar"); +149 Dependency dependency = new Dependency(file); +150 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); +151 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); +152 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); +153 Engine engine = new Engine(); +154 +155 int initial_size = engine.getDependencies().size(); +156 instance.analyze(dependency, engine); +157 int ending_size = engine.getDependencies().size(); 158 -159 int initial_size = engine.getDependencies().size(); -160 instance.analyze(dependency, engine); -161 int ending_size = engine.getDependencies().size(); -162 engine.cleanup(); -163 -164 assertTrue(initial_size < ending_size); -165 -166 } finally { -167 instance.close(); -168 } -169 } -170 -171 /** -172 * Test of analyze method, of class ArchiveAnalyzer. -173 */ -174 @Test -175 public void testAnalyzeTarGz() throws Exception { -176 ArchiveAnalyzer instance = new ArchiveAnalyzer(); -177 instance.accept(new File("zip")); //ensure analyzer is "enabled" -178 try { -179 instance.initialize(); -180 -181 //File file = new File(this.getClass().getClassLoader().getResource("file.tar.gz").getPath()); -182 File file = BaseTest.getResourceAsFile(this, "file.tar.gz"); -183 //Dependency dependency = new Dependency(file); -184 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); -185 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); -186 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); -187 Engine engine = new Engine(); -188 -189 int initial_size = engine.getDependencies().size(); -190 //instance.analyze(dependency, engine); -191 engine.scan(file); -192 engine.analyzeDependencies(); -193 int ending_size = engine.getDependencies().size(); -194 engine.cleanup(); -195 assertTrue(initial_size < ending_size); -196 -197 } finally { -198 instance.close(); -199 } -200 } -201 -202 /** -203 * Test of analyze method, of class ArchiveAnalyzer. -204 */ -205 @Test -206 public void testAnalyzeTarBz2() throws Exception { -207 ArchiveAnalyzer instance = new ArchiveAnalyzer(); -208 instance.accept(new File("zip")); //ensure analyzer is "enabled" -209 try { -210 instance.initialize(); -211 File file = BaseTest.getResourceAsFile(this, "file.tar.bz2"); -212 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); -213 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); -214 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); -215 Engine engine = new Engine(); -216 int initial_size = engine.getDependencies().size(); -217 engine.scan(file); -218 engine.analyzeDependencies(); -219 int ending_size = engine.getDependencies().size(); -220 engine.cleanup(); -221 assertTrue(initial_size < ending_size); -222 } finally { -223 instance.close(); -224 } -225 } -226 -227 /** -228 * Test of analyze method, of class ArchiveAnalyzer. -229 */ -230 @Test -231 public void testAnalyzeTgz() throws Exception { -232 ArchiveAnalyzer instance = new ArchiveAnalyzer(); -233 instance.accept(new File("zip")); //ensure analyzer is "enabled" -234 try { -235 instance.initialize(); -236 -237 //File file = new File(this.getClass().getClassLoader().getResource("file.tgz").getPath()); -238 File file = BaseTest.getResourceAsFile(this, "file.tgz"); -239 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); -240 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); -241 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); -242 Engine engine = new Engine(); -243 -244 int initial_size = engine.getDependencies().size(); -245 engine.scan(file); -246 engine.analyzeDependencies(); -247 int ending_size = engine.getDependencies().size(); -248 engine.cleanup(); -249 assertTrue(initial_size < ending_size); -250 +159 engine.cleanup(); +160 +161 assertTrue(initial_size < ending_size); +162 +163 } finally { +164 instance.close(); +165 } +166 } +167 +168 /** +169 * Test of analyze method, of class ArchiveAnalyzer. +170 */ +171 @Test +172 public void testAnalyzeTar() throws Exception { +173 ArchiveAnalyzer instance = new ArchiveAnalyzer(); +174 //trick the analyzer into thinking it is active so that it will initialize +175 instance.accept(new File("test.tar")); +176 try { +177 instance.initialize(); +178 +179 //File file = new File(this.getClass().getClassLoader().getResource("file.tar").getPath()); +180 //File file = new File(this.getClass().getClassLoader().getResource("stagedhttp-modified.tar").getPath()); +181 File file = BaseTest.getResourceAsFile(this, "stagedhttp-modified.tar"); +182 Dependency dependency = new Dependency(file); +183 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); +184 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); +185 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); +186 Engine engine = new Engine(); +187 +188 int initial_size = engine.getDependencies().size(); +189 instance.analyze(dependency, engine); +190 int ending_size = engine.getDependencies().size(); +191 engine.cleanup(); +192 +193 assertTrue(initial_size < ending_size); +194 +195 } finally { +196 instance.close(); +197 } +198 } +199 +200 /** +201 * Test of analyze method, of class ArchiveAnalyzer. +202 */ +203 @Test +204 public void testAnalyzeTarGz() throws Exception { +205 ArchiveAnalyzer instance = new ArchiveAnalyzer(); +206 instance.accept(new File("zip")); //ensure analyzer is "enabled" +207 try { +208 instance.initialize(); +209 +210 //File file = new File(this.getClass().getClassLoader().getResource("file.tar.gz").getPath()); +211 File file = BaseTest.getResourceAsFile(this, "file.tar.gz"); +212 //Dependency dependency = new Dependency(file); +213 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); +214 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); +215 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); +216 Engine engine = new Engine(); +217 +218 int initial_size = engine.getDependencies().size(); +219 //instance.analyze(dependency, engine); +220 engine.scan(file); +221 engine.analyzeDependencies(); +222 int ending_size = engine.getDependencies().size(); +223 engine.cleanup(); +224 assertTrue(initial_size < ending_size); +225 +226 } finally { +227 instance.close(); +228 } +229 } +230 +231 /** +232 * Test of analyze method, of class ArchiveAnalyzer. +233 */ +234 @Test +235 public void testAnalyzeTarBz2() throws Exception { +236 ArchiveAnalyzer instance = new ArchiveAnalyzer(); +237 instance.accept(new File("zip")); //ensure analyzer is "enabled" +238 try { +239 instance.initialize(); +240 File file = BaseTest.getResourceAsFile(this, "file.tar.bz2"); +241 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); +242 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); +243 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); +244 Engine engine = new Engine(); +245 int initial_size = engine.getDependencies().size(); +246 engine.scan(file); +247 engine.analyzeDependencies(); +248 int ending_size = engine.getDependencies().size(); +249 engine.cleanup(); +250 assertTrue(initial_size < ending_size); 251 } finally { 252 instance.close(); 253 } @@ -265,59 +265,88 @@ 257 * Test of analyze method, of class ArchiveAnalyzer. 258 */ 259 @Test -260 public void testAnalyzeTbz2() throws Exception { +260 public void testAnalyzeTgz() throws Exception { 261 ArchiveAnalyzer instance = new ArchiveAnalyzer(); 262 instance.accept(new File("zip")); //ensure analyzer is "enabled" 263 try { 264 instance.initialize(); -265 File file = BaseTest.getResourceAsFile(this, "file.tbz2"); -266 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); -267 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); -268 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); -269 Engine engine = new Engine(); -270 int initial_size = engine.getDependencies().size(); -271 engine.scan(file); -272 engine.analyzeDependencies(); -273 int ending_size = engine.getDependencies().size(); -274 engine.cleanup(); -275 assertTrue(initial_size < ending_size); -276 } finally { -277 instance.close(); -278 } -279 } -280 -281 /** -282 * Test of analyze method, of class ArchiveAnalyzer. -283 */ -284 @Test -285 public void testAnalyze_badZip() throws Exception { -286 ArchiveAnalyzer instance = new ArchiveAnalyzer(); -287 try { -288 instance.initialize(); -289 -290 //File file = new File(this.getClass().getClassLoader().getResource("test.zip").getPath()); -291 File file = BaseTest.getResourceAsFile(this, "test.zip"); -292 Dependency dependency = new Dependency(file); -293 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); -294 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); -295 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); -296 Engine engine = new Engine(); -297 int initial_size = engine.getDependencies().size(); -298 // boolean failed = false; -299 // try { -300 instance.analyze(dependency, engine); -301 // } catch (java.lang.UnsupportedClassVersionError ex) { -302 // failed = true; -303 // } -304 // assertTrue(failed); -305 int ending_size = engine.getDependencies().size(); -306 engine.cleanup(); -307 assertEquals(initial_size, ending_size); -308 } finally { -309 instance.close(); -310 } -311 } -312 } +265 +266 //File file = new File(this.getClass().getClassLoader().getResource("file.tgz").getPath()); +267 File file = BaseTest.getResourceAsFile(this, "file.tgz"); +268 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); +269 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); +270 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); +271 Engine engine = new Engine(); +272 +273 int initial_size = engine.getDependencies().size(); +274 engine.scan(file); +275 engine.analyzeDependencies(); +276 int ending_size = engine.getDependencies().size(); +277 engine.cleanup(); +278 assertTrue(initial_size < ending_size); +279 +280 } finally { +281 instance.close(); +282 } +283 } +284 +285 /** +286 * Test of analyze method, of class ArchiveAnalyzer. +287 */ +288 @Test +289 public void testAnalyzeTbz2() throws Exception { +290 ArchiveAnalyzer instance = new ArchiveAnalyzer(); +291 instance.accept(new File("zip")); //ensure analyzer is "enabled" +292 try { +293 instance.initialize(); +294 File file = BaseTest.getResourceAsFile(this, "file.tbz2"); +295 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); +296 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); +297 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); +298 Engine engine = new Engine(); +299 int initial_size = engine.getDependencies().size(); +300 engine.scan(file); +301 engine.analyzeDependencies(); +302 int ending_size = engine.getDependencies().size(); +303 engine.cleanup(); +304 assertTrue(initial_size < ending_size); +305 } finally { +306 instance.close(); +307 } +308 } +309 +310 /** +311 * Test of analyze method, of class ArchiveAnalyzer. +312 */ +313 @Test +314 public void testAnalyze_badZip() throws Exception { +315 ArchiveAnalyzer instance = new ArchiveAnalyzer(); +316 try { +317 instance.initialize(); +318 +319 //File file = new File(this.getClass().getClassLoader().getResource("test.zip").getPath()); +320 File file = BaseTest.getResourceAsFile(this, "test.zip"); +321 Dependency dependency = new Dependency(file); +322 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); +323 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); +324 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); +325 Engine engine = new Engine(); +326 int initial_size = engine.getDependencies().size(); +327 // boolean failed = false; +328 // try { +329 instance.analyze(dependency, engine); +330 // } catch (java.lang.UnsupportedClassVersionError ex) { +331 // failed = true; +332 // } +333 // assertTrue(failed); +334 int ending_size = engine.getDependencies().size(); +335 engine.cleanup(); +336 assertEquals(initial_size, ending_size); +337 } finally { +338 instance.close(); +339 } +340 } +341 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/ArchiveAnalyzerTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/ArchiveAnalyzerTest.html index 00bf4b4a6..9c9004236 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/ArchiveAnalyzerTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/ArchiveAnalyzerTest.html @@ -24,68 +24,63 @@ 16 package org.owasp.dependencycheck.analyzer; 17 18 import java.io.File; -19 import java.io.FileFilter; -20 import java.lang.reflect.InvocationTargetException; -21 import java.lang.reflect.Method; -22 import java.util.logging.Level; -23 import java.util.logging.Logger; -24 import org.junit.After; -25 import org.junit.AfterClass; -26 import org.junit.Before; -27 import org.junit.BeforeClass; -28 import org.junit.Test; -29 import static org.junit.Assert.*; -30 import static org.junit.Assume.assumeFalse; -31 import static org.junit.Assume.assumeNotNull; -32 import org.owasp.dependencycheck.BaseTest; -33 import org.owasp.dependencycheck.Engine; -34 import org.owasp.dependencycheck.dependency.Dependency; -35 import org.owasp.dependencycheck.utils.Settings; -36 -37 /** -38 * -39 * @author jeremy -40 */ -41 public class ArchiveAnalyzerTest extends BaseTest { +19 import java.lang.reflect.InvocationTargetException; +20 import java.lang.reflect.Method; +21 import java.util.logging.Level; +22 import java.util.logging.Logger; +23 +24 import org.junit.Before; +25 import org.junit.Test; +26 import static org.junit.Assert.*; +27 import static org.junit.Assume.assumeFalse; +28 +29 import org.owasp.dependencycheck.BaseTest; +30 import org.owasp.dependencycheck.utils.Settings; +31 +32 /** +33 * +34 * @author jeremy +35 */ +36 public class ArchiveAnalyzerTest extends BaseTest { +37 +38 @Before +39 public void setUp() { +40 Settings.setString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, "z2, z3"); +41 } 42 -43 @Before -44 public void setUp() { -45 Settings.setString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, "z2, z3"); -46 } -47 -48 /** -49 * Test of analyzeFileType method, of class ArchiveAnalyzer. -50 */ -51 @Test -52 public void testZippableExtensions() throws Exception { -53 assumeFalse(isPreviouslyLoaded("org.owasp.dependencycheck.analyzer.ArchiveAnalyzer")); -54 ArchiveAnalyzer instance = new ArchiveAnalyzer(); -55 assertTrue(instance.getFileFilter().accept(new File("c:/test.zip"))); -56 assertTrue(instance.getFileFilter().accept(new File("c:/test.z2"))); -57 assertTrue(instance.getFileFilter().accept(new File("c:/test.z3"))); -58 assertFalse(instance.getFileFilter().accept(new File("c:/test.z4"))); -59 } -60 -61 private boolean isPreviouslyLoaded(String className) { -62 try { -63 Method m = ClassLoader.class.getDeclaredMethod("findLoadedClass", new Class[]{String.class}); -64 m.setAccessible(true); -65 Object t = m.invoke(Thread.currentThread().getContextClassLoader(), className); -66 return t != null; -67 } catch (NoSuchMethodException ex) { -68 Logger.getLogger(ArchiveAnalyzerTest.class.getName()).log(Level.SEVERE, null, ex); -69 } catch (SecurityException ex) { -70 Logger.getLogger(ArchiveAnalyzerTest.class.getName()).log(Level.SEVERE, null, ex); -71 } catch (IllegalAccessException ex) { -72 Logger.getLogger(ArchiveAnalyzerTest.class.getName()).log(Level.SEVERE, null, ex); -73 } catch (IllegalArgumentException ex) { -74 Logger.getLogger(ArchiveAnalyzerTest.class.getName()).log(Level.SEVERE, null, ex); -75 } catch (InvocationTargetException ex) { -76 Logger.getLogger(ArchiveAnalyzerTest.class.getName()).log(Level.SEVERE, null, ex); -77 } -78 return false; -79 } -80 } +43 /** +44 * Test of analyzeFileType method, of class ArchiveAnalyzer. +45 */ +46 @Test +47 public void testZippableExtensions() throws Exception { +48 assumeFalse(isPreviouslyLoaded("org.owasp.dependencycheck.analyzer.ArchiveAnalyzer")); +49 ArchiveAnalyzer instance = new ArchiveAnalyzer(); +50 assertTrue(instance.getFileFilter().accept(new File("c:/test.zip"))); +51 assertTrue(instance.getFileFilter().accept(new File("c:/test.z2"))); +52 assertTrue(instance.getFileFilter().accept(new File("c:/test.z3"))); +53 assertFalse(instance.getFileFilter().accept(new File("c:/test.z4"))); +54 } +55 +56 private boolean isPreviouslyLoaded(String className) { +57 try { +58 Method m = ClassLoader.class.getDeclaredMethod("findLoadedClass", new Class[]{String.class}); +59 m.setAccessible(true); +60 Object t = m.invoke(Thread.currentThread().getContextClassLoader(), className); +61 return t != null; +62 } catch (NoSuchMethodException ex) { +63 Logger.getLogger(ArchiveAnalyzerTest.class.getName()).log(Level.SEVERE, null, ex); +64 } catch (SecurityException ex) { +65 Logger.getLogger(ArchiveAnalyzerTest.class.getName()).log(Level.SEVERE, null, ex); +66 } catch (IllegalAccessException ex) { +67 Logger.getLogger(ArchiveAnalyzerTest.class.getName()).log(Level.SEVERE, null, ex); +68 } catch (IllegalArgumentException ex) { +69 Logger.getLogger(ArchiveAnalyzerTest.class.getName()).log(Level.SEVERE, null, ex); +70 } catch (InvocationTargetException ex) { +71 Logger.getLogger(ArchiveAnalyzerTest.class.getName()).log(Level.SEVERE, null, ex); +72 } +73 return false; +74 } +75 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/AssemblyAnalyzerTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/AssemblyAnalyzerTest.html index d609ffcb6..5cf08bcba 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/AssemblyAnalyzerTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/AssemblyAnalyzerTest.html @@ -39,153 +39,154 @@ 31 import org.owasp.dependencycheck.dependency.Confidence; 32 import org.owasp.dependencycheck.dependency.Dependency; 33 import org.owasp.dependencycheck.dependency.Evidence; -34 import org.owasp.dependencycheck.utils.Settings; -35 import org.slf4j.Logger; -36 import org.slf4j.LoggerFactory; -37 -38 /** -39 * Tests for the AssemblyAnalyzer. -40 * -41 * @author colezlaw -42 * -43 */ -44 public class AssemblyAnalyzerTest extends BaseTest { -45 -46 private static final Logger LOGGER = LoggerFactory.getLogger(AssemblyAnalyzerTest.class); -47 -48 private static final String LOG_KEY = "org.slf4j.simpleLogger.org.owasp.dependencycheck.analyzer.AssemblyAnalyzer"; -49 -50 AssemblyAnalyzer analyzer; -51 -52 /** -53 * Sets up the analyzer. -54 * -55 * @throws Exception if anything goes sideways -56 */ -57 @Before -58 public void setUp() throws Exception { -59 try { -60 analyzer = new AssemblyAnalyzer(); -61 analyzer.accept(new File("test.dll")); // trick into "thinking it is active" -62 analyzer.initialize(); -63 } catch (Exception e) { -64 if (e.getMessage().contains("Could not execute .NET AssemblyAnalyzer")) { -65 LOGGER.warn("Exception setting up AssemblyAnalyzer. Tests will be incomplete"); -66 } else { -67 LOGGER.warn("Exception setting up AssemblyAnalyzer. Tests will be incomplete", e); -68 } -69 Assume.assumeNoException("Is mono installed? TESTS WILL BE INCOMPLETE", e); -70 } -71 } -72 -73 /** -74 * Tests to make sure the name is correct. -75 */ -76 @Test -77 public void testGetName() { -78 assertEquals("Assembly Analyzer", analyzer.getName()); -79 } -80 -81 @Test -82 public void testAnalysis() throws Exception { -83 //File f = new File(AssemblyAnalyzerTest.class.getClassLoader().getResource("GrokAssembly.exe").getPath()); -84 File f = BaseTest.getResourceAsFile(this, "GrokAssembly.exe"); -85 Dependency d = new Dependency(f); -86 analyzer.analyze(d, null); -87 boolean foundVendor = false; -88 for (Evidence e : d.getVendorEvidence().getEvidence("grokassembly", "vendor")) { -89 if ("OWASP".equals(e.getValue())) { -90 foundVendor = true; -91 } -92 } -93 assertTrue(foundVendor); -94 -95 boolean foundProduct = false; -96 for (Evidence e : d.getProductEvidence().getEvidence("grokassembly", "product")) { -97 if ("GrokAssembly".equals(e.getValue())) { -98 foundProduct = true; -99 } -100 } -101 assertTrue(foundProduct); -102 } -103 -104 @Test -105 public void testLog4Net() throws Exception { -106 //File f = new File(AssemblyAnalyzerTest.class.getClassLoader().getResource("log4net.dll").getPath()); -107 File f = BaseTest.getResourceAsFile(this, "log4net.dll"); -108 -109 Dependency d = new Dependency(f); -110 analyzer.analyze(d, null); -111 assertTrue(d.getVersionEvidence().getEvidence().contains(new Evidence("grokassembly", "version", "1.2.13.0", Confidence.HIGHEST))); -112 assertTrue(d.getVendorEvidence().getEvidence().contains(new Evidence("grokassembly", "vendor", "The Apache Software Foundation", Confidence.HIGH))); -113 assertTrue(d.getProductEvidence().getEvidence().contains(new Evidence("grokassembly", "product", "log4net", Confidence.HIGH))); -114 } -115 -116 @Test -117 public void testNonexistent() { -118 // Tweak the log level so the warning doesn't show in the console -119 String oldProp = System.getProperty(LOG_KEY, "info"); -120 //File f = new File(AssemblyAnalyzerTest.class.getClassLoader().getResource("log4net.dll").getPath()); -121 File f = BaseTest.getResourceAsFile(this, "log4net.dll"); -122 File test = new File(f.getParent(), "nonexistent.dll"); -123 Dependency d = new Dependency(test); -124 -125 try { -126 analyzer.analyze(d, null); -127 fail("Expected an AnalysisException"); -128 } catch (AnalysisException ae) { -129 assertEquals("File does not exist", ae.getMessage()); -130 } finally { -131 System.setProperty(LOG_KEY, oldProp); -132 } -133 } -134 -135 @Test -136 public void testWithSettingMono() throws Exception { -137 -138 //This test doesn't work on Windows. -139 assumeFalse(System.getProperty("os.name").startsWith("Windows")); -140 -141 String oldValue = Settings.getString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH); -142 // if oldValue is null, that means that neither the system property nor the setting has -143 // been set. If that's the case, then we have to make it such that when we recover, -144 // null still comes back. But you can't put a null value in a HashMap, so we have to set -145 // the system property rather than the setting. -146 if (oldValue == null) { -147 System.setProperty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, "/yooser/bine/mono"); -148 } else { -149 Settings.setString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, "/yooser/bine/mono"); -150 } -151 -152 String oldProp = System.getProperty(LOG_KEY, "info"); -153 try { -154 // Tweak the logging to swallow the warning when testing -155 System.setProperty(LOG_KEY, "error"); -156 // Have to make a NEW analyzer because during setUp, it would have gotten the correct one -157 AssemblyAnalyzer aanalyzer = new AssemblyAnalyzer(); -158 aanalyzer.accept(new File("test.dll")); // trick into "thinking it is active" -159 aanalyzer.initialize(); -160 fail("Expected an AnalysisException"); -161 } catch (AnalysisException ae) { -162 assertEquals("An error occurred with the .NET AssemblyAnalyzer", ae.getMessage()); -163 } finally { -164 System.setProperty(LOG_KEY, oldProp); -165 // Recover the logger -166 // Now recover the way we came in. If we had to set a System property, delete it. Otherwise, -167 // reset the old value -168 if (oldValue == null) { -169 System.getProperties().remove(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH); -170 } else { -171 Settings.setString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, oldValue); -172 } -173 } -174 } -175 -176 @After -177 public void tearDown() throws Exception { -178 analyzer.close(); -179 } -180 } +34 import org.owasp.dependencycheck.exception.InitializationException; +35 import org.owasp.dependencycheck.utils.Settings; +36 import org.slf4j.Logger; +37 import org.slf4j.LoggerFactory; +38 +39 /** +40 * Tests for the AssemblyAnalyzer. +41 * +42 * @author colezlaw +43 * +44 */ +45 public class AssemblyAnalyzerTest extends BaseTest { +46 +47 private static final Logger LOGGER = LoggerFactory.getLogger(AssemblyAnalyzerTest.class); +48 +49 private static final String LOG_KEY = "org.slf4j.simpleLogger.org.owasp.dependencycheck.analyzer.AssemblyAnalyzer"; +50 +51 AssemblyAnalyzer analyzer; +52 +53 /** +54 * Sets up the analyzer. +55 * +56 * @throws Exception if anything goes sideways +57 */ +58 @Before +59 public void setUp() throws Exception { +60 try { +61 analyzer = new AssemblyAnalyzer(); +62 analyzer.accept(new File("test.dll")); // trick into "thinking it is active" +63 analyzer.initialize(); +64 } catch (Exception e) { +65 if (e.getMessage().contains("Could not execute .NET AssemblyAnalyzer")) { +66 LOGGER.warn("Exception setting up AssemblyAnalyzer. Tests will be incomplete"); +67 } else { +68 LOGGER.warn("Exception setting up AssemblyAnalyzer. Tests will be incomplete"); +69 } +70 Assume.assumeNoException("Is mono installed? TESTS WILL BE INCOMPLETE", e); +71 } +72 } +73 +74 /** +75 * Tests to make sure the name is correct. +76 */ +77 @Test +78 public void testGetName() { +79 assertEquals("Assembly Analyzer", analyzer.getName()); +80 } +81 +82 @Test +83 public void testAnalysis() throws Exception { +84 //File f = new File(AssemblyAnalyzerTest.class.getClassLoader().getResource("GrokAssembly.exe").getPath()); +85 File f = BaseTest.getResourceAsFile(this, "GrokAssembly.exe"); +86 Dependency d = new Dependency(f); +87 analyzer.analyze(d, null); +88 boolean foundVendor = false; +89 for (Evidence e : d.getVendorEvidence().getEvidence("grokassembly", "vendor")) { +90 if ("OWASP".equals(e.getValue())) { +91 foundVendor = true; +92 } +93 } +94 assertTrue(foundVendor); +95 +96 boolean foundProduct = false; +97 for (Evidence e : d.getProductEvidence().getEvidence("grokassembly", "product")) { +98 if ("GrokAssembly".equals(e.getValue())) { +99 foundProduct = true; +100 } +101 } +102 assertTrue(foundProduct); +103 } +104 +105 @Test +106 public void testLog4Net() throws Exception { +107 //File f = new File(AssemblyAnalyzerTest.class.getClassLoader().getResource("log4net.dll").getPath()); +108 File f = BaseTest.getResourceAsFile(this, "log4net.dll"); +109 +110 Dependency d = new Dependency(f); +111 analyzer.analyze(d, null); +112 assertTrue(d.getVersionEvidence().getEvidence().contains(new Evidence("grokassembly", "version", "1.2.13.0", Confidence.HIGHEST))); +113 assertTrue(d.getVendorEvidence().getEvidence().contains(new Evidence("grokassembly", "vendor", "The Apache Software Foundation", Confidence.HIGH))); +114 assertTrue(d.getProductEvidence().getEvidence().contains(new Evidence("grokassembly", "product", "log4net", Confidence.HIGH))); +115 } +116 +117 @Test +118 public void testNonexistent() { +119 // Tweak the log level so the warning doesn't show in the console +120 String oldProp = System.getProperty(LOG_KEY, "info"); +121 //File f = new File(AssemblyAnalyzerTest.class.getClassLoader().getResource("log4net.dll").getPath()); +122 File f = BaseTest.getResourceAsFile(this, "log4net.dll"); +123 File test = new File(f.getParent(), "nonexistent.dll"); +124 Dependency d = new Dependency(test); +125 +126 try { +127 analyzer.analyze(d, null); +128 fail("Expected an AnalysisException"); +129 } catch (AnalysisException ae) { +130 assertEquals("File does not exist", ae.getMessage()); +131 } finally { +132 System.setProperty(LOG_KEY, oldProp); +133 } +134 } +135 +136 @Test +137 public void testWithSettingMono() throws Exception { +138 +139 //This test doesn't work on Windows. +140 assumeFalse(System.getProperty("os.name").startsWith("Windows")); +141 +142 String oldValue = Settings.getString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH); +143 // if oldValue is null, that means that neither the system property nor the setting has +144 // been set. If that's the case, then we have to make it such that when we recover, +145 // null still comes back. But you can't put a null value in a HashMap, so we have to set +146 // the system property rather than the setting. +147 if (oldValue == null) { +148 System.setProperty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, "/yooser/bine/mono"); +149 } else { +150 Settings.setString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, "/yooser/bine/mono"); +151 } +152 +153 String oldProp = System.getProperty(LOG_KEY, "info"); +154 try { +155 // Tweak the logging to swallow the warning when testing +156 System.setProperty(LOG_KEY, "error"); +157 // Have to make a NEW analyzer because during setUp, it would have gotten the correct one +158 AssemblyAnalyzer aanalyzer = new AssemblyAnalyzer(); +159 aanalyzer.accept(new File("test.dll")); // trick into "thinking it is active" +160 aanalyzer.initialize(); +161 fail("Expected an InitializationException"); +162 } catch (InitializationException ae) { +163 assertEquals("An error occurred with the .NET AssemblyAnalyzer", ae.getMessage()); +164 } finally { +165 System.setProperty(LOG_KEY, oldProp); +166 // Recover the logger +167 // Now recover the way we came in. If we had to set a System property, delete it. Otherwise, +168 // reset the old value +169 if (oldValue == null) { +170 System.getProperties().remove(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH); +171 } else { +172 Settings.setString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, oldValue); +173 } +174 } +175 } +176 +177 @After +178 public void tearDown() throws Exception { +179 analyzer.close(); +180 } +181 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/CPEAnalyzerIntegrationTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/CPEAnalyzerIntegrationTest.html index 036e178cb..2f11380ef 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/CPEAnalyzerIntegrationTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/CPEAnalyzerIntegrationTest.html @@ -37,231 +37,244 @@ 29 import org.junit.Test; 30 import org.owasp.dependencycheck.BaseTest; 31 import org.owasp.dependencycheck.BaseDBTestCase; -32 import org.owasp.dependencycheck.data.cpe.IndexEntry; -33 import org.owasp.dependencycheck.dependency.Confidence; -34 import org.owasp.dependencycheck.dependency.Dependency; -35 import org.owasp.dependencycheck.dependency.Identifier; -36 -37 /** -38 * -39 * @author Jeremy Long -40 */ -41 public class CPEAnalyzerIntegrationTest extends BaseDBTestCase { -42 -43 /** -44 * Tests of buildSearch of class CPEAnalyzer. -45 * -46 * @throws IOException is thrown when an IO Exception occurs. -47 * @throws CorruptIndexException is thrown when the index is corrupt. -48 * @throws ParseException is thrown when a parse exception occurs -49 */ -50 @Test -51 public void testBuildSearch() throws IOException, CorruptIndexException, ParseException { -52 Set<String> productWeightings = Collections.singleton("struts2"); -53 -54 Set<String> vendorWeightings = Collections.singleton("apache"); -55 -56 String vendor = "apache software foundation"; -57 String product = "struts 2 core"; -58 String version = "2.1.2"; -59 CPEAnalyzer instance = new CPEAnalyzer(); -60 -61 String queryText = instance.buildSearch(vendor, product, null, null); -62 String expResult = " product:( struts 2 core ) AND vendor:( apache software foundation ) "; -63 Assert.assertTrue(expResult.equals(queryText)); -64 -65 queryText = instance.buildSearch(vendor, product, null, productWeightings); -66 expResult = " product:( struts^5 struts2^5 2 core ) AND vendor:( apache software foundation ) "; -67 Assert.assertTrue(expResult.equals(queryText)); -68 -69 queryText = instance.buildSearch(vendor, product, vendorWeightings, null); -70 expResult = " product:( struts 2 core ) AND vendor:( apache^5 software foundation ) "; -71 Assert.assertTrue(expResult.equals(queryText)); -72 -73 queryText = instance.buildSearch(vendor, product, vendorWeightings, productWeightings); -74 expResult = " product:( struts^5 struts2^5 2 core ) AND vendor:( apache^5 software foundation ) "; -75 Assert.assertTrue(expResult.equals(queryText)); -76 } -77 -78 /** -79 * Test of determineCPE method, of class CPEAnalyzer. -80 * -81 * @throws Exception is thrown when an exception occurs -82 */ -83 @Test -84 public void testDetermineCPE_full() throws Exception { -85 CPEAnalyzer instance = new CPEAnalyzer(); -86 instance.open(); -87 FileNameAnalyzer fnAnalyzer = new FileNameAnalyzer(); -88 JarAnalyzer jarAnalyzer = new JarAnalyzer(); -89 HintAnalyzer hAnalyzer = new HintAnalyzer(); -90 FalsePositiveAnalyzer fp = new FalsePositiveAnalyzer(); -91 -92 try { -93 //callDetermineCPE_full("struts2-core-2.3.16.3.jar", "cpe:/a:apache:struts:2.3.16.3", instance, fnAnalyzer, jarAnalyzer, hAnalyzer, fp); -94 callDetermineCPE_full("hazelcast-2.5.jar", null, instance, fnAnalyzer, jarAnalyzer, hAnalyzer, fp); -95 callDetermineCPE_full("spring-context-support-2.5.5.jar", "cpe:/a:springsource:spring_framework:2.5.5", instance, fnAnalyzer, jarAnalyzer, hAnalyzer, fp); -96 callDetermineCPE_full("spring-core-3.0.0.RELEASE.jar", "cpe:/a:vmware:springsource_spring_framework:3.0.0", instance, fnAnalyzer, jarAnalyzer, hAnalyzer, fp); -97 callDetermineCPE_full("org.mortbay.jetty.jar", "cpe:/a:mortbay_jetty:jetty:4.2.27", instance, fnAnalyzer, jarAnalyzer, hAnalyzer, fp); -98 callDetermineCPE_full("jaxb-xercesImpl-1.5.jar", null, instance, fnAnalyzer, jarAnalyzer, hAnalyzer, fp); -99 callDetermineCPE_full("ehcache-core-2.2.0.jar", null, instance, fnAnalyzer, jarAnalyzer, hAnalyzer, fp); -100 } finally { -101 instance.close(); -102 } -103 } -104 -105 /** -106 * Test of determineCPE method, of class CPEAnalyzer. -107 * -108 * @throws Exception is thrown when an exception occurs -109 */ -110 public void callDetermineCPE_full(String depName, String expResult, CPEAnalyzer instance, FileNameAnalyzer fnAnalyzer, JarAnalyzer jarAnalyzer, HintAnalyzer hAnalyzer, FalsePositiveAnalyzer fp) throws Exception { -111 -112 //File file = new File(this.getClass().getClassLoader().getResource(depName).getPath()); -113 File file = BaseTest.getResourceAsFile(this, depName); -114 -115 Dependency dep = new Dependency(file); -116 -117 fnAnalyzer.analyze(dep, null); -118 jarAnalyzer.analyze(dep, null); -119 hAnalyzer.analyze(dep, null); -120 instance.analyze(dep, null); -121 fp.analyze(dep, null); +32 import org.owasp.dependencycheck.Engine; +33 import org.owasp.dependencycheck.data.cpe.IndexEntry; +34 import org.owasp.dependencycheck.dependency.Confidence; +35 import org.owasp.dependencycheck.dependency.Dependency; +36 import org.owasp.dependencycheck.dependency.Identifier; +37 +38 /** +39 * +40 * @author Jeremy Long +41 */ +42 public class CPEAnalyzerIntegrationTest extends BaseDBTestCase { +43 +44 /** +45 * Tests of buildSearch of class CPEAnalyzer. +46 * +47 * @throws IOException is thrown when an IO Exception occurs. +48 * @throws CorruptIndexException is thrown when the index is corrupt. +49 * @throws ParseException is thrown when a parse exception occurs +50 */ +51 @Test +52 public void testBuildSearch() throws IOException, CorruptIndexException, ParseException { +53 Set<String> productWeightings = Collections.singleton("struts2"); +54 +55 Set<String> vendorWeightings = Collections.singleton("apache"); +56 +57 String vendor = "apache software foundation"; +58 String product = "struts 2 core"; +59 String version = "2.1.2"; +60 CPEAnalyzer instance = new CPEAnalyzer(); +61 +62 String queryText = instance.buildSearch(vendor, product, null, null); +63 String expResult = " product:( struts 2 core ) AND vendor:( apache software foundation ) "; +64 Assert.assertTrue(expResult.equals(queryText)); +65 +66 queryText = instance.buildSearch(vendor, product, null, productWeightings); +67 expResult = " product:( struts^5 struts2^5 2 core ) AND vendor:( apache software foundation ) "; +68 Assert.assertTrue(expResult.equals(queryText)); +69 +70 queryText = instance.buildSearch(vendor, product, vendorWeightings, null); +71 expResult = " product:( struts 2 core ) AND vendor:( apache^5 software foundation ) "; +72 Assert.assertTrue(expResult.equals(queryText)); +73 +74 queryText = instance.buildSearch(vendor, product, vendorWeightings, productWeightings); +75 expResult = " product:( struts^5 struts2^5 2 core ) AND vendor:( apache^5 software foundation ) "; +76 Assert.assertTrue(expResult.equals(queryText)); +77 } +78 +79 /** +80 * Test of determineCPE method, of class CPEAnalyzer. +81 * +82 * @throws Exception is thrown when an exception occurs +83 */ +84 @Test +85 public void testDetermineCPE_full() throws Exception { +86 //update needs to be performed so that xtream can be tested +87 Engine e = new Engine(); +88 e.doUpdates(); +89 +90 CPEAnalyzer cpeAnalyzer = new CPEAnalyzer(); +91 try { +92 cpeAnalyzer.initialize(); +93 FileNameAnalyzer fnAnalyzer = new FileNameAnalyzer(); +94 fnAnalyzer.initialize(); +95 JarAnalyzer jarAnalyzer = new JarAnalyzer(); +96 jarAnalyzer.accept(new File("test.jar"));//trick analyzer into "thinking it is active" +97 jarAnalyzer.initialize(); +98 HintAnalyzer hAnalyzer = new HintAnalyzer(); +99 hAnalyzer.initialize(); +100 FalsePositiveAnalyzer fp = new FalsePositiveAnalyzer(); +101 fp.initialize(); +102 +103 callDetermineCPE_full("hazelcast-2.5.jar", null, cpeAnalyzer, fnAnalyzer, jarAnalyzer, hAnalyzer, fp); +104 callDetermineCPE_full("spring-context-support-2.5.5.jar", "cpe:/a:springsource:spring_framework:2.5.5", cpeAnalyzer, fnAnalyzer, jarAnalyzer, hAnalyzer, fp); +105 callDetermineCPE_full("spring-core-3.0.0.RELEASE.jar", "cpe:/a:vmware:springsource_spring_framework:3.0.0", cpeAnalyzer, fnAnalyzer, jarAnalyzer, hAnalyzer, fp); +106 callDetermineCPE_full("org.mortbay.jetty.jar", "cpe:/a:mortbay_jetty:jetty:4.2.27", cpeAnalyzer, fnAnalyzer, jarAnalyzer, hAnalyzer, fp); +107 callDetermineCPE_full("jaxb-xercesImpl-1.5.jar", null, cpeAnalyzer, fnAnalyzer, jarAnalyzer, hAnalyzer, fp); +108 callDetermineCPE_full("ehcache-core-2.2.0.jar", null, cpeAnalyzer, fnAnalyzer, jarAnalyzer, hAnalyzer, fp); +109 callDetermineCPE_full("xstream-1.4.8.jar", "cpe:/a:x-stream:xstream:1.4.8", cpeAnalyzer, fnAnalyzer, jarAnalyzer, hAnalyzer, fp); +110 +111 } finally { +112 cpeAnalyzer.close(); +113 } +114 } +115 +116 /** +117 * Test of determineCPE method, of class CPEAnalyzer. +118 * +119 * @throws Exception is thrown when an exception occurs +120 */ +121 public void callDetermineCPE_full(String depName, String expResult, CPEAnalyzer cpeAnalyzer, FileNameAnalyzer fnAnalyzer, JarAnalyzer jarAnalyzer, HintAnalyzer hAnalyzer, FalsePositiveAnalyzer fp) throws Exception { 122 -123 if (expResult != null) { -124 Identifier expIdentifier = new Identifier("cpe", expResult, expResult); -125 Assert.assertTrue("Incorrect match: { dep:'" + dep.getFileName() + "' }", dep.getIdentifiers().contains(expIdentifier)); -126 } else { -127 for (Identifier i : dep.getIdentifiers()) { -128 Assert.assertFalse(String.format("%s - found a CPE identifier when should have been none (found '%s')", dep.getFileName(), i.getValue()), "cpe".equals(i.getType())); -129 } -130 } -131 } -132 -133 /** -134 * Test of determineCPE method, of class CPEAnalyzer. -135 * -136 * @throws Exception is thrown when an exception occurs -137 */ -138 @Test -139 public void testDetermineCPE() throws Exception { -140 //File file = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath()); -141 File file = BaseTest.getResourceAsFile(this, "struts2-core-2.1.2.jar"); -142 //File file = new File(this.getClass().getClassLoader().getResource("axis2-adb-1.4.1.jar").getPath()); -143 Dependency struts = new Dependency(file); -144 -145 FileNameAnalyzer fnAnalyzer = new FileNameAnalyzer(); -146 fnAnalyzer.analyze(struts, null); -147 -148 HintAnalyzer hintAnalyzer = new HintAnalyzer(); -149 JarAnalyzer jarAnalyzer = new JarAnalyzer(); -150 jarAnalyzer.accept(new File("test.jar"));//trick analyzer into "thinking it is active" -151 -152 jarAnalyzer.analyze(struts, null); -153 hintAnalyzer.analyze(struts, null); -154 //File fileCommonValidator = new File(this.getClass().getClassLoader().getResource("commons-validator-1.4.0.jar").getPath()); -155 File fileCommonValidator = BaseTest.getResourceAsFile(this, "commons-validator-1.4.0.jar"); -156 Dependency commonValidator = new Dependency(fileCommonValidator); -157 jarAnalyzer.analyze(commonValidator, null); -158 hintAnalyzer.analyze(commonValidator, null); -159 -160 //File fileSpring = new File(this.getClass().getClassLoader().getResource("spring-core-2.5.5.jar").getPath()); -161 File fileSpring = BaseTest.getResourceAsFile(this, "spring-core-2.5.5.jar"); -162 Dependency spring = new Dependency(fileSpring); -163 jarAnalyzer.analyze(spring, null); -164 hintAnalyzer.analyze(spring, null); -165 -166 //File fileSpring3 = new File(this.getClass().getClassLoader().getResource("spring-core-3.0.0.RELEASE.jar").getPath()); -167 File fileSpring3 = BaseTest.getResourceAsFile(this, "spring-core-3.0.0.RELEASE.jar"); -168 Dependency spring3 = new Dependency(fileSpring3); -169 jarAnalyzer.analyze(spring3, null); -170 hintAnalyzer.analyze(spring3, null); -171 -172 CPEAnalyzer instance = new CPEAnalyzer(); -173 instance.open(); -174 instance.determineCPE(commonValidator); -175 instance.determineCPE(struts); -176 instance.determineCPE(spring); -177 instance.determineCPE(spring3); -178 instance.close(); -179 -180 String expResult = "cpe:/a:apache:struts:2.1.2"; -181 Identifier expIdentifier = new Identifier("cpe", expResult, expResult); -182 String expResultSpring = "cpe:/a:springsource:spring_framework:2.5.5"; -183 String expResultSpring3 = "cpe:/a:vmware:springsource_spring_framework:3.0.0"; +123 //File file = new File(this.getClass().getClassLoader().getResource(depName).getPath()); +124 File file = BaseTest.getResourceAsFile(this, depName); +125 +126 Dependency dep = new Dependency(file); +127 +128 fnAnalyzer.analyze(dep, null); +129 jarAnalyzer.analyze(dep, null); +130 hAnalyzer.analyze(dep, null); +131 cpeAnalyzer.analyze(dep, null); +132 fp.analyze(dep, null); +133 +134 if (expResult != null) { +135 Identifier expIdentifier = new Identifier("cpe", expResult, expResult); +136 Assert.assertTrue("Incorrect match: { dep:'" + dep.getFileName() + "' }", dep.getIdentifiers().contains(expIdentifier)); +137 } else { +138 for (Identifier i : dep.getIdentifiers()) { +139 Assert.assertFalse(String.format("%s - found a CPE identifier when should have been none (found '%s')", dep.getFileName(), i.getValue()), "cpe".equals(i.getType())); +140 } +141 } +142 } +143 +144 /** +145 * Test of determineCPE method, of class CPEAnalyzer. +146 * +147 * @throws Exception is thrown when an exception occurs +148 */ +149 @Test +150 public void testDetermineCPE() throws Exception { +151 //File file = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath()); +152 File file = BaseTest.getResourceAsFile(this, "struts2-core-2.1.2.jar"); +153 //File file = new File(this.getClass().getClassLoader().getResource("axis2-adb-1.4.1.jar").getPath()); +154 Dependency struts = new Dependency(file); +155 +156 FileNameAnalyzer fnAnalyzer = new FileNameAnalyzer(); +157 fnAnalyzer.analyze(struts, null); +158 +159 HintAnalyzer hintAnalyzer = new HintAnalyzer(); +160 hintAnalyzer.initialize(); +161 JarAnalyzer jarAnalyzer = new JarAnalyzer(); +162 jarAnalyzer.accept(new File("test.jar"));//trick analyzer into "thinking it is active" +163 jarAnalyzer.initialize(); +164 +165 jarAnalyzer.analyze(struts, null); +166 hintAnalyzer.analyze(struts, null); +167 //File fileCommonValidator = new File(this.getClass().getClassLoader().getResource("commons-validator-1.4.0.jar").getPath()); +168 File fileCommonValidator = BaseTest.getResourceAsFile(this, "commons-validator-1.4.0.jar"); +169 Dependency commonValidator = new Dependency(fileCommonValidator); +170 jarAnalyzer.analyze(commonValidator, null); +171 hintAnalyzer.analyze(commonValidator, null); +172 +173 //File fileSpring = new File(this.getClass().getClassLoader().getResource("spring-core-2.5.5.jar").getPath()); +174 File fileSpring = BaseTest.getResourceAsFile(this, "spring-core-2.5.5.jar"); +175 Dependency spring = new Dependency(fileSpring); +176 jarAnalyzer.analyze(spring, null); +177 hintAnalyzer.analyze(spring, null); +178 +179 //File fileSpring3 = new File(this.getClass().getClassLoader().getResource("spring-core-3.0.0.RELEASE.jar").getPath()); +180 File fileSpring3 = BaseTest.getResourceAsFile(this, "spring-core-3.0.0.RELEASE.jar"); +181 Dependency spring3 = new Dependency(fileSpring3); +182 jarAnalyzer.analyze(spring3, null); +183 hintAnalyzer.analyze(spring3, null); 184 -185 for (Identifier i : commonValidator.getIdentifiers()) { -186 Assert.assertFalse("Apache Common Validator - found a CPE identifier?", "cpe".equals(i.getType())); -187 } -188 -189 Assert.assertTrue("Incorrect match size - struts", struts.getIdentifiers().size() >= 1); -190 Assert.assertTrue("Incorrect match - struts", struts.getIdentifiers().contains(expIdentifier)); -191 Assert.assertTrue("Incorrect match size - spring3 - " + spring3.getIdentifiers().size(), spring3.getIdentifiers().size() >= 1); +185 CPEAnalyzer instance = new CPEAnalyzer(); +186 instance.open(); +187 instance.determineCPE(commonValidator); +188 instance.determineCPE(struts); +189 instance.determineCPE(spring); +190 instance.determineCPE(spring3); +191 instance.close(); 192 -193 //the following two only work if the HintAnalyzer is used. -194 //Assert.assertTrue("Incorrect match size - spring", spring.getIdentifiers().size() == 1); -195 //Assert.assertTrue("Incorrect match - spring", spring.getIdentifiers().get(0).getValue().equals(expResultSpring)); -196 jarAnalyzer.close(); -197 } -198 -199 /** -200 * Test of determineIdentifiers method, of class CPEAnalyzer. -201 * -202 * @throws Exception is thrown when an exception occurs -203 */ -204 @Test -205 public void testDetermineIdentifiers() throws Exception { -206 Dependency openssl = new Dependency(); -207 openssl.getVendorEvidence().addEvidence("test", "vendor", "openssl", Confidence.HIGHEST); -208 openssl.getProductEvidence().addEvidence("test", "product", "openssl", Confidence.HIGHEST); -209 openssl.getVersionEvidence().addEvidence("test", "version", "1.0.1c", Confidence.HIGHEST); -210 -211 CPEAnalyzer instance = new CPEAnalyzer(); -212 instance.open(); -213 instance.determineIdentifiers(openssl, "openssl", "openssl", Confidence.HIGHEST); -214 instance.close(); -215 -216 String expResult = "cpe:/a:openssl:openssl:1.0.1c"; -217 Identifier expIdentifier = new Identifier("cpe", expResult, expResult); -218 -219 assertTrue(openssl.getIdentifiers().contains(expIdentifier)); -220 -221 } -222 -223 /** -224 * Test of searchCPE method, of class CPEAnalyzer. -225 * -226 * @throws Exception is thrown when an exception occurs -227 */ -228 @Test -229 public void testSearchCPE() throws Exception { -230 String vendor = "apache software foundation"; -231 String product = "struts 2 core"; -232 String version = "2.1.2"; -233 String expVendor = "apache"; -234 String expProduct = "struts"; +193 String expResult = "cpe:/a:apache:struts:2.1.2"; +194 Identifier expIdentifier = new Identifier("cpe", expResult, expResult); +195 String expResultSpring = "cpe:/a:springsource:spring_framework:2.5.5"; +196 String expResultSpring3 = "cpe:/a:vmware:springsource_spring_framework:3.0.0"; +197 +198 for (Identifier i : commonValidator.getIdentifiers()) { +199 Assert.assertFalse("Apache Common Validator - found a CPE identifier?", "cpe".equals(i.getType())); +200 } +201 +202 Assert.assertTrue("Incorrect match size - struts", struts.getIdentifiers().size() >= 1); +203 Assert.assertTrue("Incorrect match - struts", struts.getIdentifiers().contains(expIdentifier)); +204 Assert.assertTrue("Incorrect match size - spring3 - " + spring3.getIdentifiers().size(), spring3.getIdentifiers().size() >= 1); +205 +206 //the following two only work if the HintAnalyzer is used. +207 //Assert.assertTrue("Incorrect match size - spring", spring.getIdentifiers().size() == 1); +208 //Assert.assertTrue("Incorrect match - spring", spring.getIdentifiers().get(0).getValue().equals(expResultSpring)); +209 jarAnalyzer.close(); +210 } +211 +212 /** +213 * Test of determineIdentifiers method, of class CPEAnalyzer. +214 * +215 * @throws Exception is thrown when an exception occurs +216 */ +217 @Test +218 public void testDetermineIdentifiers() throws Exception { +219 Dependency openssl = new Dependency(); +220 openssl.getVendorEvidence().addEvidence("test", "vendor", "openssl", Confidence.HIGHEST); +221 openssl.getProductEvidence().addEvidence("test", "product", "openssl", Confidence.HIGHEST); +222 openssl.getVersionEvidence().addEvidence("test", "version", "1.0.1c", Confidence.HIGHEST); +223 +224 CPEAnalyzer instance = new CPEAnalyzer(); +225 instance.open(); +226 instance.determineIdentifiers(openssl, "openssl", "openssl", Confidence.HIGHEST); +227 instance.close(); +228 +229 String expResult = "cpe:/a:openssl:openssl:1.0.1c"; +230 Identifier expIdentifier = new Identifier("cpe", expResult, expResult); +231 +232 assertTrue(openssl.getIdentifiers().contains(expIdentifier)); +233 +234 } 235 -236 CPEAnalyzer instance = new CPEAnalyzer(); -237 instance.open(); -238 -239 Set<String> productWeightings = Collections.singleton("struts2"); -240 -241 Set<String> vendorWeightings = Collections.singleton("apache"); -242 -243 List<IndexEntry> result = instance.searchCPE(vendor, product, vendorWeightings, productWeightings); -244 instance.close(); -245 -246 boolean found = false; -247 for (IndexEntry entry : result) { -248 if (expVendor.equals(entry.getVendor()) && expProduct.equals(entry.getProduct())) { -249 found = true; -250 break; -251 } -252 } -253 assertTrue("apache:struts was not identified", found); -254 -255 } -256 } +236 /** +237 * Test of searchCPE method, of class CPEAnalyzer. +238 * +239 * @throws Exception is thrown when an exception occurs +240 */ +241 @Test +242 public void testSearchCPE() throws Exception { +243 String vendor = "apache software foundation"; +244 String product = "struts 2 core"; +245 String version = "2.1.2"; +246 String expVendor = "apache"; +247 String expProduct = "struts"; +248 +249 CPEAnalyzer instance = new CPEAnalyzer(); +250 instance.open(); +251 +252 Set<String> productWeightings = Collections.singleton("struts2"); +253 +254 Set<String> vendorWeightings = Collections.singleton("apache"); +255 +256 List<IndexEntry> result = instance.searchCPE(vendor, product, vendorWeightings, productWeightings); +257 instance.close(); +258 +259 boolean found = false; +260 for (IndexEntry entry : result) { +261 if (expVendor.equals(entry.getVendor()) && expProduct.equals(entry.getProduct())) { +262 found = true; +263 break; +264 } +265 } +266 assertTrue("apache:struts was not identified", found); +267 +268 } +269 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzerTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzerTest.html index 2a4d163ba..12b21a093 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzerTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzerTest.html @@ -31,84 +31,80 @@ 23 import org.owasp.dependencycheck.BaseTest; 24 import org.owasp.dependencycheck.Engine; 25 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; -26 import org.owasp.dependencycheck.dependency.Confidence; -27 import org.owasp.dependencycheck.dependency.Dependency; -28 import org.owasp.dependencycheck.dependency.Evidence; +26 import org.owasp.dependencycheck.dependency.Dependency; +27 +28 import java.io.File; 29 -30 import java.io.File; -31 -32 import static org.hamcrest.CoreMatchers.containsString; -33 import static org.hamcrest.CoreMatchers.is; -34 import static org.junit.Assert.assertEquals; -35 import static org.junit.Assert.assertThat; -36 import static org.junit.Assert.assertTrue; -37 import org.owasp.dependencycheck.BaseDBTestCase; -38 -39 /** -40 * Unit tests for NodePackageAnalyzer. -41 * -42 * @author Dale Visser -43 */ -44 public class ComposerLockAnalyzerTest extends BaseDBTestCase { +30 import static org.junit.Assert.assertEquals; +31 import static org.junit.Assert.assertTrue; +32 import org.owasp.dependencycheck.BaseDBTestCase; +33 +34 /** +35 * Unit tests for NodePackageAnalyzer. +36 * +37 * @author Dale Visser +38 */ +39 public class ComposerLockAnalyzerTest extends BaseDBTestCase { +40 +41 /** +42 * The analyzer to test. +43 */ +44 ComposerLockAnalyzer analyzer; 45 46 /** -47 * The analyzer to test. -48 */ -49 ComposerLockAnalyzer analyzer; -50 -51 /** -52 * Correctly setup the analyzer for testing. -53 * -54 * @throws Exception thrown if there is a problem -55 */ -56 @Before -57 public void setUp() throws Exception { -58 super.setUp(); -59 analyzer = new ComposerLockAnalyzer(); -60 analyzer.setFilesMatched(true); -61 analyzer.initialize(); -62 } -63 -64 /** -65 * Cleanup the analyzer's temp files, etc. -66 * -67 * @throws Exception thrown if there is a problem -68 */ -69 @After -70 public void tearDown() throws Exception { -71 analyzer.close(); -72 analyzer = null; -73 } -74 -75 /** -76 * Test of getName method, of class ComposerLockAnalyzer. -77 */ -78 @Test -79 public void testGetName() { -80 assertEquals("Composer.lock analyzer", analyzer.getName()); -81 } -82 -83 /** -84 * Test of supportsExtension method, of class ComposerLockAnalyzer. -85 */ -86 @Test -87 public void testSupportsFiles() { -88 assertTrue(analyzer.accept(new File("composer.lock"))); -89 } -90 -91 /** -92 * Test of inspect method, of class PythonDistributionAnalyzer. -93 * -94 * @throws AnalysisException is thrown when an exception occurs. -95 */ -96 @Test -97 public void testAnalyzePackageJson() throws Exception { -98 final Engine engine = new Engine(); -99 final Dependency result = new Dependency(BaseTest.getResourceAsFile(this, -100 "composer.lock")); -101 analyzer.analyze(result, engine); -102 } -103 } +47 * Correctly setup the analyzer for testing. +48 * +49 * @throws Exception thrown if there is a problem +50 */ +51 @Override +52 @Before +53 public void setUp() throws Exception { +54 super.setUp(); +55 analyzer = new ComposerLockAnalyzer(); +56 analyzer.setFilesMatched(true); +57 analyzer.initialize(); +58 } +59 +60 /** +61 * Cleanup the analyzer's temp files, etc. +62 * +63 * @throws Exception thrown if there is a problem +64 */ +65 @After +66 public void tearDown() throws Exception { +67 analyzer.close(); +68 analyzer = null; +69 } +70 +71 /** +72 * Test of getName method, of class ComposerLockAnalyzer. +73 */ +74 @Test +75 public void testGetName() { +76 assertEquals("Composer.lock analyzer", analyzer.getName()); +77 } +78 +79 /** +80 * Test of supportsExtension method, of class ComposerLockAnalyzer. +81 */ +82 @Test +83 public void testSupportsFiles() { +84 assertTrue(analyzer.accept(new File("composer.lock"))); +85 } +86 +87 /** +88 * Test of inspect method, of class PythonDistributionAnalyzer. +89 * +90 * @throws AnalysisException is thrown when an exception occurs. +91 */ +92 @Test +93 public void testAnalyzePackageJson() throws Exception { +94 final Engine engine = new Engine(); +95 final Dependency result = new Dependency(BaseTest.getResourceAsFile(this, +96 "composer.lock")); +97 analyzer.analyze(result, engine); +98 } +99 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/HintAnalyzerTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/HintAnalyzerTest.html index 966cf76a5..33ebda689 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/HintAnalyzerTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/HintAnalyzerTest.html @@ -28,7 +28,7 @@ 20 import static org.junit.Assert.assertEquals; 21 import static org.junit.Assert.assertFalse; 22 import static org.junit.Assert.assertTrue; -23 import org.junit.Before; +23 24 import org.junit.Test; 25 import org.owasp.dependencycheck.BaseTest; 26 import org.owasp.dependencycheck.Engine; diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.html index 1a4f76d87..02d2e1b11 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.html @@ -34,203 +34,209 @@ 26 import java.util.Iterator; 27 import java.util.List; 28 import java.util.Set; -29 -30 import org.junit.After; -31 import org.junit.Assume; -32 import org.junit.Before; -33 import org.junit.Test; -34 import org.owasp.dependencycheck.BaseDBTestCase; -35 import org.owasp.dependencycheck.BaseTest; -36 import org.owasp.dependencycheck.Engine; -37 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; -38 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; -39 import org.owasp.dependencycheck.dependency.Dependency; -40 import org.owasp.dependencycheck.dependency.Evidence; -41 import org.owasp.dependencycheck.dependency.Identifier; -42 import org.owasp.dependencycheck.dependency.Vulnerability; -43 import org.owasp.dependencycheck.utils.Settings; -44 import org.slf4j.Logger; -45 import org.slf4j.LoggerFactory; -46 -47 /** -48 * Unit tests for {@link RubyBundleAuditAnalyzer}. -49 * -50 * @author Dale Visser -51 */ -52 public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase { -53 -54 private static final Logger LOGGER = LoggerFactory.getLogger(RubyBundleAuditAnalyzerTest.class); +29 import java.util.logging.Level; +30 +31 import org.junit.After; +32 import org.junit.Assume; +33 import org.junit.Before; +34 import org.junit.Test; +35 import org.owasp.dependencycheck.BaseDBTestCase; +36 import org.owasp.dependencycheck.BaseTest; +37 import org.owasp.dependencycheck.Engine; +38 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; +39 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; +40 import org.owasp.dependencycheck.dependency.Dependency; +41 import org.owasp.dependencycheck.dependency.Evidence; +42 import org.owasp.dependencycheck.dependency.Identifier; +43 import org.owasp.dependencycheck.dependency.Vulnerability; +44 import org.owasp.dependencycheck.exception.ExceptionCollection; +45 import org.owasp.dependencycheck.utils.Settings; +46 import org.slf4j.Logger; +47 import org.slf4j.LoggerFactory; +48 +49 /** +50 * Unit tests for {@link RubyBundleAuditAnalyzer}. +51 * +52 * @author Dale Visser +53 */ +54 public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase { 55 -56 /** -57 * The analyzer to test. -58 */ -59 RubyBundleAuditAnalyzer analyzer; -60 -61 /** -62 * Correctly setup the analyzer for testing. -63 * -64 * @throws Exception thrown if there is a problem -65 */ -66 @Before -67 public void setUp() throws Exception { -68 super.setUp(); -69 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); -70 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); -71 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); -72 analyzer = new RubyBundleAuditAnalyzer(); -73 analyzer.setFilesMatched(true); -74 } -75 -76 /** -77 * Cleanup the analyzer's temp files, etc. -78 * -79 * @throws Exception thrown if there is a problem -80 */ -81 @After -82 public void tearDown() throws Exception { -83 analyzer.close(); -84 analyzer = null; -85 } -86 -87 /** -88 * Test Ruby Gemspec name. -89 */ -90 @Test -91 public void testGetName() { -92 assertThat(analyzer.getName(), is("Ruby Bundle Audit Analyzer")); -93 } -94 -95 /** -96 * Test Ruby Bundler Audit file support. -97 */ -98 @Test -99 public void testSupportsFiles() { -100 assertThat(analyzer.accept(new File("Gemfile.lock")), is(true)); -101 } -102 -103 /** -104 * Test Ruby BundlerAudit analysis. -105 * -106 * @throws AnalysisException is thrown when an exception occurs. -107 */ -108 @Test -109 public void testAnalysis() throws AnalysisException, DatabaseException { -110 try { -111 analyzer.initialize(); -112 final String resource = "ruby/vulnerable/gems/rails-4.1.15/Gemfile.lock"; -113 final Dependency result = new Dependency(BaseTest.getResourceAsFile(this, resource)); -114 final Engine engine = new Engine(); -115 analyzer.analyze(result, engine); -116 int size = engine.getDependencies().size(); -117 -118 assertTrue(size >= 1); -119 -120 Dependency dependency = engine.getDependencies().get(0); -121 assertTrue(dependency.getProductEvidence().toString().toLowerCase().contains("redcarpet")); -122 assertTrue(dependency.getVersionEvidence().toString().toLowerCase().contains("2.2.2")); -123 assertTrue(dependency.getFilePath().endsWith(resource)); -124 assertTrue(dependency.getFileName().equals("Gemfile.lock")); -125 } catch (Exception e) { -126 LOGGER.warn("Exception setting up RubyBundleAuditAnalyzer. Make sure Ruby gem bundle-audit is installed. You may also need to set property \"analyzer.bundle.audit.path\"."); -127 Assume.assumeNoException("Exception setting up RubyBundleAuditAnalyzer; bundle audit may not be installed, or property \"analyzer.bundle.audit.path\" may not be set.", e); -128 } -129 } -130 -131 /** -132 * Test Ruby addCriticalityToVulnerability -133 */ -134 @Test -135 public void testAddCriticalityToVulnerability() throws AnalysisException, DatabaseException { -136 try { -137 analyzer.initialize(); -138 -139 final Dependency result = new Dependency(BaseTest.getResourceAsFile(this, -140 "ruby/vulnerable/gems/sinatra/Gemfile.lock")); -141 final Engine engine = new Engine(); -142 analyzer.analyze(result, engine); -143 -144 Dependency dependency = engine.getDependencies().get(0); -145 Vulnerability vulnerability = dependency.getVulnerabilities().first(); -146 assertEquals(vulnerability.getCvssScore(), 5.0f, 0.0); -147 -148 } catch (Exception e) { -149 LOGGER.warn("Exception setting up RubyBundleAuditAnalyzer. Make sure Ruby gem bundle-audit is installed. You may also need to set property \"analyzer.bundle.audit.path\".", e); -150 Assume.assumeNoException("Exception setting up RubyBundleAuditAnalyzer; bundle audit may not be installed, or property \"analyzer.bundle.audit.path\" may not be set.", e); -151 } -152 } -153 -154 /** -155 * Test when Ruby bundle-audit is not available on the system. -156 * -157 * @throws AnalysisException is thrown when an exception occurs. -158 */ -159 @Test -160 public void testMissingBundleAudit() throws AnalysisException, DatabaseException { -161 //set a non-exist bundle-audit -162 Settings.setString(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH, "phantom-bundle-audit"); -163 try { -164 //initialize should fail. -165 analyzer.initialize(); -166 } catch (Exception e) { -167 //expected, so ignore. -168 } finally { -169 assertThat(analyzer.isEnabled(), is(false)); -170 LOGGER.info("phantom-bundle-audit is not available. Ruby Bundle Audit Analyzer is disabled as expected."); -171 } -172 } -173 -174 /** -175 * Test Ruby dependencies and their paths. -176 * -177 * @throws AnalysisException is thrown when an exception occurs. -178 */ -179 @Test -180 public void testDependenciesPath() throws AnalysisException, DatabaseException { -181 final Engine engine = new Engine(); -182 engine.scan(BaseTest.getResourceAsFile(this, -183 "ruby/vulnerable/gems/rails-4.1.15/")); -184 try { -185 engine.analyzeDependencies(); -186 } catch (NullPointerException ex) { -187 LOGGER.error("NPE", ex); -188 throw ex; -189 } -190 List<Dependency> dependencies = engine.getDependencies(); -191 LOGGER.info(dependencies.size() + " dependencies found."); -192 Iterator<Dependency> dIterator = dependencies.iterator(); -193 while (dIterator.hasNext()) { -194 Dependency dept = dIterator.next(); -195 LOGGER.info("dept path: " + dept.getActualFilePath()); -196 -197 Set<Identifier> identifiers = dept.getIdentifiers(); -198 Iterator<Identifier> idIterator = identifiers.iterator(); -199 while (idIterator.hasNext()) { -200 Identifier id = idIterator.next(); -201 LOGGER.info(" Identifier: " + id.getValue() + ", type=" + id.getType() + ", url=" + id.getUrl() + ", conf=" + id.getConfidence()); -202 } -203 -204 Set<Evidence> prodEv = dept.getProductEvidence().getEvidence(); -205 Iterator<Evidence> it = prodEv.iterator(); -206 while (it.hasNext()) { -207 Evidence e = it.next(); -208 LOGGER.info(" prod: name=" + e.getName() + ", value=" + e.getValue() + ", source=" + e.getSource() + ", confidence=" + e.getConfidence()); -209 } -210 Set<Evidence> versionEv = dept.getVersionEvidence().getEvidence(); -211 Iterator<Evidence> vIt = versionEv.iterator(); -212 while (vIt.hasNext()) { -213 Evidence e = vIt.next(); -214 LOGGER.info(" version: name=" + e.getName() + ", value=" + e.getValue() + ", source=" + e.getSource() + ", confidence=" + e.getConfidence()); +56 private static final Logger LOGGER = LoggerFactory.getLogger(RubyBundleAuditAnalyzerTest.class); +57 +58 /** +59 * The analyzer to test. +60 */ +61 RubyBundleAuditAnalyzer analyzer; +62 +63 /** +64 * Correctly setup the analyzer for testing. +65 * +66 * @throws Exception thrown if there is a problem +67 */ +68 @Override +69 @Before +70 public void setUp() throws Exception { +71 super.setUp(); +72 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); +73 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); +74 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); +75 analyzer = new RubyBundleAuditAnalyzer(); +76 analyzer.setFilesMatched(true); +77 } +78 +79 /** +80 * Cleanup the analyzer's temp files, etc. +81 * +82 * @throws Exception thrown if there is a problem +83 */ +84 @After +85 public void tearDown() throws Exception { +86 analyzer.close(); +87 analyzer = null; +88 } +89 +90 /** +91 * Test Ruby Gemspec name. +92 */ +93 @Test +94 public void testGetName() { +95 assertThat(analyzer.getName(), is("Ruby Bundle Audit Analyzer")); +96 } +97 +98 /** +99 * Test Ruby Bundler Audit file support. +100 */ +101 @Test +102 public void testSupportsFiles() { +103 assertThat(analyzer.accept(new File("Gemfile.lock")), is(true)); +104 } +105 +106 /** +107 * Test Ruby BundlerAudit analysis. +108 * +109 * @throws AnalysisException is thrown when an exception occurs. +110 */ +111 @Test +112 public void testAnalysis() throws AnalysisException, DatabaseException { +113 try { +114 analyzer.initialize(); +115 final String resource = "ruby/vulnerable/gems/rails-4.1.15/Gemfile.lock"; +116 final Dependency result = new Dependency(BaseTest.getResourceAsFile(this, resource)); +117 final Engine engine = new Engine(); +118 analyzer.analyze(result, engine); +119 int size = engine.getDependencies().size(); +120 +121 assertTrue(size >= 1); +122 +123 Dependency dependency = engine.getDependencies().get(0); +124 assertTrue(dependency.getProductEvidence().toString().toLowerCase().contains("redcarpet")); +125 assertTrue(dependency.getVersionEvidence().toString().toLowerCase().contains("2.2.2")); +126 assertTrue(dependency.getFilePath().endsWith(resource)); +127 assertTrue(dependency.getFileName().equals("Gemfile.lock")); +128 } catch (Exception e) { +129 LOGGER.warn("Exception setting up RubyBundleAuditAnalyzer. Make sure Ruby gem bundle-audit is installed. You may also need to set property \"analyzer.bundle.audit.path\"."); +130 Assume.assumeNoException("Exception setting up RubyBundleAuditAnalyzer; bundle audit may not be installed, or property \"analyzer.bundle.audit.path\" may not be set.", e); +131 } +132 } +133 +134 /** +135 * Test Ruby addCriticalityToVulnerability +136 */ +137 @Test +138 public void testAddCriticalityToVulnerability() throws AnalysisException, DatabaseException { +139 try { +140 analyzer.initialize(); +141 +142 final Dependency result = new Dependency(BaseTest.getResourceAsFile(this, +143 "ruby/vulnerable/gems/sinatra/Gemfile.lock")); +144 final Engine engine = new Engine(); +145 analyzer.analyze(result, engine); +146 +147 Dependency dependency = engine.getDependencies().get(0); +148 Vulnerability vulnerability = dependency.getVulnerabilities().first(); +149 assertEquals(vulnerability.getCvssScore(), 5.0f, 0.0); +150 +151 } catch (Exception e) { +152 LOGGER.warn("Exception setting up RubyBundleAuditAnalyzer. Make sure Ruby gem bundle-audit is installed. You may also need to set property \"analyzer.bundle.audit.path\"."); +153 Assume.assumeNoException("Exception setting up RubyBundleAuditAnalyzer; bundle audit may not be installed, or property \"analyzer.bundle.audit.path\" may not be set.", e); +154 } +155 } +156 +157 /** +158 * Test when Ruby bundle-audit is not available on the system. +159 * +160 * @throws AnalysisException is thrown when an exception occurs. +161 */ +162 @Test +163 public void testMissingBundleAudit() throws AnalysisException, DatabaseException { +164 //set a non-exist bundle-audit +165 Settings.setString(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH, "phantom-bundle-audit"); +166 try { +167 //initialize should fail. +168 analyzer.initialize(); +169 } catch (Exception e) { +170 //expected, so ignore. +171 } finally { +172 assertThat(analyzer.isEnabled(), is(false)); +173 LOGGER.info("phantom-bundle-audit is not available. Ruby Bundle Audit Analyzer is disabled as expected."); +174 } +175 } +176 +177 /** +178 * Test Ruby dependencies and their paths. +179 * +180 * @throws AnalysisException is thrown when an exception occurs. +181 * @throws DatabaseException thrown when an exception occurs +182 */ +183 @Test +184 public void testDependenciesPath() throws AnalysisException, DatabaseException { +185 final Engine engine = new Engine(); +186 engine.scan(BaseTest.getResourceAsFile(this, +187 "ruby/vulnerable/gems/rails-4.1.15/")); +188 try { +189 engine.analyzeDependencies(); +190 } catch (NullPointerException ex) { +191 LOGGER.error("NPE", ex); +192 throw ex; +193 } catch (ExceptionCollection ex) { +194 Assume.assumeNoException("Exception setting up RubyBundleAuditAnalyzer; bundle audit may not be installed, or property \"analyzer.bundle.audit.path\" may not be set.", ex); +195 } +196 List<Dependency> dependencies = engine.getDependencies(); +197 LOGGER.info(dependencies.size() + " dependencies found."); +198 Iterator<Dependency> dIterator = dependencies.iterator(); +199 while (dIterator.hasNext()) { +200 Dependency dept = dIterator.next(); +201 LOGGER.info("dept path: " + dept.getActualFilePath()); +202 +203 Set<Identifier> identifiers = dept.getIdentifiers(); +204 Iterator<Identifier> idIterator = identifiers.iterator(); +205 while (idIterator.hasNext()) { +206 Identifier id = idIterator.next(); +207 LOGGER.info(" Identifier: " + id.getValue() + ", type=" + id.getType() + ", url=" + id.getUrl() + ", conf=" + id.getConfidence()); +208 } +209 +210 Set<Evidence> prodEv = dept.getProductEvidence().getEvidence(); +211 Iterator<Evidence> it = prodEv.iterator(); +212 while (it.hasNext()) { +213 Evidence e = it.next(); +214 LOGGER.info(" prod: name=" + e.getName() + ", value=" + e.getValue() + ", source=" + e.getSource() + ", confidence=" + e.getConfidence()); 215 } -216 -217 Set<Evidence> vendorEv = dept.getVendorEvidence().getEvidence(); -218 Iterator<Evidence> vendorIt = vendorEv.iterator(); -219 while (vendorIt.hasNext()) { -220 Evidence e = vendorIt.next(); -221 LOGGER.info(" vendor: name=" + e.getName() + ", value=" + e.getValue() + ", source=" + e.getSource() + ", confidence=" + e.getConfidence()); -222 } -223 } -224 } -225 } +216 Set<Evidence> versionEv = dept.getVersionEvidence().getEvidence(); +217 Iterator<Evidence> vIt = versionEv.iterator(); +218 while (vIt.hasNext()) { +219 Evidence e = vIt.next(); +220 LOGGER.info(" version: name=" + e.getName() + ", value=" + e.getValue() + ", source=" + e.getSource() + ", confidence=" + e.getConfidence()); +221 } +222 +223 Set<Evidence> vendorEv = dept.getVendorEvidence().getEvidence(); +224 Iterator<Evidence> vendorIt = vendorEv.iterator(); +225 while (vendorIt.hasNext()) { +226 Evidence e = vendorIt.next(); +227 LOGGER.info(" vendor: name=" + e.getName() + ", value=" + e.getValue() + ", source=" + e.getSource() + ", confidence=" + e.getConfidence()); +228 } +229 } +230 } +231 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/package-frame.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/package-frame.html index e7d182061..2aae2817a 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/package-frame.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.analyzer + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.analyzer diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/package-summary.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/package-summary.html index 17f0644b3..e7d14168a 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/package-summary.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.analyzer + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.analyzer diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/central/package-frame.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/central/package-frame.html index 5216723c3..153863233 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/central/package-frame.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/central/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.central + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.central diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/central/package-summary.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/central/package-summary.html index e3ab70d80..0c975aa84 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/central/package-summary.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/central/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.central + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.central diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/composer/package-frame.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/composer/package-frame.html index 8ec65e425..7d0ed4d35 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/composer/package-frame.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/composer/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.composer + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.composer diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/composer/package-summary.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/composer/package-summary.html index 3cdb060aa..eb833f352 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/composer/package-summary.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/composer/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.composer + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.composer diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cpe/package-frame.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cpe/package-frame.html index 1c5950b8a..99c73871c 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cpe/package-frame.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cpe/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.cpe + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.cpe diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cpe/package-summary.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cpe/package-summary.html index 1b0e8fb81..9922b9c7b 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cpe/package-summary.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cpe/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.cpe + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.cpe diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cwe/CweDBTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cwe/CweDBTest.html index 4ce949ccd..63fe9c951 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cwe/CweDBTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cwe/CweDBTest.html @@ -25,66 +25,63 @@ 17 */ 18 package org.owasp.dependencycheck.data.cwe; 19 -20 import org.junit.After; -21 import org.junit.AfterClass; -22 import static org.junit.Assert.assertEquals; -23 import org.junit.Before; -24 import org.junit.BeforeClass; -25 import org.junit.Test; -26 import org.owasp.dependencycheck.BaseTest; -27 -28 /** -29 * -30 * @author Jeremy Long -31 */ -32 public class CweDBTest extends BaseTest { -33 -34 /** -35 * Method to serialize the CWE HashMap. This is not used in production; this is only used once during dev to create -36 * the serialized HashMap. -37 */ -38 // @Test -39 // public void testUpdate() throws Exception { -40 // SAXParserFactory factory = SAXParserFactory.newInstance(); -41 // SAXParser saxParser = factory.newSAXParser(); -42 // -43 // CweHandler handler = new CweHandler(); -44 // //File file = new File(this.getClass().getClassLoader().getResource("cwe.2000.xml").getPath()); -45 // File file = new File(this.getClass().getClassLoader().getResource("cwec_v2.5.xml").getPath()); -46 // -47 // saxParser.parse(file, handler); -48 // System.out.println("Found " + handler.getCwe().size() + " cwe entries."); -49 // Map<String, String> cwe = handler.getCwe(); -50 //// FileOutputStream fout = new FileOutputStream("target/current.csv"); -51 //// //FileOutputStream fout = new FileOutputStream("target/new.csv"); -52 //// PrintWriter writer = new PrintWriter(fout); -53 //// for (Map.Entry<String, String> entry : cwe.entrySet()) { -54 //// writer.print('"'); -55 //// writer.print(entry.getKey()); -56 //// writer.print('"'); -57 //// writer.print(','); -58 //// writer.print('"'); -59 //// writer.print(entry.getValue()); -60 //// writer.println('"'); -61 //// } -62 //// writer.close(); -63 // -64 // FileOutputStream fout = new FileOutputStream("src/main/resources/data/cwe.hashmap.serialized"); -65 // ObjectOutputStream objOut = new ObjectOutputStream(fout); -66 // objOut.writeObject(cwe); -67 // objOut.close(); -68 // } -69 /** -70 * Test of getCweName method, of class CweDB. -71 */ -72 @Test -73 public void testGetCweName() { -74 String cweId = "CWE-16"; -75 String expResult = "Configuration"; -76 String result = CweDB.getCweName(cweId); -77 assertEquals(expResult, result); -78 } -79 } +20 import static org.junit.Assert.assertEquals; +21 +22 import org.junit.Test; +23 import org.owasp.dependencycheck.BaseTest; +24 +25 /** +26 * +27 * @author Jeremy Long +28 */ +29 public class CweDBTest extends BaseTest { +30 +31 /** +32 * Method to serialize the CWE HashMap. This is not used in production; this is only used once during dev to create +33 * the serialized HashMap. +34 */ +35 // @Test +36 // public void testUpdate() throws Exception { +37 // SAXParserFactory factory = SAXParserFactory.newInstance(); +38 // SAXParser saxParser = factory.newSAXParser(); +39 // +40 // CweHandler handler = new CweHandler(); +41 // //File file = new File(this.getClass().getClassLoader().getResource("cwe.2000.xml").getPath()); +42 // File file = new File(this.getClass().getClassLoader().getResource("cwec_v2.5.xml").getPath()); +43 // +44 // saxParser.parse(file, handler); +45 // System.out.println("Found " + handler.getCwe().size() + " cwe entries."); +46 // Map<String, String> cwe = handler.getCwe(); +47 //// FileOutputStream fout = new FileOutputStream("target/current.csv"); +48 //// //FileOutputStream fout = new FileOutputStream("target/new.csv"); +49 //// PrintWriter writer = new PrintWriter(fout); +50 //// for (Map.Entry<String, String> entry : cwe.entrySet()) { +51 //// writer.print('"'); +52 //// writer.print(entry.getKey()); +53 //// writer.print('"'); +54 //// writer.print(','); +55 //// writer.print('"'); +56 //// writer.print(entry.getValue()); +57 //// writer.println('"'); +58 //// } +59 //// writer.close(); +60 // +61 // FileOutputStream fout = new FileOutputStream("src/main/resources/data/cwe.hashmap.serialized"); +62 // ObjectOutputStream objOut = new ObjectOutputStream(fout); +63 // objOut.writeObject(cwe); +64 // objOut.close(); +65 // } +66 /** +67 * Test of getCweName method, of class CweDB. +68 */ +69 @Test +70 public void testGetCweName() { +71 String cweId = "CWE-16"; +72 String expResult = "Configuration"; +73 String result = CweDB.getCweName(cweId); +74 assertEquals(expResult, result); +75 } +76 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cwe/package-frame.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cwe/package-frame.html index d1e36a9e3..345a05414 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cwe/package-frame.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cwe/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.cwe + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.cwe diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cwe/package-summary.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cwe/package-summary.html index 7abed78ca..cd3df348a 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cwe/package-summary.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/cwe/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.cwe + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.cwe diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/lucene/FieldAnalyzerTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/lucene/FieldAnalyzerTest.html index 72486401a..0719ff09f 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/lucene/FieldAnalyzerTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/lucene/FieldAnalyzerTest.html @@ -44,81 +44,90 @@ 36 import org.apache.lucene.search.TopScoreDocCollector; 37 import org.apache.lucene.store.Directory; 38 import org.apache.lucene.store.RAMDirectory; -39 import org.junit.After; -40 import org.junit.AfterClass; -41 import static org.junit.Assert.assertEquals; -42 import static org.junit.Assert.assertFalse; -43 import org.junit.Before; -44 import org.junit.BeforeClass; -45 import org.junit.Test; -46 import org.owasp.dependencycheck.BaseTest; -47 -48 /** -49 * -50 * @author Jeremy Long -51 */ -52 public class FieldAnalyzerTest extends BaseTest { -53 -54 @Test -55 public void testAnalyzers() throws Exception { -56 -57 Analyzer analyzer = new FieldAnalyzer(LuceneUtils.CURRENT_VERSION); -58 Directory index = new RAMDirectory(); -59 -60 String field1 = "product"; -61 String text1 = "springframework"; -62 -63 String field2 = "vendor"; -64 String text2 = "springsource"; -65 -66 createIndex(analyzer, index, field1, text1, field2, text2); -67 -68 //Analyzer searchingAnalyzer = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION); -69 String querystr = "product:\"(Spring Framework Core)\" vendor:(SpringSource)"; +39 +40 import static org.junit.Assert.assertEquals; +41 import static org.junit.Assert.assertFalse; +42 +43 import org.junit.Test; +44 import org.owasp.dependencycheck.BaseTest; +45 +46 /** +47 * +48 * @author Jeremy Long +49 */ +50 public class FieldAnalyzerTest extends BaseTest { +51 +52 @Test +53 public void testAnalyzers() throws Exception { +54 +55 Analyzer analyzer = new FieldAnalyzer(LuceneUtils.CURRENT_VERSION); +56 Directory index = new RAMDirectory(); +57 +58 String field1 = "product"; +59 String text1 = "springframework"; +60 +61 String field2 = "vendor"; +62 String text2 = "springsource"; +63 +64 IndexWriter w = createIndex(analyzer, index); +65 addDoc(w, field1, text1, field2, text2); +66 text1 = "x-stream"; +67 text2 = "xstream"; +68 addDoc(w, field1, text1, field2, text2); +69 w.close(); 70 -71 SearchFieldAnalyzer searchAnalyzerProduct = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION); -72 SearchFieldAnalyzer searchAnalyzerVendor = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION); -73 HashMap<String, Analyzer> map = new HashMap<String, Analyzer>(); -74 map.put(field1, searchAnalyzerProduct); -75 map.put(field2, searchAnalyzerVendor); -76 PerFieldAnalyzerWrapper wrapper = new PerFieldAnalyzerWrapper(new StandardAnalyzer(LuceneUtils.CURRENT_VERSION), map); -77 QueryParser parser = new QueryParser(LuceneUtils.CURRENT_VERSION, field1, wrapper); -78 -79 Query q = parser.parse(querystr); -80 //System.out.println(q.toString()); +71 //Analyzer searchingAnalyzer = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION); +72 String querystr = "product:\"(Spring Framework Core)\" vendor:(SpringSource)"; +73 +74 SearchFieldAnalyzer searchAnalyzerProduct = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION); +75 SearchFieldAnalyzer searchAnalyzerVendor = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION); +76 HashMap<String, Analyzer> map = new HashMap<String, Analyzer>(); +77 map.put(field1, searchAnalyzerProduct); +78 map.put(field2, searchAnalyzerVendor); +79 PerFieldAnalyzerWrapper wrapper = new PerFieldAnalyzerWrapper(new StandardAnalyzer(LuceneUtils.CURRENT_VERSION), map); +80 QueryParser parser = new QueryParser(LuceneUtils.CURRENT_VERSION, field1, wrapper); 81 -82 int hitsPerPage = 10; +82 Query q = parser.parse(querystr); 83 -84 IndexReader reader = DirectoryReader.open(index); -85 IndexSearcher searcher = new IndexSearcher(reader); -86 TopScoreDocCollector collector = TopScoreDocCollector.create(hitsPerPage, true); -87 searcher.search(q, collector); -88 ScoreDoc[] hits = collector.topDocs().scoreDocs; -89 -90 assertEquals("Did not find 1 document?", 1, hits.length); +84 int hitsPerPage = 10; +85 +86 IndexReader reader = DirectoryReader.open(index); +87 IndexSearcher searcher = new IndexSearcher(reader); +88 TopScoreDocCollector collector = TopScoreDocCollector.create(hitsPerPage, true); +89 searcher.search(q, collector); +90 ScoreDoc[] hits = collector.topDocs().scoreDocs; 91 -92 searchAnalyzerProduct.clear(); //ensure we don't have anything left over from the previous search. -93 searchAnalyzerVendor.clear(); -94 querystr = "product:(Apache Struts) vendor:(Apache)"; -95 Query q2 = parser.parse(querystr); -96 //System.out.println(q2.toString()); -97 assertFalse("second parsing contains previousWord from the TokenPairConcatenatingFilter", q2.toString().contains("core")); -98 } -99 -100 private void createIndex(Analyzer analyzer, Directory index, String field1, String text1, String field2, String text2) throws IOException { -101 IndexWriterConfig config = new IndexWriterConfig(LuceneUtils.CURRENT_VERSION, analyzer); -102 IndexWriter w = new IndexWriter(index, config); -103 addDoc(w, field1, text1, field2, text2); -104 w.close(); -105 } -106 -107 private static void addDoc(IndexWriter w, String field1, String text1, String field2, String text2) throws IOException { -108 Document doc = new Document(); -109 doc.add(new TextField(field1, text1, Field.Store.YES)); -110 doc.add(new TextField(field2, text2, Field.Store.YES)); -111 w.addDocument(doc); -112 } -113 } +92 assertEquals("Did not find 1 document?", 1, hits.length); +93 assertEquals("springframework", searcher.doc(hits[0].doc).get(field1)); +94 assertEquals("springsource", searcher.doc(hits[0].doc).get(field2)); +95 +96 searchAnalyzerProduct.clear(); //ensure we don't have anything left over from the previous search. +97 searchAnalyzerVendor.clear(); +98 querystr = "product:(Apache Struts) vendor:(Apache)"; +99 Query q2 = parser.parse(querystr); +100 assertFalse("second parsing contains previousWord from the TokenPairConcatenatingFilter", q2.toString().contains("core")); +101 +102 querystr = "product:( x-stream^5 ) AND vendor:( thoughtworks.xstream )"; +103 Query q3 = parser.parse(querystr); +104 collector = TopScoreDocCollector.create(hitsPerPage, true); +105 searcher.search(q3, collector); +106 hits = collector.topDocs().scoreDocs; +107 assertEquals("x-stream", searcher.doc(hits[0].doc).get(field1)); +108 assertEquals("xstream", searcher.doc(hits[0].doc).get(field2)); +109 } +110 +111 private IndexWriter createIndex(Analyzer analyzer, Directory index) throws IOException { +112 IndexWriterConfig config = new IndexWriterConfig(LuceneUtils.CURRENT_VERSION, analyzer); +113 return new IndexWriter(index, config); +114 } +115 +116 private static void addDoc(IndexWriter w, String field1, String text1, String field2, String text2) throws IOException { +117 Document doc = new Document(); +118 doc.add(new TextField(field1, text1, Field.Store.YES)); +119 doc.add(new TextField(field2, text2, Field.Store.YES)); +120 w.addDocument(doc); +121 } +122 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/lucene/LuceneUtilsTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/lucene/LuceneUtilsTest.html index 5ebc9bc1e..2bacc4c54 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/lucene/LuceneUtilsTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/lucene/LuceneUtilsTest.html @@ -25,65 +25,62 @@ 17 */ 18 package org.owasp.dependencycheck.data.lucene; 19 -20 import org.junit.After; -21 import org.junit.AfterClass; -22 import static org.junit.Assert.assertEquals; -23 import org.junit.Before; -24 import org.junit.BeforeClass; -25 import org.junit.Test; -26 import org.owasp.dependencycheck.BaseTest; -27 -28 /** -29 * -30 * @author Jeremy Long -31 */ -32 public class LuceneUtilsTest extends BaseTest { -33 -34 /** -35 * Test of appendEscapedLuceneQuery method, of class LuceneUtils. -36 */ -37 @Test -38 public void testAppendEscapedLuceneQuery() { -39 StringBuilder buf = new StringBuilder(); -40 CharSequence text = "test encoding + - & | ! ( ) { } [ ] ^ \" ~ * ? : \\"; -41 String expResult = "test encoding \\+ \\- \\& \\| \\! \\( \\) \\{ \\} \\[ \\] \\^ \\\" \\~ \\* \\? \\: \\\\"; -42 LuceneUtils.appendEscapedLuceneQuery(buf, text); -43 assertEquals(expResult, buf.toString()); -44 } -45 -46 /** -47 * Test of appendEscapedLuceneQuery method, of class LuceneUtils. -48 */ -49 @Test -50 public void testAppendEscapedLuceneQuery_null() { -51 StringBuilder buf = new StringBuilder(); -52 CharSequence text = null; -53 LuceneUtils.appendEscapedLuceneQuery(buf, text); -54 assertEquals(0, buf.length()); -55 } -56 -57 /** -58 * Test of escapeLuceneQuery method, of class LuceneUtils. -59 */ -60 @Test -61 public void testEscapeLuceneQuery() { -62 CharSequence text = "test encoding + - & | ! ( ) { } [ ] ^ \" ~ * ? : \\"; -63 String expResult = "test encoding \\+ \\- \\& \\| \\! \\( \\) \\{ \\} \\[ \\] \\^ \\\" \\~ \\* \\? \\: \\\\"; -64 String result = LuceneUtils.escapeLuceneQuery(text); -65 assertEquals(expResult, result); -66 } -67 -68 /** -69 * Test of escapeLuceneQuery method, of class LuceneUtils. -70 */ -71 @Test -72 public void testEscapeLuceneQuery_null() { -73 CharSequence text = null; -74 String expResult = null; -75 String result = LuceneUtils.escapeLuceneQuery(text); -76 assertEquals(expResult, result); -77 } -78 } +20 import static org.junit.Assert.assertEquals; +21 +22 import org.junit.Test; +23 import org.owasp.dependencycheck.BaseTest; +24 +25 /** +26 * +27 * @author Jeremy Long +28 */ +29 public class LuceneUtilsTest extends BaseTest { +30 +31 /** +32 * Test of appendEscapedLuceneQuery method, of class LuceneUtils. +33 */ +34 @Test +35 public void testAppendEscapedLuceneQuery() { +36 StringBuilder buf = new StringBuilder(); +37 CharSequence text = "test encoding + - & | ! ( ) { } [ ] ^ \" ~ * ? : \\"; +38 String expResult = "test encoding \\+ \\- \\& \\| \\! \\( \\) \\{ \\} \\[ \\] \\^ \\\" \\~ \\* \\? \\: \\\\"; +39 LuceneUtils.appendEscapedLuceneQuery(buf, text); +40 assertEquals(expResult, buf.toString()); +41 } +42 +43 /** +44 * Test of appendEscapedLuceneQuery method, of class LuceneUtils. +45 */ +46 @Test +47 public void testAppendEscapedLuceneQuery_null() { +48 StringBuilder buf = new StringBuilder(); +49 CharSequence text = null; +50 LuceneUtils.appendEscapedLuceneQuery(buf, text); +51 assertEquals(0, buf.length()); +52 } +53 +54 /** +55 * Test of escapeLuceneQuery method, of class LuceneUtils. +56 */ +57 @Test +58 public void testEscapeLuceneQuery() { +59 CharSequence text = "test encoding + - & | ! ( ) { } [ ] ^ \" ~ * ? : \\"; +60 String expResult = "test encoding \\+ \\- \\& \\| \\! \\( \\) \\{ \\} \\[ \\] \\^ \\\" \\~ \\* \\? \\: \\\\"; +61 String result = LuceneUtils.escapeLuceneQuery(text); +62 assertEquals(expResult, result); +63 } +64 +65 /** +66 * Test of escapeLuceneQuery method, of class LuceneUtils. +67 */ +68 @Test +69 public void testEscapeLuceneQuery_null() { +70 CharSequence text = null; +71 String expResult = null; +72 String result = LuceneUtils.escapeLuceneQuery(text); +73 assertEquals(expResult, result); +74 } +75 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/lucene/TokenPairConcatenatingFilterTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/lucene/TokenPairConcatenatingFilterTest.html index f70d8c3ff..8dd9985c2 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/lucene/TokenPairConcatenatingFilterTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/lucene/TokenPairConcatenatingFilterTest.html @@ -28,65 +28,60 @@ 20 import java.io.IOException; 21 import java.io.StringReader; 22 import org.apache.lucene.analysis.BaseTokenStreamTestCase; -23 import static org.apache.lucene.analysis.BaseTokenStreamTestCase.assertTokenStreamContents; -24 import org.apache.lucene.analysis.TokenStream; -25 import org.apache.lucene.analysis.Tokenizer; -26 import org.apache.lucene.analysis.core.WhitespaceTokenizer; -27 import org.junit.After; -28 import org.junit.AfterClass; -29 import static org.junit.Assert.assertNotNull; -30 import static org.junit.Assert.assertNull; -31 import static org.junit.Assert.assertTrue; -32 import org.junit.Before; -33 import org.junit.BeforeClass; -34 import org.junit.Test; -35 -36 /** -37 * -38 * @author Jeremy Long -39 */ -40 public class TokenPairConcatenatingFilterTest extends BaseTokenStreamTestCase { -41 -42 @Override -43 @Before -44 public void setUp() throws Exception { -45 super.setUp(); -46 } -47 -48 @Override -49 @After -50 public void tearDown() throws Exception { -51 super.tearDown(); -52 } -53 -54 /** -55 * test some examples -56 */ -57 public void testExamples() throws IOException { -58 Tokenizer wsTokenizer = new WhitespaceTokenizer(LuceneUtils.CURRENT_VERSION, new StringReader("one two three")); -59 TokenStream filter = new TokenPairConcatenatingFilter(wsTokenizer); -60 assertTokenStreamContents(filter, -61 new String[]{"one", "onetwo", "two", "twothree", "three"}); -62 } -63 -64 /** -65 * Test of clear method, of class TokenPairConcatenatingFilter. -66 * -67 * @throws java.io.IOException -68 */ -69 @Test -70 public void testClear() throws IOException { -71 -72 TokenStream ts = new WhitespaceTokenizer(LuceneUtils.CURRENT_VERSION, new StringReader("one two three")); -73 TokenPairConcatenatingFilter filter = new TokenPairConcatenatingFilter(ts); -74 assertTokenStreamContents(filter, new String[]{"one", "onetwo", "two", "twothree", "three"}); -75 -76 assertNotNull(filter.getPreviousWord()); -77 filter.clear(); -78 assertNull(filter.getPreviousWord()); -79 assertTrue(filter.getWords().isEmpty()); -80 } -81 } +23 import org.apache.lucene.analysis.TokenStream; +24 import org.apache.lucene.analysis.Tokenizer; +25 import org.apache.lucene.analysis.core.WhitespaceTokenizer; +26 import org.junit.After; +27 +28 import org.junit.Before; +29 import org.junit.Test; +30 +31 /** +32 * +33 * @author Jeremy Long +34 */ +35 public class TokenPairConcatenatingFilterTest extends BaseTokenStreamTestCase { +36 +37 @Override +38 @Before +39 public void setUp() throws Exception { +40 super.setUp(); +41 } +42 +43 @Override +44 @After +45 public void tearDown() throws Exception { +46 super.tearDown(); +47 } +48 +49 /** +50 * test some examples +51 */ +52 public void testExamples() throws IOException { +53 Tokenizer wsTokenizer = new WhitespaceTokenizer(LuceneUtils.CURRENT_VERSION, new StringReader("one two three")); +54 TokenStream filter = new TokenPairConcatenatingFilter(wsTokenizer); +55 assertTokenStreamContents(filter, +56 new String[]{"one", "onetwo", "two", "twothree", "three"}); +57 } +58 +59 /** +60 * Test of clear method, of class TokenPairConcatenatingFilter. +61 * +62 * @throws java.io.IOException +63 */ +64 @Test +65 public void testClear() throws IOException { +66 +67 TokenStream ts = new WhitespaceTokenizer(LuceneUtils.CURRENT_VERSION, new StringReader("one two three")); +68 TokenPairConcatenatingFilter filter = new TokenPairConcatenatingFilter(ts); +69 assertTokenStreamContents(filter, new String[]{"one", "onetwo", "two", "twothree", "three"}); +70 +71 assertNotNull(filter.getPreviousWord()); +72 filter.clear(); +73 assertNull(filter.getPreviousWord()); +74 assertTrue(filter.getWords().isEmpty()); +75 } +76 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/lucene/package-frame.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/lucene/package-frame.html index 1b199f1ff..e8868aa26 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/lucene/package-frame.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/lucene/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.lucene + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.lucene diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/lucene/package-summary.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/lucene/package-summary.html index b20f5b9d4..22d61f710 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/lucene/package-summary.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/lucene/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.lucene + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.lucene diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nexus/package-frame.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nexus/package-frame.html index a973a5c32..f37318529 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nexus/package-frame.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nexus/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.nexus + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.nexus diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nexus/package-summary.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nexus/package-summary.html index 8ec76a390..bc64db70e 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nexus/package-summary.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nexus/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.nexus + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.nexus diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nuget/package-frame.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nuget/package-frame.html index ed3214030..51eed6cf6 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nuget/package-frame.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nuget/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.nuget + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.nuget diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nuget/package-summary.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nuget/package-summary.html index 588ad768e..962f3cd60 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nuget/package-summary.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nuget/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.nuget + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.nuget diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/ConnectionFactoryTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/ConnectionFactoryTest.html index f5db3dddd..09164ceb7 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/ConnectionFactoryTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/ConnectionFactoryTest.html @@ -25,34 +25,31 @@ 17 18 import java.sql.Connection; 19 import java.sql.SQLException; -20 import org.junit.After; -21 import org.junit.AfterClass; -22 import org.junit.Before; -23 import org.junit.BeforeClass; -24 import org.junit.Test; -25 import static org.junit.Assert.*; -26 import org.owasp.dependencycheck.BaseDBTestCase; -27 -28 /** -29 * -30 * @author jeremy -31 */ -32 public class ConnectionFactoryTest extends BaseDBTestCase { -33 -34 /** -35 * Test of initialize method, of class ConnectionFactory. -36 * -37 * @throws org.owasp.dependencycheck.data.nvdcve.DatabaseException -38 */ -39 @Test -40 public void testInitialize() throws DatabaseException, SQLException { -41 ConnectionFactory.initialize(); -42 Connection result = ConnectionFactory.getConnection(); -43 assertNotNull(result); -44 result.close(); -45 ConnectionFactory.cleanup(); -46 } -47 } +20 +21 import org.junit.Test; +22 import static org.junit.Assert.*; +23 import org.owasp.dependencycheck.BaseDBTestCase; +24 +25 /** +26 * +27 * @author jeremy +28 */ +29 public class ConnectionFactoryTest extends BaseDBTestCase { +30 +31 /** +32 * Test of initialize method, of class ConnectionFactory. +33 * +34 * @throws org.owasp.dependencycheck.data.nvdcve.DatabaseException +35 */ +36 @Test +37 public void testInitialize() throws DatabaseException, SQLException { +38 ConnectionFactory.initialize(); +39 Connection result = ConnectionFactory.getConnection(); +40 assertNotNull(result); +41 result.close(); +42 ConnectionFactory.cleanup(); +43 } +44 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/CveDBMySQLTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/CveDBMySQLTest.html index e861d3cbf..c19cb8801 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/CveDBMySQLTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/CveDBMySQLTest.html @@ -27,77 +27,74 @@ 19 20 import java.util.List; 21 import java.util.Set; -22 import org.junit.After; -23 import org.junit.AfterClass; -24 import static org.junit.Assert.assertTrue; -25 import org.junit.Before; -26 import org.junit.BeforeClass; -27 import org.junit.Test; -28 import org.owasp.dependencycheck.BaseTest; -29 import org.owasp.dependencycheck.dependency.Vulnerability; -30 import org.owasp.dependencycheck.dependency.VulnerableSoftware; -31 import org.owasp.dependencycheck.utils.Settings; -32 -33 /** -34 * -35 * @author Jeremy Long -36 */ -37 public class CveDBMySQLTest extends BaseTest { -38 -39 /** -40 * Pretty useless tests of open, commit, and close methods, of class CveDB. -41 */ -42 @Test -43 public void testOpen() throws DatabaseException { -44 try { -45 CveDB instance = new CveDB(); -46 instance.open(); -47 instance.close(); -48 } catch (DatabaseException ex) { -49 System.out.println("Unable to connect to the My SQL database; verify that the db server is running and that the schema has been generated"); -50 throw ex; -51 } -52 } -53 -54 /** -55 * Test of getCPEs method, of class CveDB. -56 */ -57 @Test -58 public void testGetCPEs() throws Exception { -59 CveDB instance = new CveDB(); -60 try { -61 String vendor = "apache"; -62 String product = "struts"; -63 instance.open(); -64 Set<VulnerableSoftware> result = instance.getCPEs(vendor, product); -65 assertTrue("Has data been loaded into the MySQL DB? if not consider using the CLI to populate it", result.size() > 5); -66 } catch (Exception ex) { -67 System.out.println("Unable to access the My SQL database; verify that the db server is running and that the schema has been generated"); -68 throw ex; -69 } finally { -70 instance.close(); -71 } -72 } -73 -74 /** -75 * Test of getVulnerabilities method, of class CveDB. -76 */ -77 @Test -78 public void testGetVulnerabilities() throws Exception { -79 String cpeStr = "cpe:/a:apache:struts:2.1.2"; -80 CveDB instance = new CveDB(); -81 try { -82 instance.open(); -83 List<Vulnerability> result = instance.getVulnerabilities(cpeStr); -84 assertTrue(result.size() > 5); -85 } catch (Exception ex) { -86 System.out.println("Unable to access the My SQL database; verify that the db server is running and that the schema has been generated"); -87 throw ex; -88 } finally { -89 instance.close(); -90 } -91 } -92 } +22 +23 import static org.junit.Assert.assertTrue; +24 +25 import org.junit.Test; +26 import org.owasp.dependencycheck.BaseTest; +27 import org.owasp.dependencycheck.dependency.Vulnerability; +28 import org.owasp.dependencycheck.dependency.VulnerableSoftware; +29 +30 /** +31 * +32 * @author Jeremy Long +33 */ +34 public class CveDBMySQLTest extends BaseTest { +35 +36 /** +37 * Pretty useless tests of open, commit, and close methods, of class CveDB. +38 */ +39 @Test +40 public void testOpen() throws DatabaseException { +41 try { +42 CveDB instance = new CveDB(); +43 instance.open(); +44 instance.close(); +45 } catch (DatabaseException ex) { +46 System.out.println("Unable to connect to the My SQL database; verify that the db server is running and that the schema has been generated"); +47 throw ex; +48 } +49 } +50 +51 /** +52 * Test of getCPEs method, of class CveDB. +53 */ +54 @Test +55 public void testGetCPEs() throws Exception { +56 CveDB instance = new CveDB(); +57 try { +58 String vendor = "apache"; +59 String product = "struts"; +60 instance.open(); +61 Set<VulnerableSoftware> result = instance.getCPEs(vendor, product); +62 assertTrue("Has data been loaded into the MySQL DB? if not consider using the CLI to populate it", result.size() > 5); +63 } catch (Exception ex) { +64 System.out.println("Unable to access the My SQL database; verify that the db server is running and that the schema has been generated"); +65 throw ex; +66 } finally { +67 instance.close(); +68 } +69 } +70 +71 /** +72 * Test of getVulnerabilities method, of class CveDB. +73 */ +74 @Test +75 public void testGetVulnerabilities() throws Exception { +76 String cpeStr = "cpe:/a:apache:struts:2.1.2"; +77 CveDB instance = new CveDB(); +78 try { +79 instance.open(); +80 List<Vulnerability> result = instance.getVulnerabilities(cpeStr); +81 assertTrue(result.size() > 5); +82 } catch (Exception ex) { +83 System.out.println("Unable to access the My SQL database; verify that the db server is running and that the schema has been generated"); +84 throw ex; +85 } finally { +86 instance.close(); +87 } +88 } +89 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/DriverLoaderTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/DriverLoaderTest.html index ddf2c22d1..9934baaf6 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/DriverLoaderTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/DriverLoaderTest.html @@ -28,122 +28,120 @@ 20 import java.io.File; 21 import java.sql.Driver; 22 import java.sql.DriverManager; -23 import org.junit.After; -24 import org.junit.AfterClass; -25 import static org.junit.Assert.assertNotNull; -26 import static org.junit.Assert.assertTrue; -27 import org.junit.Before; -28 import org.junit.BeforeClass; -29 import org.junit.Test; -30 import org.owasp.dependencycheck.BaseTest; -31 -32 /** -33 * -34 * @author Jeremy Long -35 */ -36 public class DriverLoaderTest extends BaseTest { -37 -38 /** -39 * Test of load method, of class DriverLoader. -40 */ -41 @Test -42 public void testLoad_String() throws Exception { -43 String className = "org.h2.Driver"; -44 Driver d = null; -45 try { -46 d = DriverLoader.load(className); -47 } finally { -48 if (d != null) { -49 DriverManager.deregisterDriver(d); -50 } -51 } -52 } -53 -54 /** -55 * Test of load method, of class DriverLoader; expecting an exception due to -56 * a bad driver class name. -57 */ -58 @Test(expected = DriverLoadException.class) -59 public void testLoad_String_ex() throws Exception { -60 String className = "bad.Driver"; -61 Driver d = DriverLoader.load(className); -62 } -63 -64 /** -65 * Test of load method, of class DriverLoader. -66 */ -67 @Test -68 public void testLoad_String_String() throws Exception { -69 String className = "com.mysql.jdbc.Driver"; -70 //we know this is in target/test-classes -71 //File testClassPath = (new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath())).getParentFile(); -72 File testClassPath = BaseTest.getResourceAsFile(this, "org.mortbay.jetty.jar").getParentFile(); -73 File driver = new File(testClassPath, "../../src/test/resources/mysql-connector-java-5.1.27-bin.jar"); -74 assertTrue("MySQL Driver JAR file not found in src/test/resources?", driver.isFile()); -75 -76 Driver d = null; -77 try { -78 d = DriverLoader.load(className, driver.getAbsolutePath()); -79 d = DriverManager.getDriver("jdbc:mysql://localhost:3306/dependencycheck"); -80 assertNotNull(d); -81 } finally { -82 if (d != null) { -83 DriverManager.deregisterDriver(d); -84 } -85 } -86 } -87 -88 /** -89 * Test of load method, of class DriverLoader. -90 */ -91 @Test -92 public void testLoad_String_String_multiple_paths() throws Exception { -93 final String className = "com.mysql.jdbc.Driver"; -94 //we know this is in target/test-classes -95 //final File testClassPath = (new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath())).getParentFile(); -96 final File testClassPath = BaseTest.getResourceAsFile(this, "org.mortbay.jetty.jar").getParentFile(); -97 final File dir1 = new File(testClassPath, "../../src/test/"); -98 final File dir2 = new File(testClassPath, "../../src/test/resources/"); -99 final String paths = String.format("%s" + File.pathSeparator + "%s", dir1.getAbsolutePath(), dir2.getAbsolutePath()); -100 -101 Driver d = null; -102 try { -103 d = DriverLoader.load(className, paths); -104 } finally { -105 if (d != null) { -106 DriverManager.deregisterDriver(d); -107 } -108 } -109 } -110 -111 /** -112 * Test of load method, of class DriverLoader with an incorrect class name. -113 */ -114 @Test(expected = DriverLoadException.class) -115 public void testLoad_String_String_badClassName() throws Exception { -116 String className = "com.mybad.jdbc.Driver"; -117 //we know this is in target/test-classes -118 //File testClassPath = (new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath())).getParentFile(); -119 File testClassPath = BaseTest.getResourceAsFile(this, "org.mortbay.jetty.jar").getParentFile(); -120 File driver = new File(testClassPath, "../../src/test/resources/mysql-connector-java-5.1.27-bin.jar"); -121 assertTrue("MySQL Driver JAR file not found in src/test/resources?", driver.isFile()); -122 -123 Driver d = DriverLoader.load(className, driver.getAbsolutePath()); -124 } -125 -126 /** -127 * Test of load method, of class DriverLoader with an incorrect class path. -128 */ -129 @Test(expected = DriverLoadException.class) -130 public void testLoad_String_String_badPath() throws Exception { -131 String className = "com.mysql.jdbc.Driver"; -132 //we know this is in target/test-classes -133 //File testClassPath = (new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath())).getParentFile(); -134 File testClassPath = BaseTest.getResourceAsFile(this, "org.mortbay.jetty.jar").getParentFile(); -135 File driver = new File(testClassPath, "../../src/test/bad/mysql-connector-java-5.1.27-bin.jar"); -136 Driver d = DriverLoader.load(className, driver.getAbsolutePath()); -137 } -138 } +23 +24 import static org.junit.Assert.assertNotNull; +25 import static org.junit.Assert.assertTrue; +26 +27 import org.junit.Test; +28 import org.owasp.dependencycheck.BaseTest; +29 +30 /** +31 * +32 * @author Jeremy Long +33 */ +34 public class DriverLoaderTest extends BaseTest { +35 +36 /** +37 * Test of load method, of class DriverLoader. +38 */ +39 @Test +40 public void testLoad_String() throws Exception { +41 String className = "org.h2.Driver"; +42 Driver d = null; +43 try { +44 d = DriverLoader.load(className); +45 } finally { +46 if (d != null) { +47 DriverManager.deregisterDriver(d); +48 } +49 } +50 } +51 +52 /** +53 * Test of load method, of class DriverLoader; expecting an exception due to +54 * a bad driver class name. +55 */ +56 @Test(expected = DriverLoadException.class) +57 public void testLoad_String_ex() throws Exception { +58 String className = "bad.Driver"; +59 Driver d = DriverLoader.load(className); +60 } +61 +62 /** +63 * Test of load method, of class DriverLoader. +64 */ +65 @Test +66 public void testLoad_String_String() throws Exception { +67 String className = "com.mysql.jdbc.Driver"; +68 //we know this is in target/test-classes +69 //File testClassPath = (new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath())).getParentFile(); +70 File testClassPath = BaseTest.getResourceAsFile(this, "org.mortbay.jetty.jar").getParentFile(); +71 File driver = new File(testClassPath, "../../src/test/resources/mysql-connector-java-5.1.27-bin.jar"); +72 assertTrue("MySQL Driver JAR file not found in src/test/resources?", driver.isFile()); +73 +74 Driver d = null; +75 try { +76 d = DriverLoader.load(className, driver.getAbsolutePath()); +77 d = DriverManager.getDriver("jdbc:mysql://localhost:3306/dependencycheck"); +78 assertNotNull(d); +79 } finally { +80 if (d != null) { +81 DriverManager.deregisterDriver(d); +82 } +83 } +84 } +85 +86 /** +87 * Test of load method, of class DriverLoader. +88 */ +89 @Test +90 public void testLoad_String_String_multiple_paths() throws Exception { +91 final String className = "com.mysql.jdbc.Driver"; +92 //we know this is in target/test-classes +93 //final File testClassPath = (new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath())).getParentFile(); +94 final File testClassPath = BaseTest.getResourceAsFile(this, "org.mortbay.jetty.jar").getParentFile(); +95 final File dir1 = new File(testClassPath, "../../src/test/"); +96 final File dir2 = new File(testClassPath, "../../src/test/resources/"); +97 final String paths = String.format("%s" + File.pathSeparator + "%s", dir1.getAbsolutePath(), dir2.getAbsolutePath()); +98 +99 Driver d = null; +100 try { +101 d = DriverLoader.load(className, paths); +102 } finally { +103 if (d != null) { +104 DriverManager.deregisterDriver(d); +105 } +106 } +107 } +108 +109 /** +110 * Test of load method, of class DriverLoader with an incorrect class name. +111 */ +112 @Test(expected = DriverLoadException.class) +113 public void testLoad_String_String_badClassName() throws Exception { +114 String className = "com.mybad.jdbc.Driver"; +115 //we know this is in target/test-classes +116 //File testClassPath = (new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath())).getParentFile(); +117 File testClassPath = BaseTest.getResourceAsFile(this, "org.mortbay.jetty.jar").getParentFile(); +118 File driver = new File(testClassPath, "../../src/test/resources/mysql-connector-java-5.1.27-bin.jar"); +119 assertTrue("MySQL Driver JAR file not found in src/test/resources?", driver.isFile()); +120 +121 Driver d = DriverLoader.load(className, driver.getAbsolutePath()); +122 } +123 +124 /** +125 * Test of load method, of class DriverLoader with an incorrect class path. +126 */ +127 @Test(expected = DriverLoadException.class) +128 public void testLoad_String_String_badPath() throws Exception { +129 String className = "com.mysql.jdbc.Driver"; +130 //we know this is in target/test-classes +131 //File testClassPath = (new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath())).getParentFile(); +132 File testClassPath = BaseTest.getResourceAsFile(this, "org.mortbay.jetty.jar").getParentFile(); +133 File driver = new File(testClassPath, "../../src/test/bad/mysql-connector-java-5.1.27-bin.jar"); +134 Driver d = DriverLoader.load(className, driver.getAbsolutePath()); +135 } +136 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/package-frame.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/package-frame.html index 9eb69be17..41e54f75a 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/package-frame.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.nvdcve + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.nvdcve diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/package-summary.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/package-summary.html index f0f4dc42b..a746453f5 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/package-summary.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.nvdcve + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.nvdcve diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/DownloadTaskTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/DownloadTaskTest.html index 9cb360c41..5eca9f3b6 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/DownloadTaskTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/DownloadTaskTest.html @@ -28,56 +28,54 @@ 20 import java.io.File; 21 import java.util.concurrent.ExecutorService; 22 import java.util.concurrent.Future; -23 import org.junit.After; -24 import org.junit.AfterClass; -25 import static org.junit.Assert.assertFalse; -26 import static org.junit.Assert.assertNull; -27 import static org.junit.Assert.assertTrue; -28 import org.junit.Before; -29 import org.junit.BeforeClass; -30 import org.junit.Test; -31 import org.owasp.dependencycheck.BaseTest; -32 import org.owasp.dependencycheck.data.nvdcve.CveDB; -33 import org.owasp.dependencycheck.utils.Settings; -34 -35 /** -36 * -37 * @author Jeremy Long -38 */ -39 public class DownloadTaskTest extends BaseTest { -40 -41 public DownloadTaskTest() { -42 } -43 -44 /** -45 * Test of call method, of class DownloadTask. -46 */ -47 @Test -48 public void testCall() throws Exception { -49 NvdCveInfo cve = new NvdCveInfo(); -50 cve.setId("modified"); -51 cve.setNeedsUpdate(true); -52 cve.setUrl(Settings.getString(Settings.KEYS.CVE_MODIFIED_20_URL)); -53 cve.setOldSchemaVersionUrl(Settings.getString(Settings.KEYS.CVE_MODIFIED_12_URL)); -54 ExecutorService processExecutor = null; -55 CveDB cveDB = null; -56 DownloadTask instance = new DownloadTask(cve, processExecutor, cveDB, Settings.getInstance()); -57 Future<ProcessTask> result = instance.call(); -58 assertNull(result); -59 } -60 -61 /** -62 * Test of isXml(file). -63 */ -64 @Test -65 public void testIsXML() { -66 File f = getResourceAsFile(this, "nvdcve-modified.xml"); -67 assertTrue(DownloadTask.isXml(f)); -68 f = getResourceAsFile(this, "file.tar.gz"); -69 assertFalse(DownloadTask.isXml(f)); -70 -71 } -72 } +23 +24 import static org.junit.Assert.assertFalse; +25 import static org.junit.Assert.assertNull; +26 import static org.junit.Assert.assertTrue; +27 +28 import org.junit.Test; +29 import org.owasp.dependencycheck.BaseTest; +30 import org.owasp.dependencycheck.data.nvdcve.CveDB; +31 import org.owasp.dependencycheck.utils.Settings; +32 +33 /** +34 * +35 * @author Jeremy Long +36 */ +37 public class DownloadTaskTest extends BaseTest { +38 +39 public DownloadTaskTest() { +40 } +41 +42 /** +43 * Test of call method, of class DownloadTask. +44 */ +45 @Test +46 public void testCall() throws Exception { +47 NvdCveInfo cve = new NvdCveInfo(); +48 cve.setId("modified"); +49 cve.setNeedsUpdate(true); +50 cve.setUrl(Settings.getString(Settings.KEYS.CVE_MODIFIED_20_URL)); +51 cve.setOldSchemaVersionUrl(Settings.getString(Settings.KEYS.CVE_MODIFIED_12_URL)); +52 ExecutorService processExecutor = null; +53 CveDB cveDB = null; +54 DownloadTask instance = new DownloadTask(cve, processExecutor, cveDB, Settings.getInstance()); +55 Future<ProcessTask> result = instance.call(); +56 assertNull(result); +57 } +58 +59 /** +60 * Test of isXml(file). +61 */ +62 @Test +63 public void testIsXML() { +64 File f = getResourceAsFile(this, "nvdcve-modified.xml"); +65 assertTrue(DownloadTask.isXml(f)); +66 f = getResourceAsFile(this, "file.tar.gz"); +67 assertFalse(DownloadTask.isXml(f)); +68 +69 } +70 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCve_1_2_HandlerTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCve_1_2_HandlerTest.html index 8881857a7..321476d17 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCve_1_2_HandlerTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCve_1_2_HandlerTest.html @@ -31,35 +31,33 @@ 23 import java.util.Map; 24 import javax.xml.parsers.SAXParser; 25 import javax.xml.parsers.SAXParserFactory; -26 import org.junit.After; -27 import org.junit.AfterClass; -28 import static org.junit.Assert.assertTrue; -29 import org.junit.Before; -30 import org.junit.BeforeClass; -31 import org.junit.Test; -32 import org.owasp.dependencycheck.BaseTest; -33 import org.owasp.dependencycheck.dependency.VulnerableSoftware; -34 -35 /** -36 * -37 * @author Jeremy Long -38 */ -39 public class NvdCve_1_2_HandlerTest extends BaseTest { -40 -41 @Test -42 public void testParse() throws Exception { -43 SAXParserFactory factory = SAXParserFactory.newInstance(); -44 SAXParser saxParser = factory.newSAXParser(); -45 -46 //File file = new File(this.getClass().getClassLoader().getResource("nvdcve-2012.xml").getPath()); -47 File file = BaseTest.getResourceAsFile(this, "nvdcve-2012.xml"); -48 -49 NvdCve12Handler instance = new NvdCve12Handler(); -50 saxParser.parse(file, instance); -51 Map<String, List<VulnerableSoftware>> results = instance.getVulnerabilities(); -52 assertTrue("No vulnerable software identified with a previous version in 2012 CVE 1.2?", !results.isEmpty()); -53 } -54 } +26 +27 import static org.junit.Assert.assertTrue; +28 +29 import org.junit.Test; +30 import org.owasp.dependencycheck.BaseTest; +31 import org.owasp.dependencycheck.dependency.VulnerableSoftware; +32 +33 /** +34 * +35 * @author Jeremy Long +36 */ +37 public class NvdCve_1_2_HandlerTest extends BaseTest { +38 +39 @Test +40 public void testParse() throws Exception { +41 SAXParserFactory factory = SAXParserFactory.newInstance(); +42 SAXParser saxParser = factory.newSAXParser(); +43 +44 //File file = new File(this.getClass().getClassLoader().getResource("nvdcve-2012.xml").getPath()); +45 File file = BaseTest.getResourceAsFile(this, "nvdcve-2012.xml"); +46 +47 NvdCve12Handler instance = new NvdCve12Handler(); +48 saxParser.parse(file, instance); +49 Map<String, List<VulnerableSoftware>> results = instance.getVulnerabilities(); +50 assertTrue("No vulnerable software identified with a previous version in 2012 CVE 1.2?", !results.isEmpty()); +51 } +52 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCve_2_0_HandlerTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCve_2_0_HandlerTest.html index f892447bd..91b226a04 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCve_2_0_HandlerTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCve_2_0_HandlerTest.html @@ -31,74 +31,72 @@ 23 import java.util.Map; 24 import javax.xml.parsers.SAXParser; 25 import javax.xml.parsers.SAXParserFactory; -26 import org.junit.After; -27 import org.junit.AfterClass; -28 import static org.junit.Assert.assertTrue; -29 import org.junit.Before; -30 import org.junit.BeforeClass; -31 import org.junit.Test; -32 import org.owasp.dependencycheck.BaseTest; -33 import org.owasp.dependencycheck.dependency.VulnerableSoftware; -34 -35 /** -36 * -37 * @author Jeremy Long -38 */ -39 public class NvdCve_2_0_HandlerTest extends BaseTest { -40 -41 @Test -42 public void testParse() { -43 Throwable results = null; -44 try { -45 SAXParserFactory factory = SAXParserFactory.newInstance(); -46 SAXParser saxParser = factory.newSAXParser(); -47 -48 //File file = new File(this.getClass().getClassLoader().getResource("nvdcve-2.0-2012.xml").getPath()); -49 File file = BaseTest.getResourceAsFile(this, "nvdcve-2.0-2012.xml"); +26 +27 import static org.junit.Assert.assertTrue; +28 +29 import org.junit.Test; +30 import org.owasp.dependencycheck.BaseTest; +31 import org.owasp.dependencycheck.dependency.VulnerableSoftware; +32 +33 /** +34 * +35 * @author Jeremy Long +36 */ +37 public class NvdCve_2_0_HandlerTest extends BaseTest { +38 +39 @Test +40 public void testParse() { +41 Throwable results = null; +42 try { +43 SAXParserFactory factory = SAXParserFactory.newInstance(); +44 SAXParser saxParser = factory.newSAXParser(); +45 +46 //File file = new File(this.getClass().getClassLoader().getResource("nvdcve-2.0-2012.xml").getPath()); +47 File file = BaseTest.getResourceAsFile(this, "nvdcve-2.0-2012.xml"); +48 +49 NvdCve20Handler instance = new NvdCve20Handler(); 50 -51 NvdCve20Handler instance = new NvdCve20Handler(); -52 -53 saxParser.parse(file, instance); -54 } catch (Throwable ex) { -55 ex.printStackTrace(); -56 results = ex; -57 } -58 assertTrue("Exception thrown during parse of 2012 CVE version 2.0?", results == null); -59 if (results != null) { -60 System.err.println(results); -61 } -62 } -63 -64 @Test -65 public void testParserWithPreviousVersion() { -66 Throwable results = null; -67 try { -68 SAXParserFactory factory = SAXParserFactory.newInstance(); -69 SAXParser saxParser = factory.newSAXParser(); -70 -71 File file12 = BaseTest.getResourceAsFile(this, "cve-1.2-2008_4411.xml"); -72 -73 final NvdCve12Handler cve12Handler = new NvdCve12Handler(); -74 saxParser.parse(file12, cve12Handler); -75 final Map<String, List<VulnerableSoftware>> prevVersionVulnMap = cve12Handler.getVulnerabilities(); -76 -77 //File file = new File(this.getClass().getClassLoader().getResource("nvdcve-2.0-2012.xml").getPath()); -78 File file20 = BaseTest.getResourceAsFile(this, "cve-2.0-2008_4411.xml"); -79 -80 NvdCve20Handler instance = new NvdCve20Handler(); -81 instance.setPrevVersionVulnMap(prevVersionVulnMap); -82 saxParser.parse(file20, instance); -83 -84 assertTrue(instance.getTotalNumberOfEntries()==1); -85 } catch (Throwable ex) { -86 results = ex; -87 } -88 assertTrue("Exception thrown during parse of 2012 CVE version 2.0?", results == null); -89 if (results != null) { -90 System.err.println(results); -91 } -92 } -93 } +51 saxParser.parse(file, instance); +52 } catch (Throwable ex) { +53 ex.printStackTrace(); +54 results = ex; +55 } +56 assertTrue("Exception thrown during parse of 2012 CVE version 2.0?", results == null); +57 if (results != null) { +58 System.err.println(results); +59 } +60 } +61 +62 @Test +63 public void testParserWithPreviousVersion() { +64 Throwable results = null; +65 try { +66 SAXParserFactory factory = SAXParserFactory.newInstance(); +67 SAXParser saxParser = factory.newSAXParser(); +68 +69 File file12 = BaseTest.getResourceAsFile(this, "cve-1.2-2008_4411.xml"); +70 +71 final NvdCve12Handler cve12Handler = new NvdCve12Handler(); +72 saxParser.parse(file12, cve12Handler); +73 final Map<String, List<VulnerableSoftware>> prevVersionVulnMap = cve12Handler.getVulnerabilities(); +74 +75 //File file = new File(this.getClass().getClassLoader().getResource("nvdcve-2.0-2012.xml").getPath()); +76 File file20 = BaseTest.getResourceAsFile(this, "cve-2.0-2008_4411.xml"); +77 +78 NvdCve20Handler instance = new NvdCve20Handler(); +79 instance.setPrevVersionVulnMap(prevVersionVulnMap); +80 saxParser.parse(file20, instance); +81 +82 assertTrue(instance.getTotalNumberOfEntries()==1); +83 } catch (Throwable ex) { +84 results = ex; +85 } +86 assertTrue("Exception thrown during parse of 2012 CVE version 2.0?", results == null); +87 if (results != null) { +88 System.err.println(results); +89 } +90 } +91 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/package-frame.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/package-frame.html index 5fac37a40..2d0641a0c 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/package-frame.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.update.nvd + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.update.nvd diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/package-summary.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/package-summary.html index 8c9ee5602..7ba1e7d85 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/package-summary.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.update.nvd + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.update.nvd diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/package-frame.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/package-frame.html index b5dba740f..b5664a2a5 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/package-frame.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.update + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.update diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/package-summary.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/package-summary.html index b3e35edd9..946ef7ac4 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/package-summary.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.update + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.update diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/dependency/DependencyTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/dependency/DependencyTest.html index 5016a0f4e..90fefee8d 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/dependency/DependencyTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/dependency/DependencyTest.html @@ -26,280 +26,277 @@ 18 package org.owasp.dependencycheck.dependency; 19 20 import java.io.File; -21 import java.util.List; -22 import java.util.Set; -23 import org.junit.After; -24 import org.junit.AfterClass; -25 import static org.junit.Assert.assertEquals; -26 import static org.junit.Assert.assertFalse; -27 import static org.junit.Assert.assertTrue; -28 import org.junit.Before; -29 import org.junit.BeforeClass; -30 import org.junit.Test; -31 import org.owasp.dependencycheck.BaseTest; -32 import org.owasp.dependencycheck.data.nexus.MavenArtifact; -33 -34 /** -35 * -36 * @author Jeremy Long -37 */ -38 public class DependencyTest extends BaseTest { -39 -40 /** -41 * Test of getFileName method, of class Dependency. -42 */ -43 @Test -44 public void testGetFileName() { -45 Dependency instance = new Dependency(); -46 String expResult = "filename"; -47 instance.setFileName(expResult); -48 String result = instance.getFileName(); -49 assertEquals(expResult, result); -50 } -51 -52 /** -53 * Test of setFileName method, of class Dependency. -54 */ -55 @Test -56 public void testSetFileName() { -57 String fileName = "file.tar"; -58 Dependency instance = new Dependency(); -59 instance.setFileName(fileName); -60 assertEquals(fileName, instance.getFileName()); -61 } -62 -63 /** -64 * Test of setActualFilePath method, of class Dependency. -65 */ -66 @Test -67 public void testSetActualFilePath() { -68 String actualFilePath = "file.tar"; -69 Dependency instance = new Dependency(); -70 instance.setSha1sum("non-null value"); -71 instance.setActualFilePath(actualFilePath); -72 assertEquals(actualFilePath, instance.getActualFilePath()); -73 } -74 -75 /** -76 * Test of getActualFilePath method, of class Dependency. -77 */ -78 @Test -79 public void testGetActualFilePath() { -80 Dependency instance = new Dependency(); -81 String expResult = "file.tar"; -82 instance.setSha1sum("non-null value"); -83 instance.setActualFilePath(expResult); -84 String result = instance.getActualFilePath(); -85 assertEquals(expResult, result); -86 } -87 -88 /** -89 * Test of setFilePath method, of class Dependency. -90 */ -91 @Test -92 public void testSetFilePath() { -93 String filePath = "file.tar"; -94 Dependency instance = new Dependency(); -95 instance.setFilePath(filePath); -96 assertEquals(filePath, instance.getFilePath()); -97 } -98 -99 /** -100 * Test of getFilePath method, of class Dependency. -101 */ -102 @Test -103 public void testGetFilePath() { -104 Dependency instance = new Dependency(); -105 String expResult = "file.tar"; -106 instance.setFilePath(expResult); -107 String result = instance.getFilePath(); -108 assertEquals(expResult, result); -109 } -110 -111 /** -112 * Test of getMd5sum method, of class Dependency. -113 */ -114 @Test -115 public void testGetMd5sum() { -116 //File file = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath()); -117 File file = BaseTest.getResourceAsFile(this, "struts2-core-2.1.2.jar"); -118 -119 Dependency instance = new Dependency(file); -120 //assertEquals("89CE9E36AA9A9E03F1450936D2F4F8DD0F961F8B", result.getSha1sum()); -121 //String expResult = "C30B57142E1CCBC1EFD5CD15F307358F"; -122 String expResult = "c30b57142e1ccbc1efd5cd15f307358f"; -123 String result = instance.getMd5sum(); -124 assertEquals(expResult, result); -125 } -126 -127 /** -128 * Test of setMd5sum method, of class Dependency. -129 */ -130 @Test -131 public void testSetMd5sum() { -132 String md5sum = "test"; -133 Dependency instance = new Dependency(); -134 instance.setMd5sum(md5sum); -135 assertEquals(md5sum, instance.getMd5sum()); -136 } -137 -138 /** -139 * Test of getSha1sum method, of class Dependency. -140 */ -141 @Test -142 public void testGetSha1sum() { -143 //File file = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath()); -144 File file = BaseTest.getResourceAsFile(this, "struts2-core-2.1.2.jar"); -145 Dependency instance = new Dependency(file); -146 //String expResult = "89CE9E36AA9A9E03F1450936D2F4F8DD0F961F8B"; -147 String expResult = "89ce9e36aa9a9e03f1450936d2f4f8dd0f961f8b"; -148 String result = instance.getSha1sum(); -149 assertEquals(expResult, result); -150 } -151 -152 /** -153 * Test of setSha1sum method, of class Dependency. -154 */ -155 @Test -156 public void testSetSha1sum() { -157 String sha1sum = "test"; -158 Dependency instance = new Dependency(); -159 instance.setSha1sum(sha1sum); -160 assertEquals(sha1sum, instance.getSha1sum()); -161 } -162 -163 /** -164 * Test of getIdentifiers method, of class Dependency. -165 */ -166 @Test -167 public void testGetIdentifiers() { -168 Dependency instance = new Dependency(); -169 Set<Identifier> result = instance.getIdentifiers(); +21 import java.util.Set; +22 +23 import static org.junit.Assert.assertEquals; +24 import static org.junit.Assert.assertFalse; +25 import static org.junit.Assert.assertTrue; +26 +27 import org.junit.Test; +28 import org.owasp.dependencycheck.BaseTest; +29 import org.owasp.dependencycheck.data.nexus.MavenArtifact; +30 +31 /** +32 * +33 * @author Jeremy Long +34 */ +35 public class DependencyTest extends BaseTest { +36 +37 /** +38 * Test of getFileName method, of class Dependency. +39 */ +40 @Test +41 public void testGetFileName() { +42 Dependency instance = new Dependency(); +43 String expResult = "filename"; +44 instance.setFileName(expResult); +45 String result = instance.getFileName(); +46 assertEquals(expResult, result); +47 } +48 +49 /** +50 * Test of setFileName method, of class Dependency. +51 */ +52 @Test +53 public void testSetFileName() { +54 String fileName = "file.tar"; +55 Dependency instance = new Dependency(); +56 instance.setFileName(fileName); +57 assertEquals(fileName, instance.getFileName()); +58 } +59 +60 /** +61 * Test of setActualFilePath method, of class Dependency. +62 */ +63 @Test +64 public void testSetActualFilePath() { +65 String actualFilePath = "file.tar"; +66 Dependency instance = new Dependency(); +67 instance.setSha1sum("non-null value"); +68 instance.setActualFilePath(actualFilePath); +69 assertEquals(actualFilePath, instance.getActualFilePath()); +70 } +71 +72 /** +73 * Test of getActualFilePath method, of class Dependency. +74 */ +75 @Test +76 public void testGetActualFilePath() { +77 Dependency instance = new Dependency(); +78 String expResult = "file.tar"; +79 instance.setSha1sum("non-null value"); +80 instance.setActualFilePath(expResult); +81 String result = instance.getActualFilePath(); +82 assertEquals(expResult, result); +83 } +84 +85 /** +86 * Test of setFilePath method, of class Dependency. +87 */ +88 @Test +89 public void testSetFilePath() { +90 String filePath = "file.tar"; +91 Dependency instance = new Dependency(); +92 instance.setFilePath(filePath); +93 assertEquals(filePath, instance.getFilePath()); +94 } +95 +96 /** +97 * Test of getFilePath method, of class Dependency. +98 */ +99 @Test +100 public void testGetFilePath() { +101 Dependency instance = new Dependency(); +102 String expResult = "file.tar"; +103 instance.setFilePath(expResult); +104 String result = instance.getFilePath(); +105 assertEquals(expResult, result); +106 } +107 +108 /** +109 * Test of getMd5sum method, of class Dependency. +110 */ +111 @Test +112 public void testGetMd5sum() { +113 //File file = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath()); +114 File file = BaseTest.getResourceAsFile(this, "struts2-core-2.1.2.jar"); +115 +116 Dependency instance = new Dependency(file); +117 //assertEquals("89CE9E36AA9A9E03F1450936D2F4F8DD0F961F8B", result.getSha1sum()); +118 //String expResult = "C30B57142E1CCBC1EFD5CD15F307358F"; +119 String expResult = "c30b57142e1ccbc1efd5cd15f307358f"; +120 String result = instance.getMd5sum(); +121 assertEquals(expResult, result); +122 } +123 +124 /** +125 * Test of setMd5sum method, of class Dependency. +126 */ +127 @Test +128 public void testSetMd5sum() { +129 String md5sum = "test"; +130 Dependency instance = new Dependency(); +131 instance.setMd5sum(md5sum); +132 assertEquals(md5sum, instance.getMd5sum()); +133 } +134 +135 /** +136 * Test of getSha1sum method, of class Dependency. +137 */ +138 @Test +139 public void testGetSha1sum() { +140 //File file = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath()); +141 File file = BaseTest.getResourceAsFile(this, "struts2-core-2.1.2.jar"); +142 Dependency instance = new Dependency(file); +143 //String expResult = "89CE9E36AA9A9E03F1450936D2F4F8DD0F961F8B"; +144 String expResult = "89ce9e36aa9a9e03f1450936d2f4f8dd0f961f8b"; +145 String result = instance.getSha1sum(); +146 assertEquals(expResult, result); +147 } +148 +149 /** +150 * Test of setSha1sum method, of class Dependency. +151 */ +152 @Test +153 public void testSetSha1sum() { +154 String sha1sum = "test"; +155 Dependency instance = new Dependency(); +156 instance.setSha1sum(sha1sum); +157 assertEquals(sha1sum, instance.getSha1sum()); +158 } +159 +160 /** +161 * Test of getIdentifiers method, of class Dependency. +162 */ +163 @Test +164 public void testGetIdentifiers() { +165 Dependency instance = new Dependency(); +166 Set<Identifier> result = instance.getIdentifiers(); +167 +168 assertTrue(true); //this is just a getter setter pair. +169 } 170 -171 assertTrue(true); //this is just a getter setter pair. -172 } -173 -174 /** -175 * Test of setIdentifiers method, of class Dependency. -176 */ -177 @Test -178 public void testSetIdentifiers() { -179 Set<Identifier> identifiers = null; -180 Dependency instance = new Dependency(); -181 instance.setIdentifiers(identifiers); -182 assertTrue(true); //this is just a getter setter pair. -183 } -184 -185 /** -186 * Test of addIdentifier method, of class Dependency. -187 */ -188 @Test -189 public void testAddIdentifier() { -190 String type = "cpe"; -191 String value = "cpe:/a:apache:struts:2.1.2"; -192 String url = "http://somewhere"; -193 Identifier expResult = new Identifier(type, value, url); -194 -195 Dependency instance = new Dependency(); -196 instance.addIdentifier(type, value, url); -197 assertEquals(1, instance.getIdentifiers().size()); -198 assertTrue("Identifier doesn't contain expected result.", instance.getIdentifiers().contains(expResult)); -199 } -200 -201 /** -202 * Test of getEvidence method, of class Dependency. -203 */ -204 @Test -205 public void testGetEvidence() { -206 Dependency instance = new Dependency(); -207 EvidenceCollection expResult = null; -208 EvidenceCollection result = instance.getEvidence(); -209 assertTrue(true); //this is just a getter setter pair. -210 } -211 -212 /** -213 * Test of getEvidenceUsed method, of class Dependency. -214 */ -215 @Test -216 public void testGetEvidenceUsed() { -217 Dependency instance = new Dependency(); -218 String expResult = "used"; -219 -220 instance.getProductEvidence().addEvidence("used", "used", "used", Confidence.HIGH); -221 instance.getProductEvidence().addEvidence("not", "not", "not", Confidence.MEDIUM); -222 for (Evidence e : instance.getProductEvidence().iterator(Confidence.HIGH)) { -223 String use = e.getValue(); -224 } -225 -226 EvidenceCollection result = instance.getEvidenceUsed(); -227 -228 assertEquals(1, result.size()); -229 assertTrue(result.containsUsedString(expResult)); -230 } -231 -232 /** -233 * Test of getVendorEvidence method, of class Dependency. -234 */ -235 @Test -236 public void testGetVendorEvidence() { -237 Dependency instance = new Dependency(); -238 EvidenceCollection expResult = null; -239 EvidenceCollection result = instance.getVendorEvidence(); -240 assertTrue(true); //this is just a getter setter pair. -241 } -242 -243 /** -244 * Test of getProductEvidence method, of class Dependency. -245 */ -246 @Test -247 public void testGetProductEvidence() { -248 Dependency instance = new Dependency(); -249 EvidenceCollection expResult = null; -250 EvidenceCollection result = instance.getProductEvidence(); -251 assertTrue(true); //this is just a getter setter pair. -252 } -253 -254 /** -255 * Test of getVersionEvidence method, of class Dependency. -256 */ -257 @Test -258 public void testGetVersionEvidence() { -259 Dependency instance = new Dependency(); -260 EvidenceCollection expResult = null; -261 EvidenceCollection result = instance.getVersionEvidence(); -262 assertTrue(true); //this is just a getter setter pair. -263 } -264 -265 /** -266 * Test of addAsEvidence method, of class Dependency. -267 */ -268 @Test -269 public void testAddAsEvidence() { -270 Dependency instance = new Dependency(); -271 MavenArtifact mavenArtifact = new MavenArtifact("group", "artifact", "version", "url"); -272 instance.addAsEvidence("pom", mavenArtifact, Confidence.HIGH); -273 assertTrue(instance.getEvidence().contains(Confidence.HIGH)); -274 assertFalse(instance.getEvidence().getEvidence("pom", "groupid").isEmpty()); -275 assertFalse(instance.getEvidence().getEvidence("pom", "artifactid").isEmpty()); -276 assertFalse(instance.getEvidence().getEvidence("pom", "version").isEmpty()); -277 assertFalse(instance.getIdentifiers().isEmpty()); -278 } -279 -280 /** -281 * Test of addAsEvidence method, of class Dependency. -282 */ -283 @Test -284 public void testAddAsEvidenceWithEmptyArtefact() { -285 Dependency instance = new Dependency(); -286 MavenArtifact mavenArtifact = new MavenArtifact(null, null, null, null); -287 instance.addAsEvidence("pom", mavenArtifact, Confidence.HIGH); -288 assertFalse(instance.getEvidence().contains(Confidence.HIGH)); -289 assertTrue(instance.getEvidence().getEvidence("pom", "groupid").isEmpty()); -290 assertTrue(instance.getEvidence().getEvidence("pom", "artifactid").isEmpty()); -291 assertTrue(instance.getEvidence().getEvidence("pom", "version").isEmpty()); -292 assertTrue(instance.getIdentifiers().isEmpty()); -293 } -294 } +171 /** +172 * Test of setIdentifiers method, of class Dependency. +173 */ +174 @Test +175 public void testSetIdentifiers() { +176 Set<Identifier> identifiers = null; +177 Dependency instance = new Dependency(); +178 instance.setIdentifiers(identifiers); +179 assertTrue(true); //this is just a getter setter pair. +180 } +181 +182 /** +183 * Test of addIdentifier method, of class Dependency. +184 */ +185 @Test +186 public void testAddIdentifier() { +187 String type = "cpe"; +188 String value = "cpe:/a:apache:struts:2.1.2"; +189 String url = "http://somewhere"; +190 Identifier expResult = new Identifier(type, value, url); +191 +192 Dependency instance = new Dependency(); +193 instance.addIdentifier(type, value, url); +194 assertEquals(1, instance.getIdentifiers().size()); +195 assertTrue("Identifier doesn't contain expected result.", instance.getIdentifiers().contains(expResult)); +196 } +197 +198 /** +199 * Test of getEvidence method, of class Dependency. +200 */ +201 @Test +202 public void testGetEvidence() { +203 Dependency instance = new Dependency(); +204 EvidenceCollection expResult = null; +205 EvidenceCollection result = instance.getEvidence(); +206 assertTrue(true); //this is just a getter setter pair. +207 } +208 +209 /** +210 * Test of getEvidenceUsed method, of class Dependency. +211 */ +212 @Test +213 public void testGetEvidenceUsed() { +214 Dependency instance = new Dependency(); +215 String expResult = "used"; +216 +217 instance.getProductEvidence().addEvidence("used", "used", "used", Confidence.HIGH); +218 instance.getProductEvidence().addEvidence("not", "not", "not", Confidence.MEDIUM); +219 for (Evidence e : instance.getProductEvidence().iterator(Confidence.HIGH)) { +220 String use = e.getValue(); +221 } +222 +223 EvidenceCollection result = instance.getEvidenceUsed(); +224 +225 assertEquals(1, result.size()); +226 assertTrue(result.containsUsedString(expResult)); +227 } +228 +229 /** +230 * Test of getVendorEvidence method, of class Dependency. +231 */ +232 @Test +233 public void testGetVendorEvidence() { +234 Dependency instance = new Dependency(); +235 EvidenceCollection expResult = null; +236 EvidenceCollection result = instance.getVendorEvidence(); +237 assertTrue(true); //this is just a getter setter pair. +238 } +239 +240 /** +241 * Test of getProductEvidence method, of class Dependency. +242 */ +243 @Test +244 public void testGetProductEvidence() { +245 Dependency instance = new Dependency(); +246 EvidenceCollection expResult = null; +247 EvidenceCollection result = instance.getProductEvidence(); +248 assertTrue(true); //this is just a getter setter pair. +249 } +250 +251 /** +252 * Test of getVersionEvidence method, of class Dependency. +253 */ +254 @Test +255 public void testGetVersionEvidence() { +256 Dependency instance = new Dependency(); +257 EvidenceCollection expResult = null; +258 EvidenceCollection result = instance.getVersionEvidence(); +259 assertTrue(true); //this is just a getter setter pair. +260 } +261 +262 /** +263 * Test of addAsEvidence method, of class Dependency. +264 */ +265 @Test +266 public void testAddAsEvidence() { +267 Dependency instance = new Dependency(); +268 MavenArtifact mavenArtifact = new MavenArtifact("group", "artifact", "version", "url"); +269 instance.addAsEvidence("pom", mavenArtifact, Confidence.HIGH); +270 assertTrue(instance.getEvidence().contains(Confidence.HIGH)); +271 assertFalse(instance.getEvidence().getEvidence("pom", "groupid").isEmpty()); +272 assertFalse(instance.getEvidence().getEvidence("pom", "artifactid").isEmpty()); +273 assertFalse(instance.getEvidence().getEvidence("pom", "version").isEmpty()); +274 assertFalse(instance.getIdentifiers().isEmpty()); +275 } +276 +277 /** +278 * Test of addAsEvidence method, of class Dependency. +279 */ +280 @Test +281 public void testAddAsEvidenceWithEmptyArtefact() { +282 Dependency instance = new Dependency(); +283 MavenArtifact mavenArtifact = new MavenArtifact(null, null, null, null); +284 instance.addAsEvidence("pom", mavenArtifact, Confidence.HIGH); +285 assertFalse(instance.getEvidence().contains(Confidence.HIGH)); +286 assertTrue(instance.getEvidence().getEvidence("pom", "groupid").isEmpty()); +287 assertTrue(instance.getEvidence().getEvidence("pom", "artifactid").isEmpty()); +288 assertTrue(instance.getEvidence().getEvidence("pom", "version").isEmpty()); +289 assertTrue(instance.getIdentifiers().isEmpty()); +290 } +291 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/dependency/VulnerabilityTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/dependency/VulnerabilityTest.html index ceb4706a0..7bfb0206e 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/dependency/VulnerabilityTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/dependency/VulnerabilityTest.html @@ -26,147 +26,144 @@ 18 package org.owasp.dependencycheck.dependency; 19 20 import java.util.Set; -21 import org.junit.After; -22 import org.junit.AfterClass; -23 import static org.junit.Assert.assertEquals; -24 import static org.junit.Assert.assertTrue; -25 import static org.junit.Assert.assertFalse; -26 import org.junit.Before; -27 import org.junit.BeforeClass; -28 import org.junit.Test; -29 import org.owasp.dependencycheck.BaseTest; -30 -31 /** -32 * -33 * @author Jens Hausherr -34 */ -35 public class VulnerabilityTest extends BaseTest { -36 -37 /** -38 * Test of equals method, of class VulnerableSoftware. -39 */ -40 @Test -41 public void testDuplicateVersions() { -42 Vulnerability obj = new Vulnerability(); -43 -44 obj.addVulnerableSoftware("cpe:/a:mortbay:jetty:6.1.0"); -45 obj.addVulnerableSoftware("cpe:/a:mortbay:jetty:6.1.1"); -46 obj.addVulnerableSoftware("cpe:/a:mortbay:jetty:6.1.0"); +21 +22 import static org.junit.Assert.assertEquals; +23 import static org.junit.Assert.assertTrue; +24 +25 import org.junit.Test; +26 import org.owasp.dependencycheck.BaseTest; +27 +28 /** +29 * +30 * @author Jens Hausherr +31 */ +32 public class VulnerabilityTest extends BaseTest { +33 +34 /** +35 * Test of equals method, of class VulnerableSoftware. +36 */ +37 @Test +38 public void testDuplicateVersions() { +39 Vulnerability obj = new Vulnerability(); +40 +41 obj.addVulnerableSoftware("cpe:/a:mortbay:jetty:6.1.0"); +42 obj.addVulnerableSoftware("cpe:/a:mortbay:jetty:6.1.1"); +43 obj.addVulnerableSoftware("cpe:/a:mortbay:jetty:6.1.0"); +44 +45 assertEquals(2, obj.getVulnerableSoftware().size()); +46 } 47 -48 assertEquals(2, obj.getVulnerableSoftware().size()); -49 } -50 -51 @Test -52 public void testDpulicateVersionsWithPreviousVersion() { -53 Vulnerability obj = new Vulnerability(); -54 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-103%28a%29", null); -55 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-118", null); -56 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.3.132", null); -57 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.12-200", null); -58 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.2-127", null); -59 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.9", null); -60 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.10", null); -61 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.11", null); -62 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.12-118", null); -63 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.4-143", null); -64 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-109", null); -65 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.6-156", null); -66 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.4", null); -67 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.3", null); -68 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1", null); -69 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.10-186", null); -70 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.6", null); -71 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.5", null); -72 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.5-146", null); -73 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.8", null); -74 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.7", null); -75 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.2", null); -76 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.0.2", null); -77 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.1", null); -78 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.8-177", null); -79 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.0.1", null); -80 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.0.0", null); -81 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.7-168", null); -82 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-103", null); -83 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.11-197", null); -84 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.9-178", null); -85 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.12-200", "1"); -86 assertEquals(31, obj.getVulnerableSoftware().size()); -87 } -88 -89 @Test -90 public void testSoftwareSorting() { -91 Vulnerability obj = new Vulnerability(); -92 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-103%28a%29", null); -93 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-118", null); -94 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.3.132", null); -95 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.12-200", null); -96 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.2-127", null); -97 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.9", null); -98 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.10", null); -99 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.11", null); -100 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.12-118", null); -101 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.4-143", null); -102 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-109", null); -103 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.6-156", null); -104 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.4", null); -105 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.3", null); -106 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1", null); -107 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.10-186", null); -108 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.6", null); -109 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.5", null); -110 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.5-146", null); -111 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.8", null); -112 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.7", null); -113 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.2", null); -114 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.0.2", null); -115 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.1", null); -116 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.8-177", null); -117 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.0.1", null); -118 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.0.0", null); -119 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.7-168", null); -120 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-103", null); -121 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.11-197", null); -122 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.9-178", null); +48 @Test +49 public void testDpulicateVersionsWithPreviousVersion() { +50 Vulnerability obj = new Vulnerability(); +51 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-103%28a%29", null); +52 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-118", null); +53 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.3.132", null); +54 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.12-200", null); +55 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.2-127", null); +56 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.9", null); +57 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.10", null); +58 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.11", null); +59 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.12-118", null); +60 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.4-143", null); +61 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-109", null); +62 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.6-156", null); +63 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.4", null); +64 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.3", null); +65 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1", null); +66 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.10-186", null); +67 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.6", null); +68 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.5", null); +69 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.5-146", null); +70 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.8", null); +71 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.7", null); +72 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.2", null); +73 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.0.2", null); +74 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.1", null); +75 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.8-177", null); +76 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.0.1", null); +77 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.0.0", null); +78 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.7-168", null); +79 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-103", null); +80 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.11-197", null); +81 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.9-178", null); +82 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.12-200", "1"); +83 assertEquals(31, obj.getVulnerableSoftware().size()); +84 } +85 +86 @Test +87 public void testSoftwareSorting() { +88 Vulnerability obj = new Vulnerability(); +89 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-103%28a%29", null); +90 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-118", null); +91 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.3.132", null); +92 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.12-200", null); +93 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.2-127", null); +94 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.9", null); +95 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.10", null); +96 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.11", null); +97 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.12-118", null); +98 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.4-143", null); +99 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-109", null); +100 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.6-156", null); +101 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.4", null); +102 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.3", null); +103 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1", null); +104 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.10-186", null); +105 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.6", null); +106 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.5", null); +107 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.5-146", null); +108 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.8", null); +109 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.7", null); +110 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.2", null); +111 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.0.2", null); +112 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.1", null); +113 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.8-177", null); +114 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.0.1", null); +115 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.0.0", null); +116 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.7-168", null); +117 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-103", null); +118 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.11-197", null); +119 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.9-178", null); +120 +121 Set<VulnerableSoftware> software = obj.getVulnerableSoftware(); +122 VulnerableSoftware vs[] = software.toArray(new VulnerableSoftware[software.size()]); 123 -124 Set<VulnerableSoftware> software = obj.getVulnerableSoftware(); -125 VulnerableSoftware vs[] = software.toArray(new VulnerableSoftware[software.size()]); -126 -127 assertTrue("cpe:/a:hp:system_management_homepage:2.0.0".equals(vs[0].getName())); -128 assertTrue("cpe:/a:hp:system_management_homepage:2.0.1".equals(vs[1].getName())); -129 assertTrue("cpe:/a:hp:system_management_homepage:2.0.2".equals(vs[2].getName())); -130 assertTrue("cpe:/a:hp:system_management_homepage:2.1".equals(vs[3].getName())); -131 assertTrue("cpe:/a:hp:system_management_homepage:2.1.0-103".equals(vs[4].getName())); -132 assertTrue("cpe:/a:hp:system_management_homepage:2.1.0-103%28a%29".equals(vs[5].getName())); -133 assertTrue("cpe:/a:hp:system_management_homepage:2.1.0-109".equals(vs[6].getName())); -134 assertTrue("cpe:/a:hp:system_management_homepage:2.1.0-118".equals(vs[7].getName())); -135 assertTrue("cpe:/a:hp:system_management_homepage:2.1.1".equals(vs[8].getName())); -136 assertTrue("cpe:/a:hp:system_management_homepage:2.1.2".equals(vs[9].getName())); -137 assertTrue("cpe:/a:hp:system_management_homepage:2.1.2-127".equals(vs[10].getName())); -138 assertTrue("cpe:/a:hp:system_management_homepage:2.1.3".equals(vs[11].getName())); -139 assertTrue("cpe:/a:hp:system_management_homepage:2.1.3.132".equals(vs[12].getName())); -140 assertTrue("cpe:/a:hp:system_management_homepage:2.1.4".equals(vs[13].getName())); -141 assertTrue("cpe:/a:hp:system_management_homepage:2.1.4-143".equals(vs[14].getName())); -142 assertTrue("cpe:/a:hp:system_management_homepage:2.1.5".equals(vs[15].getName())); -143 assertTrue("cpe:/a:hp:system_management_homepage:2.1.5-146".equals(vs[16].getName())); -144 assertTrue("cpe:/a:hp:system_management_homepage:2.1.6".equals(vs[17].getName())); -145 assertTrue("cpe:/a:hp:system_management_homepage:2.1.6-156".equals(vs[18].getName())); -146 assertTrue("cpe:/a:hp:system_management_homepage:2.1.7".equals(vs[19].getName())); -147 assertTrue("cpe:/a:hp:system_management_homepage:2.1.7-168".equals(vs[20].getName())); -148 assertTrue("cpe:/a:hp:system_management_homepage:2.1.8".equals(vs[21].getName())); -149 assertTrue("cpe:/a:hp:system_management_homepage:2.1.8-177".equals(vs[22].getName())); -150 assertTrue("cpe:/a:hp:system_management_homepage:2.1.9".equals(vs[23].getName())); -151 assertTrue("cpe:/a:hp:system_management_homepage:2.1.9-178".equals(vs[24].getName())); -152 assertTrue("cpe:/a:hp:system_management_homepage:2.1.10".equals(vs[25].getName())); -153 assertTrue("cpe:/a:hp:system_management_homepage:2.1.10-186".equals(vs[26].getName())); -154 assertTrue("cpe:/a:hp:system_management_homepage:2.1.11".equals(vs[27].getName())); -155 assertTrue("cpe:/a:hp:system_management_homepage:2.1.11-197".equals(vs[28].getName())); -156 assertTrue("cpe:/a:hp:system_management_homepage:2.1.12-118".equals(vs[29].getName())); -157 assertTrue("cpe:/a:hp:system_management_homepage:2.1.12-200".equals(vs[30].getName())); -158 -159 } -160 -161 } +124 assertTrue("cpe:/a:hp:system_management_homepage:2.0.0".equals(vs[0].getName())); +125 assertTrue("cpe:/a:hp:system_management_homepage:2.0.1".equals(vs[1].getName())); +126 assertTrue("cpe:/a:hp:system_management_homepage:2.0.2".equals(vs[2].getName())); +127 assertTrue("cpe:/a:hp:system_management_homepage:2.1".equals(vs[3].getName())); +128 assertTrue("cpe:/a:hp:system_management_homepage:2.1.0-103".equals(vs[4].getName())); +129 assertTrue("cpe:/a:hp:system_management_homepage:2.1.0-103%28a%29".equals(vs[5].getName())); +130 assertTrue("cpe:/a:hp:system_management_homepage:2.1.0-109".equals(vs[6].getName())); +131 assertTrue("cpe:/a:hp:system_management_homepage:2.1.0-118".equals(vs[7].getName())); +132 assertTrue("cpe:/a:hp:system_management_homepage:2.1.1".equals(vs[8].getName())); +133 assertTrue("cpe:/a:hp:system_management_homepage:2.1.2".equals(vs[9].getName())); +134 assertTrue("cpe:/a:hp:system_management_homepage:2.1.2-127".equals(vs[10].getName())); +135 assertTrue("cpe:/a:hp:system_management_homepage:2.1.3".equals(vs[11].getName())); +136 assertTrue("cpe:/a:hp:system_management_homepage:2.1.3.132".equals(vs[12].getName())); +137 assertTrue("cpe:/a:hp:system_management_homepage:2.1.4".equals(vs[13].getName())); +138 assertTrue("cpe:/a:hp:system_management_homepage:2.1.4-143".equals(vs[14].getName())); +139 assertTrue("cpe:/a:hp:system_management_homepage:2.1.5".equals(vs[15].getName())); +140 assertTrue("cpe:/a:hp:system_management_homepage:2.1.5-146".equals(vs[16].getName())); +141 assertTrue("cpe:/a:hp:system_management_homepage:2.1.6".equals(vs[17].getName())); +142 assertTrue("cpe:/a:hp:system_management_homepage:2.1.6-156".equals(vs[18].getName())); +143 assertTrue("cpe:/a:hp:system_management_homepage:2.1.7".equals(vs[19].getName())); +144 assertTrue("cpe:/a:hp:system_management_homepage:2.1.7-168".equals(vs[20].getName())); +145 assertTrue("cpe:/a:hp:system_management_homepage:2.1.8".equals(vs[21].getName())); +146 assertTrue("cpe:/a:hp:system_management_homepage:2.1.8-177".equals(vs[22].getName())); +147 assertTrue("cpe:/a:hp:system_management_homepage:2.1.9".equals(vs[23].getName())); +148 assertTrue("cpe:/a:hp:system_management_homepage:2.1.9-178".equals(vs[24].getName())); +149 assertTrue("cpe:/a:hp:system_management_homepage:2.1.10".equals(vs[25].getName())); +150 assertTrue("cpe:/a:hp:system_management_homepage:2.1.10-186".equals(vs[26].getName())); +151 assertTrue("cpe:/a:hp:system_management_homepage:2.1.11".equals(vs[27].getName())); +152 assertTrue("cpe:/a:hp:system_management_homepage:2.1.11-197".equals(vs[28].getName())); +153 assertTrue("cpe:/a:hp:system_management_homepage:2.1.12-118".equals(vs[29].getName())); +154 assertTrue("cpe:/a:hp:system_management_homepage:2.1.12-200".equals(vs[30].getName())); +155 +156 } +157 +158 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/dependency/VulnerableSoftwareTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/dependency/VulnerableSoftwareTest.html index a7afdef9f..62fa8a74e 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/dependency/VulnerableSoftwareTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/dependency/VulnerableSoftwareTest.html @@ -25,141 +25,138 @@ 17 */ 18 package org.owasp.dependencycheck.dependency; 19 -20 import org.junit.After; -21 import org.junit.AfterClass; -22 import static org.junit.Assert.assertEquals; -23 import static org.junit.Assert.assertTrue; -24 import static org.junit.Assert.assertFalse; -25 import org.junit.Before; -26 import org.junit.BeforeClass; -27 import org.junit.Test; -28 import org.owasp.dependencycheck.BaseTest; -29 -30 /** -31 * -32 * @author Jeremy Long -33 */ -34 public class VulnerableSoftwareTest extends BaseTest { -35 -36 /** -37 * Test of equals method, of class VulnerableSoftware. -38 */ -39 @Test -40 public void testEquals() { -41 VulnerableSoftware obj = new VulnerableSoftware(); -42 obj.setCpe("cpe:/a:mortbay:jetty:6.1.0"); -43 VulnerableSoftware instance = new VulnerableSoftware(); -44 instance.setCpe("cpe:/a:mortbay:jetty:6.1"); -45 assertFalse(instance.equals(obj)); -46 } -47 -48 /** -49 * Test of equals method, of class VulnerableSoftware. -50 */ -51 @Test -52 public void testEquals2() { -53 VulnerableSoftware obj = new VulnerableSoftware(); -54 obj.setCpe("cpe:/a:mortbay:jetty:6.1.0"); -55 VulnerableSoftware instance = new VulnerableSoftware(); -56 instance.setCpe("cpe:/a:mortbay:jetty:6.1.0"); -57 obj.setPreviousVersion("1"); -58 assertTrue(instance.equals(obj)); -59 } -60 -61 /** -62 * Test of hashCode method, of class VulnerableSoftware. -63 */ -64 @Test -65 public void testHashCode() { -66 VulnerableSoftware instance = new VulnerableSoftware(); -67 instance.setCpe("cpe:/a:mortbay:jetty:6.1"); -68 int expResult = 1849413912; -69 int result = instance.hashCode(); -70 assertEquals(expResult, result); -71 } -72 -73 /** -74 * Test of compareTo method, of class VulnerableSoftware. -75 */ -76 @Test -77 public void testCompareTo() { -78 VulnerableSoftware vs = new VulnerableSoftware(); -79 vs.setCpe("cpe:/a:mortbay:jetty:6.1.0"); -80 VulnerableSoftware instance = new VulnerableSoftware(); -81 instance.setCpe("cpe:/a:mortbay:jetty:6.1"); -82 int expResult = -2; -83 int result = instance.compareTo(vs); -84 assertEquals(expResult, result); -85 -86 vs = new VulnerableSoftware(); -87 vs.setCpe("cpe:/a:yahoo:toolbar:3.1.0.20130813024103"); -88 instance = new VulnerableSoftware(); -89 instance.setCpe("cpe:/a:yahoo:toolbar:3.1.0.20130813024104"); -90 expResult = 1; -91 result = instance.compareTo(vs); -92 assertEquals(expResult, result); -93 } -94 -95 @Test -96 public void testCompareToNonNumerical() { -97 VulnerableSoftware vs = new VulnerableSoftware(); -98 vs.setCpe("cpe:/a:mysql:mysql:5.1.23a"); -99 VulnerableSoftware vs1 = new VulnerableSoftware(); -100 vs1.setCpe("cpe:/a:mysql:mysql:5.1.23a"); -101 vs1.setPreviousVersion("1"); -102 assertEquals(0, vs.compareTo(vs1)); -103 assertEquals(0, vs1.compareTo(vs)); -104 } -105 -106 @Test -107 public void testCompareToComplex() { -108 VulnerableSoftware vs = new VulnerableSoftware(); -109 VulnerableSoftware vs1 = new VulnerableSoftware(); -110 -111 vs.setCpe("2.1"); -112 vs1.setCpe("2.1.10"); -113 assertTrue(vs.compareTo(vs1) < 0); -114 -115 vs.setCpe("cpe:/a:hp:system_management_homepage:2.1.1"); -116 vs1.setCpe("cpe:/a:hp:system_management_homepage:2.1.10"); -117 assertTrue(vs.compareTo(vs1) < 0); -118 -119 vs.setCpe("10"); -120 vs1.setCpe("10-186"); -121 assertTrue(vs.compareTo(vs1) < 0); -122 -123 vs.setCpe("2.1.10"); -124 vs1.setCpe("2.1.10-186"); -125 assertTrue(vs.compareTo(vs1) < 0); -126 -127 vs.setCpe("cpe:/a:hp:system_management_homepage:2.1.10"); -128 vs1.setCpe("cpe:/a:hp:system_management_homepage:2.1.10-186"); -129 assertTrue(vs.compareTo(vs1) < 0); -130 //assertTrue(vs1.compareTo(vs)>0); -131 } -132 -133 @Test -134 public void testEqualsPreviousVersion() { -135 VulnerableSoftware vs = new VulnerableSoftware(); -136 vs.setCpe("cpe:/a:mysql:mysql:5.1.23a"); -137 VulnerableSoftware vs1 = new VulnerableSoftware(); -138 vs1.setCpe("cpe:/a:mysql:mysql:5.1.23a"); -139 vs1.setPreviousVersion("1"); -140 assertEquals(vs, vs1); -141 assertEquals(vs1, vs); -142 -143 } -144 -145 @Test -146 public void testParseCPE() { -147 VulnerableSoftware vs = new VulnerableSoftware(); -148 /* Version for test taken from CVE-2008-2079 */ -149 vs.setCpe("cpe:/a:mysql:mysql:5.1.23a"); -150 assertEquals("mysql", vs.getVendor()); -151 assertEquals("mysql", vs.getProduct()); -152 assertEquals("5.1.23a", vs.getVersion()); -153 } -154 } +20 import static org.junit.Assert.assertEquals; +21 import static org.junit.Assert.assertTrue; +22 import static org.junit.Assert.assertFalse; +23 +24 import org.junit.Test; +25 import org.owasp.dependencycheck.BaseTest; +26 +27 /** +28 * +29 * @author Jeremy Long +30 */ +31 public class VulnerableSoftwareTest extends BaseTest { +32 +33 /** +34 * Test of equals method, of class VulnerableSoftware. +35 */ +36 @Test +37 public void testEquals() { +38 VulnerableSoftware obj = new VulnerableSoftware(); +39 obj.setCpe("cpe:/a:mortbay:jetty:6.1.0"); +40 VulnerableSoftware instance = new VulnerableSoftware(); +41 instance.setCpe("cpe:/a:mortbay:jetty:6.1"); +42 assertFalse(instance.equals(obj)); +43 } +44 +45 /** +46 * Test of equals method, of class VulnerableSoftware. +47 */ +48 @Test +49 public void testEquals2() { +50 VulnerableSoftware obj = new VulnerableSoftware(); +51 obj.setCpe("cpe:/a:mortbay:jetty:6.1.0"); +52 VulnerableSoftware instance = new VulnerableSoftware(); +53 instance.setCpe("cpe:/a:mortbay:jetty:6.1.0"); +54 obj.setPreviousVersion("1"); +55 assertTrue(instance.equals(obj)); +56 } +57 +58 /** +59 * Test of hashCode method, of class VulnerableSoftware. +60 */ +61 @Test +62 public void testHashCode() { +63 VulnerableSoftware instance = new VulnerableSoftware(); +64 instance.setCpe("cpe:/a:mortbay:jetty:6.1"); +65 int expResult = 1849413912; +66 int result = instance.hashCode(); +67 assertEquals(expResult, result); +68 } +69 +70 /** +71 * Test of compareTo method, of class VulnerableSoftware. +72 */ +73 @Test +74 public void testCompareTo() { +75 VulnerableSoftware vs = new VulnerableSoftware(); +76 vs.setCpe("cpe:/a:mortbay:jetty:6.1.0"); +77 VulnerableSoftware instance = new VulnerableSoftware(); +78 instance.setCpe("cpe:/a:mortbay:jetty:6.1"); +79 int expResult = -2; +80 int result = instance.compareTo(vs); +81 assertEquals(expResult, result); +82 +83 vs = new VulnerableSoftware(); +84 vs.setCpe("cpe:/a:yahoo:toolbar:3.1.0.20130813024103"); +85 instance = new VulnerableSoftware(); +86 instance.setCpe("cpe:/a:yahoo:toolbar:3.1.0.20130813024104"); +87 expResult = 1; +88 result = instance.compareTo(vs); +89 assertEquals(expResult, result); +90 } +91 +92 @Test +93 public void testCompareToNonNumerical() { +94 VulnerableSoftware vs = new VulnerableSoftware(); +95 vs.setCpe("cpe:/a:mysql:mysql:5.1.23a"); +96 VulnerableSoftware vs1 = new VulnerableSoftware(); +97 vs1.setCpe("cpe:/a:mysql:mysql:5.1.23a"); +98 vs1.setPreviousVersion("1"); +99 assertEquals(0, vs.compareTo(vs1)); +100 assertEquals(0, vs1.compareTo(vs)); +101 } +102 +103 @Test +104 public void testCompareToComplex() { +105 VulnerableSoftware vs = new VulnerableSoftware(); +106 VulnerableSoftware vs1 = new VulnerableSoftware(); +107 +108 vs.setCpe("2.1"); +109 vs1.setCpe("2.1.10"); +110 assertTrue(vs.compareTo(vs1) < 0); +111 +112 vs.setCpe("cpe:/a:hp:system_management_homepage:2.1.1"); +113 vs1.setCpe("cpe:/a:hp:system_management_homepage:2.1.10"); +114 assertTrue(vs.compareTo(vs1) < 0); +115 +116 vs.setCpe("10"); +117 vs1.setCpe("10-186"); +118 assertTrue(vs.compareTo(vs1) < 0); +119 +120 vs.setCpe("2.1.10"); +121 vs1.setCpe("2.1.10-186"); +122 assertTrue(vs.compareTo(vs1) < 0); +123 +124 vs.setCpe("cpe:/a:hp:system_management_homepage:2.1.10"); +125 vs1.setCpe("cpe:/a:hp:system_management_homepage:2.1.10-186"); +126 assertTrue(vs.compareTo(vs1) < 0); +127 //assertTrue(vs1.compareTo(vs)>0); +128 } +129 +130 @Test +131 public void testEqualsPreviousVersion() { +132 VulnerableSoftware vs = new VulnerableSoftware(); +133 vs.setCpe("cpe:/a:mysql:mysql:5.1.23a"); +134 VulnerableSoftware vs1 = new VulnerableSoftware(); +135 vs1.setCpe("cpe:/a:mysql:mysql:5.1.23a"); +136 vs1.setPreviousVersion("1"); +137 assertEquals(vs, vs1); +138 assertEquals(vs1, vs); +139 +140 } +141 +142 @Test +143 public void testParseCPE() { +144 VulnerableSoftware vs = new VulnerableSoftware(); +145 /* Version for test taken from CVE-2008-2079 */ +146 vs.setCpe("cpe:/a:mysql:mysql:5.1.23a"); +147 assertEquals("mysql", vs.getVendor()); +148 assertEquals("mysql", vs.getProduct()); +149 assertEquals("5.1.23a", vs.getVersion()); +150 } +151 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/dependency/package-frame.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/dependency/package-frame.html index 3fd533653..3a67080c2 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/dependency/package-frame.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/dependency/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.dependency + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.dependency diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/dependency/package-summary.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/dependency/package-summary.html index eaf133384..c7f69de41 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/dependency/package-summary.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/dependency/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.dependency + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.dependency diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/package-frame.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/package-frame.html index b10a76da8..26625084b 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/package-frame.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/package-summary.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/package-summary.html index 4de0d840e..b8b8c63c0 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/package-summary.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/reporting/ReportGeneratorIntegrationTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/reporting/ReportGeneratorIntegrationTest.html index 89534aafb..694f1e2bd 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/reporting/ReportGeneratorIntegrationTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/reporting/ReportGeneratorIntegrationTest.html @@ -32,7 +32,7 @@ 24 import javax.xml.validation.Schema; 25 import javax.xml.validation.SchemaFactory; 26 import javax.xml.validation.Validator; -27 import org.junit.Before; +27 28 import org.junit.Test; 29 import org.owasp.dependencycheck.BaseDBTestCase; 30 import org.owasp.dependencycheck.BaseTest; diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/reporting/package-frame.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/reporting/package-frame.html index 78fb460bd..2347b4ca1 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/reporting/package-frame.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/reporting/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.reporting + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.reporting diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/reporting/package-summary.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/reporting/package-summary.html index 67a4c5f86..725df7315 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/reporting/package-summary.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/reporting/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.reporting + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.reporting diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/utils/DateUtilTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/utils/DateUtilTest.html index 998326f28..284e3835b 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/utils/DateUtilTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/utils/DateUtilTest.html @@ -24,41 +24,39 @@ 16 package org.owasp.dependencycheck.utils; 17 18 import java.util.Calendar; -19 import org.junit.After; -20 import org.junit.AfterClass; -21 import static org.junit.Assert.assertEquals; -22 import org.junit.Before; -23 import org.junit.BeforeClass; -24 import org.junit.Test; -25 import org.owasp.dependencycheck.BaseTest; -26 -27 /** -28 * -29 * @author Jeremy Long -30 */ -31 public class DateUtilTest extends BaseTest { -32 -33 /** -34 * Test of withinDateRange method, of class DateUtil. -35 */ -36 @Test -37 public void testWithinDateRange() { -38 Calendar c = Calendar.getInstance(); -39 -40 long current = c.getTimeInMillis(); -41 long lastRun = c.getTimeInMillis() - (3 * (1000 * 60 * 60 * 24)); -42 int range = 7; // 7 days -43 boolean expResult = true; -44 boolean result = DateUtil.withinDateRange(lastRun, current, range); -45 assertEquals(expResult, result); -46 -47 lastRun = c.getTimeInMillis() - (8 * (1000 * 60 * 60 * 24)); -48 expResult = false; -49 result = DateUtil.withinDateRange(lastRun, current, range); -50 assertEquals(expResult, result); -51 } -52 -53 } +19 +20 import static org.junit.Assert.assertEquals; +21 +22 import org.junit.Test; +23 import org.owasp.dependencycheck.BaseTest; +24 +25 /** +26 * +27 * @author Jeremy Long +28 */ +29 public class DateUtilTest extends BaseTest { +30 +31 /** +32 * Test of withinDateRange method, of class DateUtil. +33 */ +34 @Test +35 public void testWithinDateRange() { +36 Calendar c = Calendar.getInstance(); +37 +38 long current = c.getTimeInMillis(); +39 long lastRun = c.getTimeInMillis() - (3 * (1000 * 60 * 60 * 24)); +40 int range = 7; // 7 days +41 boolean expResult = true; +42 boolean result = DateUtil.withinDateRange(lastRun, current, range); +43 assertEquals(expResult, result); +44 +45 lastRun = c.getTimeInMillis() - (8 * (1000 * 60 * 60 * 24)); +46 expResult = false; +47 result = DateUtil.withinDateRange(lastRun, current, range); +48 assertEquals(expResult, result); +49 } +50 +51 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/utils/DependencyVersionUtilTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/utils/DependencyVersionUtilTest.html index 9bcab3e6d..8ad9fe896 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/utils/DependencyVersionUtilTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/utils/DependencyVersionUtilTest.html @@ -25,52 +25,49 @@ 17 */ 18 package org.owasp.dependencycheck.utils; 19 -20 import org.junit.After; -21 import org.junit.AfterClass; -22 import static org.junit.Assert.assertEquals; -23 import static org.junit.Assert.assertNull; -24 import org.junit.Before; -25 import org.junit.BeforeClass; -26 import org.junit.Test; -27 import org.owasp.dependencycheck.BaseTest; -28 -29 /** -30 * -31 * @author Jeremy Long -32 */ -33 public class DependencyVersionUtilTest extends BaseTest { -34 -35 /** -36 * Test of parseVersion method, of class DependencyVersionUtil. -37 */ -38 @Test -39 public void testParseVersion() { -40 final String[] fileName = {"something-0.9.5.jar", "lib2-1.1.jar", "lib1.5r4-someflag-R26.jar", -41 "lib-1.2.5-dev-20050313.jar", "testlib_V4.4.0.jar", "lib-core-2.0.0-RC1-SNAPSHOT.jar", -42 "lib-jsp-2.0.1_R114940.jar", "dev-api-2.3.11_R121413.jar", "lib-api-3.7-SNAPSHOT.jar", -43 "-", "", "1.3-beta", "6", "openssl1.0.1c", "jsf-impl-2.2.8-02.jar", -44 "plone.rfc822-1.1.1-py2-none-any.whl"}; -45 final String[] expResult = {"0.9.5", "1.1", "1.5.r4", "1.2.5", "4.4.0", "2.0.0.rc1", -46 "2.0.1.r114940", "2.3.11.r121413", "3.7", "-", null, "1.3.beta", "6", "1.0.1c", -47 "2.2.8.02", "1.1.1"}; -48 -49 for (int i = 0; i < fileName.length; i++) { -50 final DependencyVersion version = DependencyVersionUtil.parseVersion(fileName[i]); -51 String result = null; -52 if (version != null) { -53 result = version.toString(); -54 } -55 assertEquals("Failed extraction on \"" + fileName[i] + "\".", expResult[i], result); -56 } -57 -58 String[] failingNames = {"no-version-identified.jar", "somelib-04aug2000r7-dev.jar", /*"no.version15.jar",*/ -59 "lib_1.0_spec-1.1.jar", "lib-api_1.0_spec-1.0.1.jar"}; -60 for (String failingName : failingNames) { -61 final DependencyVersion version = DependencyVersionUtil.parseVersion(failingName); -62 assertNull("Found version in name that should have failed \"" + failingName + "\".", version); -63 } -64 } -65 } +20 import static org.junit.Assert.assertEquals; +21 import static org.junit.Assert.assertNull; +22 +23 import org.junit.Test; +24 import org.owasp.dependencycheck.BaseTest; +25 +26 /** +27 * +28 * @author Jeremy Long +29 */ +30 public class DependencyVersionUtilTest extends BaseTest { +31 +32 /** +33 * Test of parseVersion method, of class DependencyVersionUtil. +34 */ +35 @Test +36 public void testParseVersion() { +37 final String[] fileName = {"something-0.9.5.jar", "lib2-1.1.jar", "lib1.5r4-someflag-R26.jar", +38 "lib-1.2.5-dev-20050313.jar", "testlib_V4.4.0.jar", "lib-core-2.0.0-RC1-SNAPSHOT.jar", +39 "lib-jsp-2.0.1_R114940.jar", "dev-api-2.3.11_R121413.jar", "lib-api-3.7-SNAPSHOT.jar", +40 "-", "", "1.3-beta", "6", "openssl1.0.1c", "jsf-impl-2.2.8-02.jar", +41 "plone.rfc822-1.1.1-py2-none-any.whl"}; +42 final String[] expResult = {"0.9.5", "1.1", "1.5.r4", "1.2.5", "4.4.0", "2.0.0.rc1", +43 "2.0.1.r114940", "2.3.11.r121413", "3.7", "-", null, "1.3.beta", "6", "1.0.1c", +44 "2.2.8.02", "1.1.1"}; +45 +46 for (int i = 0; i < fileName.length; i++) { +47 final DependencyVersion version = DependencyVersionUtil.parseVersion(fileName[i]); +48 String result = null; +49 if (version != null) { +50 result = version.toString(); +51 } +52 assertEquals("Failed extraction on \"" + fileName[i] + "\".", expResult[i], result); +53 } +54 +55 String[] failingNames = {"no-version-identified.jar", "somelib-04aug2000r7-dev.jar", /*"no.version15.jar",*/ +56 "lib_1.0_spec-1.1.jar", "lib-api_1.0_spec-1.0.1.jar"}; +57 for (String failingName : failingNames) { +58 final DependencyVersion version = DependencyVersionUtil.parseVersion(failingName); +59 assertNull("Found version in name that should have failed \"" + failingName + "\".", version); +60 } +61 } +62 }
      diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/utils/package-frame.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/utils/package-frame.html index 95b2d0da8..7e9e98b17 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/utils/package-frame.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/utils/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.utils + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.utils diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/utils/package-summary.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/utils/package-summary.html index e9278ec91..eb7292890 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/utils/package-summary.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/utils/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.utils + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.utils diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/hints/HintHandlerTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/hints/HintHandlerTest.html new file mode 100644 index 000000000..24a30c1b7 --- /dev/null +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/hints/HintHandlerTest.html @@ -0,0 +1,90 @@ + + + +HintHandlerTest xref + + + +
      +1   /*
      +2    * This file is part of dependency-check-core.
      +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) 2016 Jeremy Long. All Rights Reserved.
      +17   */
      +18  package org.owasp.dependencycheck.xml.hints;
      +19  
      +20  import java.io.File;
      +21  import java.io.FileInputStream;
      +22  import java.io.FileNotFoundException;
      +23  import java.io.IOException;
      +24  import java.io.InputStream;
      +25  import java.io.InputStreamReader;
      +26  import java.io.Reader;
      +27  import java.io.UnsupportedEncodingException;
      +28  import java.util.List;
      +29  import javax.xml.parsers.ParserConfigurationException;
      +30  import javax.xml.parsers.SAXParser;
      +31  import javax.xml.parsers.SAXParserFactory;
      +32  import org.junit.Test;
      +33  import static org.junit.Assert.*;
      +34  import org.owasp.dependencycheck.BaseTest;
      +35  import org.owasp.dependencycheck.xml.suppression.SuppressionErrorHandler;
      +36  import org.owasp.dependencycheck.xml.suppression.SuppressionHandler;
      +37  import org.owasp.dependencycheck.xml.suppression.SuppressionParser;
      +38  import org.owasp.dependencycheck.xml.suppression.SuppressionRule;
      +39  import org.xml.sax.Attributes;
      +40  import org.xml.sax.InputSource;
      +41  import org.xml.sax.SAXException;
      +42  import org.xml.sax.SAXNotRecognizedException;
      +43  import org.xml.sax.SAXNotSupportedException;
      +44  import org.xml.sax.XMLReader;
      +45  
      +46  /**
      +47   *
      +48   * @author Jeremy Long
      +49   */
      +50  public class HintHandlerTest extends BaseTest {
      +51      
      +52      @Test
      +53      public void testHandler() throws ParserConfigurationException, SAXNotRecognizedException, SAXNotSupportedException, SAXException, FileNotFoundException, UnsupportedEncodingException, IOException {
      +54          File file = BaseTest.getResourceAsFile(this, "hints.xml");
      +55          File schema = BaseTest.getResourceAsFile(this, "schema/dependency-hint.1.0.xsd");
      +56          HintHandler handler = new HintHandler();
      +57  
      +58          SAXParserFactory factory = SAXParserFactory.newInstance();
      +59          factory.setNamespaceAware(true);
      +60          factory.setValidating(true);
      +61          SAXParser saxParser = factory.newSAXParser();
      +62          saxParser.setProperty(HintParser.JAXP_SCHEMA_LANGUAGE, HintParser.W3C_XML_SCHEMA);
      +63          saxParser.setProperty(HintParser.JAXP_SCHEMA_SOURCE, schema);
      +64          XMLReader xmlReader = saxParser.getXMLReader();
      +65          xmlReader.setErrorHandler(new HintErrorHandler());
      +66          xmlReader.setContentHandler(handler);
      +67  
      +68          InputStream inputStream = new FileInputStream(file);
      +69          Reader reader = new InputStreamReader(inputStream, "UTF-8");
      +70          InputSource in = new InputSource(reader);
      +71          xmlReader.parse(in);
      +72  
      +73          List<HintRule> result = handler.getHintRules();
      +74          assertEquals("two hint rules should have been loaded",2,result.size());
      +75      }
      +76  
      +77  }
      +
      +
      + + + diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/hints/HintParserTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/hints/HintParserTest.html new file mode 100644 index 000000000..9c6125639 --- /dev/null +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/hints/HintParserTest.html @@ -0,0 +1,86 @@ + + + +HintParserTest xref + + + +
      +1   /*
      +2    * This file is part of dependency-check-core.
      +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) 2016 Jeremy Long. All Rights Reserved.
      +17   */
      +18  package org.owasp.dependencycheck.xml.hints;
      +19  
      +20  import java.io.File;
      +21  import java.io.InputStream;
      +22  import org.junit.Test;
      +23  import static org.junit.Assert.assertEquals;
      +24  import org.owasp.dependencycheck.BaseTest;
      +25  
      +26  /**
      +27   *
      +28   * @author Jeremy Long
      +29   */
      +30  public class HintParserTest extends BaseTest {
      +31  
      +32      /**
      +33       * Test of parseHints method, of class HintParser.
      +34       */
      +35      @Test
      +36      public void testParseHints_File() throws Exception {
      +37          File file = BaseTest.getResourceAsFile(this, "hints.xml");
      +38          HintParser instance = new HintParser();
      +39          Hints results = instance.parseHints(file);
      +40          assertEquals("Two duplicating hints should have been read", 2, results.getVendorDuplicatingHintRules().size());
      +41          assertEquals("Two hint rules should have been read", 2, results.getHintRules().size());
      +42      }
      +43  
      +44      /**
      +45       * Test of parseHints method, of class HintParser.
      +46       */
      +47      @Test
      +48      public void testParseHints_InputStream() throws Exception {
      +49          InputStream ins = BaseTest.getResourceAsStream(this, "hints.xml");
      +50          HintParser instance = new HintParser();
      +51          Hints results = instance.parseHints(ins);
      +52          assertEquals("Two duplicating hints should have been read", 2, results.getVendorDuplicatingHintRules().size());
      +53          assertEquals("Two hint rules should have been read", 2, results.getHintRules().size());
      +54          assertEquals("One add product should have been read", 1, results.getHintRules().get(0).getAddProduct().size());
      +55          assertEquals("One add vendor should have been read", 1, results.getHintRules().get(0).getAddVendor().size());
      +56          assertEquals("Two file name should have been read", 2, results.getHintRules().get(1).getFilenames().size());
      +57  
      +58          assertEquals("add product name not found", "add product name", results.getHintRules().get(0).getAddProduct().get(0).getName());
      +59          assertEquals("add vendor name not found", "add vendor name", results.getHintRules().get(0).getAddVendor().get(0).getName());
      +60          assertEquals("given product name not found", "given product name", results.getHintRules().get(0).getGivenProduct().get(0).getName());
      +61          assertEquals("given vendor name not found", "given vendor name", results.getHintRules().get(0).getGivenVendor().get(0).getName());
      +62  
      +63          assertEquals("spring file name not found", "spring", results.getHintRules().get(1).getFilenames().get(0).getValue());
      +64          assertEquals("file name 1 should not be case sensitive", false, results.getHintRules().get(1).getFilenames().get(0).isCaseSensitive());
      +65          assertEquals("file name 1 should not be a regex", false, results.getHintRules().get(1).getFilenames().get(0).isRegex());
      +66          assertEquals("file name 2 should be case sensitive", true, results.getHintRules().get(1).getFilenames().get(1).isCaseSensitive());
      +67          assertEquals("file name 2 should be a regex", true, results.getHintRules().get(1).getFilenames().get(1).isRegex());
      +68          
      +69          
      +70          assertEquals("sun duplicating vendor", "sun", results.getVendorDuplicatingHintRules().get(0).getValue());
      +71          assertEquals("sun duplicates vendor oracle", "oracle", results.getVendorDuplicatingHintRules().get(0).getDuplicate());
      +72      }
      +73  }
      +
      +
      + + + diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/hints/package-frame.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/hints/package-frame.html new file mode 100644 index 000000000..ff24e93a1 --- /dev/null +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/hints/package-frame.html @@ -0,0 +1,27 @@ + + + + + + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.xml.hints + + + + +

      + org.owasp.dependencycheck.xml.hints +

      + +

      Classes

      + + + + + \ No newline at end of file diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/hints/package-summary.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/hints/package-summary.html new file mode 100644 index 000000000..f5abc0d96 --- /dev/null +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/hints/package-summary.html @@ -0,0 +1,74 @@ + + + + + + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.xml.hints + + + +
      + +
      +
      + +
      + +

      Package org.owasp.dependencycheck.xml.hints

      + + + + + + + + + + + + + + + +
      Class Summary
      + HintHandlerTest +
      + HintParserTest +
      + +
      + +
      +
      + +
      +
      + + + \ No newline at end of file diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/pom/package-frame.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/pom/package-frame.html index b011975e2..cdc21cc41 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/pom/package-frame.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/pom/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.xml.pom + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.xml.pom diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/pom/package-summary.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/pom/package-summary.html index aaba3714e..635690fc9 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/pom/package-summary.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/pom/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.xml.pom + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.xml.pom diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/suppression/PropertyTypeTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/suppression/PropertyTypeTest.html new file mode 100644 index 000000000..3061732b2 --- /dev/null +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/suppression/PropertyTypeTest.html @@ -0,0 +1,101 @@ + + + +PropertyTypeTest xref + + + +
      +1   /*
      +2    * This file is part of dependency-check-core.
      +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) 2013 Jeremy Long. All Rights Reserved.
      +17   */
      +18  package org.owasp.dependencycheck.xml.suppression;
      +19  
      +20  import static org.junit.Assert.assertEquals;
      +21  import static org.junit.Assert.assertFalse;
      +22  import static org.junit.Assert.assertTrue;
      +23  
      +24  import org.junit.Test;
      +25  import org.owasp.dependencycheck.BaseTest;
      +26  
      +27  /**
      +28   *
      +29   * @author Jeremy Long
      +30   */
      +31  public class PropertyTypeTest extends BaseTest {
      +32  
      +33      /**
      +34       * Test of set and getValue method, of class PropertyType.
      +35       */
      +36      @Test
      +37      public void testSetGetValue() {
      +38  
      +39          PropertyType instance = new PropertyType();
      +40          String expResult = "test";
      +41          instance.setValue(expResult);
      +42          String result = instance.getValue();
      +43          assertEquals(expResult, result);
      +44      }
      +45  
      +46      /**
      +47       * Test of isRegex method, of class PropertyType.
      +48       */
      +49      @Test
      +50      public void testIsRegex() {
      +51          PropertyType instance = new PropertyType();
      +52          boolean result = instance.isRegex();
      +53          assertFalse(instance.isRegex());
      +54          instance.setRegex(true);
      +55          assertTrue(instance.isRegex());
      +56      }
      +57  
      +58      /**
      +59       * Test of isCaseSensitive method, of class PropertyType.
      +60       */
      +61      @Test
      +62      public void testIsCaseSensitive() {
      +63          PropertyType instance = new PropertyType();
      +64          assertFalse(instance.isCaseSensitive());
      +65          instance.setCaseSensitive(true);
      +66          assertTrue(instance.isCaseSensitive());
      +67      }
      +68  
      +69      /**
      +70       * Test of matches method, of class PropertyType.
      +71       */
      +72      @Test
      +73      public void testMatches() {
      +74          String text = "Simple";
      +75  
      +76          PropertyType instance = new PropertyType();
      +77          instance.setValue("simple");
      +78          assertTrue(instance.matches(text));
      +79          instance.setCaseSensitive(true);
      +80          assertFalse(instance.matches(text));
      +81  
      +82          instance.setValue("s.*le");
      +83          instance.setRegex(true);
      +84          assertFalse(instance.matches(text));
      +85          instance.setCaseSensitive(false);
      +86          assertTrue(instance.matches(text));
      +87      }
      +88  }
      +
      +
      + + + diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/suppression/SuppressionHandlerTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/suppression/SuppressionHandlerTest.html new file mode 100644 index 000000000..e067360c1 --- /dev/null +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/suppression/SuppressionHandlerTest.html @@ -0,0 +1,91 @@ + + + +SuppressionHandlerTest xref + + + +
      +1   /*
      +2    * This file is part of dependency-check-core.
      +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) 2013 Jeremy Long. All Rights Reserved.
      +17   */
      +18  package org.owasp.dependencycheck.xml.suppression;
      +19  
      +20  import java.io.File;
      +21  import java.io.FileInputStream;
      +22  import java.io.InputStream;
      +23  import java.io.InputStreamReader;
      +24  import java.io.Reader;
      +25  import java.util.List;
      +26  import javax.xml.parsers.SAXParser;
      +27  import javax.xml.parsers.SAXParserFactory;
      +28  import static org.junit.Assert.assertTrue;
      +29  import org.junit.Test;
      +30  import org.owasp.dependencycheck.BaseTest;
      +31  import org.xml.sax.InputSource;
      +32  import org.xml.sax.XMLReader;
      +33  
      +34  /**
      +35   *
      +36   * @author Jeremy Long
      +37   */
      +38  public class SuppressionHandlerTest extends BaseTest {
      +39  
      +40      /**
      +41       * Test of getSuppressionRules method, of class SuppressionHandler.
      +42       *
      +43       * @throws Exception thrown if there is an exception....
      +44       */
      +45      @Test
      +46      public void testHandler() throws Exception {
      +47          File file = BaseTest.getResourceAsFile(this, "suppressions.xml");
      +48          File schema = BaseTest.getResourceAsFile(this, "schema/suppression.xsd");
      +49          SuppressionHandler handler = new SuppressionHandler();
      +50  
      +51          SAXParserFactory factory = SAXParserFactory.newInstance();
      +52          factory.setNamespaceAware(true);
      +53          factory.setValidating(true);
      +54          SAXParser saxParser = factory.newSAXParser();
      +55          saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_LANGUAGE, SuppressionParser.W3C_XML_SCHEMA);
      +56          saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_SOURCE, schema);
      +57          XMLReader xmlReader = saxParser.getXMLReader();
      +58          xmlReader.setErrorHandler(new SuppressionErrorHandler());
      +59          xmlReader.setContentHandler(handler);
      +60  
      +61          InputStream inputStream = new FileInputStream(file);
      +62          Reader reader = new InputStreamReader(inputStream, "UTF-8");
      +63          InputSource in = new InputSource(reader);
      +64          //in.setEncoding("UTF-8");
      +65  
      +66          xmlReader.parse(in);
      +67  
      +68          List<SuppressionRule> result = handler.getSuppressionRules();
      +69          assertTrue(result.size() > 3);
      +70          int baseCount = 0;
      +71          for (SuppressionRule r : result) {
      +72              if (r.isBase()) {
      +73                  baseCount++;
      +74              }
      +75          }
      +76          assertTrue(baseCount > 0);
      +77      }
      +78  }
      +
      +
      + + + diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/suppression/SuppressionParserTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/suppression/SuppressionParserTest.html new file mode 100644 index 000000000..eeb0c44ae --- /dev/null +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/suppression/SuppressionParserTest.html @@ -0,0 +1,59 @@ + + + +SuppressionParserTest xref + + + +
      +1   /*
      +2    * This file is part of dependency-check-core.
      +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) 2013 Jeremy Long. All Rights Reserved.
      +17   */
      +18  package org.owasp.dependencycheck.xml.suppression;
      +19  
      +20  import java.io.File;
      +21  import java.util.List;
      +22  
      +23  import static org.junit.Assert.assertTrue;
      +24  
      +25  import org.junit.Test;
      +26  import org.owasp.dependencycheck.BaseTest;
      +27  
      +28  /**
      +29   * Test of the suppression parser.
      +30   *
      +31   * @author Jeremy Long
      +32   */
      +33  public class SuppressionParserTest extends BaseTest {
      +34  
      +35      /**
      +36       * Test of parseSuppressionRules method, of class SuppressionParser.
      +37       */
      +38      @Test
      +39      public void testParseSuppressionRules() throws Exception {
      +40          //File file = new File(this.getClass().getClassLoader().getResource("suppressions.xml").getPath());
      +41          File file = BaseTest.getResourceAsFile(this, "suppressions.xml");
      +42          SuppressionParser instance = new SuppressionParser();
      +43          List<SuppressionRule> result = instance.parseSuppressionRules(file);
      +44          assertTrue(result.size() > 3);
      +45      }
      +46  }
      +
      +
      + + + diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/suppression/SuppressionRuleTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/suppression/SuppressionRuleTest.html new file mode 100644 index 000000000..5928e1fdf --- /dev/null +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/suppression/SuppressionRuleTest.html @@ -0,0 +1,515 @@ + + + +SuppressionRuleTest xref + + + +
      +1   /*
      +2    * This file is part of dependency-check-core.
      +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) 2013 Jeremy Long. All Rights Reserved.
      +17   */
      +18  package org.owasp.dependencycheck.xml.suppression;
      +19  
      +20  import java.io.File;
      +21  import java.util.ArrayList;
      +22  import java.util.List;
      +23  import static org.junit.Assert.assertEquals;
      +24  import static org.junit.Assert.assertFalse;
      +25  import static org.junit.Assert.assertTrue;
      +26  import org.junit.Test;
      +27  import org.owasp.dependencycheck.BaseTest;
      +28  import org.owasp.dependencycheck.dependency.Dependency;
      +29  import org.owasp.dependencycheck.dependency.Identifier;
      +30  import org.owasp.dependencycheck.dependency.Vulnerability;
      +31  
      +32  /**
      +33   * Test of the suppression rule.
      +34   *
      +35   * @author Jeremy Long
      +36   */
      +37  public class SuppressionRuleTest extends BaseTest {
      +38  
      +39      //<editor-fold defaultstate="collapsed" desc="Stupid tests of properties">
      +40      /**
      +41       * Test of FilePath property, of class SuppressionRule.
      +42       */
      +43      @Test
      +44      public void testFilePath() {
      +45          SuppressionRule instance = new SuppressionRule();
      +46          PropertyType expResult = new PropertyType();
      +47          expResult.setValue("test");
      +48          instance.setFilePath(expResult);
      +49          PropertyType result = instance.getFilePath();
      +50          assertEquals(expResult, result);
      +51      }
      +52  
      +53      /**
      +54       * Test of Sha1 property, of class SuppressionRule.
      +55       */
      +56      @Test
      +57      public void testSha1() {
      +58          SuppressionRule instance = new SuppressionRule();
      +59          String expResult = "384FAA82E193D4E4B0546059CA09572654BC3970";
      +60          instance.setSha1(expResult);
      +61          String result = instance.getSha1();
      +62          assertEquals(expResult, result);
      +63      }
      +64  
      +65      /**
      +66       * Test of Cpe property, of class SuppressionRule.
      +67       */
      +68      @Test
      +69      public void testCpe() {
      +70          SuppressionRule instance = new SuppressionRule();
      +71          List<PropertyType> cpe = new ArrayList<PropertyType>();
      +72          instance.setCpe(cpe);
      +73          assertFalse(instance.hasCpe());
      +74          PropertyType pt = new PropertyType();
      +75          pt.setValue("one");
      +76          instance.addCpe(pt);
      +77          assertTrue(instance.hasCpe());
      +78          List<PropertyType> result = instance.getCpe();
      +79          assertEquals(cpe, result);
      +80  
      +81      }
      +82  
      +83      /**
      +84       * Test of CvssBelow property, of class SuppressionRule.
      +85       */
      +86      @Test
      +87      public void testGetCvssBelow() {
      +88          SuppressionRule instance = new SuppressionRule();
      +89          List<Float> cvss = new ArrayList<Float>();
      +90          instance.setCvssBelow(cvss);
      +91          assertFalse(instance.hasCvssBelow());
      +92          instance.addCvssBelow(0.7f);
      +93          assertTrue(instance.hasCvssBelow());
      +94          List<Float> result = instance.getCvssBelow();
      +95          assertEquals(cvss, result);
      +96      }
      +97  
      +98      /**
      +99       * Test of Cwe property, of class SuppressionRule.
      +100      */
      +101     @Test
      +102     public void testCwe() {
      +103         SuppressionRule instance = new SuppressionRule();
      +104         List<String> cwe = new ArrayList<String>();
      +105         instance.setCwe(cwe);
      +106         assertFalse(instance.hasCwe());
      +107         instance.addCwe("2");
      +108         assertTrue(instance.hasCwe());
      +109         List<String> result = instance.getCwe();
      +110         assertEquals(cwe, result);
      +111     }
      +112 
      +113     /**
      +114      * Test of Cve property, of class SuppressionRule.
      +115      */
      +116     @Test
      +117     public void testCve() {
      +118         SuppressionRule instance = new SuppressionRule();
      +119         List<String> cve = new ArrayList<String>();
      +120         instance.setCve(cve);
      +121         assertFalse(instance.hasCve());
      +122         instance.addCve("CVE-2013-1337");
      +123         assertTrue(instance.hasCve());
      +124         List<String> result = instance.getCve();
      +125         assertEquals(cve, result);
      +126     }
      +127 
      +128     /**
      +129      * Test of base property, of class SuppressionRule.
      +130      */
      +131     @Test
      +132     public void testBase() {
      +133         SuppressionRule instance = new SuppressionRule();
      +134         assertFalse(instance.isBase());
      +135         instance.setBase(true);
      +136         assertTrue(instance.isBase());
      +137     }
      +138     //</editor-fold>
      +139 
      +140     //<editor-fold defaultstate="collapsed" desc="Ignored duplicate tests, left in, as empty tests, so IDE doesn't re-generate them">
      +141     /**
      +142      * Test of getFilePath method, of class SuppressionRule.
      +143      */
      +144     @Test
      +145     public void testGetFilePath() {
      +146         //already tested, this is just left so the IDE doesn't recreate it.
      +147     }
      +148 
      +149     /**
      +150      * Test of setFilePath method, of class SuppressionRule.
      +151      */
      +152     @Test
      +153     public void testSetFilePath() {
      +154         //already tested, this is just left so the IDE doesn't recreate it.
      +155     }
      +156 
      +157     /**
      +158      * Test of getSha1 method, of class SuppressionRule.
      +159      */
      +160     @Test
      +161     public void testGetSha1() {
      +162         //already tested, this is just left so the IDE doesn't recreate it.
      +163     }
      +164 
      +165     /**
      +166      * Test of setSha1 method, of class SuppressionRule.
      +167      */
      +168     @Test
      +169     public void testSetSha1() {
      +170         //already tested, this is just left so the IDE doesn't recreate it.
      +171     }
      +172 
      +173     /**
      +174      * Test of getCpe method, of class SuppressionRule.
      +175      */
      +176     @Test
      +177     public void testGetCpe() {
      +178         //already tested, this is just left so the IDE doesn't recreate it.
      +179     }
      +180 
      +181     /**
      +182      * Test of setCpe method, of class SuppressionRule.
      +183      */
      +184     @Test
      +185     public void testSetCpe() {
      +186         //already tested, this is just left so the IDE doesn't recreate it.
      +187     }
      +188 
      +189     /**
      +190      * Test of addCpe method, of class SuppressionRule.
      +191      */
      +192     @Test
      +193     public void testAddCpe() {
      +194         //already tested, this is just left so the IDE doesn't recreate it.
      +195     }
      +196 
      +197     /**
      +198      * Test of hasCpe method, of class SuppressionRule.
      +199      */
      +200     @Test
      +201     public void testHasCpe() {
      +202         //already tested, this is just left so the IDE doesn't recreate it.
      +203     }
      +204 
      +205     /**
      +206      * Test of setCvssBelow method, of class SuppressionRule.
      +207      */
      +208     @Test
      +209     public void testSetCvssBelow() {
      +210         //already tested, this is just left so the IDE doesn't recreate it.
      +211     }
      +212 
      +213     /**
      +214      * Test of addCvssBelow method, of class SuppressionRule.
      +215      */
      +216     @Test
      +217     public void testAddCvssBelow() {
      +218         //already tested, this is just left so the IDE doesn't recreate it.
      +219     }
      +220 
      +221     /**
      +222      * Test of hasCvssBelow method, of class SuppressionRule.
      +223      */
      +224     @Test
      +225     public void testHasCvssBelow() {
      +226         //already tested, this is just left so the IDE doesn't recreate it.
      +227     }
      +228 
      +229     /**
      +230      * Test of getCwe method, of class SuppressionRule.
      +231      */
      +232     @Test
      +233     public void testGetCwe() {
      +234         //already tested, this is just left so the IDE doesn't recreate it.
      +235     }
      +236 
      +237     /**
      +238      * Test of setCwe method, of class SuppressionRule.
      +239      */
      +240     @Test
      +241     public void testSetCwe() {
      +242         //already tested, this is just left so the IDE doesn't recreate it.
      +243     }
      +244 
      +245     /**
      +246      * Test of addCwe method, of class SuppressionRule.
      +247      */
      +248     @Test
      +249     public void testAddCwe() {
      +250         //already tested, this is just left so the IDE doesn't recreate it.
      +251     }
      +252 
      +253     /**
      +254      * Test of hasCwe method, of class SuppressionRule.
      +255      */
      +256     @Test
      +257     public void testHasCwe() {
      +258         //already tested, this is just left so the IDE doesn't recreate it.
      +259     }
      +260 
      +261     /**
      +262      * Test of getCve method, of class SuppressionRule.
      +263      */
      +264     @Test
      +265     public void testGetCve() {
      +266         //already tested, this is just left so the IDE doesn't recreate it.
      +267     }
      +268 
      +269     /**
      +270      * Test of setCve method, of class SuppressionRule.
      +271      */
      +272     @Test
      +273     public void testSetCve() {
      +274         //already tested, this is just left so the IDE doesn't recreate it.
      +275     }
      +276 
      +277     /**
      +278      * Test of addCve method, of class SuppressionRule.
      +279      */
      +280     @Test
      +281     public void testAddCve() {
      +282         //already tested, this is just left so the IDE doesn't recreate it.
      +283     }
      +284 
      +285     /**
      +286      * Test of hasCve method, of class SuppressionRule.
      +287      */
      +288     @Test
      +289     public void testHasCve() {
      +290         //already tested, this is just left so the IDE doesn't recreate it.
      +291     }
      +292     //</editor-fold>
      +293 
      +294     /**
      +295      * Test of cpeHasNoVersion method, of class SuppressionRule.
      +296      */
      +297     @Test
      +298     public void testCpeHasNoVersion() {
      +299         PropertyType c = new PropertyType();
      +300         c.setValue("cpe:/a:microsoft:.net_framework:4.5");
      +301         SuppressionRule instance = new SuppressionRule();
      +302         assertFalse(instance.cpeHasNoVersion(c));
      +303         c.setValue("cpe:/a:microsoft:.net_framework:");
      +304         assertFalse(instance.cpeHasNoVersion(c));
      +305         c.setValue("cpe:/a:microsoft:.net_framework");
      +306         assertTrue(instance.cpeHasNoVersion(c));
      +307     }
      +308 
      +309     /**
      +310      * Test of identifierMatches method, of class SuppressionRule.
      +311      */
      +312     @Test
      +313     public void testCpeMatches() {
      +314         Identifier identifier = new Identifier("cpe", "cpe:/a:microsoft:.net_framework:4.5", "some url not needed for this test");
      +315 
      +316         PropertyType cpe = new PropertyType();
      +317         cpe.setValue("cpe:/a:microsoft:.net_framework:4.5");
      +318 
      +319         SuppressionRule instance = new SuppressionRule();
      +320         boolean expResult = true;
      +321         boolean result = instance.identifierMatches("cpe", cpe, identifier);
      +322         assertEquals(expResult, result);
      +323 
      +324         cpe.setValue("cpe:/a:microsoft:.net_framework:4.0");
      +325         expResult = false;
      +326         result = instance.identifierMatches("cpe", cpe, identifier);
      +327         assertEquals(expResult, result);
      +328 
      +329         cpe.setValue("CPE:/a:microsoft:.net_framework:4.5");
      +330         cpe.setCaseSensitive(true);
      +331         expResult = false;
      +332         result = instance.identifierMatches("cpe", cpe, identifier);
      +333         assertEquals(expResult, result);
      +334 
      +335         cpe.setValue("cpe:/a:microsoft:.net_framework");
      +336         cpe.setCaseSensitive(false);
      +337         expResult = true;
      +338         result = instance.identifierMatches("cpe", cpe, identifier);
      +339         assertEquals(expResult, result);
      +340 
      +341         cpe.setValue("cpe:/a:microsoft:.*");
      +342         cpe.setRegex(true);
      +343         expResult = true;
      +344         result = instance.identifierMatches("cpe", cpe, identifier);
      +345         assertEquals(expResult, result);
      +346 
      +347         cpe.setValue("CPE:/a:microsoft:.*");
      +348         cpe.setRegex(true);
      +349         cpe.setCaseSensitive(true);
      +350         expResult = false;
      +351         result = instance.identifierMatches("cpe", cpe, identifier);
      +352         assertEquals(expResult, result);
      +353 
      +354         cpe.setValue("cpe:/a:apache:.*");
      +355         cpe.setRegex(true);
      +356         cpe.setCaseSensitive(false);
      +357         expResult = false;
      +358         result = instance.identifierMatches("cpe", cpe, identifier);
      +359         assertEquals(expResult, result);
      +360 
      +361         identifier = new Identifier("maven", "org.springframework:spring-core:2.5.5", "https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.springframework&a=spring-core&v=2.5.5&e=jar");
      +362         cpe.setValue("org.springframework:spring-core:2.5.5");
      +363         cpe.setRegex(false);
      +364         cpe.setCaseSensitive(false);
      +365         expResult = true;
      +366         result = instance.identifierMatches("maven", cpe, identifier);
      +367         assertEquals(expResult, result);
      +368 
      +369         cpe.setValue("org\\.springframework\\.security:spring.*");
      +370         cpe.setRegex(true);
      +371         cpe.setCaseSensitive(false);
      +372         expResult = false;
      +373         result = instance.identifierMatches("maven", cpe, identifier);
      +374         assertEquals(expResult, result);
      +375     }
      +376 
      +377     /**
      +378      * Test of process method, of class SuppressionRule.
      +379      */
      +380     @Test
      +381     public void testProcess() {
      +382         //File struts = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath());
      +383         File struts = BaseTest.getResourceAsFile(this, "struts2-core-2.1.2.jar");
      +384         Dependency dependency = new Dependency(struts);
      +385         dependency.addIdentifier("cpe", "cpe:/a:microsoft:.net_framework:4.5", "some url not needed for this test");
      +386         String sha1 = dependency.getSha1sum();
      +387         dependency.setSha1sum("384FAA82E193D4E4B0546059CA09572654BC3970");
      +388         Vulnerability v = createVulnerability();
      +389         dependency.addVulnerability(v);
      +390 
      +391         //cwe
      +392         SuppressionRule instance = new SuppressionRule();
      +393         instance.setSha1(sha1);
      +394         instance.addCwe("287");
      +395         instance.process(dependency);
      +396         assertEquals(1, dependency.getVulnerabilities().size());
      +397         dependency.setSha1sum(sha1);
      +398         instance.process(dependency);
      +399         assertTrue(dependency.getVulnerabilities().isEmpty());
      +400         assertEquals(1, dependency.getSuppressedVulnerabilities().size());
      +401 
      +402         //cvss
      +403         dependency.addVulnerability(v);
      +404         instance = new SuppressionRule();
      +405         instance.addCvssBelow(5f);
      +406         instance.process(dependency);
      +407         assertEquals(1, dependency.getVulnerabilities().size());
      +408         instance.addCvssBelow(8f);
      +409         instance.process(dependency);
      +410         assertTrue(dependency.getVulnerabilities().isEmpty());
      +411         assertEquals(1, dependency.getSuppressedVulnerabilities().size());
      +412 
      +413         //cve
      +414         dependency.addVulnerability(v);
      +415         instance = new SuppressionRule();
      +416         instance.addCve("CVE-2012-1337");
      +417         instance.process(dependency);
      +418         assertEquals(1, dependency.getVulnerabilities().size());
      +419         instance.addCve("CVE-2013-1337");
      +420         instance.process(dependency);
      +421         assertTrue(dependency.getVulnerabilities().isEmpty());
      +422         assertEquals(1, dependency.getSuppressedVulnerabilities().size());
      +423 
      +424         //cpe
      +425         instance = new SuppressionRule();
      +426         PropertyType pt = new PropertyType();
      +427         pt.setValue("cpe:/a:microsoft:.net_framework:4.0");
      +428         instance.addCpe(pt);
      +429         instance.process(dependency);
      +430         assertTrue(dependency.getIdentifiers().size() == 1);
      +431         pt = new PropertyType();
      +432         pt.setValue("cpe:/a:microsoft:.net_framework:4.5");
      +433         instance.addCpe(pt);
      +434         pt = new PropertyType();
      +435         pt.setValue(".*");
      +436         pt.setRegex(true);
      +437         instance.setFilePath(pt);
      +438         instance.process(dependency);
      +439         assertTrue(dependency.getIdentifiers().isEmpty());
      +440         assertEquals(1, dependency.getSuppressedIdentifiers().size());
      +441 
      +442         instance = new SuppressionRule();
      +443         dependency.addIdentifier("cpe", "cpe:/a:microsoft:.net_framework:4.0", "some url not needed for this test");
      +444         dependency.addIdentifier("cpe", "cpe:/a:microsoft:.net_framework:4.5", "some url not needed for this test");
      +445         dependency.addIdentifier("cpe", "cpe:/a:microsoft:.net_framework:5.0", "some url not needed for this test");
      +446         pt = new PropertyType();
      +447         pt.setValue("cpe:/a:microsoft:.net_framework");
      +448         instance.addCpe(pt);
      +449         instance.setBase(true);
      +450         assertEquals(3, dependency.getIdentifiers().size());
      +451         assertEquals(1, dependency.getSuppressedIdentifiers().size());
      +452         instance.process(dependency);
      +453         assertTrue(dependency.getIdentifiers().isEmpty());
      +454         assertEquals(1, dependency.getSuppressedIdentifiers().size());
      +455     }
      +456 
      +457     /**
      +458      * Test of process method, of class SuppressionRule.
      +459      */
      +460     @Test
      +461     public void testProcessGAV() {
      +462         //File spring = new File(this.getClass().getClassLoader().getResource("spring-security-web-3.0.0.RELEASE.jar").getPath());
      +463         File spring = BaseTest.getResourceAsFile(this, "spring-security-web-3.0.0.RELEASE.jar");
      +464         Dependency dependency = new Dependency(spring);
      +465         dependency.addIdentifier("cpe", "cpe:/a:vmware:springsource_spring_framework:3.0.0", "some url not needed for this test");
      +466         dependency.addIdentifier("cpe", "cpe:/a:springsource:spring_framework:3.0.0", "some url not needed for this test");
      +467         dependency.addIdentifier("cpe", "cpe:/a:mod_security:mod_security:3.0.0", "some url not needed for this test");
      +468         dependency.addIdentifier("cpe", "cpe:/a:vmware:springsource_spring_security:3.0.0", "some url not needed for this test");
      +469         dependency.addIdentifier("maven", "org.springframework.security:spring-security-web:3.0.0.RELEASE", "some url not needed for this test");
      +470 
      +471         //cpe
      +472         SuppressionRule instance = new SuppressionRule();
      +473         PropertyType pt = new PropertyType();
      +474 
      +475         pt.setValue("org\\.springframework\\.security:spring.*");
      +476         pt.setRegex(true);
      +477         pt.setCaseSensitive(false);
      +478         instance.setGav(pt);
      +479 
      +480         pt = new PropertyType();
      +481         pt.setValue("cpe:/a:mod_security:mod_security");
      +482         instance.addCpe(pt);
      +483         pt = new PropertyType();
      +484         pt.setValue("cpe:/a:springsource:spring_framework");
      +485         instance.addCpe(pt);
      +486         pt = new PropertyType();
      +487         pt.setValue("cpe:/a:vmware:springsource_spring_framework");
      +488         instance.addCpe(pt);
      +489 
      +490         instance.process(dependency);
      +491         assertEquals(2, dependency.getIdentifiers().size());
      +492 
      +493     }
      +494 
      +495     private Vulnerability createVulnerability() {
      +496         Vulnerability v = new Vulnerability();
      +497         v.setCwe("CWE-287 Improper Authentication");
      +498         v.setName("CVE-2013-1337");
      +499         v.setCvssScore(7.5f);
      +500         return v;
      +501     }
      +502 }
      +
      +
      + + + diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/suppression/package-frame.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/suppression/package-frame.html new file mode 100644 index 000000000..2fad43252 --- /dev/null +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/suppression/package-frame.html @@ -0,0 +1,33 @@ + + + + + + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.xml.suppression + + + + +

      + org.owasp.dependencycheck.xml.suppression +

      + +

      Classes

      + + + + + \ No newline at end of file diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/suppression/package-summary.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/suppression/package-summary.html new file mode 100644 index 000000000..c42af6355 --- /dev/null +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/xml/suppression/package-summary.html @@ -0,0 +1,84 @@ + + + + + + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.xml.suppression + + + +
      + +
      +
      + +
      + +

      Package org.owasp.dependencycheck.xml.suppression

      + + + + + + + + + + + + + + + + + + + + + +
      Class Summary
      + PropertyTypeTest +
      + SuppressionHandlerTest +
      + SuppressionParserTest +
      + SuppressionRuleTest +
      + +
      + +
      +
      + +
      +
      + + + \ No newline at end of file diff --git a/dependency-check-core/xref-test/overview-frame.html b/dependency-check-core/xref-test/overview-frame.html index 35225aabb..7763a64e9 100644 --- a/dependency-check-core/xref-test/overview-frame.html +++ b/dependency-check-core/xref-test/overview-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference + Dependency-Check Core 1.4.2 Reference @@ -56,15 +56,18 @@
    202. org.owasp.dependencycheck.reporting -
    203. -
    204. - org.owasp.dependencycheck.suppression
    205. org.owasp.dependencycheck.utils +
    206. +
    207. + org.owasp.dependencycheck.xml.hints
    208. org.owasp.dependencycheck.xml.pom +
    209. +
    210. + org.owasp.dependencycheck.xml.suppression
    211. diff --git a/dependency-check-core/xref-test/overview-summary.html b/dependency-check-core/xref-test/overview-summary.html index 1d6874ae8..cf3bc72e7 100644 --- a/dependency-check-core/xref-test/overview-summary.html +++ b/dependency-check-core/xref-test/overview-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference + Dependency-Check Core 1.4.2 Reference @@ -24,7 +24,7 @@
      -

      Dependency-Check Core 1.4.0 Reference

      +

      Dependency-Check Core 1.4.2 Reference

      @@ -102,21 +102,26 @@ - - - + + + + + +
      org.owasp.dependencycheck.reporting
      - org.owasp.dependencycheck.suppression -
      org.owasp.dependencycheck.utils
      + org.owasp.dependencycheck.xml.hints +
      org.owasp.dependencycheck.xml.pom
      + org.owasp.dependencycheck.xml.suppression +
      diff --git a/dependency-check-core/xref/allclasses-frame.html b/dependency-check-core/xref/allclasses-frame.html index e5ebac828..ae6b3291d 100644 --- a/dependency-check-core/xref/allclasses-frame.html +++ b/dependency-check-core/xref/allclasses-frame.html @@ -175,6 +175,9 @@
    212. EvidenceCollection +
    213. +
    214. + ExceptionCollection
    215. Experimental @@ -211,6 +214,24 @@
    216. HintAnalyzer +
    217. +
    218. + HintErrorHandler +
    219. +
    220. + HintHandler +
    221. +
    222. + HintParseException +
    223. +
    224. + HintParser +
    225. +
    226. + HintRule +
    227. +
    228. + Hints
    229. Identifier @@ -226,6 +247,9 @@
    230. IndexException +
    231. +
    232. + InitializationException
    233. InvalidDataException @@ -309,7 +333,7 @@ PropertyLookup
    234. - PropertyType + PropertyType
    235. PythonDistributionAnalyzer @@ -319,6 +343,9 @@
    236. Reference +
    237. +
    238. + ReportException
    239. ReportGenerator @@ -339,19 +366,19 @@ SearchFieldAnalyzer
    240. - SuppressionErrorHandler + SuppressionErrorHandler
    241. - SuppressionHandler + SuppressionHandler
    242. - SuppressionParseException + SuppressionParseException
    243. - SuppressionParser + SuppressionParser
    244. - SuppressionRule + SuppressionRule
    245. TokenPairConcatenatingFilter @@ -373,6 +400,9 @@
    246. VelocityLoggerRedirect +
    247. +
    248. + VendorDuplicatingHintRule
    249. Vulnerability diff --git a/dependency-check-core/xref/index.html b/dependency-check-core/xref/index.html index e71e8ba73..49f52c91f 100644 --- a/dependency-check-core/xref/index.html +++ b/dependency-check-core/xref/index.html @@ -4,7 +4,7 @@ - Dependency-Check Core 1.4.0 Reference + Dependency-Check Core 1.4.2 Reference diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/Engine.html b/dependency-check-core/xref/org/owasp/dependencycheck/Engine.html index e8916237e..3f0c2ae7e 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/Engine.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/Engine.html @@ -38,478 +38,537 @@ 30 import org.owasp.dependencycheck.data.update.exception.UpdateException; 31 import org.owasp.dependencycheck.dependency.Dependency; 32 import org.owasp.dependencycheck.exception.NoDataException; -33 import org.owasp.dependencycheck.utils.InvalidSettingException; -34 import org.owasp.dependencycheck.utils.Settings; -35 import org.slf4j.Logger; -36 import org.slf4j.LoggerFactory; -37 -38 import java.io.File; -39 import java.io.FileFilter; -40 import java.util.ArrayList; -41 import java.util.Collection; -42 import java.util.EnumMap; -43 import java.util.HashSet; -44 import java.util.Iterator; -45 import java.util.List; -46 import java.util.Map; -47 import java.util.Set; -48 -49 /** -50 * Scans files, directories, etc. for Dependencies. Analyzers are loaded and used to process the files found by the scan, if a -51 * file is encountered and an Analyzer is associated with the file type then the file is turned into a dependency. -52 * -53 * @author Jeremy Long -54 */ -55 public class Engine implements FileFilter { -56 -57 /** -58 * The list of dependencies. -59 */ -60 private List<Dependency> dependencies = new ArrayList<Dependency>(); +33 import org.owasp.dependencycheck.exception.ExceptionCollection; +34 import org.owasp.dependencycheck.exception.InitializationException; +35 import org.owasp.dependencycheck.utils.InvalidSettingException; +36 import org.owasp.dependencycheck.utils.Settings; +37 import org.slf4j.Logger; +38 import org.slf4j.LoggerFactory; +39 +40 import java.io.File; +41 import java.io.FileFilter; +42 import java.util.ArrayList; +43 import java.util.Collection; +44 import java.util.EnumMap; +45 import java.util.HashSet; +46 import java.util.Iterator; +47 import java.util.List; +48 import java.util.Map; +49 import java.util.Set; +50 +51 /** +52 * Scans files, directories, etc. for Dependencies. Analyzers are loaded and +53 * used to process the files found by the scan, if a file is encountered and an +54 * Analyzer is associated with the file type then the file is turned into a +55 * dependency. +56 * +57 * @author Jeremy Long +58 */ +59 public class Engine implements FileFilter { +60 61 /** -62 * A Map of analyzers grouped by Analysis phase. +62 * The list of dependencies. 63 */ -64 private Map<AnalysisPhase, List<Analyzer>> analyzers = new EnumMap<AnalysisPhase, List<Analyzer>>(AnalysisPhase.class); -65 -66 /** -67 * A Map of analyzers grouped by Analysis phase. -68 */ -69 private Set<FileTypeAnalyzer> fileTypeAnalyzers = new HashSet<FileTypeAnalyzer>(); -70 -71 /** -72 * The ClassLoader to use when dynamically loading Analyzer and Update services. -73 */ -74 private ClassLoader serviceClassLoader = Thread.currentThread().getContextClassLoader(); +64 private List<Dependency> dependencies = new ArrayList<Dependency>(); +65 /** +66 * A Map of analyzers grouped by Analysis phase. +67 */ +68 private final Map<AnalysisPhase, List<Analyzer>> analyzers = new EnumMap<AnalysisPhase, List<Analyzer>>(AnalysisPhase.class); +69 +70 /** +71 * A Map of analyzers grouped by Analysis phase. +72 */ +73 private final Set<FileTypeAnalyzer> fileTypeAnalyzers = new HashSet<FileTypeAnalyzer>(); +74 75 /** -76 * The Logger for use throughout the class. -77 */ -78 private static final Logger LOGGER = LoggerFactory.getLogger(Engine.class); -79 +76 * The ClassLoader to use when dynamically loading Analyzer and Update +77 * services. +78 */ +79 private ClassLoader serviceClassLoader = Thread.currentThread().getContextClassLoader(); 80 /** -81 * Creates a new Engine. -82 * -83 * @throws DatabaseException thrown if there is an error connecting to the database -84 */ -85 public Engine() throws DatabaseException { -86 initializeEngine(); -87 } -88 -89 /** -90 * Creates a new Engine. -91 * -92 * @param serviceClassLoader a reference the class loader being used -93 * @throws DatabaseException thrown if there is an error connecting to the database -94 */ -95 public Engine(ClassLoader serviceClassLoader) throws DatabaseException { -96 this.serviceClassLoader = serviceClassLoader; -97 initializeEngine(); -98 } -99 -100 /** -101 * Creates a new Engine using the specified classloader to dynamically load Analyzer and Update services. -102 * -103 * @throws DatabaseException thrown if there is an error connecting to the database -104 */ -105 protected final void initializeEngine() throws DatabaseException { -106 ConnectionFactory.initialize(); -107 loadAnalyzers(); -108 } -109 -110 /** -111 * Properly cleans up resources allocated during analysis. -112 */ -113 public void cleanup() { -114 ConnectionFactory.cleanup(); -115 } -116 -117 /** -118 * Loads the analyzers specified in the configuration file (or system properties). -119 */ -120 private void loadAnalyzers() { -121 if (!analyzers.isEmpty()) { -122 return; -123 } -124 for (AnalysisPhase phase : AnalysisPhase.values()) { -125 analyzers.put(phase, new ArrayList<Analyzer>()); -126 } -127 -128 final AnalyzerService service = new AnalyzerService(serviceClassLoader); -129 final List<Analyzer> iterator = service.getAnalyzers(); -130 for (Analyzer a : iterator) { -131 analyzers.get(a.getAnalysisPhase()).add(a); -132 if (a instanceof FileTypeAnalyzer) { -133 this.fileTypeAnalyzers.add((FileTypeAnalyzer) a); -134 } -135 } -136 } +81 * The Logger for use throughout the class. +82 */ +83 private static final Logger LOGGER = LoggerFactory.getLogger(Engine.class); +84 +85 /** +86 * Creates a new Engine. +87 * +88 * @throws DatabaseException thrown if there is an error connecting to the +89 * database +90 */ +91 public Engine() throws DatabaseException { +92 initializeEngine(); +93 } +94 +95 /** +96 * Creates a new Engine. +97 * +98 * @param serviceClassLoader a reference the class loader being used +99 * @throws DatabaseException thrown if there is an error connecting to the +100 * database +101 */ +102 public Engine(ClassLoader serviceClassLoader) throws DatabaseException { +103 this.serviceClassLoader = serviceClassLoader; +104 initializeEngine(); +105 } +106 +107 /** +108 * Creates a new Engine using the specified classloader to dynamically load +109 * Analyzer and Update services. +110 * +111 * @throws DatabaseException thrown if there is an error connecting to the +112 * database +113 */ +114 protected final void initializeEngine() throws DatabaseException { +115 ConnectionFactory.initialize(); +116 loadAnalyzers(); +117 } +118 +119 /** +120 * Properly cleans up resources allocated during analysis. +121 */ +122 public void cleanup() { +123 ConnectionFactory.cleanup(); +124 } +125 +126 /** +127 * Loads the analyzers specified in the configuration file (or system +128 * properties). +129 */ +130 private void loadAnalyzers() { +131 if (!analyzers.isEmpty()) { +132 return; +133 } +134 for (AnalysisPhase phase : AnalysisPhase.values()) { +135 analyzers.put(phase, new ArrayList<Analyzer>()); +136 } 137 -138 /** -139 * Get the List of the analyzers for a specific phase of analysis. -140 * -141 * @param phase the phase to get the configured analyzers. -142 * @return the analyzers loaded -143 */ -144 public List<Analyzer> getAnalyzers(AnalysisPhase phase) { -145 return analyzers.get(phase); +138 final AnalyzerService service = new AnalyzerService(serviceClassLoader); +139 final List<Analyzer> iterator = service.getAnalyzers(); +140 for (Analyzer a : iterator) { +141 analyzers.get(a.getAnalysisPhase()).add(a); +142 if (a instanceof FileTypeAnalyzer) { +143 this.fileTypeAnalyzers.add((FileTypeAnalyzer) a); +144 } +145 } 146 } 147 148 /** -149 * Get the dependencies identified. +149 * Get the List of the analyzers for a specific phase of analysis. 150 * -151 * @return the dependencies identified -152 */ -153 public List<Dependency> getDependencies() { -154 return dependencies; -155 } -156 -157 /** -158 * Sets the dependencies. -159 * -160 * @param dependencies the dependencies -161 */ -162 public void setDependencies(List<Dependency> dependencies) { -163 this.dependencies = dependencies; -164 } -165 -166 /** -167 * Scans an array of files or directories. If a directory is specified, it will be scanned recursively. Any dependencies -168 * identified are added to the dependency collection. +151 * @param phase the phase to get the configured analyzers. +152 * @return the analyzers loaded +153 */ +154 public List<Analyzer> getAnalyzers(AnalysisPhase phase) { +155 return analyzers.get(phase); +156 } +157 +158 /** +159 * Get the dependencies identified. +160 * +161 * @return the dependencies identified +162 */ +163 public List<Dependency> getDependencies() { +164 return dependencies; +165 } +166 +167 /** +168 * Sets the dependencies. 169 * -170 * @param paths an array of paths to files or directories to be analyzed -171 * @return the list of dependencies scanned -172 * @since v0.3.2.5 -173 */ -174 public List<Dependency> scan(String[] paths) { -175 final List<Dependency> deps = new ArrayList<Dependency>(); -176 for (String path : paths) { -177 final List<Dependency> d = scan(path); -178 if (d != null) { -179 deps.addAll(d); -180 } -181 } -182 return deps; -183 } -184 -185 /** -186 * Scans a given file or directory. If a directory is specified, it will be scanned recursively. Any dependencies identified -187 * are added to the dependency collection. -188 * -189 * @param path the path to a file or directory to be analyzed -190 * @return the list of dependencies scanned -191 */ -192 public List<Dependency> scan(String path) { -193 final File file = new File(path); -194 return scan(file); -195 } -196 -197 /** -198 * Scans an array of files or directories. If a directory is specified, it will be scanned recursively. Any dependencies -199 * identified are added to the dependency collection. +170 * @param dependencies the dependencies +171 */ +172 public void setDependencies(List<Dependency> dependencies) { +173 this.dependencies = dependencies; +174 } +175 +176 /** +177 * Scans an array of files or directories. If a directory is specified, it +178 * will be scanned recursively. Any dependencies identified are added to the +179 * dependency collection. +180 * +181 * @param paths an array of paths to files or directories to be analyzed +182 * @return the list of dependencies scanned +183 * @since v0.3.2.5 +184 */ +185 public List<Dependency> scan(String[] paths) { +186 final List<Dependency> deps = new ArrayList<Dependency>(); +187 for (String path : paths) { +188 final List<Dependency> d = scan(path); +189 if (d != null) { +190 deps.addAll(d); +191 } +192 } +193 return deps; +194 } +195 +196 /** +197 * Scans a given file or directory. If a directory is specified, it will be +198 * scanned recursively. Any dependencies identified are added to the +199 * dependency collection. 200 * -201 * @param files an array of paths to files or directories to be analyzed. -202 * @return the list of dependencies -203 * @since v0.3.2.5 -204 */ -205 public List<Dependency> scan(File[] files) { -206 final List<Dependency> deps = new ArrayList<Dependency>(); -207 for (File file : files) { -208 final List<Dependency> d = scan(file); -209 if (d != null) { -210 deps.addAll(d); -211 } -212 } -213 return deps; -214 } -215 -216 /** -217 * Scans a collection of files or directories. If a directory is specified, it will be scanned recursively. Any dependencies -218 * identified are added to the dependency collection. -219 * -220 * @param files a set of paths to files or directories to be analyzed -221 * @return the list of dependencies scanned -222 * @since v0.3.2.5 -223 */ -224 public List<Dependency> scan(Collection<File> files) { -225 final List<Dependency> deps = new ArrayList<Dependency>(); -226 for (File file : files) { -227 final List<Dependency> d = scan(file); -228 if (d != null) { -229 deps.addAll(d); -230 } -231 } -232 return deps; -233 } -234 -235 /** -236 * Scans a given file or directory. If a directory is specified, it will be scanned recursively. Any dependencies identified -237 * are added to the dependency collection. -238 * -239 * @param file the path to a file or directory to be analyzed -240 * @return the list of dependencies scanned -241 * @since v0.3.2.4 -242 */ -243 public List<Dependency> scan(File file) { -244 if (file.exists()) { -245 if (file.isDirectory()) { -246 return scanDirectory(file); -247 } else { -248 final Dependency d = scanFile(file); -249 if (d != null) { -250 final List<Dependency> deps = new ArrayList<Dependency>(); -251 deps.add(d); -252 return deps; -253 } -254 } -255 } -256 return null; -257 } -258 -259 /** -260 * Recursively scans files and directories. Any dependencies identified are added to the dependency collection. -261 * -262 * @param dir the directory to scan -263 * @return the list of Dependency objects scanned -264 */ -265 protected List<Dependency> scanDirectory(File dir) { -266 final File[] files = dir.listFiles(); -267 final List<Dependency> deps = new ArrayList<Dependency>(); -268 if (files != null) { -269 for (File f : files) { -270 if (f.isDirectory()) { -271 final List<Dependency> d = scanDirectory(f); -272 if (d != null) { -273 deps.addAll(d); -274 } -275 } else { -276 final Dependency d = scanFile(f); -277 deps.add(d); -278 } -279 } -280 } -281 return deps; -282 } -283 -284 /** -285 * Scans a specified file. If a dependency is identified it is added to the dependency collection. -286 * -287 * @param file The file to scan -288 * @return the scanned dependency -289 */ -290 protected Dependency scanFile(File file) { -291 Dependency dependency = null; -292 if (file.isFile()) { -293 if (accept(file)) { -294 dependency = new Dependency(file); -295 dependencies.add(dependency); -296 } -297 } else { -298 LOGGER.debug("Path passed to scanFile(File) is not a file: {}. Skipping the file.", file); -299 } -300 return dependency; -301 } -302 -303 /** -304 * Runs the analyzers against all of the dependencies. Since the mutable dependencies list is exposed via -305 * {@link #getDependencies()}, this method iterates over a copy of the dependencies list. Thus, the potential for -306 * {@link java.util.ConcurrentModificationException}s is avoided, and analyzers may safely add or remove entries from the -307 * dependencies list. -308 */ -309 public void analyzeDependencies() { -310 boolean autoUpdate = true; -311 try { -312 autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE); -313 } catch (InvalidSettingException ex) { -314 LOGGER.debug("Invalid setting for auto-update; using true."); -315 } -316 if (autoUpdate) { -317 doUpdates(); -318 } +201 * @param path the path to a file or directory to be analyzed +202 * @return the list of dependencies scanned +203 */ +204 public List<Dependency> scan(String path) { +205 final File file = new File(path); +206 return scan(file); +207 } +208 +209 /** +210 * Scans an array of files or directories. If a directory is specified, it +211 * will be scanned recursively. Any dependencies identified are added to the +212 * dependency collection. +213 * +214 * @param files an array of paths to files or directories to be analyzed. +215 * @return the list of dependencies +216 * @since v0.3.2.5 +217 */ +218 public List<Dependency> scan(File[] files) { +219 final List<Dependency> deps = new ArrayList<Dependency>(); +220 for (File file : files) { +221 final List<Dependency> d = scan(file); +222 if (d != null) { +223 deps.addAll(d); +224 } +225 } +226 return deps; +227 } +228 +229 /** +230 * Scans a collection of files or directories. If a directory is specified, +231 * it will be scanned recursively. Any dependencies identified are added to +232 * the dependency collection. +233 * +234 * @param files a set of paths to files or directories to be analyzed +235 * @return the list of dependencies scanned +236 * @since v0.3.2.5 +237 */ +238 public List<Dependency> scan(Collection<File> files) { +239 final List<Dependency> deps = new ArrayList<Dependency>(); +240 for (File file : files) { +241 final List<Dependency> d = scan(file); +242 if (d != null) { +243 deps.addAll(d); +244 } +245 } +246 return deps; +247 } +248 +249 /** +250 * Scans a given file or directory. If a directory is specified, it will be +251 * scanned recursively. Any dependencies identified are added to the +252 * dependency collection. +253 * +254 * @param file the path to a file or directory to be analyzed +255 * @return the list of dependencies scanned +256 * @since v0.3.2.4 +257 */ +258 public List<Dependency> scan(File file) { +259 if (file.exists()) { +260 if (file.isDirectory()) { +261 return scanDirectory(file); +262 } else { +263 final Dependency d = scanFile(file); +264 if (d != null) { +265 final List<Dependency> deps = new ArrayList<Dependency>(); +266 deps.add(d); +267 return deps; +268 } +269 } +270 } +271 return null; +272 } +273 +274 /** +275 * Recursively scans files and directories. Any dependencies identified are +276 * added to the dependency collection. +277 * +278 * @param dir the directory to scan +279 * @return the list of Dependency objects scanned +280 */ +281 protected List<Dependency> scanDirectory(File dir) { +282 final File[] files = dir.listFiles(); +283 final List<Dependency> deps = new ArrayList<Dependency>(); +284 if (files != null) { +285 for (File f : files) { +286 if (f.isDirectory()) { +287 final List<Dependency> d = scanDirectory(f); +288 if (d != null) { +289 deps.addAll(d); +290 } +291 } else { +292 final Dependency d = scanFile(f); +293 deps.add(d); +294 } +295 } +296 } +297 return deps; +298 } +299 +300 /** +301 * Scans a specified file. If a dependency is identified it is added to the +302 * dependency collection. +303 * +304 * @param file The file to scan +305 * @return the scanned dependency +306 */ +307 protected Dependency scanFile(File file) { +308 Dependency dependency = null; +309 if (file.isFile()) { +310 if (accept(file)) { +311 dependency = new Dependency(file); +312 dependencies.add(dependency); +313 } +314 } else { +315 LOGGER.debug("Path passed to scanFile(File) is not a file: {}. Skipping the file.", file); +316 } +317 return dependency; +318 } 319 -320 //need to ensure that data exists -321 try { -322 ensureDataExists(); -323 } catch (NoDataException ex) { -324 LOGGER.error("{}\n\nUnable to continue dependency-check analysis.", ex.getMessage()); -325 LOGGER.debug("", ex); -326 return; -327 } catch (DatabaseException ex) { -328 LOGGER.error("{}\n\nUnable to continue dependency-check analysis.", ex.getMessage()); -329 LOGGER.debug("", ex); -330 return; -331 -332 } -333 -334 LOGGER.debug("\n----------------------------------------------------\nBEGIN ANALYSIS\n----------------------------------------------------"); -335 LOGGER.info("Analysis Starting"); -336 final long analysisStart = System.currentTimeMillis(); -337 -338 // analysis phases -339 for (AnalysisPhase phase : AnalysisPhase.values()) { -340 final List<Analyzer> analyzerList = analyzers.get(phase); -341 -342 for (Analyzer a : analyzerList) { -343 a = initializeAnalyzer(a); -344 -345 /* need to create a copy of the collection because some of the -346 * analyzers may modify it. This prevents ConcurrentModificationExceptions. -347 * This is okay for adds/deletes because it happens per analyzer. -348 */ -349 LOGGER.debug("Begin Analyzer '{}'", a.getName()); -350 final Set<Dependency> dependencySet = new HashSet<Dependency>(dependencies); -351 for (Dependency d : dependencySet) { -352 boolean shouldAnalyze = true; -353 if (a instanceof FileTypeAnalyzer) { -354 final FileTypeAnalyzer fAnalyzer = (FileTypeAnalyzer) a; -355 shouldAnalyze = fAnalyzer.accept(d.getActualFile()); -356 } -357 if (shouldAnalyze) { -358 LOGGER.debug("Begin Analysis of '{}'", d.getActualFilePath()); -359 try { -360 a.analyze(d, this); -361 } catch (AnalysisException ex) { -362 LOGGER.warn("An error occurred while analyzing '{}'.", d.getActualFilePath()); -363 LOGGER.debug("", ex); -364 } catch (Throwable ex) { -365 //final AnalysisException ax = new AnalysisException(axMsg, ex); -366 LOGGER.warn("An unexpected error occurred during analysis of '{}'", d.getActualFilePath()); -367 LOGGER.debug("", ex); -368 } -369 } -370 } -371 } -372 } -373 for (AnalysisPhase phase : AnalysisPhase.values()) { -374 final List<Analyzer> analyzerList = analyzers.get(phase); -375 -376 for (Analyzer a : analyzerList) { -377 closeAnalyzer(a); -378 } -379 } -380 -381 LOGGER.debug("\n----------------------------------------------------\nEND ANALYSIS\n----------------------------------------------------"); -382 LOGGER.info("Analysis Complete ({} ms)", System.currentTimeMillis() - analysisStart); -383 } -384 -385 /** -386 * Initializes the given analyzer. -387 * -388 * @param analyzer the analyzer to initialize -389 * @return the initialized analyzer -390 */ -391 protected Analyzer initializeAnalyzer(Analyzer analyzer) { -392 try { -393 LOGGER.debug("Initializing {}", analyzer.getName()); -394 analyzer.initialize(); -395 } catch (Throwable ex) { -396 LOGGER.error("Exception occurred initializing {}.", analyzer.getName()); -397 LOGGER.debug("", ex); -398 try { -399 analyzer.close(); -400 } catch (Throwable ex1) { -401 LOGGER.trace("", ex1); -402 } -403 } -404 return analyzer; -405 } -406 -407 /** -408 * Closes the given analyzer. -409 * -410 * @param analyzer the analyzer to close -411 */ -412 protected void closeAnalyzer(Analyzer analyzer) { -413 LOGGER.debug("Closing Analyzer '{}'", analyzer.getName()); -414 try { -415 analyzer.close(); -416 } catch (Throwable ex) { -417 LOGGER.trace("", ex); -418 } -419 } -420 -421 /** -422 * Cycles through the cached web data sources and calls update on all of them. -423 */ -424 public void doUpdates() { -425 LOGGER.info("Checking for updates"); -426 final long updateStart = System.currentTimeMillis(); -427 final UpdateService service = new UpdateService(serviceClassLoader); -428 final Iterator<CachedWebDataSource> iterator = service.getDataSources(); -429 while (iterator.hasNext()) { -430 final CachedWebDataSource source = iterator.next(); -431 try { -432 source.update(); -433 } catch (UpdateException ex) { -434 LOGGER.warn( -435 "Unable to update Cached Web DataSource, using local data instead. Results may not include recent vulnerabilities."); -436 LOGGER.debug("Unable to update details for {}", source.getClass().getName(), ex); -437 } -438 } -439 LOGGER.info("Check for updates complete ({} ms)", System.currentTimeMillis() - updateStart); -440 } -441 -442 /** -443 * Returns a full list of all of the analyzers. This is useful for reporting which analyzers where used. -444 * -445 * @return a list of Analyzers -446 */ -447 public List<Analyzer> getAnalyzers() { -448 final List<Analyzer> ret = new ArrayList<Analyzer>(); -449 for (AnalysisPhase phase : AnalysisPhase.values()) { -450 final List<Analyzer> analyzerList = analyzers.get(phase); -451 ret.addAll(analyzerList); -452 } -453 return ret; -454 } -455 -456 /** -457 * Checks all analyzers to see if an extension is supported. -458 * -459 * @param file a file extension -460 * @return true or false depending on whether or not the file extension is supported -461 */ -462 @Override -463 public boolean accept(File file) { -464 if (file == null) { -465 return false; -466 } -467 boolean scan = false; -468 for (FileTypeAnalyzer a : this.fileTypeAnalyzers) { -469 /* note, we can't break early on this loop as the analyzers need to know if -470 they have files to work on prior to initialization */ -471 scan |= a.accept(file); -472 } -473 return scan; -474 } -475 -476 /** -477 * Returns the set of file type analyzers. -478 * -479 * @return the set of file type analyzers -480 */ -481 public Set<FileTypeAnalyzer> getFileTypeAnalyzers() { -482 return this.fileTypeAnalyzers; -483 } -484 -485 /** -486 * Checks the CPE Index to ensure documents exists. If none exist a NoDataException is thrown. -487 * -488 * @throws NoDataException thrown if no data exists in the CPE Index -489 * @throws DatabaseException thrown if there is an exception opening the database -490 */ -491 private void ensureDataExists() throws NoDataException, DatabaseException { -492 final CveDB cve = new CveDB(); -493 try { -494 cve.open(); -495 if (!cve.dataExists()) { -496 throw new NoDataException("No documents exist"); -497 } -498 } catch (DatabaseException ex) { -499 throw new NoDataException(ex.getMessage(), ex); -500 } finally { -501 cve.close(); -502 } -503 } -504 } +320 /** +321 * Runs the analyzers against all of the dependencies. Since the mutable +322 * dependencies list is exposed via {@link #getDependencies()}, this method +323 * iterates over a copy of the dependencies list. Thus, the potential for +324 * {@link java.util.ConcurrentModificationException}s is avoided, and +325 * analyzers may safely add or remove entries from the dependencies list. +326 * +327 * Every effort is made to complete analysis on the dependencies. In some +328 * cases an exception will occur with part of the analysis being performed +329 * which may not affect the entire analysis. If an exception occurs it will +330 * be included in the thrown exception collection. +331 * +332 * @throws ExceptionCollection a collections of any exceptions that occurred +333 * during analysis +334 */ +335 public void analyzeDependencies() throws ExceptionCollection { +336 final List<Throwable> exceptions = new ArrayList<Throwable>(); +337 boolean autoUpdate = true; +338 try { +339 autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE); +340 } catch (InvalidSettingException ex) { +341 LOGGER.debug("Invalid setting for auto-update; using true."); +342 exceptions.add(ex); +343 } +344 if (autoUpdate) { +345 try { +346 doUpdates(); +347 } catch (UpdateException ex) { +348 exceptions.add(ex); +349 LOGGER.warn("Unable to update Cached Web DataSource, using local " +350 + "data instead. Results may not include recent vulnerabilities."); +351 LOGGER.debug("Update Error", ex); +352 } +353 } +354 +355 //need to ensure that data exists +356 try { +357 ensureDataExists(); +358 } catch (NoDataException ex) { +359 LOGGER.error("{}\n\nUnable to continue dependency-check analysis.", ex.getMessage()); +360 LOGGER.debug("", ex); +361 exceptions.add(ex); +362 throw new ExceptionCollection("Unable to continue dependency-check analysis.", exceptions, true); +363 } catch (DatabaseException ex) { +364 LOGGER.error("{}\n\nUnable to continue dependency-check analysis.", ex.getMessage()); +365 LOGGER.debug("", ex); +366 exceptions.add(ex); +367 throw new ExceptionCollection("Unable to connect to the dependency-check database", exceptions, true); +368 } +369 +370 LOGGER.debug("\n----------------------------------------------------\nBEGIN ANALYSIS\n----------------------------------------------------"); +371 LOGGER.info("Analysis Starting"); +372 final long analysisStart = System.currentTimeMillis(); +373 +374 // analysis phases +375 for (AnalysisPhase phase : AnalysisPhase.values()) { +376 final List<Analyzer> analyzerList = analyzers.get(phase); +377 +378 for (Analyzer a : analyzerList) { +379 try { +380 a = initializeAnalyzer(a); +381 } catch (InitializationException ex) { +382 exceptions.add(ex); +383 continue; +384 } +385 +386 /* need to create a copy of the collection because some of the +387 * analyzers may modify it. This prevents ConcurrentModificationExceptions. +388 * This is okay for adds/deletes because it happens per analyzer. +389 */ +390 LOGGER.debug("Begin Analyzer '{}'", a.getName()); +391 final Set<Dependency> dependencySet = new HashSet<Dependency>(dependencies); +392 for (Dependency d : dependencySet) { +393 boolean shouldAnalyze = true; +394 if (a instanceof FileTypeAnalyzer) { +395 final FileTypeAnalyzer fAnalyzer = (FileTypeAnalyzer) a; +396 shouldAnalyze = fAnalyzer.accept(d.getActualFile()); +397 } +398 if (shouldAnalyze) { +399 LOGGER.debug("Begin Analysis of '{}'", d.getActualFilePath()); +400 try { +401 a.analyze(d, this); +402 } catch (AnalysisException ex) { +403 LOGGER.warn("An error occurred while analyzing '{}'.", d.getActualFilePath()); +404 LOGGER.debug("", ex); +405 exceptions.add(ex); +406 } catch (Throwable ex) { +407 //final AnalysisException ax = new AnalysisException(axMsg, ex); +408 LOGGER.warn("An unexpected error occurred during analysis of '{}'", d.getActualFilePath()); +409 LOGGER.debug("", ex); +410 exceptions.add(ex); +411 } +412 } +413 } +414 } +415 } +416 for (AnalysisPhase phase : AnalysisPhase.values()) { +417 final List<Analyzer> analyzerList = analyzers.get(phase); +418 +419 for (Analyzer a : analyzerList) { +420 closeAnalyzer(a); +421 } +422 } +423 +424 LOGGER.debug("\n----------------------------------------------------\nEND ANALYSIS\n----------------------------------------------------"); +425 LOGGER.info("Analysis Complete ({} ms)", System.currentTimeMillis() - analysisStart); +426 if (exceptions.size() > 0) { +427 throw new ExceptionCollection("One or more exceptions occured during dependency-check analysis", exceptions); +428 } +429 } +430 +431 /** +432 * Initializes the given analyzer. +433 * +434 * @param analyzer the analyzer to initialize +435 * @return the initialized analyzer +436 * @throws InitializationException thrown when there is a problem +437 * initializing the analyzer +438 */ +439 protected Analyzer initializeAnalyzer(Analyzer analyzer) throws InitializationException { +440 try { +441 LOGGER.debug("Initializing {}", analyzer.getName()); +442 analyzer.initialize(); +443 } catch (InitializationException ex) { +444 LOGGER.error("Exception occurred initializing {}.", analyzer.getName()); +445 LOGGER.debug("", ex); +446 try { +447 analyzer.close(); +448 } catch (Throwable ex1) { +449 LOGGER.trace("", ex1); +450 } +451 throw ex; +452 } catch (Throwable ex) { +453 LOGGER.error("Unexpected exception occurred initializing {}.", analyzer.getName()); +454 LOGGER.debug("", ex); +455 try { +456 analyzer.close(); +457 } catch (Throwable ex1) { +458 LOGGER.trace("", ex1); +459 } +460 throw new InitializationException("Unexpected Exception", ex); +461 } +462 return analyzer; +463 } +464 +465 /** +466 * Closes the given analyzer. +467 * +468 * @param analyzer the analyzer to close +469 */ +470 protected void closeAnalyzer(Analyzer analyzer) { +471 LOGGER.debug("Closing Analyzer '{}'", analyzer.getName()); +472 try { +473 analyzer.close(); +474 } catch (Throwable ex) { +475 LOGGER.trace("", ex); +476 } +477 } +478 +479 /** +480 * Cycles through the cached web data sources and calls update on all of +481 * them. +482 * +483 * @throws UpdateException thrown if the operation fails +484 */ +485 public void doUpdates() throws UpdateException { +486 LOGGER.info("Checking for updates"); +487 final long updateStart = System.currentTimeMillis(); +488 final UpdateService service = new UpdateService(serviceClassLoader); +489 final Iterator<CachedWebDataSource> iterator = service.getDataSources(); +490 while (iterator.hasNext()) { +491 final CachedWebDataSource source = iterator.next(); +492 source.update(); +493 } +494 LOGGER.info("Check for updates complete ({} ms)", System.currentTimeMillis() - updateStart); +495 } +496 +497 /** +498 * Returns a full list of all of the analyzers. This is useful for reporting +499 * which analyzers where used. +500 * +501 * @return a list of Analyzers +502 */ +503 public List<Analyzer> getAnalyzers() { +504 final List<Analyzer> ret = new ArrayList<Analyzer>(); +505 for (AnalysisPhase phase : AnalysisPhase.values()) { +506 final List<Analyzer> analyzerList = analyzers.get(phase); +507 ret.addAll(analyzerList); +508 } +509 return ret; +510 } +511 +512 /** +513 * Checks all analyzers to see if an extension is supported. +514 * +515 * @param file a file extension +516 * @return true or false depending on whether or not the file extension is +517 * supported +518 */ +519 @Override +520 public boolean accept(File file) { +521 if (file == null) { +522 return false; +523 } +524 boolean scan = false; +525 for (FileTypeAnalyzer a : this.fileTypeAnalyzers) { +526 /* note, we can't break early on this loop as the analyzers need to know if +527 they have files to work on prior to initialization */ +528 scan |= a.accept(file); +529 } +530 return scan; +531 } +532 +533 /** +534 * Returns the set of file type analyzers. +535 * +536 * @return the set of file type analyzers +537 */ +538 public Set<FileTypeAnalyzer> getFileTypeAnalyzers() { +539 return this.fileTypeAnalyzers; +540 } +541 +542 /** +543 * Checks the CPE Index to ensure documents exists. If none exist a +544 * NoDataException is thrown. +545 * +546 * @throws NoDataException thrown if no data exists in the CPE Index +547 * @throws DatabaseException thrown if there is an exception opening the +548 * database +549 */ +550 private void ensureDataExists() throws NoDataException, DatabaseException { +551 final CveDB cve = new CveDB(); +552 try { +553 cve.open(); +554 if (!cve.dataExists()) { +555 throw new NoDataException("No documents exist"); +556 } +557 } catch (DatabaseException ex) { +558 throw new NoDataException(ex.getMessage(), ex); +559 } finally { +560 cve.close(); +561 } +562 } +563 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/agent/DependencyCheckScanAgent.html b/dependency-check-core/xref/org/owasp/dependencycheck/agent/DependencyCheckScanAgent.html index 1e31947e7..6f6a63245 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/agent/DependencyCheckScanAgent.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/agent/DependencyCheckScanAgent.html @@ -35,1004 +35,1025 @@ 27 import org.owasp.dependencycheck.dependency.Dependency; 28 import org.owasp.dependencycheck.dependency.Identifier; 29 import org.owasp.dependencycheck.dependency.Vulnerability; -30 import org.owasp.dependencycheck.exception.ScanAgentException; -31 import org.owasp.dependencycheck.reporting.ReportGenerator; -32 import org.owasp.dependencycheck.utils.Settings; -33 import org.slf4j.Logger; -34 import org.slf4j.LoggerFactory; -35 -36 /** -37 * This class provides a way to easily conduct a scan solely based on existing evidence metadata rather than collecting evidence -38 * from the files themselves. This class is based on the Ant task and Maven plugin with the exception that it takes a list of -39 * dependencies that can be programmatically added from data in a spreadsheet, database or some other datasource and conduct a -40 * scan based on this pre-defined evidence. -41 * -42 * <h2>Example:</h2> -43 * <pre> -44 * List&lt;Dependency&gt; dependencies = new ArrayList&lt;Dependency&gt;(); -45 * Dependency dependency = new Dependency(new File(FileUtils.getBitBucket())); -46 * dependency.getProductEvidence().addEvidence("my-datasource", "name", "Jetty", Confidence.HIGH); -47 * dependency.getVersionEvidence().addEvidence("my-datasource", "version", "5.1.10", Confidence.HIGH); -48 * dependency.getVendorEvidence().addEvidence("my-datasource", "vendor", "mortbay", Confidence.HIGH); -49 * dependencies.add(dependency); -50 * -51 * DependencyCheckScanAgent scan = new DependencyCheckScanAgent(); -52 * scan.setDependencies(dependencies); -53 * scan.setReportFormat(ReportGenerator.Format.ALL); -54 * scan.setReportOutputDirectory(System.getProperty("user.home")); -55 * scan.execute(); -56 * </pre> -57 * -58 * @author Steve Springett -59 */ -60 @SuppressWarnings("unused") -61 public class DependencyCheckScanAgent { -62 -63 /** -64 * System specific new line character. -65 */ -66 private static final String NEW_LINE = System.getProperty("line.separator", "\n").intern(); -67 /** -68 * Logger for use throughout the class. -69 */ -70 private static final Logger LOGGER = LoggerFactory.getLogger(DependencyCheckScanAgent.class); -71 /** -72 * The application name for the report. -73 */ -74 private String applicationName = "Dependency-Check"; -75 -76 /** -77 * Get the value of applicationName. -78 * -79 * @return the value of applicationName -80 */ -81 public String getApplicationName() { -82 return applicationName; -83 } -84 -85 /** -86 * Set the value of applicationName. -87 * -88 * @param applicationName new value of applicationName -89 */ -90 public void setApplicationName(String applicationName) { -91 this.applicationName = applicationName; -92 } -93 -94 /** -95 * The pre-determined dependencies to scan -96 */ -97 private List<Dependency> dependencies; -98 -99 /** -100 * Returns a list of pre-determined dependencies. -101 * -102 * @return returns a list of dependencies -103 */ -104 public List<Dependency> getDependencies() { -105 return dependencies; -106 } -107 -108 /** -109 * Sets the list of dependencies to scan. -110 * -111 * @param dependencies new value of dependencies -112 */ -113 public void setDependencies(List<Dependency> dependencies) { -114 this.dependencies = dependencies; -115 } -116 -117 /** -118 * The location of the data directory that contains -119 */ -120 private String dataDirectory = null; -121 -122 /** -123 * Get the value of dataDirectory. -124 * -125 * @return the value of dataDirectory -126 */ -127 public String getDataDirectory() { -128 return dataDirectory; -129 } -130 -131 /** -132 * Set the value of dataDirectory. -133 * -134 * @param dataDirectory new value of dataDirectory -135 */ -136 public void setDataDirectory(String dataDirectory) { -137 this.dataDirectory = dataDirectory; -138 } -139 -140 /** -141 * Specifies the destination directory for the generated Dependency-Check report. -142 */ -143 private String reportOutputDirectory; -144 -145 /** -146 * Get the value of reportOutputDirectory. -147 * -148 * @return the value of reportOutputDirectory -149 */ -150 public String getReportOutputDirectory() { -151 return reportOutputDirectory; -152 } -153 -154 /** -155 * Set the value of reportOutputDirectory. -156 * -157 * @param reportOutputDirectory new value of reportOutputDirectory -158 */ -159 public void setReportOutputDirectory(String reportOutputDirectory) { -160 this.reportOutputDirectory = reportOutputDirectory; -161 } -162 -163 /** -164 * Specifies if the build should be failed if a CVSS score above a specified level is identified. The default is 11 which -165 * means since the CVSS scores are 0-10, by default the build will never fail and the CVSS score is set to 11. The valid range -166 * for the fail build on CVSS is 0 to 11, where anything above 10 will not cause the build to fail. -167 */ -168 private float failBuildOnCVSS = 11; -169 -170 /** -171 * Get the value of failBuildOnCVSS. -172 * -173 * @return the value of failBuildOnCVSS -174 */ -175 public float getFailBuildOnCVSS() { -176 return failBuildOnCVSS; -177 } -178 -179 /** -180 * Set the value of failBuildOnCVSS. -181 * -182 * @param failBuildOnCVSS new value of failBuildOnCVSS -183 */ -184 public void setFailBuildOnCVSS(float failBuildOnCVSS) { -185 this.failBuildOnCVSS = failBuildOnCVSS; -186 } -187 -188 /** -189 * Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not recommended that this be turned to false. Default -190 * is true. -191 */ -192 private boolean autoUpdate = true; +30 import org.owasp.dependencycheck.exception.ExceptionCollection; +31 import org.owasp.dependencycheck.exception.ScanAgentException; +32 import org.owasp.dependencycheck.reporting.ReportGenerator; +33 import org.owasp.dependencycheck.utils.Settings; +34 import org.slf4j.Logger; +35 import org.slf4j.LoggerFactory; +36 +37 /** +38 * This class provides a way to easily conduct a scan solely based on existing +39 * evidence metadata rather than collecting evidence from the files themselves. +40 * This class is based on the Ant task and Maven plugin with the exception that +41 * it takes a list of dependencies that can be programmatically added from data +42 * in a spreadsheet, database or some other datasource and conduct a scan based +43 * on this pre-defined evidence. +44 * +45 * <h2>Example:</h2> +46 * <pre> +47 * List&lt;Dependency&gt; dependencies = new ArrayList&lt;Dependency&gt;(); +48 * Dependency dependency = new Dependency(new File(FileUtils.getBitBucket())); +49 * dependency.getProductEvidence().addEvidence("my-datasource", "name", "Jetty", Confidence.HIGH); +50 * dependency.getVersionEvidence().addEvidence("my-datasource", "version", "5.1.10", Confidence.HIGH); +51 * dependency.getVendorEvidence().addEvidence("my-datasource", "vendor", "mortbay", Confidence.HIGH); +52 * dependencies.add(dependency); +53 * +54 * DependencyCheckScanAgent scan = new DependencyCheckScanAgent(); +55 * scan.setDependencies(dependencies); +56 * scan.setReportFormat(ReportGenerator.Format.ALL); +57 * scan.setReportOutputDirectory(System.getProperty("user.home")); +58 * scan.execute(); +59 * </pre> +60 * +61 * @author Steve Springett +62 */ +63 @SuppressWarnings("unused") +64 public class DependencyCheckScanAgent { +65 +66 /** +67 * System specific new line character. +68 */ +69 private static final String NEW_LINE = System.getProperty("line.separator", "\n").intern(); +70 /** +71 * Logger for use throughout the class. +72 */ +73 private static final Logger LOGGER = LoggerFactory.getLogger(DependencyCheckScanAgent.class); +74 /** +75 * The application name for the report. +76 */ +77 private String applicationName = "Dependency-Check"; +78 +79 /** +80 * Get the value of applicationName. +81 * +82 * @return the value of applicationName +83 */ +84 public String getApplicationName() { +85 return applicationName; +86 } +87 +88 /** +89 * Set the value of applicationName. +90 * +91 * @param applicationName new value of applicationName +92 */ +93 public void setApplicationName(String applicationName) { +94 this.applicationName = applicationName; +95 } +96 +97 /** +98 * The pre-determined dependencies to scan +99 */ +100 private List<Dependency> dependencies; +101 +102 /** +103 * Returns a list of pre-determined dependencies. +104 * +105 * @return returns a list of dependencies +106 */ +107 public List<Dependency> getDependencies() { +108 return dependencies; +109 } +110 +111 /** +112 * Sets the list of dependencies to scan. +113 * +114 * @param dependencies new value of dependencies +115 */ +116 public void setDependencies(List<Dependency> dependencies) { +117 this.dependencies = dependencies; +118 } +119 +120 /** +121 * The location of the data directory that contains +122 */ +123 private String dataDirectory = null; +124 +125 /** +126 * Get the value of dataDirectory. +127 * +128 * @return the value of dataDirectory +129 */ +130 public String getDataDirectory() { +131 return dataDirectory; +132 } +133 +134 /** +135 * Set the value of dataDirectory. +136 * +137 * @param dataDirectory new value of dataDirectory +138 */ +139 public void setDataDirectory(String dataDirectory) { +140 this.dataDirectory = dataDirectory; +141 } +142 +143 /** +144 * Specifies the destination directory for the generated Dependency-Check +145 * report. +146 */ +147 private String reportOutputDirectory; +148 +149 /** +150 * Get the value of reportOutputDirectory. +151 * +152 * @return the value of reportOutputDirectory +153 */ +154 public String getReportOutputDirectory() { +155 return reportOutputDirectory; +156 } +157 +158 /** +159 * Set the value of reportOutputDirectory. +160 * +161 * @param reportOutputDirectory new value of reportOutputDirectory +162 */ +163 public void setReportOutputDirectory(String reportOutputDirectory) { +164 this.reportOutputDirectory = reportOutputDirectory; +165 } +166 +167 /** +168 * Specifies if the build should be failed if a CVSS score above a specified +169 * level is identified. The default is 11 which means since the CVSS scores +170 * are 0-10, by default the build will never fail and the CVSS score is set +171 * to 11. The valid range for the fail build on CVSS is 0 to 11, where +172 * anything above 10 will not cause the build to fail. +173 */ +174 private float failBuildOnCVSS = 11; +175 +176 /** +177 * Get the value of failBuildOnCVSS. +178 * +179 * @return the value of failBuildOnCVSS +180 */ +181 public float getFailBuildOnCVSS() { +182 return failBuildOnCVSS; +183 } +184 +185 /** +186 * Set the value of failBuildOnCVSS. +187 * +188 * @param failBuildOnCVSS new value of failBuildOnCVSS +189 */ +190 public void setFailBuildOnCVSS(float failBuildOnCVSS) { +191 this.failBuildOnCVSS = failBuildOnCVSS; +192 } 193 194 /** -195 * Get the value of autoUpdate. -196 * -197 * @return the value of autoUpdate -198 */ -199 public boolean isAutoUpdate() { -200 return autoUpdate; -201 } -202 -203 /** -204 * Set the value of autoUpdate. -205 * -206 * @param autoUpdate new value of autoUpdate -207 */ -208 public void setAutoUpdate(boolean autoUpdate) { -209 this.autoUpdate = autoUpdate; -210 } -211 -212 /** -213 * flag indicating whether or not to generate a report of findings. -214 */ -215 private boolean generateReport = true; -216 -217 /** -218 * Get the value of generateReport. -219 * -220 * @return the value of generateReport -221 */ -222 public boolean isGenerateReport() { -223 return generateReport; -224 } -225 -226 /** -227 * Set the value of generateReport. -228 * -229 * @param generateReport new value of generateReport -230 */ -231 public void setGenerateReport(boolean generateReport) { -232 this.generateReport = generateReport; -233 } -234 -235 /** -236 * The report format to be generated (HTML, XML, VULN, ALL). This configuration option has no affect if using this within the -237 * Site plugin unless the externalReport is set to true. Default is HTML. -238 */ -239 private ReportGenerator.Format reportFormat = ReportGenerator.Format.HTML; +195 * Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not +196 * recommended that this be turned to false. Default is true. +197 */ +198 private boolean autoUpdate = true; +199 +200 /** +201 * Get the value of autoUpdate. +202 * +203 * @return the value of autoUpdate +204 */ +205 public boolean isAutoUpdate() { +206 return autoUpdate; +207 } +208 +209 /** +210 * Set the value of autoUpdate. +211 * +212 * @param autoUpdate new value of autoUpdate +213 */ +214 public void setAutoUpdate(boolean autoUpdate) { +215 this.autoUpdate = autoUpdate; +216 } +217 +218 /** +219 * flag indicating whether or not to generate a report of findings. +220 */ +221 private boolean generateReport = true; +222 +223 /** +224 * Get the value of generateReport. +225 * +226 * @return the value of generateReport +227 */ +228 public boolean isGenerateReport() { +229 return generateReport; +230 } +231 +232 /** +233 * Set the value of generateReport. +234 * +235 * @param generateReport new value of generateReport +236 */ +237 public void setGenerateReport(boolean generateReport) { +238 this.generateReport = generateReport; +239 } 240 241 /** -242 * Get the value of reportFormat. -243 * -244 * @return the value of reportFormat +242 * The report format to be generated (HTML, XML, VULN, ALL). This +243 * configuration option has no affect if using this within the Site plugin +244 * unless the externalReport is set to true. Default is HTML. 245 */ -246 public ReportGenerator.Format getReportFormat() { -247 return reportFormat; -248 } -249 -250 /** -251 * Set the value of reportFormat. -252 * -253 * @param reportFormat new value of reportFormat -254 */ -255 public void setReportFormat(ReportGenerator.Format reportFormat) { -256 this.reportFormat = reportFormat; -257 } -258 -259 /** -260 * The Proxy Server. +246 private ReportGenerator.Format reportFormat = ReportGenerator.Format.HTML; +247 +248 /** +249 * Get the value of reportFormat. +250 * +251 * @return the value of reportFormat +252 */ +253 public ReportGenerator.Format getReportFormat() { +254 return reportFormat; +255 } +256 +257 /** +258 * Set the value of reportFormat. +259 * +260 * @param reportFormat new value of reportFormat 261 */ -262 private String proxyServer; -263 -264 /** -265 * Get the value of proxyServer. -266 * -267 * @return the value of proxyServer +262 public void setReportFormat(ReportGenerator.Format reportFormat) { +263 this.reportFormat = reportFormat; +264 } +265 +266 /** +267 * The Proxy Server. 268 */ -269 public String getProxyServer() { -270 return proxyServer; -271 } -272 -273 /** -274 * Set the value of proxyServer. -275 * -276 * @param proxyServer new value of proxyServer -277 */ -278 public void setProxyServer(String proxyServer) { -279 this.proxyServer = proxyServer; -280 } -281 -282 /** -283 * Get the value of proxyServer. -284 * -285 * @return the value of proxyServer -286 * @deprecated use {@link org.owasp.dependencycheck.agent.DependencyCheckScanAgent#getProxyServer()} instead -287 */ -288 @Deprecated -289 public String getProxyUrl() { -290 return proxyServer; -291 } -292 -293 /** -294 * Set the value of proxyServer. -295 * -296 * @param proxyUrl new value of proxyServer -297 * @deprecated use {@link org.owasp.dependencycheck.agent.DependencyCheckScanAgent#setProxyServer(java.lang.String) -298 * } instead -299 */ -300 @Deprecated -301 public void setProxyUrl(String proxyUrl) { -302 this.proxyServer = proxyUrl; -303 } -304 -305 /** -306 * The Proxy Port. -307 */ -308 private String proxyPort; -309 -310 /** -311 * Get the value of proxyPort. -312 * -313 * @return the value of proxyPort -314 */ -315 public String getProxyPort() { -316 return proxyPort; -317 } +269 private String proxyServer; +270 +271 /** +272 * Get the value of proxyServer. +273 * +274 * @return the value of proxyServer +275 */ +276 public String getProxyServer() { +277 return proxyServer; +278 } +279 +280 /** +281 * Set the value of proxyServer. +282 * +283 * @param proxyServer new value of proxyServer +284 */ +285 public void setProxyServer(String proxyServer) { +286 this.proxyServer = proxyServer; +287 } +288 +289 /** +290 * Get the value of proxyServer. +291 * +292 * @return the value of proxyServer +293 * @deprecated use +294 * {@link org.owasp.dependencycheck.agent.DependencyCheckScanAgent#getProxyServer()} +295 * instead +296 */ +297 @Deprecated +298 public String getProxyUrl() { +299 return proxyServer; +300 } +301 +302 /** +303 * Set the value of proxyServer. +304 * +305 * @param proxyUrl new value of proxyServer +306 * @deprecated use {@link org.owasp.dependencycheck.agent.DependencyCheckScanAgent#setProxyServer(java.lang.String) +307 * } instead +308 */ +309 @Deprecated +310 public void setProxyUrl(String proxyUrl) { +311 this.proxyServer = proxyUrl; +312 } +313 +314 /** +315 * The Proxy Port. +316 */ +317 private String proxyPort; 318 319 /** -320 * Set the value of proxyPort. +320 * Get the value of proxyPort. 321 * -322 * @param proxyPort new value of proxyPort +322 * @return the value of proxyPort 323 */ -324 public void setProxyPort(String proxyPort) { -325 this.proxyPort = proxyPort; +324 public String getProxyPort() { +325 return proxyPort; 326 } 327 328 /** -329 * The Proxy username. -330 */ -331 private String proxyUsername; -332 -333 /** -334 * Get the value of proxyUsername. -335 * -336 * @return the value of proxyUsername -337 */ -338 public String getProxyUsername() { -339 return proxyUsername; -340 } +329 * Set the value of proxyPort. +330 * +331 * @param proxyPort new value of proxyPort +332 */ +333 public void setProxyPort(String proxyPort) { +334 this.proxyPort = proxyPort; +335 } +336 +337 /** +338 * The Proxy username. +339 */ +340 private String proxyUsername; 341 342 /** -343 * Set the value of proxyUsername. +343 * Get the value of proxyUsername. 344 * -345 * @param proxyUsername new value of proxyUsername +345 * @return the value of proxyUsername 346 */ -347 public void setProxyUsername(String proxyUsername) { -348 this.proxyUsername = proxyUsername; +347 public String getProxyUsername() { +348 return proxyUsername; 349 } 350 351 /** -352 * The Proxy password. -353 */ -354 private String proxyPassword; -355 -356 /** -357 * Get the value of proxyPassword. -358 * -359 * @return the value of proxyPassword -360 */ -361 public String getProxyPassword() { -362 return proxyPassword; -363 } +352 * Set the value of proxyUsername. +353 * +354 * @param proxyUsername new value of proxyUsername +355 */ +356 public void setProxyUsername(String proxyUsername) { +357 this.proxyUsername = proxyUsername; +358 } +359 +360 /** +361 * The Proxy password. +362 */ +363 private String proxyPassword; 364 365 /** -366 * Set the value of proxyPassword. +366 * Get the value of proxyPassword. 367 * -368 * @param proxyPassword new value of proxyPassword +368 * @return the value of proxyPassword 369 */ -370 public void setProxyPassword(String proxyPassword) { -371 this.proxyPassword = proxyPassword; +370 public String getProxyPassword() { +371 return proxyPassword; 372 } 373 374 /** -375 * The Connection Timeout. -376 */ -377 private String connectionTimeout; -378 -379 /** -380 * Get the value of connectionTimeout. -381 * -382 * @return the value of connectionTimeout -383 */ -384 public String getConnectionTimeout() { -385 return connectionTimeout; -386 } +375 * Set the value of proxyPassword. +376 * +377 * @param proxyPassword new value of proxyPassword +378 */ +379 public void setProxyPassword(String proxyPassword) { +380 this.proxyPassword = proxyPassword; +381 } +382 +383 /** +384 * The Connection Timeout. +385 */ +386 private String connectionTimeout; 387 388 /** -389 * Set the value of connectionTimeout. +389 * Get the value of connectionTimeout. 390 * -391 * @param connectionTimeout new value of connectionTimeout +391 * @return the value of connectionTimeout 392 */ -393 public void setConnectionTimeout(String connectionTimeout) { -394 this.connectionTimeout = connectionTimeout; +393 public String getConnectionTimeout() { +394 return connectionTimeout; 395 } 396 397 /** -398 * The file path used for verbose logging. -399 */ -400 private String logFile = null; -401 -402 /** -403 * Get the value of logFile. -404 * -405 * @return the value of logFile -406 */ -407 public String getLogFile() { -408 return logFile; -409 } +398 * Set the value of connectionTimeout. +399 * +400 * @param connectionTimeout new value of connectionTimeout +401 */ +402 public void setConnectionTimeout(String connectionTimeout) { +403 this.connectionTimeout = connectionTimeout; +404 } +405 +406 /** +407 * The file path used for verbose logging. +408 */ +409 private String logFile = null; 410 411 /** -412 * Set the value of logFile. +412 * Get the value of logFile. 413 * -414 * @param logFile new value of logFile +414 * @return the value of logFile 415 */ -416 public void setLogFile(String logFile) { -417 this.logFile = logFile; +416 public String getLogFile() { +417 return logFile; 418 } 419 420 /** -421 * The path to the suppression file. -422 */ -423 private String suppressionFile; -424 -425 /** -426 * Get the value of suppressionFile. -427 * -428 * @return the value of suppressionFile -429 */ -430 public String getSuppressionFile() { -431 return suppressionFile; -432 } +421 * Set the value of logFile. +422 * +423 * @param logFile new value of logFile +424 */ +425 public void setLogFile(String logFile) { +426 this.logFile = logFile; +427 } +428 +429 /** +430 * The path to the suppression file. +431 */ +432 private String suppressionFile; 433 434 /** -435 * Set the value of suppressionFile. +435 * Get the value of suppressionFile. 436 * -437 * @param suppressionFile new value of suppressionFile +437 * @return the value of suppressionFile 438 */ -439 public void setSuppressionFile(String suppressionFile) { -440 this.suppressionFile = suppressionFile; +439 public String getSuppressionFile() { +440 return suppressionFile; 441 } 442 443 /** -444 * flag indicating whether or not to show a summary of findings. -445 */ -446 private boolean showSummary = true; -447 -448 /** -449 * Get the value of showSummary. -450 * -451 * @return the value of showSummary -452 */ -453 public boolean isShowSummary() { -454 return showSummary; -455 } +444 * Set the value of suppressionFile. +445 * +446 * @param suppressionFile new value of suppressionFile +447 */ +448 public void setSuppressionFile(String suppressionFile) { +449 this.suppressionFile = suppressionFile; +450 } +451 +452 /** +453 * flag indicating whether or not to show a summary of findings. +454 */ +455 private boolean showSummary = true; 456 457 /** -458 * Set the value of showSummary. +458 * Get the value of showSummary. 459 * -460 * @param showSummary new value of showSummary +460 * @return the value of showSummary 461 */ -462 public void setShowSummary(boolean showSummary) { -463 this.showSummary = showSummary; +462 public boolean isShowSummary() { +463 return showSummary; 464 } 465 466 /** -467 * Whether or not the Maven Central analyzer is enabled. -468 */ -469 private boolean centralAnalyzerEnabled = true; -470 -471 /** -472 * Get the value of centralAnalyzerEnabled. -473 * -474 * @return the value of centralAnalyzerEnabled -475 */ -476 public boolean isCentralAnalyzerEnabled() { -477 return centralAnalyzerEnabled; -478 } +467 * Set the value of showSummary. +468 * +469 * @param showSummary new value of showSummary +470 */ +471 public void setShowSummary(boolean showSummary) { +472 this.showSummary = showSummary; +473 } +474 +475 /** +476 * Whether or not the Maven Central analyzer is enabled. +477 */ +478 private boolean centralAnalyzerEnabled = true; 479 480 /** -481 * Set the value of centralAnalyzerEnabled. +481 * Get the value of centralAnalyzerEnabled. 482 * -483 * @param centralAnalyzerEnabled new value of centralAnalyzerEnabled +483 * @return the value of centralAnalyzerEnabled 484 */ -485 public void setCentralAnalyzerEnabled(boolean centralAnalyzerEnabled) { -486 this.centralAnalyzerEnabled = centralAnalyzerEnabled; +485 public boolean isCentralAnalyzerEnabled() { +486 return centralAnalyzerEnabled; 487 } 488 489 /** -490 * The URL of Maven Central. -491 */ -492 private String centralUrl; -493 -494 /** -495 * Get the value of centralUrl. -496 * -497 * @return the value of centralUrl -498 */ -499 public String getCentralUrl() { -500 return centralUrl; -501 } +490 * Set the value of centralAnalyzerEnabled. +491 * +492 * @param centralAnalyzerEnabled new value of centralAnalyzerEnabled +493 */ +494 public void setCentralAnalyzerEnabled(boolean centralAnalyzerEnabled) { +495 this.centralAnalyzerEnabled = centralAnalyzerEnabled; +496 } +497 +498 /** +499 * The URL of Maven Central. +500 */ +501 private String centralUrl; 502 503 /** -504 * Set the value of centralUrl. +504 * Get the value of centralUrl. 505 * -506 * @param centralUrl new value of centralUrl +506 * @return the value of centralUrl 507 */ -508 public void setCentralUrl(String centralUrl) { -509 this.centralUrl = centralUrl; +508 public String getCentralUrl() { +509 return centralUrl; 510 } 511 512 /** -513 * Whether or not the nexus analyzer is enabled. -514 */ -515 private boolean nexusAnalyzerEnabled = true; -516 -517 /** -518 * Get the value of nexusAnalyzerEnabled. -519 * -520 * @return the value of nexusAnalyzerEnabled -521 */ -522 public boolean isNexusAnalyzerEnabled() { -523 return nexusAnalyzerEnabled; -524 } +513 * Set the value of centralUrl. +514 * +515 * @param centralUrl new value of centralUrl +516 */ +517 public void setCentralUrl(String centralUrl) { +518 this.centralUrl = centralUrl; +519 } +520 +521 /** +522 * Whether or not the nexus analyzer is enabled. +523 */ +524 private boolean nexusAnalyzerEnabled = true; 525 526 /** -527 * Set the value of nexusAnalyzerEnabled. +527 * Get the value of nexusAnalyzerEnabled. 528 * -529 * @param nexusAnalyzerEnabled new value of nexusAnalyzerEnabled +529 * @return the value of nexusAnalyzerEnabled 530 */ -531 public void setNexusAnalyzerEnabled(boolean nexusAnalyzerEnabled) { -532 this.nexusAnalyzerEnabled = nexusAnalyzerEnabled; +531 public boolean isNexusAnalyzerEnabled() { +532 return nexusAnalyzerEnabled; 533 } 534 535 /** -536 * The URL of the Nexus server. -537 */ -538 private String nexusUrl; -539 -540 /** -541 * Get the value of nexusUrl. -542 * -543 * @return the value of nexusUrl -544 */ -545 public String getNexusUrl() { -546 return nexusUrl; -547 } +536 * Set the value of nexusAnalyzerEnabled. +537 * +538 * @param nexusAnalyzerEnabled new value of nexusAnalyzerEnabled +539 */ +540 public void setNexusAnalyzerEnabled(boolean nexusAnalyzerEnabled) { +541 this.nexusAnalyzerEnabled = nexusAnalyzerEnabled; +542 } +543 +544 /** +545 * The URL of the Nexus server. +546 */ +547 private String nexusUrl; 548 549 /** -550 * Set the value of nexusUrl. +550 * Get the value of nexusUrl. 551 * -552 * @param nexusUrl new value of nexusUrl +552 * @return the value of nexusUrl 553 */ -554 public void setNexusUrl(String nexusUrl) { -555 this.nexusUrl = nexusUrl; +554 public String getNexusUrl() { +555 return nexusUrl; 556 } 557 558 /** -559 * Whether or not the defined proxy should be used when connecting to Nexus. -560 */ -561 private boolean nexusUsesProxy = true; -562 -563 /** -564 * Get the value of nexusUsesProxy. -565 * -566 * @return the value of nexusUsesProxy -567 */ -568 public boolean isNexusUsesProxy() { -569 return nexusUsesProxy; -570 } +559 * Set the value of nexusUrl. +560 * +561 * @param nexusUrl new value of nexusUrl +562 */ +563 public void setNexusUrl(String nexusUrl) { +564 this.nexusUrl = nexusUrl; +565 } +566 +567 /** +568 * Whether or not the defined proxy should be used when connecting to Nexus. +569 */ +570 private boolean nexusUsesProxy = true; 571 572 /** -573 * Set the value of nexusUsesProxy. +573 * Get the value of nexusUsesProxy. 574 * -575 * @param nexusUsesProxy new value of nexusUsesProxy +575 * @return the value of nexusUsesProxy 576 */ -577 public void setNexusUsesProxy(boolean nexusUsesProxy) { -578 this.nexusUsesProxy = nexusUsesProxy; +577 public boolean isNexusUsesProxy() { +578 return nexusUsesProxy; 579 } 580 581 /** -582 * The database driver name; such as org.h2.Driver. -583 */ -584 private String databaseDriverName; -585 -586 /** -587 * Get the value of databaseDriverName. -588 * -589 * @return the value of databaseDriverName -590 */ -591 public String getDatabaseDriverName() { -592 return databaseDriverName; -593 } +582 * Set the value of nexusUsesProxy. +583 * +584 * @param nexusUsesProxy new value of nexusUsesProxy +585 */ +586 public void setNexusUsesProxy(boolean nexusUsesProxy) { +587 this.nexusUsesProxy = nexusUsesProxy; +588 } +589 +590 /** +591 * The database driver name; such as org.h2.Driver. +592 */ +593 private String databaseDriverName; 594 595 /** -596 * Set the value of databaseDriverName. +596 * Get the value of databaseDriverName. 597 * -598 * @param databaseDriverName new value of databaseDriverName +598 * @return the value of databaseDriverName 599 */ -600 public void setDatabaseDriverName(String databaseDriverName) { -601 this.databaseDriverName = databaseDriverName; +600 public String getDatabaseDriverName() { +601 return databaseDriverName; 602 } 603 604 /** -605 * The path to the database driver JAR file if it is not on the class path. -606 */ -607 private String databaseDriverPath; -608 -609 /** -610 * Get the value of databaseDriverPath. -611 * -612 * @return the value of databaseDriverPath -613 */ -614 public String getDatabaseDriverPath() { -615 return databaseDriverPath; -616 } +605 * Set the value of databaseDriverName. +606 * +607 * @param databaseDriverName new value of databaseDriverName +608 */ +609 public void setDatabaseDriverName(String databaseDriverName) { +610 this.databaseDriverName = databaseDriverName; +611 } +612 +613 /** +614 * The path to the database driver JAR file if it is not on the class path. +615 */ +616 private String databaseDriverPath; 617 618 /** -619 * Set the value of databaseDriverPath. +619 * Get the value of databaseDriverPath. 620 * -621 * @param databaseDriverPath new value of databaseDriverPath +621 * @return the value of databaseDriverPath 622 */ -623 public void setDatabaseDriverPath(String databaseDriverPath) { -624 this.databaseDriverPath = databaseDriverPath; +623 public String getDatabaseDriverPath() { +624 return databaseDriverPath; 625 } 626 627 /** -628 * The database connection string. -629 */ -630 private String connectionString; -631 -632 /** -633 * Get the value of connectionString. -634 * -635 * @return the value of connectionString -636 */ -637 public String getConnectionString() { -638 return connectionString; -639 } +628 * Set the value of databaseDriverPath. +629 * +630 * @param databaseDriverPath new value of databaseDriverPath +631 */ +632 public void setDatabaseDriverPath(String databaseDriverPath) { +633 this.databaseDriverPath = databaseDriverPath; +634 } +635 +636 /** +637 * The database connection string. +638 */ +639 private String connectionString; 640 641 /** -642 * Set the value of connectionString. +642 * Get the value of connectionString. 643 * -644 * @param connectionString new value of connectionString +644 * @return the value of connectionString 645 */ -646 public void setConnectionString(String connectionString) { -647 this.connectionString = connectionString; +646 public String getConnectionString() { +647 return connectionString; 648 } 649 650 /** -651 * The user name for connecting to the database. -652 */ -653 private String databaseUser; -654 -655 /** -656 * Get the value of databaseUser. -657 * -658 * @return the value of databaseUser -659 */ -660 public String getDatabaseUser() { -661 return databaseUser; -662 } +651 * Set the value of connectionString. +652 * +653 * @param connectionString new value of connectionString +654 */ +655 public void setConnectionString(String connectionString) { +656 this.connectionString = connectionString; +657 } +658 +659 /** +660 * The user name for connecting to the database. +661 */ +662 private String databaseUser; 663 664 /** -665 * Set the value of databaseUser. +665 * Get the value of databaseUser. 666 * -667 * @param databaseUser new value of databaseUser +667 * @return the value of databaseUser 668 */ -669 public void setDatabaseUser(String databaseUser) { -670 this.databaseUser = databaseUser; +669 public String getDatabaseUser() { +670 return databaseUser; 671 } 672 673 /** -674 * The password to use when connecting to the database. -675 */ -676 private String databasePassword; -677 -678 /** -679 * Get the value of databasePassword. -680 * -681 * @return the value of databasePassword -682 */ -683 public String getDatabasePassword() { -684 return databasePassword; -685 } +674 * Set the value of databaseUser. +675 * +676 * @param databaseUser new value of databaseUser +677 */ +678 public void setDatabaseUser(String databaseUser) { +679 this.databaseUser = databaseUser; +680 } +681 +682 /** +683 * The password to use when connecting to the database. +684 */ +685 private String databasePassword; 686 687 /** -688 * Set the value of databasePassword. +688 * Get the value of databasePassword. 689 * -690 * @param databasePassword new value of databasePassword +690 * @return the value of databasePassword 691 */ -692 public void setDatabasePassword(String databasePassword) { -693 this.databasePassword = databasePassword; +692 public String getDatabasePassword() { +693 return databasePassword; 694 } 695 696 /** -697 * Additional ZIP File extensions to add analyze. This should be a comma-separated list of file extensions to treat like ZIP -698 * files. -699 */ -700 private String zipExtensions; -701 -702 /** -703 * Get the value of zipExtensions. -704 * -705 * @return the value of zipExtensions -706 */ -707 public String getZipExtensions() { -708 return zipExtensions; -709 } +697 * Set the value of databasePassword. +698 * +699 * @param databasePassword new value of databasePassword +700 */ +701 public void setDatabasePassword(String databasePassword) { +702 this.databasePassword = databasePassword; +703 } +704 +705 /** +706 * Additional ZIP File extensions to add analyze. This should be a +707 * comma-separated list of file extensions to treat like ZIP files. +708 */ +709 private String zipExtensions; 710 711 /** -712 * Set the value of zipExtensions. +712 * Get the value of zipExtensions. 713 * -714 * @param zipExtensions new value of zipExtensions +714 * @return the value of zipExtensions 715 */ -716 public void setZipExtensions(String zipExtensions) { -717 this.zipExtensions = zipExtensions; +716 public String getZipExtensions() { +717 return zipExtensions; 718 } 719 720 /** -721 * The url for the modified NVD CVE (1.2 schema). -722 */ -723 private String cveUrl12Modified; -724 -725 /** -726 * Get the value of cveUrl12Modified. -727 * -728 * @return the value of cveUrl12Modified -729 */ -730 public String getCveUrl12Modified() { -731 return cveUrl12Modified; -732 } +721 * Set the value of zipExtensions. +722 * +723 * @param zipExtensions new value of zipExtensions +724 */ +725 public void setZipExtensions(String zipExtensions) { +726 this.zipExtensions = zipExtensions; +727 } +728 +729 /** +730 * The url for the modified NVD CVE (1.2 schema). +731 */ +732 private String cveUrl12Modified; 733 734 /** -735 * Set the value of cveUrl12Modified. +735 * Get the value of cveUrl12Modified. 736 * -737 * @param cveUrl12Modified new value of cveUrl12Modified +737 * @return the value of cveUrl12Modified 738 */ -739 public void setCveUrl12Modified(String cveUrl12Modified) { -740 this.cveUrl12Modified = cveUrl12Modified; +739 public String getCveUrl12Modified() { +740 return cveUrl12Modified; 741 } 742 743 /** -744 * The url for the modified NVD CVE (2.0 schema). -745 */ -746 private String cveUrl20Modified; -747 -748 /** -749 * Get the value of cveUrl20Modified. -750 * -751 * @return the value of cveUrl20Modified -752 */ -753 public String getCveUrl20Modified() { -754 return cveUrl20Modified; -755 } +744 * Set the value of cveUrl12Modified. +745 * +746 * @param cveUrl12Modified new value of cveUrl12Modified +747 */ +748 public void setCveUrl12Modified(String cveUrl12Modified) { +749 this.cveUrl12Modified = cveUrl12Modified; +750 } +751 +752 /** +753 * The url for the modified NVD CVE (2.0 schema). +754 */ +755 private String cveUrl20Modified; 756 757 /** -758 * Set the value of cveUrl20Modified. +758 * Get the value of cveUrl20Modified. 759 * -760 * @param cveUrl20Modified new value of cveUrl20Modified +760 * @return the value of cveUrl20Modified 761 */ -762 public void setCveUrl20Modified(String cveUrl20Modified) { -763 this.cveUrl20Modified = cveUrl20Modified; +762 public String getCveUrl20Modified() { +763 return cveUrl20Modified; 764 } 765 766 /** -767 * Base Data Mirror URL for CVE 1.2. -768 */ -769 private String cveUrl12Base; -770 -771 /** -772 * Get the value of cveUrl12Base. -773 * -774 * @return the value of cveUrl12Base -775 */ -776 public String getCveUrl12Base() { -777 return cveUrl12Base; -778 } +767 * Set the value of cveUrl20Modified. +768 * +769 * @param cveUrl20Modified new value of cveUrl20Modified +770 */ +771 public void setCveUrl20Modified(String cveUrl20Modified) { +772 this.cveUrl20Modified = cveUrl20Modified; +773 } +774 +775 /** +776 * Base Data Mirror URL for CVE 1.2. +777 */ +778 private String cveUrl12Base; 779 780 /** -781 * Set the value of cveUrl12Base. +781 * Get the value of cveUrl12Base. 782 * -783 * @param cveUrl12Base new value of cveUrl12Base +783 * @return the value of cveUrl12Base 784 */ -785 public void setCveUrl12Base(String cveUrl12Base) { -786 this.cveUrl12Base = cveUrl12Base; +785 public String getCveUrl12Base() { +786 return cveUrl12Base; 787 } 788 789 /** -790 * Data Mirror URL for CVE 2.0. -791 */ -792 private String cveUrl20Base; -793 -794 /** -795 * Get the value of cveUrl20Base. -796 * -797 * @return the value of cveUrl20Base -798 */ -799 public String getCveUrl20Base() { -800 return cveUrl20Base; -801 } +790 * Set the value of cveUrl12Base. +791 * +792 * @param cveUrl12Base new value of cveUrl12Base +793 */ +794 public void setCveUrl12Base(String cveUrl12Base) { +795 this.cveUrl12Base = cveUrl12Base; +796 } +797 +798 /** +799 * Data Mirror URL for CVE 2.0. +800 */ +801 private String cveUrl20Base; 802 803 /** -804 * Set the value of cveUrl20Base. +804 * Get the value of cveUrl20Base. 805 * -806 * @param cveUrl20Base new value of cveUrl20Base +806 * @return the value of cveUrl20Base 807 */ -808 public void setCveUrl20Base(String cveUrl20Base) { -809 this.cveUrl20Base = cveUrl20Base; +808 public String getCveUrl20Base() { +809 return cveUrl20Base; 810 } 811 812 /** -813 * The path to Mono for .NET assembly analysis on non-windows systems. -814 */ -815 private String pathToMono; -816 -817 /** -818 * Get the value of pathToMono. -819 * -820 * @return the value of pathToMono -821 */ -822 public String getPathToMono() { -823 return pathToMono; -824 } +813 * Set the value of cveUrl20Base. +814 * +815 * @param cveUrl20Base new value of cveUrl20Base +816 */ +817 public void setCveUrl20Base(String cveUrl20Base) { +818 this.cveUrl20Base = cveUrl20Base; +819 } +820 +821 /** +822 * The path to Mono for .NET assembly analysis on non-windows systems. +823 */ +824 private String pathToMono; 825 826 /** -827 * Set the value of pathToMono. +827 * Get the value of pathToMono. 828 * -829 * @param pathToMono new value of pathToMono +829 * @return the value of pathToMono 830 */ -831 public void setPathToMono(String pathToMono) { -832 this.pathToMono = pathToMono; +831 public String getPathToMono() { +832 return pathToMono; 833 } 834 835 /** -836 * Executes the Dependency-Check on the dependent libraries. +836 * Set the value of pathToMono. 837 * -838 * @return the Engine used to scan the dependencies. -839 * @throws org.owasp.dependencycheck.data.nvdcve.DatabaseException thrown if there is an exception connecting to the database -840 */ -841 private Engine executeDependencyCheck() throws DatabaseException { -842 populateSettings(); -843 final Engine engine = new Engine(); -844 engine.setDependencies(this.dependencies); -845 engine.analyzeDependencies(); -846 return engine; -847 } -848 -849 /** -850 * Generates the reports for a given dependency-check engine. -851 * -852 * @param engine a dependency-check engine -853 * @param outDirectory the directory to write the reports to -854 */ -855 private void generateExternalReports(Engine engine, File outDirectory) { -856 DatabaseProperties prop = null; -857 CveDB cve = null; -858 try { -859 cve = new CveDB(); -860 cve.open(); -861 prop = cve.getDatabaseProperties(); -862 } catch (DatabaseException ex) { -863 LOGGER.debug("Unable to retrieve DB Properties", ex); -864 } finally { -865 if (cve != null) { -866 cve.close(); -867 } -868 } -869 final ReportGenerator r = new ReportGenerator(this.applicationName, engine.getDependencies(), engine.getAnalyzers(), prop); -870 try { -871 r.generateReports(outDirectory.getCanonicalPath(), this.reportFormat.name()); -872 } catch (IOException ex) { -873 LOGGER.error( -874 "Unexpected exception occurred during analysis; please see the verbose error log for more details."); -875 LOGGER.debug("", ex); -876 } catch (Throwable ex) { -877 LOGGER.error( -878 "Unexpected exception occurred during analysis; please see the verbose error log for more details."); -879 LOGGER.debug("", ex); -880 } -881 } -882 -883 /** -884 * Takes the properties supplied and updates the dependency-check settings. Additionally, this sets the system properties -885 * required to change the proxy server, port, and connection timeout. -886 */ -887 private void populateSettings() { -888 Settings.initialize(); -889 if (dataDirectory != null) { -890 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory); -891 } else { -892 final File jarPath = new File(DependencyCheckScanAgent.class.getProtectionDomain().getCodeSource().getLocation().getPath()); -893 final File base = jarPath.getParentFile(); -894 final String sub = Settings.getString(Settings.KEYS.DATA_DIRECTORY); -895 final File dataDir = new File(base, sub); -896 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath()); -897 } -898 -899 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate); -900 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_SERVER, proxyServer); -901 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PORT, proxyPort); -902 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_USERNAME, proxyUsername); -903 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PASSWORD, proxyPassword); -904 Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout); -905 Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile); -906 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, centralAnalyzerEnabled); -907 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_CENTRAL_URL, centralUrl); -908 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled); -909 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl); -910 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy); -911 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName); -912 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath); -913 Settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString); -914 Settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser); -915 Settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword); -916 Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions); -917 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_12_URL, cveUrl12Modified); -918 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_20_URL, cveUrl20Modified); -919 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_1_2, cveUrl12Base); -920 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_2_0, cveUrl20Base); -921 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono); -922 } -923 -924 /** -925 * Executes the dependency-check and generates the report. -926 * -927 * @return a reference to the engine used to perform the scan. -928 * @throws org.owasp.dependencycheck.exception.ScanAgentException thrown if there is an exception executing the scan. -929 */ -930 public Engine execute() throws ScanAgentException { -931 Engine engine = null; -932 try { -933 engine = executeDependencyCheck(); -934 if (this.generateReport) { -935 generateExternalReports(engine, new File(this.reportOutputDirectory)); -936 } -937 if (this.showSummary) { -938 showSummary(engine.getDependencies()); -939 } -940 if (this.failBuildOnCVSS <= 10) { -941 checkForFailure(engine.getDependencies()); -942 } -943 } catch (DatabaseException ex) { -944 LOGGER.error( -945 "Unable to connect to the dependency-check database; analysis has stopped"); -946 LOGGER.debug("", ex); -947 } finally { -948 Settings.cleanup(true); -949 if (engine != null) { -950 engine.cleanup(); -951 } -952 } -953 return engine; -954 } -955 -956 /** -957 * Checks to see if a vulnerability has been identified with a CVSS score that is above the threshold set in the -958 * configuration. -959 * -960 * @param dependencies the list of dependency objects -961 * @throws org.owasp.dependencycheck.exception.ScanAgentException thrown if there is an exception executing the scan. -962 */ -963 private void checkForFailure(List<Dependency> dependencies) throws ScanAgentException { -964 final StringBuilder ids = new StringBuilder(); -965 for (Dependency d : dependencies) { -966 boolean addName = true; -967 for (Vulnerability v : d.getVulnerabilities()) { -968 if (v.getCvssScore() >= failBuildOnCVSS) { -969 if (addName) { -970 addName = false; -971 ids.append(NEW_LINE).append(d.getFileName()).append(": "); -972 ids.append(v.getName()); -973 } else { -974 ids.append(", ").append(v.getName()); -975 } -976 } -977 } -978 } -979 if (ids.length() > 0) { -980 final String msg = String.format("%n%nDependency-Check Failure:%n" -981 + "One or more dependencies were identified with vulnerabilities that have a CVSS score greater then '%.1f': %s%n" -982 + "See the dependency-check report for more details.%n%n", failBuildOnCVSS, ids.toString()); -983 -984 throw new ScanAgentException(msg); -985 } -986 } -987 -988 /** -989 * Generates a warning message listing a summary of dependencies and their associated CPE and CVE entries. -990 * -991 * @param dependencies a list of dependency objects -992 */ -993 private void showSummary(List<Dependency> dependencies) { -994 final StringBuilder summary = new StringBuilder(); -995 for (Dependency d : dependencies) { -996 boolean firstEntry = true; -997 final StringBuilder ids = new StringBuilder(); -998 for (Vulnerability v : d.getVulnerabilities()) { -999 if (firstEntry) { -1000 firstEntry = false; -1001 } else { -1002 ids.append(", "); -1003 } -1004 ids.append(v.getName()); -1005 } -1006 if (ids.length() > 0) { -1007 summary.append(d.getFileName()).append(" ("); -1008 firstEntry = true; -1009 for (Identifier id : d.getIdentifiers()) { -1010 if (firstEntry) { -1011 firstEntry = false; -1012 } else { -1013 summary.append(", "); -1014 } -1015 summary.append(id.getValue()); -1016 } -1017 summary.append(") : ").append(ids).append(NEW_LINE); -1018 } -1019 } -1020 if (summary.length() > 0) { -1021 LOGGER.warn("\n\nOne or more dependencies were identified with known vulnerabilities:\n\n{}\n\n" -1022 + "See the dependency-check report for more details.\n\n", -1023 summary.toString()); -1024 } -1025 } -1026 -1027 } +838 * @param pathToMono new value of pathToMono +839 */ +840 public void setPathToMono(String pathToMono) { +841 this.pathToMono = pathToMono; +842 } +843 +844 /** +845 * Executes the Dependency-Check on the dependent libraries. +846 * +847 * @return the Engine used to scan the dependencies. +848 * @throws ExceptionCollection a collection of one or more exceptions that +849 * occurred during analysis. +850 */ +851 private Engine executeDependencyCheck() throws ExceptionCollection { +852 populateSettings(); +853 final Engine engine; +854 try { +855 engine = new Engine(); +856 } catch (DatabaseException ex) { +857 throw new ExceptionCollection(ex, true); +858 } +859 engine.setDependencies(this.dependencies); +860 engine.analyzeDependencies(); +861 return engine; +862 } +863 +864 /** +865 * Generates the reports for a given dependency-check engine. +866 * +867 * @param engine a dependency-check engine +868 * @param outDirectory the directory to write the reports to +869 */ +870 private void generateExternalReports(Engine engine, File outDirectory) { +871 DatabaseProperties prop = null; +872 CveDB cve = null; +873 try { +874 cve = new CveDB(); +875 cve.open(); +876 prop = cve.getDatabaseProperties(); +877 } catch (DatabaseException ex) { +878 LOGGER.debug("Unable to retrieve DB Properties", ex); +879 } finally { +880 if (cve != null) { +881 cve.close(); +882 } +883 } +884 final ReportGenerator r = new ReportGenerator(this.applicationName, engine.getDependencies(), engine.getAnalyzers(), prop); +885 try { +886 r.generateReports(outDirectory.getCanonicalPath(), this.reportFormat.name()); +887 } catch (IOException ex) { +888 LOGGER.error( +889 "Unexpected exception occurred during analysis; please see the verbose error log for more details."); +890 LOGGER.debug("", ex); +891 } catch (Throwable ex) { +892 LOGGER.error( +893 "Unexpected exception occurred during analysis; please see the verbose error log for more details."); +894 LOGGER.debug("", ex); +895 } +896 } +897 +898 /** +899 * Takes the properties supplied and updates the dependency-check settings. +900 * Additionally, this sets the system properties required to change the +901 * proxy server, port, and connection timeout. +902 */ +903 private void populateSettings() { +904 Settings.initialize(); +905 if (dataDirectory != null) { +906 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory); +907 } else { +908 final File jarPath = new File(DependencyCheckScanAgent.class.getProtectionDomain().getCodeSource().getLocation().getPath()); +909 final File base = jarPath.getParentFile(); +910 final String sub = Settings.getString(Settings.KEYS.DATA_DIRECTORY); +911 final File dataDir = new File(base, sub); +912 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath()); +913 } +914 +915 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate); +916 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_SERVER, proxyServer); +917 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PORT, proxyPort); +918 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_USERNAME, proxyUsername); +919 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PASSWORD, proxyPassword); +920 Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout); +921 Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile); +922 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, centralAnalyzerEnabled); +923 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_CENTRAL_URL, centralUrl); +924 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled); +925 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl); +926 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy); +927 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName); +928 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath); +929 Settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString); +930 Settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser); +931 Settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword); +932 Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions); +933 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_12_URL, cveUrl12Modified); +934 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_20_URL, cveUrl20Modified); +935 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_1_2, cveUrl12Base); +936 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_2_0, cveUrl20Base); +937 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono); +938 } +939 +940 /** +941 * Executes the dependency-check and generates the report. +942 * +943 * @return a reference to the engine used to perform the scan. +944 * @throws org.owasp.dependencycheck.exception.ScanAgentException thrown if +945 * there is an exception executing the scan. +946 */ +947 public Engine execute() throws ScanAgentException { +948 Engine engine = null; +949 try { +950 engine = executeDependencyCheck(); +951 if (this.generateReport) { +952 generateExternalReports(engine, new File(this.reportOutputDirectory)); +953 } +954 if (this.showSummary) { +955 showSummary(engine.getDependencies()); +956 } +957 if (this.failBuildOnCVSS <= 10) { +958 checkForFailure(engine.getDependencies()); +959 } +960 } catch (ExceptionCollection ex) { +961 if (ex.isFatal()) { +962 LOGGER.error("A fatal exception occurred during analysis; analysis has stopped. Please see the debug log for more details."); +963 LOGGER.debug("", ex); +964 } +965 throw new ScanAgentException("One or more exceptions occurred during analysis; please see the debug log for more details.", ex); +966 } finally { +967 Settings.cleanup(true); +968 if (engine != null) { +969 engine.cleanup(); +970 } +971 } +972 return engine; +973 } +974 +975 /** +976 * Checks to see if a vulnerability has been identified with a CVSS score +977 * that is above the threshold set in the configuration. +978 * +979 * @param dependencies the list of dependency objects +980 * @throws org.owasp.dependencycheck.exception.ScanAgentException thrown if +981 * there is an exception executing the scan. +982 */ +983 private void checkForFailure(List<Dependency> dependencies) throws ScanAgentException { +984 final StringBuilder ids = new StringBuilder(); +985 for (Dependency d : dependencies) { +986 boolean addName = true; +987 for (Vulnerability v : d.getVulnerabilities()) { +988 if (v.getCvssScore() >= failBuildOnCVSS) { +989 if (addName) { +990 addName = false; +991 ids.append(NEW_LINE).append(d.getFileName()).append(": "); +992 ids.append(v.getName()); +993 } else { +994 ids.append(", ").append(v.getName()); +995 } +996 } +997 } +998 } +999 if (ids.length() > 0) { +1000 final String msg = String.format("%n%nDependency-Check Failure:%n" +1001 + "One or more dependencies were identified with vulnerabilities that have a CVSS score greater then '%.1f': %s%n" +1002 + "See the dependency-check report for more details.%n%n", failBuildOnCVSS, ids.toString()); +1003 +1004 throw new ScanAgentException(msg); +1005 } +1006 } +1007 +1008 /** +1009 * Generates a warning message listing a summary of dependencies and their +1010 * associated CPE and CVE entries. +1011 * +1012 * @param dependencies a list of dependency objects +1013 */ +1014 private void showSummary(List<Dependency> dependencies) { +1015 final StringBuilder summary = new StringBuilder(); +1016 for (Dependency d : dependencies) { +1017 boolean firstEntry = true; +1018 final StringBuilder ids = new StringBuilder(); +1019 for (Vulnerability v : d.getVulnerabilities()) { +1020 if (firstEntry) { +1021 firstEntry = false; +1022 } else { +1023 ids.append(", "); +1024 } +1025 ids.append(v.getName()); +1026 } +1027 if (ids.length() > 0) { +1028 summary.append(d.getFileName()).append(" ("); +1029 firstEntry = true; +1030 for (Identifier id : d.getIdentifiers()) { +1031 if (firstEntry) { +1032 firstEntry = false; +1033 } else { +1034 summary.append(", "); +1035 } +1036 summary.append(id.getValue()); +1037 } +1038 summary.append(") : ").append(ids).append(NEW_LINE); +1039 } +1040 } +1041 if (summary.length() > 0) { +1042 LOGGER.warn("\n\nOne or more dependencies were identified with known vulnerabilities:\n\n{}\n\n" +1043 + "See the dependency-check report for more details.\n\n", +1044 summary.toString()); +1045 } +1046 } +1047 +1048 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/agent/package-frame.html b/dependency-check-core/xref/org/owasp/dependencycheck/agent/package-frame.html index 8a6447bc9..84cb20b59 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/agent/package-frame.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/agent/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.agent + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.agent diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/agent/package-summary.html b/dependency-check-core/xref/org/owasp/dependencycheck/agent/package-summary.html index 8084e6d6e..054104309 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/agent/package-summary.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/agent/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.agent + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.agent diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AbstractAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AbstractAnalyzer.html index 076b5f721..a7a1237ad 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AbstractAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AbstractAnalyzer.html @@ -25,32 +25,36 @@ 17 */ 18 package org.owasp.dependencycheck.analyzer; 19 -20 /** -21 * -22 * @author Jeremy Long -23 */ -24 public abstract class AbstractAnalyzer implements Analyzer { -25 -26 /** -27 * The initialize method does nothing for this Analyzer. -28 * -29 * @throws Exception thrown if there is an exception -30 */ -31 @Override -32 public void initialize() throws Exception { -33 //do nothing -34 } -35 -36 /** -37 * The close method does nothing for this Analyzer. -38 * -39 * @throws Exception thrown if there is an exception -40 */ -41 @Override -42 public void close() throws Exception { -43 //do nothing -44 } -45 } +20 import org.owasp.dependencycheck.exception.InitializationException; +21 +22 /** +23 * Base class for analyzers to avoid code duplication of initialize and close +24 * as most analyzers do not need these methods. +25 * +26 * @author Jeremy Long +27 */ +28 public abstract class AbstractAnalyzer implements Analyzer { +29 +30 /** +31 * The initialize method does nothing for this Analyzer. +32 * +33 * @throws InitializationException thrown if there is an exception +34 */ +35 @Override +36 public void initialize() throws InitializationException { +37 //do nothing +38 } +39 +40 /** +41 * The close method does nothing for this Analyzer. +42 * +43 * @throws Exception thrown if there is an exception +44 */ +45 @Override +46 public void close() throws Exception { +47 //do nothing +48 } +49 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AbstractFileTypeAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AbstractFileTypeAnalyzer.html index 2c2eaceef..46135995f 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AbstractFileTypeAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AbstractFileTypeAnalyzer.html @@ -38,195 +38,206 @@ 30 import java.util.Collections; 31 import java.util.HashSet; 32 import java.util.Set; -33 -34 /** -35 * The base FileTypeAnalyzer that all analyzers that have specific file types they analyze should extend. -36 * -37 * @author Jeremy Long -38 */ -39 public abstract class AbstractFileTypeAnalyzer extends AbstractAnalyzer implements FileTypeAnalyzer { -40 -41 //<editor-fold defaultstate="collapsed" desc="Constructor"> -42 /** -43 * Base constructor that all children must call. This checks the configuration to determine if the analyzer is enabled. -44 */ -45 public AbstractFileTypeAnalyzer() { -46 reset(); -47 } -48 //</editor-fold> -49 -50 //<editor-fold defaultstate="collapsed" desc="Field definitions"> -51 /** -52 * The logger. -53 */ -54 private static final Logger LOGGER = LoggerFactory.getLogger(AbstractFileTypeAnalyzer.class); -55 /** -56 * Whether the file type analyzer detected any files it needs to analyze. -57 */ -58 private boolean filesMatched = false; -59 -60 /** -61 * Get the value of filesMatched. A flag indicating whether the scan included any file types this analyzer supports. -62 * -63 * @return the value of filesMatched -64 */ -65 protected boolean isFilesMatched() { -66 return filesMatched; -67 } -68 -69 /** -70 * Set the value of filesMatched. A flag indicating whether the scan included any file types this analyzer supports. -71 * -72 * @param filesMatched new value of filesMatched -73 */ -74 protected void setFilesMatched(boolean filesMatched) { -75 this.filesMatched = filesMatched; -76 } -77 -78 /** -79 * A flag indicating whether or not the analyzer is enabled. -80 */ -81 private boolean enabled = true; +33 import org.owasp.dependencycheck.exception.InitializationException; +34 +35 /** +36 * The base FileTypeAnalyzer that all analyzers that have specific file types +37 * they analyze should extend. +38 * +39 * @author Jeremy Long +40 */ +41 public abstract class AbstractFileTypeAnalyzer extends AbstractAnalyzer implements FileTypeAnalyzer { +42 +43 //<editor-fold defaultstate="collapsed" desc="Constructor"> +44 /** +45 * Base constructor that all children must call. This checks the +46 * configuration to determine if the analyzer is enabled. +47 */ +48 public AbstractFileTypeAnalyzer() { +49 reset(); +50 } +51 //</editor-fold> +52 +53 //<editor-fold defaultstate="collapsed" desc="Field definitions"> +54 /** +55 * The logger. +56 */ +57 private static final Logger LOGGER = LoggerFactory.getLogger(AbstractFileTypeAnalyzer.class); +58 /** +59 * Whether the file type analyzer detected any files it needs to analyze. +60 */ +61 private boolean filesMatched = false; +62 +63 /** +64 * Get the value of filesMatched. A flag indicating whether the scan +65 * included any file types this analyzer supports. +66 * +67 * @return the value of filesMatched +68 */ +69 protected boolean isFilesMatched() { +70 return filesMatched; +71 } +72 +73 /** +74 * Set the value of filesMatched. A flag indicating whether the scan +75 * included any file types this analyzer supports. +76 * +77 * @param filesMatched new value of filesMatched +78 */ +79 protected void setFilesMatched(boolean filesMatched) { +80 this.filesMatched = filesMatched; +81 } 82 83 /** -84 * Get the value of enabled. -85 * -86 * @return the value of enabled -87 */ -88 public boolean isEnabled() { -89 return enabled; -90 } -91 -92 /** -93 * Set the value of enabled. -94 * -95 * @param enabled new value of enabled -96 */ -97 public void setEnabled(boolean enabled) { -98 this.enabled = enabled; -99 } -100 //</editor-fold> -101 -102 //<editor-fold defaultstate="collapsed" desc="Abstract methods children must implement"> -103 /** -104 * <p> -105 * Returns the {@link java.io.FileFilter} used to determine which files are to be analyzed. An example would be an analyzer -106 * that inspected Java jar files. Implementors may use {@link org.owasp.dependencycheck.utils.FileFilterBuilder}.</p> -107 * <p> -108 * If the analyzer returns null it will not cause additional files to be analyzed, but will be executed against every file -109 * loaded.</p> -110 * -111 * @return the file filter used to determine which files are to be analyzed -112 */ -113 protected abstract FileFilter getFileFilter(); -114 -115 /** -116 * Initializes the file type analyzer. +84 * A flag indicating whether or not the analyzer is enabled. +85 */ +86 private boolean enabled = true; +87 +88 /** +89 * Get the value of enabled. +90 * +91 * @return the value of enabled +92 */ +93 public boolean isEnabled() { +94 return enabled; +95 } +96 +97 /** +98 * Set the value of enabled. +99 * +100 * @param enabled new value of enabled +101 */ +102 public void setEnabled(boolean enabled) { +103 this.enabled = enabled; +104 } +105 //</editor-fold> +106 +107 //<editor-fold defaultstate="collapsed" desc="Abstract methods children must implement"> +108 /** +109 * <p> +110 * Returns the {@link java.io.FileFilter} used to determine which files are +111 * to be analyzed. An example would be an analyzer that inspected Java jar +112 * files. Implementors may use +113 * {@link org.owasp.dependencycheck.utils.FileFilterBuilder}.</p> +114 * <p> +115 * If the analyzer returns null it will not cause additional files to be +116 * analyzed, but will be executed against every file loaded.</p> 117 * -118 * @throws Exception thrown if there is an exception during initialization +118 * @return the file filter used to determine which files are to be analyzed 119 */ -120 protected abstract void initializeFileTypeAnalyzer() throws Exception; +120 protected abstract FileFilter getFileFilter(); 121 122 /** -123 * Analyzes a given dependency. If the dependency is an archive, such as a WAR or EAR, the contents are extracted, scanned, -124 * and added to the list of dependencies within the engine. -125 * -126 * @param dependency the dependency to analyze -127 * @param engine the engine scanning -128 * @throws AnalysisException thrown if there is an analysis exception -129 */ -130 protected abstract void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException; -131 -132 /** -133 * <p> -134 * Returns the setting key to determine if the analyzer is enabled.</p> -135 * -136 * @return the key for the analyzer's enabled property -137 */ -138 protected abstract String getAnalyzerEnabledSettingKey(); -139 -140 //</editor-fold> -141 //<editor-fold defaultstate="collapsed" desc="Final implementations for the Analyzer interface"> -142 /** -143 * Initializes the analyzer. +123 * Initializes the file type analyzer. +124 * +125 * @throws InitializationException thrown if there is an exception during +126 * initialization +127 */ +128 protected abstract void initializeFileTypeAnalyzer() throws InitializationException; +129 +130 /** +131 * Analyzes a given dependency. If the dependency is an archive, such as a +132 * WAR or EAR, the contents are extracted, scanned, and added to the list of +133 * dependencies within the engine. +134 * +135 * @param dependency the dependency to analyze +136 * @param engine the engine scanning +137 * @throws AnalysisException thrown if there is an analysis exception +138 */ +139 protected abstract void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException; +140 +141 /** +142 * <p> +143 * Returns the setting key to determine if the analyzer is enabled.</p> 144 * -145 * @throws Exception thrown if there is an exception during initialization +145 * @return the key for the analyzer's enabled property 146 */ -147 @Override -148 public final void initialize() throws Exception { -149 if (filesMatched) { -150 initializeFileTypeAnalyzer(); -151 } else { -152 enabled = false; -153 } -154 } -155 -156 /** -157 * Resets the enabled flag on the analyzer. -158 */ -159 @Override -160 public final void reset() { -161 final String key = getAnalyzerEnabledSettingKey(); -162 try { -163 enabled = Settings.getBoolean(key, true); -164 } catch (InvalidSettingException ex) { -165 LOGGER.warn("Invalid setting for property '{}'", key); -166 LOGGER.debug("", ex); -167 LOGGER.warn("{} has been disabled", getName()); -168 } -169 } -170 -171 /** -172 * Analyzes a given dependency. If the dependency is an archive, such as a WAR or EAR, the contents are extracted, scanned, -173 * and added to the list of dependencies within the engine. -174 * -175 * @param dependency the dependency to analyze -176 * @param engine the engine scanning -177 * @throws AnalysisException thrown if there is an analysis exception -178 */ -179 @Override -180 public final void analyze(Dependency dependency, Engine engine) throws AnalysisException { -181 if (enabled) { -182 analyzeFileType(dependency, engine); -183 } -184 } -185 -186 @Override -187 public boolean accept(File pathname) { -188 final FileFilter filter = getFileFilter(); -189 boolean accepted = false; -190 if (null == filter) { -191 LOGGER.error("The '{}' analyzer is misconfigured and does not have a file filter; it will be disabled", getName()); -192 } else if (enabled) { -193 accepted = filter.accept(pathname); -194 if (accepted) { -195 filesMatched = true; -196 } -197 } -198 return accepted; -199 } -200 -201 //</editor-fold> -202 //<editor-fold defaultstate="collapsed" desc="Static utility methods"> -203 /** -204 * <p> -205 * Utility method to help in the creation of the extensions set. This constructs a new Set that can be used in a final static -206 * declaration.</p> -207 * <p> -208 * This implementation was copied from -209 * http://stackoverflow.com/questions/2041778/initialize-java-hashset-values-by-construction</p>; -210 * -211 * @param strings a list of strings to add to the set. -212 * @return a Set of strings. -213 */ -214 protected static Set<String> newHashSet(String... strings) { -215 final Set<String> set = new HashSet<String>(strings.length); -216 Collections.addAll(set, strings); -217 return set; -218 } -219 -220 //</editor-fold> -221 } +147 protected abstract String getAnalyzerEnabledSettingKey(); +148 +149 //</editor-fold> +150 //<editor-fold defaultstate="collapsed" desc="Final implementations for the Analyzer interface"> +151 /** +152 * Initializes the analyzer. +153 * +154 * @throws InitializationException thrown if there is an exception during +155 * initialization +156 */ +157 @Override +158 public final void initialize() throws InitializationException { +159 if (filesMatched) { +160 initializeFileTypeAnalyzer(); +161 } else { +162 enabled = false; +163 } +164 } +165 +166 /** +167 * Resets the enabled flag on the analyzer. +168 */ +169 @Override +170 public final void reset() { +171 final String key = getAnalyzerEnabledSettingKey(); +172 try { +173 enabled = Settings.getBoolean(key, true); +174 } catch (InvalidSettingException ex) { +175 LOGGER.warn("Invalid setting for property '{}'", key); +176 LOGGER.debug("", ex); +177 LOGGER.warn("{} has been disabled", getName()); +178 } +179 } +180 +181 /** +182 * Analyzes a given dependency. If the dependency is an archive, such as a +183 * WAR or EAR, the contents are extracted, scanned, and added to the list of +184 * dependencies within the engine. +185 * +186 * @param dependency the dependency to analyze +187 * @param engine the engine scanning +188 * @throws AnalysisException thrown if there is an analysis exception +189 */ +190 @Override +191 public final void analyze(Dependency dependency, Engine engine) throws AnalysisException { +192 if (enabled) { +193 analyzeFileType(dependency, engine); +194 } +195 } +196 +197 @Override +198 public boolean accept(File pathname) { +199 final FileFilter filter = getFileFilter(); +200 boolean accepted = false; +201 if (null == filter) { +202 LOGGER.error("The '{}' analyzer is misconfigured and does not have a file filter; it will be disabled", getName()); +203 } else if (enabled) { +204 accepted = filter.accept(pathname); +205 if (accepted) { +206 filesMatched = true; +207 } +208 } +209 return accepted; +210 } +211 +212 //</editor-fold> +213 //<editor-fold defaultstate="collapsed" desc="Static utility methods"> +214 /** +215 * <p> +216 * Utility method to help in the creation of the extensions set. This +217 * constructs a new Set that can be used in a final static declaration.</p> +218 * <p> +219 * This implementation was copied from +220 * http://stackoverflow.com/questions/2041778/initialize-java-hashset-values-by-construction</p>; +221 * +222 * @param strings a list of strings to add to the set. +223 * @return a Set of strings. +224 */ +225 protected static Set<String> newHashSet(String... strings) { +226 final Set<String> set = new HashSet<String>(strings.length); +227 Collections.addAll(set, strings); +228 return set; +229 } +230 +231 //</editor-fold> +232 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzer.html index 974fddd8b..0e9f20d3b 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzer.html @@ -33,163 +33,161 @@ 25 import java.util.List; 26 import java.util.Set; 27 import java.util.regex.Pattern; -28 import org.owasp.dependencycheck.suppression.SuppressionParseException; -29 import org.owasp.dependencycheck.suppression.SuppressionParser; -30 import org.owasp.dependencycheck.suppression.SuppressionRule; -31 import org.owasp.dependencycheck.utils.DownloadFailedException; -32 import org.owasp.dependencycheck.utils.Downloader; -33 import org.owasp.dependencycheck.utils.FileUtils; -34 import org.owasp.dependencycheck.utils.Settings; -35 import org.slf4j.Logger; -36 import org.slf4j.LoggerFactory; -37 import org.xml.sax.SAXException; -38 -39 /** -40 * Abstract base suppression analyzer that contains methods for parsing the -41 * suppression xml file. -42 * -43 * @author Jeremy Long -44 */ -45 public abstract class AbstractSuppressionAnalyzer extends AbstractAnalyzer { -46 -47 /** -48 * The Logger for use throughout the class -49 */ -50 private static final Logger LOGGER = LoggerFactory.getLogger(AbstractSuppressionAnalyzer.class); -51 -52 //<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer"> -53 /** -54 * Returns a list of file EXTENSIONS supported by this analyzer. -55 * -56 * @return a list of file EXTENSIONS supported by this analyzer. -57 */ -58 public Set<String> getSupportedExtensions() { -59 return null; -60 } -61 -62 //</editor-fold> -63 /** -64 * The initialize method loads the suppression XML file. -65 * -66 * @throws Exception thrown if there is an exception -67 */ -68 @Override -69 public void initialize() throws Exception { -70 super.initialize(); -71 loadSuppressionData(); -72 } -73 -74 /** -75 * The list of suppression rules -76 */ -77 private List<SuppressionRule> rules; +28 import org.owasp.dependencycheck.exception.InitializationException; +29 import org.owasp.dependencycheck.xml.suppression.SuppressionParseException; +30 import org.owasp.dependencycheck.xml.suppression.SuppressionParser; +31 import org.owasp.dependencycheck.xml.suppression.SuppressionRule; +32 import org.owasp.dependencycheck.utils.DownloadFailedException; +33 import org.owasp.dependencycheck.utils.Downloader; +34 import org.owasp.dependencycheck.utils.FileUtils; +35 import org.owasp.dependencycheck.utils.Settings; +36 import org.slf4j.Logger; +37 import org.slf4j.LoggerFactory; +38 import org.xml.sax.SAXException; +39 +40 /** +41 * Abstract base suppression analyzer that contains methods for parsing the +42 * suppression xml file. +43 * +44 * @author Jeremy Long +45 */ +46 public abstract class AbstractSuppressionAnalyzer extends AbstractAnalyzer { +47 +48 /** +49 * The Logger for use throughout the class +50 */ +51 private static final Logger LOGGER = LoggerFactory.getLogger(AbstractSuppressionAnalyzer.class); +52 +53 //<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer"> +54 /** +55 * Returns a list of file EXTENSIONS supported by this analyzer. +56 * +57 * @return a list of file EXTENSIONS supported by this analyzer. +58 */ +59 public Set<String> getSupportedExtensions() { +60 return null; +61 } +62 +63 //</editor-fold> +64 /** +65 * The initialize method loads the suppression XML file. +66 * +67 * @throws InitializationException thrown if there is an exception +68 */ +69 @Override +70 public void initialize() throws InitializationException { +71 super.initialize(); +72 try { +73 loadSuppressionData(); +74 } catch (SuppressionParseException ex) { +75 throw new InitializationException("Error initializing the suppression analyzer", ex); +76 } +77 } 78 79 /** -80 * Get the value of rules. -81 * -82 * @return the value of rules -83 */ -84 public List<SuppressionRule> getRules() { -85 return rules; -86 } -87 -88 /** -89 * Set the value of rules. -90 * -91 * @param rules new value of rules -92 */ -93 public void setRules(List<SuppressionRule> rules) { -94 this.rules = rules; -95 } -96 -97 /** -98 * Loads the suppression rules file. -99 * -100 * @throws SuppressionParseException thrown if the XML cannot be parsed. -101 */ -102 private void loadSuppressionData() throws SuppressionParseException { -103 final SuppressionParser parser = new SuppressionParser(); -104 File file = null; -105 try { -106 rules = parser.parseSuppressionRules(this.getClass().getClassLoader().getResourceAsStream("dependencycheck-base-suppression.xml")); -107 } catch (SuppressionParseException ex) { -108 LOGGER.error("Unable to parse the base suppression data file"); -109 LOGGER.debug("Unable to parse the base suppression data file", ex); -110 } catch (SAXException ex) { -111 LOGGER.error("Unable to parse the base suppression data file"); -112 LOGGER.debug("Unable to parse the base suppression data file", ex); -113 } -114 final String suppressionFilePath = Settings.getString(Settings.KEYS.SUPPRESSION_FILE); -115 if (suppressionFilePath == null) { -116 return; -117 } -118 boolean deleteTempFile = false; -119 try { -120 final Pattern uriRx = Pattern.compile("^(https?|file)\\:.*", Pattern.CASE_INSENSITIVE); -121 if (uriRx.matcher(suppressionFilePath).matches()) { -122 deleteTempFile = true; -123 file = FileUtils.getTempFile("suppression", "xml"); -124 final URL url = new URL(suppressionFilePath); -125 try { -126 Downloader.fetchFile(url, file, false); -127 } catch (DownloadFailedException ex) { -128 Downloader.fetchFile(url, file, true); -129 } -130 } else { -131 file = new File(suppressionFilePath); -132 if (!file.exists()) { -133 final InputStream suppressionsFromClasspath = this.getClass().getClassLoader().getResourceAsStream(suppressionFilePath); -134 if (suppressionsFromClasspath != null) { -135 deleteTempFile = true; -136 file = FileUtils.getTempFile("suppression", "xml"); -137 try { -138 org.apache.commons.io.FileUtils.copyInputStreamToFile(suppressionsFromClasspath, file); -139 } catch (IOException ex) { -140 throwSuppressionParseException("Unable to locate suppressions file in classpath", ex); -141 } -142 } -143 } -144 } -145 +80 * The list of suppression rules +81 */ +82 private List<SuppressionRule> rules; +83 +84 /** +85 * Get the value of rules. +86 * +87 * @return the value of rules +88 */ +89 public List<SuppressionRule> getRules() { +90 return rules; +91 } +92 +93 /** +94 * Set the value of rules. +95 * +96 * @param rules new value of rules +97 */ +98 public void setRules(List<SuppressionRule> rules) { +99 this.rules = rules; +100 } +101 +102 /** +103 * Loads the suppression rules file. +104 * +105 * @throws SuppressionParseException thrown if the XML cannot be parsed. +106 */ +107 private void loadSuppressionData() throws SuppressionParseException { +108 final SuppressionParser parser = new SuppressionParser(); +109 File file = null; +110 try { +111 rules = parser.parseSuppressionRules(this.getClass().getClassLoader().getResourceAsStream("dependencycheck-base-suppression.xml")); +112 } catch (SAXException ex) { +113 throw new SuppressionParseException("Unable to parse the base suppression data file", ex); +114 } +115 final String suppressionFilePath = Settings.getString(Settings.KEYS.SUPPRESSION_FILE); +116 if (suppressionFilePath == null) { +117 return; +118 } +119 boolean deleteTempFile = false; +120 try { +121 final Pattern uriRx = Pattern.compile("^(https?|file)\\:.*", Pattern.CASE_INSENSITIVE); +122 if (uriRx.matcher(suppressionFilePath).matches()) { +123 deleteTempFile = true; +124 file = FileUtils.getTempFile("suppression", "xml"); +125 final URL url = new URL(suppressionFilePath); +126 try { +127 Downloader.fetchFile(url, file, false); +128 } catch (DownloadFailedException ex) { +129 Downloader.fetchFile(url, file, true); +130 } +131 } else { +132 file = new File(suppressionFilePath); +133 if (!file.exists()) { +134 final InputStream suppressionsFromClasspath = this.getClass().getClassLoader().getResourceAsStream(suppressionFilePath); +135 if (suppressionsFromClasspath != null) { +136 deleteTempFile = true; +137 file = FileUtils.getTempFile("suppression", "xml"); +138 try { +139 org.apache.commons.io.FileUtils.copyInputStreamToFile(suppressionsFromClasspath, file); +140 } catch (IOException ex) { +141 throwSuppressionParseException("Unable to locate suppressions file in classpath", ex); +142 } +143 } +144 } +145 } 146 if (file != null) { 147 try { -148 //rules = parser.parseSuppressionRules(file); -149 rules.addAll(parser.parseSuppressionRules(file)); -150 LOGGER.debug("{} suppression rules were loaded.", rules.size()); -151 } catch (SuppressionParseException ex) { -152 LOGGER.warn("Unable to parse suppression xml file '{}'", file.getPath()); -153 LOGGER.warn(ex.getMessage()); -154 LOGGER.debug("", ex); -155 throw ex; -156 } -157 } -158 } catch (DownloadFailedException ex) { -159 throwSuppressionParseException("Unable to fetch the configured suppression file", ex); -160 } catch (MalformedURLException ex) { -161 throwSuppressionParseException("Configured suppression file has an invalid URL", ex); -162 } catch (IOException ex) { -163 throwSuppressionParseException("Unable to create temp file for suppressions", ex); -164 } finally { -165 if (deleteTempFile && file != null) { -166 FileUtils.delete(file); -167 } -168 } -169 } -170 -171 /** -172 * Utility method to throw parse exceptions. -173 * -174 * @param message the exception message -175 * @param exception the cause of the exception -176 * @throws SuppressionParseException throws the generated -177 * SuppressionParseException -178 */ -179 private void throwSuppressionParseException(String message, Exception exception) throws SuppressionParseException { -180 LOGGER.warn(message); -181 LOGGER.debug("", exception); -182 throw new SuppressionParseException(message, exception); -183 } -184 } +148 rules.addAll(parser.parseSuppressionRules(file)); +149 LOGGER.debug("{} suppression rules were loaded.", rules.size()); +150 } catch (SuppressionParseException ex) { +151 LOGGER.warn("Unable to parse suppression xml file '{}'", file.getPath()); +152 LOGGER.warn(ex.getMessage()); +153 throw ex; +154 } +155 } +156 } catch (DownloadFailedException ex) { +157 throwSuppressionParseException("Unable to fetch the configured suppression file", ex); +158 } catch (MalformedURLException ex) { +159 throwSuppressionParseException("Configured suppression file has an invalid URL", ex); +160 } catch (IOException ex) { +161 throwSuppressionParseException("Unable to create temp file for suppressions", ex); +162 } finally { +163 if (deleteTempFile && file != null) { +164 FileUtils.delete(file); +165 } +166 } +167 } +168 +169 /** +170 * Utility method to throw parse exceptions. +171 * +172 * @param message the exception message +173 * @param exception the cause of the exception +174 * @throws SuppressionParseException throws the generated +175 * SuppressionParseException +176 */ +177 private void throwSuppressionParseException(String message, Exception exception) throws SuppressionParseException { +178 LOGGER.warn(message); +179 LOGGER.debug("", exception); +180 throw new SuppressionParseException(message, exception); +181 } +182 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/Analyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/Analyzer.html index 5d083a6e3..b363ffba7 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/Analyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/Analyzer.html @@ -28,55 +28,62 @@ 20 import org.owasp.dependencycheck.Engine; 21 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; 22 import org.owasp.dependencycheck.dependency.Dependency; -23 -24 /** -25 * An interface that defines an Analyzer that is used to identify Dependencies. An analyzer will collect information -26 * about the dependency in the form of Evidence. -27 * -28 * @author Jeremy Long -29 */ -30 public interface Analyzer { -31 -32 /** -33 * Analyzes the given dependency. The analysis could be anything from identifying an Identifier for the dependency, -34 * to finding vulnerabilities, etc. Additionally, if the analyzer collects enough information to add a description -35 * or license information for the dependency it should be added. -36 * -37 * @param dependency a dependency to analyze. -38 * @param engine the engine that is scanning the dependencies - this is useful if we need to check other -39 * dependencies -40 * @throws AnalysisException is thrown if there is an error analyzing the dependency file -41 */ -42 void analyze(Dependency dependency, Engine engine) throws AnalysisException; -43 -44 /** -45 * Returns the name of the analyzer. -46 * -47 * @return the name of the analyzer. -48 */ -49 String getName(); -50 -51 /** -52 * Returns the phase that the analyzer is intended to run in. -53 * -54 * @return the phase that the analyzer is intended to run in. -55 */ -56 AnalysisPhase getAnalysisPhase(); -57 -58 /** -59 * The initialize method is called (once) prior to the analyze method being called on all of the dependencies. -60 * -61 * @throws Exception is thrown if an exception occurs initializing the analyzer. -62 */ -63 void initialize() throws Exception; -64 -65 /** -66 * The close method is called after all of the dependencies have been analyzed. -67 * -68 * @throws Exception is thrown if an exception occurs closing the analyzer. -69 */ -70 void close() throws Exception; -71 } +23 import org.owasp.dependencycheck.exception.InitializationException; +24 +25 /** +26 * An interface that defines an Analyzer that is used to identify Dependencies. +27 * An analyzer will collect information about the dependency in the form of +28 * Evidence. +29 * +30 * @author Jeremy Long +31 */ +32 public interface Analyzer { +33 +34 /** +35 * Analyzes the given dependency. The analysis could be anything from +36 * identifying an Identifier for the dependency, to finding vulnerabilities, +37 * etc. Additionally, if the analyzer collects enough information to add a +38 * description or license information for the dependency it should be added. +39 * +40 * @param dependency a dependency to analyze. +41 * @param engine the engine that is scanning the dependencies - this is +42 * useful if we need to check other dependencies +43 * @throws AnalysisException is thrown if there is an error analyzing the +44 * dependency file +45 */ +46 void analyze(Dependency dependency, Engine engine) throws AnalysisException; +47 +48 /** +49 * Returns the name of the analyzer. +50 * +51 * @return the name of the analyzer. +52 */ +53 String getName(); +54 +55 /** +56 * Returns the phase that the analyzer is intended to run in. +57 * +58 * @return the phase that the analyzer is intended to run in. +59 */ +60 AnalysisPhase getAnalysisPhase(); +61 +62 /** +63 * The initialize method is called (once) prior to the analyze method being +64 * called on all of the dependencies. +65 * +66 * @throws InitializationException is thrown if an exception occurs +67 * initializing the analyzer. +68 */ +69 void initialize() throws InitializationException; +70 +71 /** +72 * The close method is called after all of the dependencies have been +73 * analyzed. +74 * +75 * @throws Exception is thrown if an exception occurs closing the analyzer. +76 */ +77 void close() throws Exception; +78 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/ArchiveAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/ArchiveAnalyzer.html index 4bfdf4f7f..357c4dac7 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/ArchiveAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/ArchiveAnalyzer.html @@ -57,467 +57,538 @@ 49 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; 50 import org.owasp.dependencycheck.analyzer.exception.ArchiveExtractionException; 51 import org.owasp.dependencycheck.dependency.Dependency; -52 import org.owasp.dependencycheck.utils.FileFilterBuilder; -53 import org.owasp.dependencycheck.utils.FileUtils; -54 import org.owasp.dependencycheck.utils.Settings; -55 -56 import org.slf4j.Logger; -57 import org.slf4j.LoggerFactory; -58 -59 /** -60 * <p> -61 * An analyzer that extracts files from archives and ensures any supported files contained within the archive are added to the -62 * dependency list.</p> -63 * -64 * @author Jeremy Long -65 */ -66 public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer { -67 -68 /** -69 * The logger. -70 */ -71 private static final Logger LOGGER = LoggerFactory.getLogger(ArchiveAnalyzer.class); -72 /** -73 * The count of directories created during analysis. This is used for creating temporary directories. -74 */ -75 private static int dirCount = 0; -76 /** -77 * The parent directory for the individual directories per archive. -78 */ -79 private File tempFileLocation = null; -80 /** -81 * The max scan depth that the analyzer will recursively extract nested archives. -82 */ -83 private static final int MAX_SCAN_DEPTH = Settings.getInt("archive.scan.depth", 3); -84 /** -85 * Tracks the current scan/extraction depth for nested archives. -86 */ -87 private int scanDepth = 0; -88 -89 //<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer"> -90 /** -91 * The name of the analyzer. -92 */ -93 private static final String ANALYZER_NAME = "Archive Analyzer"; -94 /** -95 * The phase that this analyzer is intended to run in. -96 */ -97 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INITIAL; -98 /** -99 * The set of things we can handle with Zip methods -100 */ -101 private static final Set<String> ZIPPABLES = newHashSet("zip", "ear", "war", "jar", "sar", "apk", "nupkg"); -102 /** -103 * The set of file extensions supported by this analyzer. Note for developers, any additions to this list will need to be -104 * explicitly handled in {@link #extractFiles(File, File, Engine)}. -105 */ -106 private static final Set<String> EXTENSIONS = newHashSet("tar", "gz", "tgz", "bz2", "tbz2"); -107 -108 /** -109 * Detects files with extensions to remove from the engine's collection of dependencies. -110 */ -111 private static final FileFilter REMOVE_FROM_ANALYSIS = FileFilterBuilder.newInstance().addExtensions("zip", "tar", "gz", "tgz", "bz2", "tbz2") -112 .build(); -113 -114 static { -115 final String additionalZipExt = Settings.getString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS); -116 if (additionalZipExt != null) { -117 final String[] ext = additionalZipExt.split("\\s*,\\s*"); -118 Collections.addAll(ZIPPABLES, ext); -119 } -120 EXTENSIONS.addAll(ZIPPABLES); -121 } -122 -123 /** -124 * The file filter used to filter supported files. -125 */ -126 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(EXTENSIONS).build(); +52 import org.owasp.dependencycheck.exception.InitializationException; +53 import org.owasp.dependencycheck.utils.FileFilterBuilder; +54 import org.owasp.dependencycheck.utils.FileUtils; +55 import org.owasp.dependencycheck.utils.Settings; +56 +57 import org.slf4j.Logger; +58 import org.slf4j.LoggerFactory; +59 +60 /** +61 * <p> +62 * An analyzer that extracts files from archives and ensures any supported files +63 * contained within the archive are added to the dependency list.</p> +64 * +65 * @author Jeremy Long +66 */ +67 public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer { +68 +69 /** +70 * The logger. +71 */ +72 private static final Logger LOGGER = LoggerFactory.getLogger(ArchiveAnalyzer.class); +73 /** +74 * The count of directories created during analysis. This is used for +75 * creating temporary directories. +76 */ +77 private static int dirCount = 0; +78 /** +79 * The parent directory for the individual directories per archive. +80 */ +81 private File tempFileLocation = null; +82 /** +83 * The max scan depth that the analyzer will recursively extract nested +84 * archives. +85 */ +86 private static final int MAX_SCAN_DEPTH = Settings.getInt("archive.scan.depth", 3); +87 /** +88 * Tracks the current scan/extraction depth for nested archives. +89 */ +90 private int scanDepth = 0; +91 +92 //<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer"> +93 /** +94 * The name of the analyzer. +95 */ +96 private static final String ANALYZER_NAME = "Archive Analyzer"; +97 /** +98 * The phase that this analyzer is intended to run in. +99 */ +100 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INITIAL; +101 /** +102 * The set of things we can handle with Zip methods +103 */ +104 private static final Set<String> ZIPPABLES = newHashSet("zip", "ear", "war", "jar", "sar", "apk", "nupkg"); +105 /** +106 * The set of file extensions supported by this analyzer. Note for +107 * developers, any additions to this list will need to be explicitly handled +108 * in {@link #extractFiles(File, File, Engine)}. +109 */ +110 private static final Set<String> EXTENSIONS = newHashSet("tar", "gz", "tgz", "bz2", "tbz2"); +111 +112 /** +113 * Detects files with extensions to remove from the engine's collection of +114 * dependencies. +115 */ +116 private static final FileFilter REMOVE_FROM_ANALYSIS = FileFilterBuilder.newInstance().addExtensions("zip", "tar", "gz", "tgz", "bz2", "tbz2") +117 .build(); +118 +119 static { +120 final String additionalZipExt = Settings.getString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS); +121 if (additionalZipExt != null) { +122 final String[] ext = additionalZipExt.split("\\s*,\\s*"); +123 Collections.addAll(ZIPPABLES, ext); +124 } +125 EXTENSIONS.addAll(ZIPPABLES); +126 } 127 -128 @Override -129 protected FileFilter getFileFilter() { -130 return FILTER; -131 } +128 /** +129 * The file filter used to filter supported files. +130 */ +131 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(EXTENSIONS).build(); 132 -133 /** -134 * Detects files with .zip extension. -135 */ -136 private static final FileFilter ZIP_FILTER = FileFilterBuilder.newInstance().addExtensions("zip").build(); +133 @Override +134 protected FileFilter getFileFilter() { +135 return FILTER; +136 } 137 138 /** -139 * Returns the name of the analyzer. -140 * -141 * @return the name of the analyzer. -142 */ -143 @Override -144 public String getName() { -145 return ANALYZER_NAME; -146 } -147 -148 /** -149 * Returns the phase that the analyzer is intended to run in. -150 * -151 * @return the phase that the analyzer is intended to run in. -152 */ -153 @Override -154 public AnalysisPhase getAnalysisPhase() { -155 return ANALYSIS_PHASE; -156 } -157 //</editor-fold> -158 -159 /** -160 * Returns the key used in the properties file to reference the analyzer's enabled property. -161 * -162 * @return the analyzer's enabled property setting key -163 */ -164 @Override -165 protected String getAnalyzerEnabledSettingKey() { -166 return Settings.KEYS.ANALYZER_ARCHIVE_ENABLED; -167 } -168 -169 /** -170 * The initialize method does nothing for this Analyzer. -171 * -172 * @throws Exception is thrown if there is an exception deleting or creating temporary files -173 */ -174 @Override -175 public void initializeFileTypeAnalyzer() throws Exception { -176 final File baseDir = Settings.getTempDirectory(); -177 tempFileLocation = File.createTempFile("check", "tmp", baseDir); -178 if (!tempFileLocation.delete()) { -179 final String msg = String.format("Unable to delete temporary file '%s'.", tempFileLocation.getAbsolutePath()); -180 throw new AnalysisException(msg); -181 } -182 if (!tempFileLocation.mkdirs()) { -183 final String msg = String.format("Unable to create directory '%s'.", tempFileLocation.getAbsolutePath()); -184 throw new AnalysisException(msg); -185 } -186 } -187 -188 /** -189 * The close method deletes any temporary files and directories created during analysis. -190 * -191 * @throws Exception thrown if there is an exception deleting temporary files -192 */ -193 @Override -194 public void close() throws Exception { -195 if (tempFileLocation != null && tempFileLocation.exists()) { -196 LOGGER.debug("Attempting to delete temporary files"); -197 final boolean success = FileUtils.delete(tempFileLocation); -198 if (!success && tempFileLocation.exists()) { -199 final String[] l = tempFileLocation.list(); -200 if (l != null && l.length > 0) { -201 LOGGER.warn("Failed to delete some temporary files, see the log for more details"); -202 } -203 } -204 } -205 } -206 -207 /** -208 * Analyzes a given dependency. If the dependency is an archive, such as a WAR or EAR, the contents are extracted, scanned, -209 * and added to the list of dependencies within the engine. -210 * -211 * @param dependency the dependency to analyze -212 * @param engine the engine scanning -213 * @throws AnalysisException thrown if there is an analysis exception -214 */ -215 @Override -216 public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { -217 final File f = new File(dependency.getActualFilePath()); -218 final File tmpDir = getNextTempDirectory(); -219 extractFiles(f, tmpDir, engine); -220 -221 //make a copy -222 final Set<Dependency> dependencySet = findMoreDependencies(engine, tmpDir); -223 if (!dependencySet.isEmpty()) { -224 for (Dependency d : dependencySet) { -225 //fix the dependency's display name and path -226 final String displayPath = String.format("%s%s", -227 dependency.getFilePath(), -228 d.getActualFilePath().substring(tmpDir.getAbsolutePath().length())); -229 final String displayName = String.format("%s: %s", -230 dependency.getFileName(), -231 d.getFileName()); -232 d.setFilePath(displayPath); -233 d.setFileName(displayName); -234 -235 //TODO - can we get more evidence from the parent? EAR contains module name, etc. -236 //analyze the dependency (i.e. extract files) if it is a supported type. -237 if (this.accept(d.getActualFile()) && scanDepth < MAX_SCAN_DEPTH) { -238 scanDepth += 1; -239 analyze(d, engine); -240 scanDepth -= 1; -241 } -242 } -243 } -244 if (REMOVE_FROM_ANALYSIS.accept(dependency.getActualFile())) { -245 addDisguisedJarsToDependencies(dependency, engine); -246 engine.getDependencies().remove(dependency); -247 } -248 Collections.sort(engine.getDependencies()); -249 } -250 -251 /** -252 * If a zip file was identified as a possible JAR, this method will add the zip to the list of dependencies. -253 * -254 * @param dependency the zip file -255 * @param engine the engine -256 * @throws AnalysisException thrown if there is an issue -257 */ -258 private void addDisguisedJarsToDependencies(Dependency dependency, Engine engine) throws AnalysisException { -259 if (ZIP_FILTER.accept(dependency.getActualFile()) && isZipFileActuallyJarFile(dependency)) { -260 final File tdir = getNextTempDirectory(); -261 final String fileName = dependency.getFileName(); -262 -263 LOGGER.info("The zip file '{}' appears to be a JAR file, making a copy and analyzing it as a JAR.", fileName); -264 -265 final File tmpLoc = new File(tdir, fileName.substring(0, fileName.length() - 3) + "jar"); -266 try { -267 org.apache.commons.io.FileUtils.copyFile(tdir, tmpLoc); -268 final Set<Dependency> dependencySet = findMoreDependencies(engine, tmpLoc); -269 if (!dependencySet.isEmpty()) { -270 if (dependencySet.size() != 1) { -271 LOGGER.info("Deep copy of ZIP to JAR file resulted in more than one dependency?"); -272 } -273 for (Dependency d : dependencySet) { -274 //fix the dependency's display name and path -275 d.setFilePath(dependency.getFilePath()); -276 d.setDisplayFileName(dependency.getFileName()); -277 } -278 } -279 } catch (IOException ex) { -280 LOGGER.debug("Unable to perform deep copy on '{}'", dependency.getActualFile().getPath(), ex); -281 } -282 } -283 } -284 /** -285 * An empty dependency set. -286 */ -287 private static final Set<Dependency> EMPTY_DEPENDENCY_SET = Collections.emptySet(); -288 -289 /** -290 * Scan the given file/folder, and return any new dependencies found. -291 * -292 * @param engine used to scan -293 * @param file target of scanning -294 * @return any dependencies that weren't known to the engine before -295 */ -296 private static Set<Dependency> findMoreDependencies(Engine engine, File file) { -297 final List<Dependency> before = new ArrayList<Dependency>(engine.getDependencies()); -298 engine.scan(file); -299 final List<Dependency> after = engine.getDependencies(); -300 final boolean sizeChanged = before.size() != after.size(); -301 final Set<Dependency> newDependencies; -302 if (sizeChanged) { -303 //get the new dependencies -304 newDependencies = new HashSet<Dependency>(after); -305 newDependencies.removeAll(before); -306 } else { -307 newDependencies = EMPTY_DEPENDENCY_SET; -308 } -309 return newDependencies; -310 } -311 -312 /** -313 * Retrieves the next temporary directory to extract an archive too. -314 * -315 * @return a directory -316 * @throws AnalysisException thrown if unable to create temporary directory -317 */ -318 private File getNextTempDirectory() throws AnalysisException { -319 dirCount += 1; -320 final File directory = new File(tempFileLocation, String.valueOf(dirCount)); -321 //getting an exception for some directories not being able to be created; might be because the directory already exists? -322 if (directory.exists()) { -323 return getNextTempDirectory(); -324 } -325 if (!directory.mkdirs()) { -326 final String msg = String.format("Unable to create temp directory '%s'.", directory.getAbsolutePath()); -327 throw new AnalysisException(msg); -328 } -329 return directory; -330 } -331 -332 /** -333 * Extracts the contents of an archive into the specified directory. -334 * -335 * @param archive an archive file such as a WAR or EAR -336 * @param destination a directory to extract the contents to -337 * @param engine the scanning engine -338 * @throws AnalysisException thrown if the archive is not found -339 */ -340 private void extractFiles(File archive, File destination, Engine engine) throws AnalysisException { -341 if (archive != null && destination != null) { -342 FileInputStream fis; -343 try { -344 fis = new FileInputStream(archive); -345 } catch (FileNotFoundException ex) { -346 LOGGER.debug("", ex); -347 throw new AnalysisException("Archive file was not found.", ex); -348 } -349 final String archiveExt = FileUtils.getFileExtension(archive.getName()).toLowerCase(); -350 try { -351 if (ZIPPABLES.contains(archiveExt)) { -352 extractArchive(new ZipArchiveInputStream(new BufferedInputStream(fis)), destination, engine); -353 } else if ("tar".equals(archiveExt)) { -354 extractArchive(new TarArchiveInputStream(new BufferedInputStream(fis)), destination, engine); -355 } else if ("gz".equals(archiveExt) || "tgz".equals(archiveExt)) { -356 final String uncompressedName = GzipUtils.getUncompressedFilename(archive.getName()); -357 final File f = new File(destination, uncompressedName); -358 if (engine.accept(f)) { -359 decompressFile(new GzipCompressorInputStream(new BufferedInputStream(fis)), f); -360 } -361 } else if ("bz2".equals(archiveExt) || "tbz2".equals(archiveExt)) { -362 final String uncompressedName = BZip2Utils.getUncompressedFilename(archive.getName()); -363 final File f = new File(destination, uncompressedName); -364 if (engine.accept(f)) { -365 decompressFile(new BZip2CompressorInputStream(new BufferedInputStream(fis)), f); -366 } -367 } -368 } catch (ArchiveExtractionException ex) { -369 LOGGER.warn("Exception extracting archive '{}'.", archive.getName()); -370 LOGGER.debug("", ex); -371 } catch (IOException ex) { -372 LOGGER.warn("Exception reading archive '{}'.", archive.getName()); -373 LOGGER.debug("", ex); -374 } finally { -375 close(fis); -376 } -377 } -378 } -379 -380 /** -381 * Extracts files from an archive. -382 * -383 * @param input the archive to extract files from -384 * @param destination the location to write the files too -385 * @param engine the dependency-check engine -386 * @throws ArchiveExtractionException thrown if there is an exception extracting files from the archive -387 */ -388 private void extractArchive(ArchiveInputStream input, File destination, Engine engine) throws ArchiveExtractionException { -389 ArchiveEntry entry; -390 try { -391 while ((entry = input.getNextEntry()) != null) { -392 final File file = new File(destination, entry.getName()); -393 if (entry.isDirectory()) { -394 if (!file.exists() && !file.mkdirs()) { -395 final String msg = String.format("Unable to create directory '%s'.", file.getAbsolutePath()); -396 throw new AnalysisException(msg); -397 } -398 } else if (engine.accept(file)) { -399 extractAcceptedFile(input, file); -400 } -401 } -402 } catch (Throwable ex) { -403 throw new ArchiveExtractionException(ex); -404 } finally { -405 close(input); -406 } -407 } -408 -409 /** -410 * Extracts a file from an archive. -411 * -412 * @param input the archives input stream -413 * @param file the file to extract -414 * @throws AnalysisException thrown if there is an error -415 */ -416 private static void extractAcceptedFile(ArchiveInputStream input, File file) throws AnalysisException { -417 LOGGER.debug("Extracting '{}'", file.getPath()); -418 FileOutputStream fos = null; -419 try { -420 final File parent = file.getParentFile(); -421 if (!parent.isDirectory() && !parent.mkdirs()) { -422 final String msg = String.format("Unable to build directory '%s'.", parent.getAbsolutePath()); -423 throw new AnalysisException(msg); -424 } -425 fos = new FileOutputStream(file); -426 IOUtils.copy(input, fos); -427 } catch (FileNotFoundException ex) { -428 LOGGER.debug("", ex); -429 final String msg = String.format("Unable to find file '%s'.", file.getName()); -430 throw new AnalysisException(msg, ex); -431 } catch (IOException ex) { -432 LOGGER.debug("", ex); -433 final String msg = String.format("IO Exception while parsing file '%s'.", file.getName()); -434 throw new AnalysisException(msg, ex); -435 } finally { -436 close(fos); -437 } -438 } -439 -440 /** -441 * Decompresses a file. -442 * -443 * @param inputStream the compressed file -444 * @param outputFile the location to write the decompressed file -445 * @throws ArchiveExtractionException thrown if there is an exception decompressing the file -446 */ -447 private void decompressFile(CompressorInputStream inputStream, File outputFile) throws ArchiveExtractionException { -448 LOGGER.debug("Decompressing '{}'", outputFile.getPath()); -449 FileOutputStream out = null; -450 try { -451 out = new FileOutputStream(outputFile); -452 IOUtils.copy(inputStream, out); -453 } catch (FileNotFoundException ex) { -454 LOGGER.debug("", ex); -455 throw new ArchiveExtractionException(ex); -456 } catch (IOException ex) { -457 LOGGER.debug("", ex); -458 throw new ArchiveExtractionException(ex); -459 } finally { -460 close(out); -461 } -462 } -463 -464 /** -465 * Close the given {@link Closeable} instance, ignoring nulls, and logging any thrown {@link IOException}. -466 * -467 * @param closeable to be closed -468 */ -469 private static void close(Closeable closeable) { -470 if (null != closeable) { -471 try { -472 closeable.close(); -473 } catch (IOException ex) { -474 LOGGER.trace("", ex); -475 } -476 } -477 } -478 -479 /** -480 * Attempts to determine if a zip file is actually a JAR file. -481 * -482 * @param dependency the dependency to check -483 * @return true if the dependency appears to be a JAR file; otherwise false +139 * Detects files with .zip extension. +140 */ +141 private static final FileFilter ZIP_FILTER = FileFilterBuilder.newInstance().addExtensions("zip").build(); +142 +143 /** +144 * Returns the name of the analyzer. +145 * +146 * @return the name of the analyzer. +147 */ +148 @Override +149 public String getName() { +150 return ANALYZER_NAME; +151 } +152 +153 /** +154 * Returns the phase that the analyzer is intended to run in. +155 * +156 * @return the phase that the analyzer is intended to run in. +157 */ +158 @Override +159 public AnalysisPhase getAnalysisPhase() { +160 return ANALYSIS_PHASE; +161 } +162 //</editor-fold> +163 +164 /** +165 * Returns the key used in the properties file to reference the analyzer's +166 * enabled property. +167 * +168 * @return the analyzer's enabled property setting key +169 */ +170 @Override +171 protected String getAnalyzerEnabledSettingKey() { +172 return Settings.KEYS.ANALYZER_ARCHIVE_ENABLED; +173 } +174 +175 /** +176 * The initialize method does nothing for this Analyzer. +177 * +178 * @throws InitializationException is thrown if there is an exception +179 * deleting or creating temporary files +180 */ +181 @Override +182 public void initializeFileTypeAnalyzer() throws InitializationException { +183 try { +184 final File baseDir = Settings.getTempDirectory(); +185 tempFileLocation = File.createTempFile("check", "tmp", baseDir); +186 if (!tempFileLocation.delete()) { +187 setEnabled(false); +188 final String msg = String.format("Unable to delete temporary file '%s'.", tempFileLocation.getAbsolutePath()); +189 throw new InitializationException(msg); +190 } +191 if (!tempFileLocation.mkdirs()) { +192 setEnabled(false); +193 final String msg = String.format("Unable to create directory '%s'.", tempFileLocation.getAbsolutePath()); +194 throw new InitializationException(msg); +195 } +196 } catch (IOException ex) { +197 setEnabled(false); +198 throw new InitializationException("Unable to create a temporary file", ex); +199 } +200 } +201 +202 /** +203 * The close method deletes any temporary files and directories created +204 * during analysis. +205 * +206 * @throws Exception thrown if there is an exception deleting temporary +207 * files +208 */ +209 @Override +210 public void close() throws Exception { +211 if (tempFileLocation != null && tempFileLocation.exists()) { +212 LOGGER.debug("Attempting to delete temporary files"); +213 final boolean success = FileUtils.delete(tempFileLocation); +214 if (!success && tempFileLocation.exists()) { +215 final String[] l = tempFileLocation.list(); +216 if (l != null && l.length > 0) { +217 LOGGER.warn("Failed to delete some temporary files, see the log for more details"); +218 } +219 } +220 } +221 } +222 +223 /** +224 * Analyzes a given dependency. If the dependency is an archive, such as a +225 * WAR or EAR, the contents are extracted, scanned, and added to the list of +226 * dependencies within the engine. +227 * +228 * @param dependency the dependency to analyze +229 * @param engine the engine scanning +230 * @throws AnalysisException thrown if there is an analysis exception +231 */ +232 @Override +233 public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { +234 final File f = new File(dependency.getActualFilePath()); +235 final File tmpDir = getNextTempDirectory(); +236 extractFiles(f, tmpDir, engine); +237 +238 //make a copy +239 final Set<Dependency> dependencySet = findMoreDependencies(engine, tmpDir); +240 if (!dependencySet.isEmpty()) { +241 for (Dependency d : dependencySet) { +242 //fix the dependency's display name and path +243 final String displayPath = String.format("%s%s", +244 dependency.getFilePath(), +245 d.getActualFilePath().substring(tmpDir.getAbsolutePath().length())); +246 final String displayName = String.format("%s: %s", +247 dependency.getFileName(), +248 d.getFileName()); +249 d.setFilePath(displayPath); +250 d.setFileName(displayName); +251 +252 //TODO - can we get more evidence from the parent? EAR contains module name, etc. +253 //analyze the dependency (i.e. extract files) if it is a supported type. +254 if (this.accept(d.getActualFile()) && scanDepth < MAX_SCAN_DEPTH) { +255 scanDepth += 1; +256 analyze(d, engine); +257 scanDepth -= 1; +258 } +259 } +260 } +261 if (REMOVE_FROM_ANALYSIS.accept(dependency.getActualFile())) { +262 addDisguisedJarsToDependencies(dependency, engine); +263 engine.getDependencies().remove(dependency); +264 } +265 Collections.sort(engine.getDependencies()); +266 } +267 +268 /** +269 * If a zip file was identified as a possible JAR, this method will add the +270 * zip to the list of dependencies. +271 * +272 * @param dependency the zip file +273 * @param engine the engine +274 * @throws AnalysisException thrown if there is an issue +275 */ +276 private void addDisguisedJarsToDependencies(Dependency dependency, Engine engine) throws AnalysisException { +277 if (ZIP_FILTER.accept(dependency.getActualFile()) && isZipFileActuallyJarFile(dependency)) { +278 final File tdir = getNextTempDirectory(); +279 final String fileName = dependency.getFileName(); +280 +281 LOGGER.info("The zip file '{}' appears to be a JAR file, making a copy and analyzing it as a JAR.", fileName); +282 +283 final File tmpLoc = new File(tdir, fileName.substring(0, fileName.length() - 3) + "jar"); +284 try { +285 org.apache.commons.io.FileUtils.copyFile(tdir, tmpLoc); +286 final Set<Dependency> dependencySet = findMoreDependencies(engine, tmpLoc); +287 if (!dependencySet.isEmpty()) { +288 if (dependencySet.size() != 1) { +289 LOGGER.info("Deep copy of ZIP to JAR file resulted in more than one dependency?"); +290 } +291 for (Dependency d : dependencySet) { +292 //fix the dependency's display name and path +293 d.setFilePath(dependency.getFilePath()); +294 d.setDisplayFileName(dependency.getFileName()); +295 } +296 } +297 } catch (IOException ex) { +298 LOGGER.debug("Unable to perform deep copy on '{}'", dependency.getActualFile().getPath(), ex); +299 } +300 } +301 } +302 /** +303 * An empty dependency set. +304 */ +305 private static final Set<Dependency> EMPTY_DEPENDENCY_SET = Collections.emptySet(); +306 +307 /** +308 * Scan the given file/folder, and return any new dependencies found. +309 * +310 * @param engine used to scan +311 * @param file target of scanning +312 * @return any dependencies that weren't known to the engine before +313 */ +314 private static Set<Dependency> findMoreDependencies(Engine engine, File file) { +315 final List<Dependency> before = new ArrayList<Dependency>(engine.getDependencies()); +316 engine.scan(file); +317 final List<Dependency> after = engine.getDependencies(); +318 final boolean sizeChanged = before.size() != after.size(); +319 final Set<Dependency> newDependencies; +320 if (sizeChanged) { +321 //get the new dependencies +322 newDependencies = new HashSet<Dependency>(after); +323 newDependencies.removeAll(before); +324 } else { +325 newDependencies = EMPTY_DEPENDENCY_SET; +326 } +327 return newDependencies; +328 } +329 +330 /** +331 * Retrieves the next temporary directory to extract an archive too. +332 * +333 * @return a directory +334 * @throws AnalysisException thrown if unable to create temporary directory +335 */ +336 private File getNextTempDirectory() throws AnalysisException { +337 dirCount += 1; +338 final File directory = new File(tempFileLocation, String.valueOf(dirCount)); +339 //getting an exception for some directories not being able to be created; might be because the directory already exists? +340 if (directory.exists()) { +341 return getNextTempDirectory(); +342 } +343 if (!directory.mkdirs()) { +344 final String msg = String.format("Unable to create temp directory '%s'.", directory.getAbsolutePath()); +345 throw new AnalysisException(msg); +346 } +347 return directory; +348 } +349 +350 /** +351 * Extracts the contents of an archive into the specified directory. +352 * +353 * @param archive an archive file such as a WAR or EAR +354 * @param destination a directory to extract the contents to +355 * @param engine the scanning engine +356 * @throws AnalysisException thrown if the archive is not found +357 */ +358 private void extractFiles(File archive, File destination, Engine engine) throws AnalysisException { +359 if (archive != null && destination != null) { +360 FileInputStream fis; +361 try { +362 fis = new FileInputStream(archive); +363 } catch (FileNotFoundException ex) { +364 LOGGER.debug("", ex); +365 throw new AnalysisException("Archive file was not found.", ex); +366 } +367 final String archiveExt = FileUtils.getFileExtension(archive.getName()).toLowerCase(); +368 try { +369 if (ZIPPABLES.contains(archiveExt)) { +370 final BufferedInputStream in = new BufferedInputStream(fis); +371 ensureReadableJar(archiveExt, in); +372 extractArchive(new ZipArchiveInputStream(in), destination, engine); +373 } else if ("tar".equals(archiveExt)) { +374 extractArchive(new TarArchiveInputStream(new BufferedInputStream(fis)), destination, engine); +375 } else if ("gz".equals(archiveExt) || "tgz".equals(archiveExt)) { +376 final String uncompressedName = GzipUtils.getUncompressedFilename(archive.getName()); +377 final File f = new File(destination, uncompressedName); +378 if (engine.accept(f)) { +379 decompressFile(new GzipCompressorInputStream(new BufferedInputStream(fis)), f); +380 } +381 } else if ("bz2".equals(archiveExt) || "tbz2".equals(archiveExt)) { +382 final String uncompressedName = BZip2Utils.getUncompressedFilename(archive.getName()); +383 final File f = new File(destination, uncompressedName); +384 if (engine.accept(f)) { +385 decompressFile(new BZip2CompressorInputStream(new BufferedInputStream(fis)), f); +386 } +387 } +388 } catch (ArchiveExtractionException ex) { +389 LOGGER.warn("Exception extracting archive '{}'.", archive.getName()); +390 LOGGER.debug("", ex); +391 } catch (IOException ex) { +392 LOGGER.warn("Exception reading archive '{}'.", archive.getName()); +393 LOGGER.debug("", ex); +394 } finally { +395 close(fis); +396 } +397 } +398 } +399 +400 /** +401 * Checks if the file being scanned is a JAR that begins with '#!/bin' which +402 * indicates it is a fully executable jar. If a fully executable JAR is +403 * identified the input stream will be advanced to the start of the actual +404 * JAR file ( skipping the script). +405 * +406 * @see +407 * <a href="http://docs.spring.io/spring-boot/docs/1.3.0.BUILD-SNAPSHOT/reference/htmlsingle/#deployment-install">Installing +408 * Spring Boot Applications</a> +409 * @param archiveExt the file extension +410 * @param in the input stream +411 * @throws IOException thrown if there is an error reading the stream +412 */ +413 private void ensureReadableJar(final String archiveExt, BufferedInputStream in) throws IOException { +414 if ("jar".equals(archiveExt) && in.markSupported()) { +415 in.mark(7); +416 final byte[] b = new byte[7]; +417 in.read(b); +418 if (b[0] == '#' +419 && b[1] == '!' +420 && b[2] == '/' +421 && b[3] == 'b' +422 && b[4] == 'i' +423 && b[5] == 'n' +424 && b[6] == '/') { +425 boolean stillLooking = true; +426 int chr, nxtChr; +427 while (stillLooking && (chr = in.read()) != -1) { +428 if (chr == '\n' || chr == '\r') { +429 in.mark(4); +430 if ((chr = in.read()) != -1) { +431 if (chr == 'P' && (chr = in.read()) != -1) { +432 if (chr == 'K' && (chr = in.read()) != -1) { +433 if ((chr == 3 || chr == 5 || chr == 7) && (nxtChr = in.read()) != -1) { +434 if (nxtChr == chr + 1) { +435 stillLooking = false; +436 in.reset(); +437 } +438 } +439 } +440 } +441 } +442 } +443 } +444 } +445 } +446 } +447 +448 /** +449 * Extracts files from an archive. +450 * +451 * @param input the archive to extract files from +452 * @param destination the location to write the files too +453 * @param engine the dependency-check engine +454 * @throws ArchiveExtractionException thrown if there is an exception +455 * extracting files from the archive +456 */ +457 private void extractArchive(ArchiveInputStream input, File destination, Engine engine) throws ArchiveExtractionException { +458 ArchiveEntry entry; +459 try { +460 while ((entry = input.getNextEntry()) != null) { +461 final File file = new File(destination, entry.getName()); +462 if (entry.isDirectory()) { +463 if (!file.exists() && !file.mkdirs()) { +464 final String msg = String.format("Unable to create directory '%s'.", file.getAbsolutePath()); +465 throw new AnalysisException(msg); +466 } +467 } else if (engine.accept(file)) { +468 extractAcceptedFile(input, file); +469 } +470 } +471 } catch (Throwable ex) { +472 throw new ArchiveExtractionException(ex); +473 } finally { +474 close(input); +475 } +476 } +477 +478 /** +479 * Extracts a file from an archive. +480 * +481 * @param input the archives input stream +482 * @param file the file to extract +483 * @throws AnalysisException thrown if there is an error 484 */ -485 private boolean isZipFileActuallyJarFile(Dependency dependency) { -486 boolean isJar = false; -487 ZipFile zip = null; +485 private static void extractAcceptedFile(ArchiveInputStream input, File file) throws AnalysisException { +486 LOGGER.debug("Extracting '{}'", file.getPath()); +487 FileOutputStream fos = null; 488 try { -489 zip = new ZipFile(dependency.getActualFilePath()); -490 if (zip.getEntry("META-INF/MANIFEST.MF") != null -491 || zip.getEntry("META-INF/maven") != null) { -492 final Enumeration<ZipArchiveEntry> entries = zip.getEntries(); -493 while (entries.hasMoreElements()) { -494 final ZipArchiveEntry entry = entries.nextElement(); -495 if (!entry.isDirectory()) { -496 final String name = entry.getName().toLowerCase(); -497 if (name.endsWith(".class")) { -498 isJar = true; -499 break; -500 } -501 } -502 } -503 } -504 } catch (IOException ex) { -505 LOGGER.debug("Unable to unzip zip file '{}'", dependency.getFilePath(), ex); -506 } finally { -507 ZipFile.closeQuietly(zip); -508 } -509 -510 return isJar; -511 } -512 } +489 final File parent = file.getParentFile(); +490 if (!parent.isDirectory() && !parent.mkdirs()) { +491 final String msg = String.format("Unable to build directory '%s'.", parent.getAbsolutePath()); +492 throw new AnalysisException(msg); +493 } +494 fos = new FileOutputStream(file); +495 IOUtils.copy(input, fos); +496 } catch (FileNotFoundException ex) { +497 LOGGER.debug("", ex); +498 final String msg = String.format("Unable to find file '%s'.", file.getName()); +499 throw new AnalysisException(msg, ex); +500 } catch (IOException ex) { +501 LOGGER.debug("", ex); +502 final String msg = String.format("IO Exception while parsing file '%s'.", file.getName()); +503 throw new AnalysisException(msg, ex); +504 } finally { +505 close(fos); +506 } +507 } +508 +509 /** +510 * Decompresses a file. +511 * +512 * @param inputStream the compressed file +513 * @param outputFile the location to write the decompressed file +514 * @throws ArchiveExtractionException thrown if there is an exception +515 * decompressing the file +516 */ +517 private void decompressFile(CompressorInputStream inputStream, File outputFile) throws ArchiveExtractionException { +518 LOGGER.debug("Decompressing '{}'", outputFile.getPath()); +519 FileOutputStream out = null; +520 try { +521 out = new FileOutputStream(outputFile); +522 IOUtils.copy(inputStream, out); +523 } catch (FileNotFoundException ex) { +524 LOGGER.debug("", ex); +525 throw new ArchiveExtractionException(ex); +526 } catch (IOException ex) { +527 LOGGER.debug("", ex); +528 throw new ArchiveExtractionException(ex); +529 } finally { +530 close(out); +531 } +532 } +533 +534 /** +535 * Close the given {@link Closeable} instance, ignoring nulls, and logging +536 * any thrown {@link IOException}. +537 * +538 * @param closeable to be closed +539 */ +540 private static void close(Closeable closeable) { +541 if (null != closeable) { +542 try { +543 closeable.close(); +544 } catch (IOException ex) { +545 LOGGER.trace("", ex); +546 } +547 } +548 } +549 +550 /** +551 * Attempts to determine if a zip file is actually a JAR file. +552 * +553 * @param dependency the dependency to check +554 * @return true if the dependency appears to be a JAR file; otherwise false +555 */ +556 private boolean isZipFileActuallyJarFile(Dependency dependency) { +557 boolean isJar = false; +558 ZipFile zip = null; +559 try { +560 zip = new ZipFile(dependency.getActualFilePath()); +561 if (zip.getEntry("META-INF/MANIFEST.MF") != null +562 || zip.getEntry("META-INF/maven") != null) { +563 final Enumeration<ZipArchiveEntry> entries = zip.getEntries(); +564 while (entries.hasMoreElements()) { +565 final ZipArchiveEntry entry = entries.nextElement(); +566 if (!entry.isDirectory()) { +567 final String name = entry.getName().toLowerCase(); +568 if (name.endsWith(".class")) { +569 isJar = true; +570 break; +571 } +572 } +573 } +574 } +575 } catch (IOException ex) { +576 LOGGER.debug("Unable to unzip zip file '{}'", dependency.getFilePath(), ex); +577 } finally { +578 ZipFile.closeQuietly(zip); +579 } +580 +581 return isJar; +582 } +583 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AssemblyAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AssemblyAnalyzer.html index 0c7ce37cf..12b21ab99 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AssemblyAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AssemblyAnalyzer.html @@ -51,268 +51,284 @@ 43 import javax.xml.xpath.XPathFactory; 44 import java.util.ArrayList; 45 import java.util.List; -46 -47 /** -48 * Analyzer for getting company, product, and version information from a .NET assembly. -49 * -50 * @author colezlaw -51 * -52 */ -53 public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer { -54 -55 /** -56 * The analyzer name -57 */ -58 private static final String ANALYZER_NAME = "Assembly Analyzer"; -59 /** -60 * The analysis phase -61 */ -62 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; -63 /** -64 * The list of supported extensions -65 */ -66 private static final String[] SUPPORTED_EXTENSIONS = {"dll", "exe"}; -67 /** -68 * The temp value for GrokAssembly.exe -69 */ -70 private File grokAssemblyExe = null; -71 /** -72 * The DocumentBuilder for parsing the XML -73 */ -74 private DocumentBuilder builder; -75 /** -76 * Logger -77 */ -78 private static final Logger LOGGER = LoggerFactory.getLogger(AssemblyAnalyzer.class); -79 -80 /** -81 * Builds the beginnings of a List for ProcessBuilder -82 * -83 * @return the list of arguments to begin populating the ProcessBuilder -84 */ -85 private List<String> buildArgumentList() { -86 // Use file.separator as a wild guess as to whether this is Windows -87 final List<String> args = new ArrayList<String>(); -88 if (!"\\".equals(System.getProperty("file.separator"))) { -89 if (Settings.getString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH) != null) { -90 args.add(Settings.getString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH)); -91 } else { -92 args.add("mono"); -93 } -94 } -95 args.add(grokAssemblyExe.getPath()); -96 -97 return args; -98 } +46 import javax.xml.parsers.ParserConfigurationException; +47 import org.owasp.dependencycheck.exception.InitializationException; +48 +49 /** +50 * Analyzer for getting company, product, and version information from a .NET +51 * assembly. +52 * +53 * @author colezlaw +54 * +55 */ +56 public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer { +57 +58 /** +59 * The analyzer name +60 */ +61 private static final String ANALYZER_NAME = "Assembly Analyzer"; +62 /** +63 * The analysis phase +64 */ +65 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; +66 /** +67 * The list of supported extensions +68 */ +69 private static final String[] SUPPORTED_EXTENSIONS = {"dll", "exe"}; +70 /** +71 * The temp value for GrokAssembly.exe +72 */ +73 private File grokAssemblyExe = null; +74 /** +75 * The DocumentBuilder for parsing the XML +76 */ +77 private DocumentBuilder builder; +78 /** +79 * Logger +80 */ +81 private static final Logger LOGGER = LoggerFactory.getLogger(AssemblyAnalyzer.class); +82 +83 /** +84 * Builds the beginnings of a List for ProcessBuilder +85 * +86 * @return the list of arguments to begin populating the ProcessBuilder +87 */ +88 private List<String> buildArgumentList() { +89 // Use file.separator as a wild guess as to whether this is Windows +90 final List<String> args = new ArrayList<String>(); +91 if (!"\\".equals(System.getProperty("file.separator"))) { +92 if (Settings.getString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH) != null) { +93 args.add(Settings.getString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH)); +94 } else { +95 args.add("mono"); +96 } +97 } +98 args.add(grokAssemblyExe.getPath()); 99 -100 /** -101 * Performs the analysis on a single Dependency. -102 * -103 * @param dependency the dependency to analyze -104 * @param engine the engine to perform the analysis under -105 * @throws AnalysisException if anything goes sideways -106 */ -107 @Override -108 public void analyzeFileType(Dependency dependency, Engine engine) -109 throws AnalysisException { -110 if (grokAssemblyExe == null) { -111 LOGGER.warn("GrokAssembly didn't get deployed"); -112 return; -113 } -114 -115 final List<String> args = buildArgumentList(); -116 args.add(dependency.getActualFilePath()); -117 final ProcessBuilder pb = new ProcessBuilder(args); -118 Document doc = null; -119 try { -120 final Process proc = pb.start(); -121 -122 doc = builder.parse(proc.getInputStream()); -123 -124 // Try evacuating the error stream -125 final String errorStream = IOUtils.toString(proc.getErrorStream(), "UTF-8"); -126 if (null != errorStream && !errorStream.isEmpty()) { -127 LOGGER.warn("Error from GrokAssembly: {}", errorStream); -128 } -129 -130 int rc = 0; -131 try { -132 rc = proc.waitFor(); -133 } catch (InterruptedException ie) { -134 return; -135 } -136 if (rc == 3) { -137 LOGGER.debug("{} is not a .NET assembly or executable and as such cannot be analyzed by dependency-check", -138 dependency.getActualFilePath()); -139 return; -140 } else if (rc != 0) { -141 LOGGER.warn("Return code {} from GrokAssembly", rc); -142 } -143 -144 final XPath xpath = XPathFactory.newInstance().newXPath(); -145 -146 // First, see if there was an error -147 final String error = xpath.evaluate("/assembly/error", doc); -148 if (error != null && !error.isEmpty()) { -149 throw new AnalysisException(error); -150 } -151 -152 final String version = xpath.evaluate("/assembly/version", doc); -153 if (version != null) { -154 dependency.getVersionEvidence().addEvidence(new Evidence("grokassembly", "version", -155 version, Confidence.HIGHEST)); -156 } -157 -158 final String vendor = xpath.evaluate("/assembly/company", doc); -159 if (vendor != null) { -160 dependency.getVendorEvidence().addEvidence(new Evidence("grokassembly", "vendor", -161 vendor, Confidence.HIGH)); -162 } -163 -164 final String product = xpath.evaluate("/assembly/product", doc); -165 if (product != null) { -166 dependency.getProductEvidence().addEvidence(new Evidence("grokassembly", "product", -167 product, Confidence.HIGH)); -168 } -169 -170 } catch (IOException ioe) { -171 throw new AnalysisException(ioe); -172 } catch (SAXException saxe) { -173 throw new AnalysisException("Couldn't parse GrokAssembly result", saxe); -174 } catch (XPathExpressionException xpe) { -175 // This shouldn't happen -176 throw new AnalysisException(xpe); -177 } -178 } -179 -180 /** -181 * Initialize the analyzer. In this case, extract GrokAssembly.exe to a temporary location. -182 * -183 * @throws Exception if anything goes wrong -184 */ -185 @Override -186 public void initializeFileTypeAnalyzer() throws Exception { -187 final File tempFile = File.createTempFile("GKA", ".exe", Settings.getTempDirectory()); -188 FileOutputStream fos = null; -189 InputStream is = null; -190 try { -191 fos = new FileOutputStream(tempFile); -192 is = AssemblyAnalyzer.class.getClassLoader().getResourceAsStream("GrokAssembly.exe"); -193 IOUtils.copy(is, fos); -194 -195 grokAssemblyExe = tempFile; -196 // Set the temp file to get deleted when we're done -197 grokAssemblyExe.deleteOnExit(); -198 LOGGER.debug("Extracted GrokAssembly.exe to {}", grokAssemblyExe.getPath()); -199 } catch (IOException ioe) { -200 this.setEnabled(false); -201 LOGGER.warn("Could not extract GrokAssembly.exe: {}", ioe.getMessage()); -202 throw new AnalysisException("Could not extract GrokAssembly.exe", ioe); -203 } finally { -204 if (fos != null) { -205 try { -206 fos.close(); -207 } catch (Throwable e) { -208 LOGGER.debug("Error closing output stream"); -209 } -210 } -211 if (is != null) { -212 try { -213 is.close(); -214 } catch (Throwable e) { -215 LOGGER.debug("Error closing input stream"); -216 } -217 } -218 } -219 -220 // Now, need to see if GrokAssembly actually runs from this location. -221 final List<String> args = buildArgumentList(); -222 try { -223 final ProcessBuilder pb = new ProcessBuilder(args); -224 final Process p = pb.start(); -225 // Try evacuating the error stream -226 IOUtils.copy(p.getErrorStream(), NullOutputStream.NULL_OUTPUT_STREAM); -227 -228 final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(p.getInputStream()); -229 final XPath xpath = XPathFactory.newInstance().newXPath(); -230 final String error = xpath.evaluate("/assembly/error", doc); -231 if (p.waitFor() != 1 || error == null || error.isEmpty()) { -232 LOGGER.warn("An error occurred with the .NET AssemblyAnalyzer, please see the log for more details."); -233 LOGGER.debug("GrokAssembly.exe is not working properly"); -234 grokAssemblyExe = null; -235 this.setEnabled(false); -236 throw new AnalysisException("Could not execute .NET AssemblyAnalyzer"); -237 } -238 } catch (AnalysisException e) { -239 throw e; -240 } catch (Throwable e) { -241 LOGGER.warn("An error occurred with the .NET AssemblyAnalyzer;\n" -242 + "this can be ignored unless you are scanning .NET DLLs. Please see the log for more details."); -243 LOGGER.debug("Could not execute GrokAssembly {}", e.getMessage()); -244 this.setEnabled(false); -245 throw new AnalysisException("An error occurred with the .NET AssemblyAnalyzer", e); -246 } -247 builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); -248 } -249 -250 /** -251 * Removes resources used from the local file system. -252 * -253 * @throws Exception thrown if there is a problem closing the analyzer -254 */ -255 @Override -256 public void close() throws Exception { -257 super.close(); -258 try { -259 if (grokAssemblyExe != null && !grokAssemblyExe.delete()) { -260 grokAssemblyExe.deleteOnExit(); -261 } -262 } catch (SecurityException se) { -263 LOGGER.debug("Can't delete temporary GrokAssembly.exe"); -264 } -265 } -266 -267 /** -268 * The File Filter used to filter supported extensions. +100 return args; +101 } +102 +103 /** +104 * Performs the analysis on a single Dependency. +105 * +106 * @param dependency the dependency to analyze +107 * @param engine the engine to perform the analysis under +108 * @throws AnalysisException if anything goes sideways +109 */ +110 @Override +111 public void analyzeFileType(Dependency dependency, Engine engine) +112 throws AnalysisException { +113 if (grokAssemblyExe == null) { +114 LOGGER.warn("GrokAssembly didn't get deployed"); +115 return; +116 } +117 +118 final List<String> args = buildArgumentList(); +119 args.add(dependency.getActualFilePath()); +120 final ProcessBuilder pb = new ProcessBuilder(args); +121 Document doc = null; +122 try { +123 final Process proc = pb.start(); +124 +125 doc = builder.parse(proc.getInputStream()); +126 +127 // Try evacuating the error stream +128 final String errorStream = IOUtils.toString(proc.getErrorStream(), "UTF-8"); +129 if (null != errorStream && !errorStream.isEmpty()) { +130 LOGGER.warn("Error from GrokAssembly: {}", errorStream); +131 } +132 +133 int rc = 0; +134 try { +135 rc = proc.waitFor(); +136 } catch (InterruptedException ie) { +137 return; +138 } +139 if (rc == 3) { +140 LOGGER.debug("{} is not a .NET assembly or executable and as such cannot be analyzed by dependency-check", +141 dependency.getActualFilePath()); +142 return; +143 } else if (rc != 0) { +144 LOGGER.warn("Return code {} from GrokAssembly", rc); +145 } +146 +147 final XPath xpath = XPathFactory.newInstance().newXPath(); +148 +149 // First, see if there was an error +150 final String error = xpath.evaluate("/assembly/error", doc); +151 if (error != null && !error.isEmpty()) { +152 throw new AnalysisException(error); +153 } +154 +155 final String version = xpath.evaluate("/assembly/version", doc); +156 if (version != null) { +157 dependency.getVersionEvidence().addEvidence(new Evidence("grokassembly", "version", +158 version, Confidence.HIGHEST)); +159 } +160 +161 final String vendor = xpath.evaluate("/assembly/company", doc); +162 if (vendor != null) { +163 dependency.getVendorEvidence().addEvidence(new Evidence("grokassembly", "vendor", +164 vendor, Confidence.HIGH)); +165 } +166 +167 final String product = xpath.evaluate("/assembly/product", doc); +168 if (product != null) { +169 dependency.getProductEvidence().addEvidence(new Evidence("grokassembly", "product", +170 product, Confidence.HIGH)); +171 } +172 +173 } catch (IOException ioe) { +174 throw new AnalysisException(ioe); +175 } catch (SAXException saxe) { +176 throw new AnalysisException("Couldn't parse GrokAssembly result", saxe); +177 } catch (XPathExpressionException xpe) { +178 // This shouldn't happen +179 throw new AnalysisException(xpe); +180 } +181 } +182 +183 /** +184 * Initialize the analyzer. In this case, extract GrokAssembly.exe to a +185 * temporary location. +186 * +187 * @throws InitializationException thrown if anything goes wrong +188 */ +189 @Override +190 public void initializeFileTypeAnalyzer() throws InitializationException { +191 final File tempFile; +192 try { +193 tempFile = File.createTempFile("GKA", ".exe", Settings.getTempDirectory()); +194 } catch (IOException ex) { +195 setEnabled(false); +196 throw new InitializationException("Unable to create temporary file for the assembly analyzerr", ex); +197 } +198 FileOutputStream fos = null; +199 InputStream is = null; +200 try { +201 fos = new FileOutputStream(tempFile); +202 is = AssemblyAnalyzer.class.getClassLoader().getResourceAsStream("GrokAssembly.exe"); +203 IOUtils.copy(is, fos); +204 +205 grokAssemblyExe = tempFile; +206 // Set the temp file to get deleted when we're done +207 grokAssemblyExe.deleteOnExit(); +208 LOGGER.debug("Extracted GrokAssembly.exe to {}", grokAssemblyExe.getPath()); +209 } catch (IOException ioe) { +210 this.setEnabled(false); +211 LOGGER.warn("Could not extract GrokAssembly.exe: {}", ioe.getMessage()); +212 throw new InitializationException("Could not extract GrokAssembly.exe", ioe); +213 } finally { +214 if (fos != null) { +215 try { +216 fos.close(); +217 } catch (Throwable e) { +218 LOGGER.debug("Error closing output stream"); +219 } +220 } +221 if (is != null) { +222 try { +223 is.close(); +224 } catch (Throwable e) { +225 LOGGER.debug("Error closing input stream"); +226 } +227 } +228 } +229 +230 // Now, need to see if GrokAssembly actually runs from this location. +231 final List<String> args = buildArgumentList(); +232 try { +233 final ProcessBuilder pb = new ProcessBuilder(args); +234 final Process p = pb.start(); +235 // Try evacuating the error stream +236 IOUtils.copy(p.getErrorStream(), NullOutputStream.NULL_OUTPUT_STREAM); +237 +238 final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(p.getInputStream()); +239 final XPath xpath = XPathFactory.newInstance().newXPath(); +240 final String error = xpath.evaluate("/assembly/error", doc); +241 if (p.waitFor() != 1 || error == null || error.isEmpty()) { +242 LOGGER.warn("An error occurred with the .NET AssemblyAnalyzer, please see the log for more details."); +243 LOGGER.debug("GrokAssembly.exe is not working properly"); +244 grokAssemblyExe = null; +245 setEnabled(false); +246 throw new InitializationException("Could not execute .NET AssemblyAnalyzer"); +247 } +248 } catch (InitializationException e) { +249 throw e; +250 } catch (Throwable e) { +251 LOGGER.warn("An error occurred with the .NET AssemblyAnalyzer;\n" +252 + "this can be ignored unless you are scanning .NET DLLs. Please see the log for more details."); +253 LOGGER.debug("Could not execute GrokAssembly {}", e.getMessage()); +254 setEnabled(false); +255 throw new InitializationException("An error occurred with the .NET AssemblyAnalyzer", e); +256 } +257 try { +258 builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); +259 } catch (ParserConfigurationException ex) { +260 setEnabled(false); +261 throw new InitializationException("Error initializing the assembly analyzer", ex); +262 } +263 } +264 +265 /** +266 * Removes resources used from the local file system. +267 * +268 * @throws Exception thrown if there is a problem closing the analyzer 269 */ -270 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions( -271 SUPPORTED_EXTENSIONS).build(); -272 -273 @Override -274 protected FileFilter getFileFilter() { -275 return FILTER; -276 } -277 -278 /** -279 * Gets this analyzer's name. -280 * -281 * @return the analyzer name -282 */ -283 @Override -284 public String getName() { -285 return ANALYZER_NAME; -286 } +270 @Override +271 public void close() throws Exception { +272 super.close(); +273 try { +274 if (grokAssemblyExe != null && !grokAssemblyExe.delete()) { +275 grokAssemblyExe.deleteOnExit(); +276 } +277 } catch (SecurityException se) { +278 LOGGER.debug("Can't delete temporary GrokAssembly.exe"); +279 } +280 } +281 +282 /** +283 * The File Filter used to filter supported extensions. +284 */ +285 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions( +286 SUPPORTED_EXTENSIONS).build(); 287 -288 /** -289 * Returns the phase this analyzer runs under. -290 * -291 * @return the phase this runs under -292 */ -293 @Override -294 public AnalysisPhase getAnalysisPhase() { -295 return ANALYSIS_PHASE; -296 } -297 -298 /** -299 * Returns the key used in the properties file to reference the analyzer's enabled property. -300 * -301 * @return the analyzer's enabled property setting key -302 */ -303 @Override -304 protected String getAnalyzerEnabledSettingKey() { -305 return Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED; -306 } -307 } +288 @Override +289 protected FileFilter getFileFilter() { +290 return FILTER; +291 } +292 +293 /** +294 * Gets this analyzer's name. +295 * +296 * @return the analyzer name +297 */ +298 @Override +299 public String getName() { +300 return ANALYZER_NAME; +301 } +302 +303 /** +304 * Returns the phase this analyzer runs under. +305 * +306 * @return the phase this runs under +307 */ +308 @Override +309 public AnalysisPhase getAnalysisPhase() { +310 return ANALYSIS_PHASE; +311 } +312 +313 /** +314 * Returns the key used in the properties file to reference the analyzer's +315 * enabled property. +316 * +317 * @return the analyzer's enabled property setting key +318 */ +319 @Override +320 protected String getAnalyzerEnabledSettingKey() { +321 return Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED; +322 } +323 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AutoconfAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AutoconfAnalyzer.html index 7561a4627..3ca94822e 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AutoconfAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AutoconfAnalyzer.html @@ -43,248 +43,253 @@ 35 import java.util.List; 36 import java.util.regex.Matcher; 37 import java.util.regex.Pattern; -38 -39 /** -40 * Used to analyze Autoconf input files named configure.ac or configure.in. Files simply named "configure" are also analyzed, -41 * assuming they are generated by Autoconf, and contain certain special package descriptor variables. -42 * -43 * @author Dale Visser -44 * @see <a href="https://www.gnu.org/software/autoconf/">Autoconf - GNU Project - Free Software Foundation (FSF)</a> -45 */ -46 @Experimental -47 public class AutoconfAnalyzer extends AbstractFileTypeAnalyzer { -48 -49 /** -50 * Autoconf output filename. -51 */ -52 private static final String CONFIGURE = "configure"; -53 -54 /** -55 * Autoconf input filename. -56 */ -57 private static final String CONFIGURE_IN = "configure.in"; -58 -59 /** -60 * Autoconf input filename. -61 */ -62 private static final String CONFIGURE_AC = "configure.ac"; -63 -64 /** -65 * The name of the analyzer. -66 */ -67 private static final String ANALYZER_NAME = "Autoconf Analyzer"; -68 -69 /** -70 * The phase that this analyzer is intended to run in. -71 */ -72 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; -73 -74 /** -75 * The set of file extensions supported by this analyzer. -76 */ -77 private static final String[] EXTENSIONS = {"ac", "in"}; -78 -79 /** -80 * Matches AC_INIT variables in the output configure script. -81 */ -82 private static final Pattern PACKAGE_VAR = Pattern.compile( -83 "PACKAGE_(.+?)='(.*?)'", Pattern.DOTALL | Pattern.CASE_INSENSITIVE); -84 -85 /** -86 * Matches AC_INIT statement in configure.ac file. -87 */ -88 private static final Pattern AC_INIT_PATTERN; -89 -90 static { -91 // each instance of param or sep_param has a capture group -92 final String param = "\\[{0,2}(.+?)\\]{0,2}"; -93 final String sepParam = "\\s*,\\s*" + param; -94 // Group 1: Package -95 // Group 2: Version -96 // Group 3: optional -97 // Group 4: Bug report address (if it exists) -98 // Group 5: optional -99 // Group 6: Tarname (if it exists) -100 // Group 7: optional -101 // Group 8: URL (if it exists) -102 AC_INIT_PATTERN = Pattern.compile(String.format( -103 "AC_INIT\\(%s%s(%s)?(%s)?(%s)?\\s*\\)", param, sepParam, -104 sepParam, sepParam, sepParam), Pattern.DOTALL -105 | Pattern.CASE_INSENSITIVE); -106 } -107 -108 /** -109 * The file filter used to determine which files this analyzer supports. -110 */ -111 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addFilenames(CONFIGURE).addExtensions( -112 EXTENSIONS).build(); -113 -114 /** -115 * Returns the FileFilter -116 * -117 * @return the FileFilter -118 */ -119 @Override -120 protected FileFilter getFileFilter() { -121 return FILTER; -122 } -123 -124 /** -125 * Returns the name of the analyzer. -126 * -127 * @return the name of the analyzer. -128 */ -129 @Override -130 public String getName() { -131 return ANALYZER_NAME; -132 } -133 -134 /** -135 * Returns the phase that the analyzer is intended to run in. -136 * -137 * @return the phase that the analyzer is intended to run in. -138 */ -139 @Override -140 public AnalysisPhase getAnalysisPhase() { -141 return ANALYSIS_PHASE; -142 } -143 -144 /** -145 * Returns the key used in the properties file to reference the analyzer's enabled property. -146 * -147 * @return the analyzer's enabled property setting key -148 */ -149 @Override -150 protected String getAnalyzerEnabledSettingKey() { -151 return Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED; -152 } -153 -154 @Override -155 protected void analyzeFileType(Dependency dependency, Engine engine) -156 throws AnalysisException { -157 final File actualFile = dependency.getActualFile(); -158 final String name = actualFile.getName(); -159 if (name.startsWith(CONFIGURE)) { -160 final File parent = actualFile.getParentFile(); -161 final String parentName = parent.getName(); -162 dependency.setDisplayFileName(parentName + "/" + name); -163 final boolean isOutputScript = CONFIGURE.equals(name); -164 if (isOutputScript || CONFIGURE_AC.equals(name) -165 || CONFIGURE_IN.equals(name)) { -166 final String contents = getFileContents(actualFile); -167 if (!contents.isEmpty()) { -168 if (isOutputScript) { -169 extractConfigureScriptEvidence(dependency, name, -170 contents); -171 } else { -172 gatherEvidence(dependency, name, contents); -173 } -174 } -175 } -176 } else { -177 // copy, alter and set in case some other thread is iterating over -178 final List<Dependency> dependencies = new ArrayList<Dependency>( -179 engine.getDependencies()); -180 dependencies.remove(dependency); -181 engine.setDependencies(dependencies); -182 } -183 } -184 -185 /** -186 * Extracts evidence from the configuration. -187 * -188 * @param dependency the dependency being analyzed -189 * @param name the name of the source of evidence -190 * @param contents the contents to analyze for evidence -191 */ -192 private void extractConfigureScriptEvidence(Dependency dependency, -193 final String name, final String contents) { -194 final Matcher matcher = PACKAGE_VAR.matcher(contents); -195 while (matcher.find()) { -196 final String variable = matcher.group(1); -197 final String value = matcher.group(2); -198 if (!value.isEmpty()) { -199 if (variable.endsWith("NAME")) { -200 dependency.getProductEvidence().addEvidence(name, variable, -201 value, Confidence.HIGHEST); -202 } else if ("VERSION".equals(variable)) { -203 dependency.getVersionEvidence().addEvidence(name, variable, -204 value, Confidence.HIGHEST); -205 } else if ("BUGREPORT".equals(variable)) { -206 dependency.getVendorEvidence().addEvidence(name, variable, -207 value, Confidence.HIGH); -208 } else if ("URL".equals(variable)) { -209 dependency.getVendorEvidence().addEvidence(name, variable, -210 value, Confidence.HIGH); -211 } -212 } -213 } -214 } -215 -216 /** -217 * Retrieves the contents of a given file. -218 * -219 * @param actualFile the file to read -220 * @return the contents of the file -221 * @throws AnalysisException thrown if there is an IO Exception -222 */ -223 private String getFileContents(final File actualFile) -224 throws AnalysisException { -225 try { -226 return FileUtils.readFileToString(actualFile, Charset.defaultCharset()).trim(); -227 } catch (IOException e) { -228 throw new AnalysisException( -229 "Problem occurred while reading dependency file.", e); -230 } -231 } -232 -233 /** -234 * Gathers evidence from a given file -235 * -236 * @param dependency the dependency to add evidence to -237 * @param name the source of the evidence -238 * @param contents the evidence to analyze -239 */ -240 private void gatherEvidence(Dependency dependency, final String name, -241 String contents) { -242 final Matcher matcher = AC_INIT_PATTERN.matcher(contents); -243 if (matcher.find()) { -244 final EvidenceCollection productEvidence = dependency -245 .getProductEvidence(); -246 productEvidence.addEvidence(name, "Package", matcher.group(1), -247 Confidence.HIGHEST); -248 dependency.getVersionEvidence().addEvidence(name, -249 "Package Version", matcher.group(2), Confidence.HIGHEST); -250 final EvidenceCollection vendorEvidence = dependency -251 .getVendorEvidence(); -252 if (null != matcher.group(3)) { -253 vendorEvidence.addEvidence(name, "Bug report address", -254 matcher.group(4), Confidence.HIGH); -255 } -256 if (null != matcher.group(5)) { -257 productEvidence.addEvidence(name, "Tarname", matcher.group(6), -258 Confidence.HIGH); +38 import org.owasp.dependencycheck.exception.InitializationException; +39 +40 /** +41 * Used to analyze Autoconf input files named configure.ac or configure.in. +42 * Files simply named "configure" are also analyzed, assuming they are generated +43 * by Autoconf, and contain certain special package descriptor variables. +44 * +45 * @author Dale Visser +46 * @see <a href="https://www.gnu.org/software/autoconf/">Autoconf - GNU Project +47 * - Free Software Foundation (FSF)</a> +48 */ +49 @Experimental +50 public class AutoconfAnalyzer extends AbstractFileTypeAnalyzer { +51 +52 /** +53 * Autoconf output filename. +54 */ +55 private static final String CONFIGURE = "configure"; +56 +57 /** +58 * Autoconf input filename. +59 */ +60 private static final String CONFIGURE_IN = "configure.in"; +61 +62 /** +63 * Autoconf input filename. +64 */ +65 private static final String CONFIGURE_AC = "configure.ac"; +66 +67 /** +68 * The name of the analyzer. +69 */ +70 private static final String ANALYZER_NAME = "Autoconf Analyzer"; +71 +72 /** +73 * The phase that this analyzer is intended to run in. +74 */ +75 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; +76 +77 /** +78 * The set of file extensions supported by this analyzer. +79 */ +80 private static final String[] EXTENSIONS = {"ac", "in"}; +81 +82 /** +83 * Matches AC_INIT variables in the output configure script. +84 */ +85 private static final Pattern PACKAGE_VAR = Pattern.compile( +86 "PACKAGE_(.+?)='(.*?)'", Pattern.DOTALL | Pattern.CASE_INSENSITIVE); +87 +88 /** +89 * Matches AC_INIT statement in configure.ac file. +90 */ +91 private static final Pattern AC_INIT_PATTERN; +92 +93 static { +94 // each instance of param or sep_param has a capture group +95 final String param = "\\[{0,2}(.+?)\\]{0,2}"; +96 final String sepParam = "\\s*,\\s*" + param; +97 // Group 1: Package +98 // Group 2: Version +99 // Group 3: optional +100 // Group 4: Bug report address (if it exists) +101 // Group 5: optional +102 // Group 6: Tarname (if it exists) +103 // Group 7: optional +104 // Group 8: URL (if it exists) +105 AC_INIT_PATTERN = Pattern.compile(String.format( +106 "AC_INIT\\(%s%s(%s)?(%s)?(%s)?\\s*\\)", param, sepParam, +107 sepParam, sepParam, sepParam), Pattern.DOTALL +108 | Pattern.CASE_INSENSITIVE); +109 } +110 +111 /** +112 * The file filter used to determine which files this analyzer supports. +113 */ +114 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addFilenames(CONFIGURE).addExtensions( +115 EXTENSIONS).build(); +116 +117 /** +118 * Returns the FileFilter +119 * +120 * @return the FileFilter +121 */ +122 @Override +123 protected FileFilter getFileFilter() { +124 return FILTER; +125 } +126 +127 /** +128 * Returns the name of the analyzer. +129 * +130 * @return the name of the analyzer. +131 */ +132 @Override +133 public String getName() { +134 return ANALYZER_NAME; +135 } +136 +137 /** +138 * Returns the phase that the analyzer is intended to run in. +139 * +140 * @return the phase that the analyzer is intended to run in. +141 */ +142 @Override +143 public AnalysisPhase getAnalysisPhase() { +144 return ANALYSIS_PHASE; +145 } +146 +147 /** +148 * Returns the key used in the properties file to reference the analyzer's +149 * enabled property. +150 * +151 * @return the analyzer's enabled property setting key +152 */ +153 @Override +154 protected String getAnalyzerEnabledSettingKey() { +155 return Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED; +156 } +157 +158 @Override +159 protected void analyzeFileType(Dependency dependency, Engine engine) +160 throws AnalysisException { +161 final File actualFile = dependency.getActualFile(); +162 final String name = actualFile.getName(); +163 if (name.startsWith(CONFIGURE)) { +164 final File parent = actualFile.getParentFile(); +165 final String parentName = parent.getName(); +166 dependency.setDisplayFileName(parentName + "/" + name); +167 final boolean isOutputScript = CONFIGURE.equals(name); +168 if (isOutputScript || CONFIGURE_AC.equals(name) +169 || CONFIGURE_IN.equals(name)) { +170 final String contents = getFileContents(actualFile); +171 if (!contents.isEmpty()) { +172 if (isOutputScript) { +173 extractConfigureScriptEvidence(dependency, name, +174 contents); +175 } else { +176 gatherEvidence(dependency, name, contents); +177 } +178 } +179 } +180 } else { +181 // copy, alter and set in case some other thread is iterating over +182 final List<Dependency> dependencies = new ArrayList<Dependency>( +183 engine.getDependencies()); +184 dependencies.remove(dependency); +185 engine.setDependencies(dependencies); +186 } +187 } +188 +189 /** +190 * Extracts evidence from the configuration. +191 * +192 * @param dependency the dependency being analyzed +193 * @param name the name of the source of evidence +194 * @param contents the contents to analyze for evidence +195 */ +196 private void extractConfigureScriptEvidence(Dependency dependency, +197 final String name, final String contents) { +198 final Matcher matcher = PACKAGE_VAR.matcher(contents); +199 while (matcher.find()) { +200 final String variable = matcher.group(1); +201 final String value = matcher.group(2); +202 if (!value.isEmpty()) { +203 if (variable.endsWith("NAME")) { +204 dependency.getProductEvidence().addEvidence(name, variable, +205 value, Confidence.HIGHEST); +206 } else if ("VERSION".equals(variable)) { +207 dependency.getVersionEvidence().addEvidence(name, variable, +208 value, Confidence.HIGHEST); +209 } else if ("BUGREPORT".equals(variable)) { +210 dependency.getVendorEvidence().addEvidence(name, variable, +211 value, Confidence.HIGH); +212 } else if ("URL".equals(variable)) { +213 dependency.getVendorEvidence().addEvidence(name, variable, +214 value, Confidence.HIGH); +215 } +216 } +217 } +218 } +219 +220 /** +221 * Retrieves the contents of a given file. +222 * +223 * @param actualFile the file to read +224 * @return the contents of the file +225 * @throws AnalysisException thrown if there is an IO Exception +226 */ +227 private String getFileContents(final File actualFile) +228 throws AnalysisException { +229 try { +230 return FileUtils.readFileToString(actualFile, Charset.defaultCharset()).trim(); +231 } catch (IOException e) { +232 throw new AnalysisException( +233 "Problem occurred while reading dependency file.", e); +234 } +235 } +236 +237 /** +238 * Gathers evidence from a given file +239 * +240 * @param dependency the dependency to add evidence to +241 * @param name the source of the evidence +242 * @param contents the evidence to analyze +243 */ +244 private void gatherEvidence(Dependency dependency, final String name, +245 String contents) { +246 final Matcher matcher = AC_INIT_PATTERN.matcher(contents); +247 if (matcher.find()) { +248 final EvidenceCollection productEvidence = dependency +249 .getProductEvidence(); +250 productEvidence.addEvidence(name, "Package", matcher.group(1), +251 Confidence.HIGHEST); +252 dependency.getVersionEvidence().addEvidence(name, +253 "Package Version", matcher.group(2), Confidence.HIGHEST); +254 final EvidenceCollection vendorEvidence = dependency +255 .getVendorEvidence(); +256 if (null != matcher.group(3)) { +257 vendorEvidence.addEvidence(name, "Bug report address", +258 matcher.group(4), Confidence.HIGH); 259 } -260 if (null != matcher.group(7)) { -261 final String url = matcher.group(8); -262 if (UrlStringUtils.isUrl(url)) { -263 vendorEvidence.addEvidence(name, "URL", url, -264 Confidence.HIGH); -265 } -266 } -267 } -268 } -269 -270 /** -271 * Initializes the file type analyzer. -272 * -273 * @throws Exception thrown if there is an exception during initialization -274 */ -275 @Override -276 protected void initializeFileTypeAnalyzer() throws Exception { -277 // No initialization needed. -278 } -279 } +260 if (null != matcher.group(5)) { +261 productEvidence.addEvidence(name, "Tarname", matcher.group(6), +262 Confidence.HIGH); +263 } +264 if (null != matcher.group(7)) { +265 final String url = matcher.group(8); +266 if (UrlStringUtils.isUrl(url)) { +267 vendorEvidence.addEvidence(name, "URL", url, +268 Confidence.HIGH); +269 } +270 } +271 } +272 } +273 +274 /** +275 * Initializes the file type analyzer. +276 * +277 * @throws InitializationException thrown if there is an exception during +278 * initialization +279 */ +280 @Override +281 protected void initializeFileTypeAnalyzer() throws InitializationException { +282 // No initialization needed. +283 } +284 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/CMakeAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/CMakeAnalyzer.html index f5f3f1e81..f090a3223 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/CMakeAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/CMakeAnalyzer.html @@ -46,205 +46,211 @@ 38 import java.security.NoSuchAlgorithmException; 39 import java.util.regex.Matcher; 40 import java.util.regex.Pattern; -41 -42 /** -43 * <p> -44 * Used to analyze CMake build files, and collect information that can be used to determine the associated CPE.</p> -45 * <p> -46 * Note: This analyzer catches straightforward invocations of the project command, plus some other observed patterns of version -47 * inclusion in real CMake projects. Many projects make use of older versions of CMake and/or use custom "homebrew" ways to insert -48 * version information. Hopefully as the newer CMake call pattern grows in usage, this analyzer allow more CPEs to be -49 * identified.</p> -50 * -51 * @author Dale Visser -52 */ -53 @Experimental -54 public class CMakeAnalyzer extends AbstractFileTypeAnalyzer { -55 -56 /** -57 * The logger. -58 */ -59 private static final Logger LOGGER = LoggerFactory.getLogger(CMakeAnalyzer.class); -60 -61 /** -62 * Used when compiling file scanning regex patterns. -63 */ -64 private static final int REGEX_OPTIONS = Pattern.DOTALL -65 | Pattern.CASE_INSENSITIVE | Pattern.MULTILINE; -66 -67 /** -68 * Regex to extract the product information. -69 */ -70 private static final Pattern PROJECT = Pattern.compile( -71 "^ *project *\\([ \\n]*(\\w+)[ \\n]*.*?\\)", REGEX_OPTIONS); -72 -73 /** -74 * Regex to extract product and version information. -75 * -76 * Group 1: Product -77 * -78 * Group 2: Version -79 */ -80 private static final Pattern SET_VERSION = Pattern -81 .compile( -82 "^ *set\\s*\\(\\s*(\\w+)_version\\s+\"?(\\d+(?:\\.\\d+)+)[\\s\"]?\\)", -83 REGEX_OPTIONS); -84 -85 /** -86 * Detects files that can be analyzed. -87 */ -88 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(".cmake") -89 .addFilenames("CMakeLists.txt").build(); -90 -91 /** -92 * A reference to SHA1 message digest. -93 */ -94 private static MessageDigest sha1 = null; -95 -96 static { -97 try { -98 sha1 = MessageDigest.getInstance("SHA1"); -99 } catch (NoSuchAlgorithmException e) { -100 LOGGER.error(e.getMessage()); -101 } -102 } -103 -104 /** -105 * Returns the name of the CMake analyzer. -106 * -107 * @return the name of the analyzer -108 * -109 */ -110 @Override -111 public String getName() { -112 return "CMake Analyzer"; -113 } -114 -115 /** -116 * Tell that we are used for information collection. -117 * -118 * @return INFORMATION_COLLECTION -119 */ -120 @Override -121 public AnalysisPhase getAnalysisPhase() { -122 return AnalysisPhase.INFORMATION_COLLECTION; -123 } -124 -125 /** -126 * Returns the set of supported file extensions. -127 * -128 * @return the set of supported file extensions -129 */ -130 @Override -131 protected FileFilter getFileFilter() { -132 return FILTER; -133 } -134 -135 /** -136 * No-op initializer implementation. -137 * -138 * @throws Exception never thrown -139 */ -140 @Override -141 protected void initializeFileTypeAnalyzer() throws Exception { -142 // Nothing to do here. -143 } -144 -145 /** -146 * Analyzes python packages and adds evidence to the dependency. -147 * -148 * @param dependency the dependency being analyzed -149 * @param engine the engine being used to perform the scan -150 * @throws AnalysisException thrown if there is an unrecoverable error analyzing the dependency -151 */ -152 @Override -153 protected void analyzeFileType(Dependency dependency, Engine engine) -154 throws AnalysisException { -155 final File file = dependency.getActualFile(); -156 final String parentName = file.getParentFile().getName(); -157 final String name = file.getName(); -158 dependency.setDisplayFileName(String.format("%s%c%s", parentName, File.separatorChar, name)); -159 String contents; -160 try { -161 contents = FileUtils.readFileToString(file, Charset.defaultCharset()).trim(); -162 } catch (IOException e) { -163 throw new AnalysisException( -164 "Problem occurred while reading dependency file.", e); -165 } -166 -167 if (StringUtils.isNotBlank(contents)) { -168 final Matcher m = PROJECT.matcher(contents); -169 int count = 0; -170 while (m.find()) { -171 count++; -172 LOGGER.debug(String.format( -173 "Found project command match with %d groups: %s", -174 m.groupCount(), m.group(0))); -175 final String group = m.group(1); -176 LOGGER.debug("Group 1: " + group); -177 dependency.getProductEvidence().addEvidence(name, "Project", -178 group, Confidence.HIGH); -179 } -180 LOGGER.debug("Found {} matches.", count); -181 analyzeSetVersionCommand(dependency, engine, contents); -182 } -183 } -184 -185 /** -186 * Extracts the version information from the contents. If more then one version is found additional dependencies are added to -187 * the dependency list. -188 * -189 * @param dependency the dependency being analyzed -190 * @param engine the dependency-check engine -191 * @param contents the version information -192 */ -193 private void analyzeSetVersionCommand(Dependency dependency, Engine engine, String contents) { -194 Dependency currentDep = dependency; -195 -196 final Matcher m = SET_VERSION.matcher(contents); -197 int count = 0; -198 while (m.find()) { -199 count++; -200 LOGGER.debug("Found project command match with {} groups: {}", -201 m.groupCount(), m.group(0)); -202 String product = m.group(1); -203 final String version = m.group(2); -204 LOGGER.debug("Group 1: " + product); -205 LOGGER.debug("Group 2: " + version); -206 final String aliasPrefix = "ALIASOF_"; -207 if (product.startsWith(aliasPrefix)) { -208 product = product.replaceFirst(aliasPrefix, ""); -209 } -210 if (count > 1) { -211 //TODO - refactor so we do not assign to the parameter (checkstyle) -212 currentDep = new Dependency(dependency.getActualFile()); -213 currentDep.setDisplayFileName(String.format("%s:%s", dependency.getDisplayFileName(), product)); -214 final String filePath = String.format("%s:%s", dependency.getFilePath(), product); -215 currentDep.setFilePath(filePath); -216 -217 byte[] path; -218 try { -219 path = filePath.getBytes("UTF-8"); -220 } catch (UnsupportedEncodingException ex) { -221 path = filePath.getBytes(); -222 } -223 currentDep.setSha1sum(Checksum.getHex(sha1.digest(path))); -224 engine.getDependencies().add(currentDep); -225 } -226 final String source = currentDep.getDisplayFileName(); -227 currentDep.getProductEvidence().addEvidence(source, "Product", -228 product, Confidence.MEDIUM); -229 currentDep.getVersionEvidence().addEvidence(source, "Version", -230 version, Confidence.MEDIUM); -231 } -232 LOGGER.debug(String.format("Found %d matches.", count)); -233 } -234 -235 @Override -236 protected String getAnalyzerEnabledSettingKey() { -237 return Settings.KEYS.ANALYZER_CMAKE_ENABLED; -238 } -239 } +41 import org.owasp.dependencycheck.exception.InitializationException; +42 +43 /** +44 * <p> +45 * Used to analyze CMake build files, and collect information that can be used +46 * to determine the associated CPE.</p> +47 * <p> +48 * Note: This analyzer catches straightforward invocations of the project +49 * command, plus some other observed patterns of version inclusion in real CMake +50 * projects. Many projects make use of older versions of CMake and/or use custom +51 * "homebrew" ways to insert version information. Hopefully as the newer CMake +52 * call pattern grows in usage, this analyzer allow more CPEs to be +53 * identified.</p> +54 * +55 * @author Dale Visser +56 */ +57 @Experimental +58 public class CMakeAnalyzer extends AbstractFileTypeAnalyzer { +59 +60 /** +61 * The logger. +62 */ +63 private static final Logger LOGGER = LoggerFactory.getLogger(CMakeAnalyzer.class); +64 +65 /** +66 * Used when compiling file scanning regex patterns. +67 */ +68 private static final int REGEX_OPTIONS = Pattern.DOTALL +69 | Pattern.CASE_INSENSITIVE | Pattern.MULTILINE; +70 +71 /** +72 * Regex to extract the product information. +73 */ +74 private static final Pattern PROJECT = Pattern.compile( +75 "^ *project *\\([ \\n]*(\\w+)[ \\n]*.*?\\)", REGEX_OPTIONS); +76 +77 /** +78 * Regex to extract product and version information. +79 * +80 * Group 1: Product +81 * +82 * Group 2: Version +83 */ +84 private static final Pattern SET_VERSION = Pattern +85 .compile( +86 "^ *set\\s*\\(\\s*(\\w+)_version\\s+\"?(\\d+(?:\\.\\d+)+)[\\s\"]?\\)", +87 REGEX_OPTIONS); +88 +89 /** +90 * Detects files that can be analyzed. +91 */ +92 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(".cmake") +93 .addFilenames("CMakeLists.txt").build(); +94 +95 /** +96 * A reference to SHA1 message digest. +97 */ +98 private static MessageDigest sha1 = null; +99 +100 static { +101 try { +102 sha1 = MessageDigest.getInstance("SHA1"); +103 } catch (NoSuchAlgorithmException e) { +104 LOGGER.error(e.getMessage()); +105 } +106 } +107 +108 /** +109 * Returns the name of the CMake analyzer. +110 * +111 * @return the name of the analyzer +112 * +113 */ +114 @Override +115 public String getName() { +116 return "CMake Analyzer"; +117 } +118 +119 /** +120 * Tell that we are used for information collection. +121 * +122 * @return INFORMATION_COLLECTION +123 */ +124 @Override +125 public AnalysisPhase getAnalysisPhase() { +126 return AnalysisPhase.INFORMATION_COLLECTION; +127 } +128 +129 /** +130 * Returns the set of supported file extensions. +131 * +132 * @return the set of supported file extensions +133 */ +134 @Override +135 protected FileFilter getFileFilter() { +136 return FILTER; +137 } +138 +139 /** +140 * No-op initializer implementation. +141 * +142 * @throws InitializationException never thrown +143 */ +144 @Override +145 protected void initializeFileTypeAnalyzer() throws InitializationException { +146 // Nothing to do here. +147 } +148 +149 /** +150 * Analyzes python packages and adds evidence to the dependency. +151 * +152 * @param dependency the dependency being analyzed +153 * @param engine the engine being used to perform the scan +154 * @throws AnalysisException thrown if there is an unrecoverable error +155 * analyzing the dependency +156 */ +157 @Override +158 protected void analyzeFileType(Dependency dependency, Engine engine) +159 throws AnalysisException { +160 final File file = dependency.getActualFile(); +161 final String parentName = file.getParentFile().getName(); +162 final String name = file.getName(); +163 dependency.setDisplayFileName(String.format("%s%c%s", parentName, File.separatorChar, name)); +164 String contents; +165 try { +166 contents = FileUtils.readFileToString(file, Charset.defaultCharset()).trim(); +167 } catch (IOException e) { +168 throw new AnalysisException( +169 "Problem occurred while reading dependency file.", e); +170 } +171 +172 if (StringUtils.isNotBlank(contents)) { +173 final Matcher m = PROJECT.matcher(contents); +174 int count = 0; +175 while (m.find()) { +176 count++; +177 LOGGER.debug(String.format( +178 "Found project command match with %d groups: %s", +179 m.groupCount(), m.group(0))); +180 final String group = m.group(1); +181 LOGGER.debug("Group 1: " + group); +182 dependency.getProductEvidence().addEvidence(name, "Project", +183 group, Confidence.HIGH); +184 } +185 LOGGER.debug("Found {} matches.", count); +186 analyzeSetVersionCommand(dependency, engine, contents); +187 } +188 } +189 +190 /** +191 * Extracts the version information from the contents. If more then one +192 * version is found additional dependencies are added to the dependency +193 * list. +194 * +195 * @param dependency the dependency being analyzed +196 * @param engine the dependency-check engine +197 * @param contents the version information +198 */ +199 private void analyzeSetVersionCommand(Dependency dependency, Engine engine, String contents) { +200 Dependency currentDep = dependency; +201 +202 final Matcher m = SET_VERSION.matcher(contents); +203 int count = 0; +204 while (m.find()) { +205 count++; +206 LOGGER.debug("Found project command match with {} groups: {}", +207 m.groupCount(), m.group(0)); +208 String product = m.group(1); +209 final String version = m.group(2); +210 LOGGER.debug("Group 1: " + product); +211 LOGGER.debug("Group 2: " + version); +212 final String aliasPrefix = "ALIASOF_"; +213 if (product.startsWith(aliasPrefix)) { +214 product = product.replaceFirst(aliasPrefix, ""); +215 } +216 if (count > 1) { +217 //TODO - refactor so we do not assign to the parameter (checkstyle) +218 currentDep = new Dependency(dependency.getActualFile()); +219 currentDep.setDisplayFileName(String.format("%s:%s", dependency.getDisplayFileName(), product)); +220 final String filePath = String.format("%s:%s", dependency.getFilePath(), product); +221 currentDep.setFilePath(filePath); +222 +223 byte[] path; +224 try { +225 path = filePath.getBytes("UTF-8"); +226 } catch (UnsupportedEncodingException ex) { +227 path = filePath.getBytes(); +228 } +229 currentDep.setSha1sum(Checksum.getHex(sha1.digest(path))); +230 engine.getDependencies().add(currentDep); +231 } +232 final String source = currentDep.getDisplayFileName(); +233 currentDep.getProductEvidence().addEvidence(source, "Product", +234 product, Confidence.MEDIUM); +235 currentDep.getVersionEvidence().addEvidence(source, "Version", +236 version, Confidence.MEDIUM); +237 } +238 LOGGER.debug(String.format("Found %d matches.", count)); +239 } +240 +241 @Override +242 protected String getAnalyzerEnabledSettingKey() { +243 return Settings.KEYS.ANALYZER_CMAKE_ENABLED; +244 } +245 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/CPEAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/CPEAnalyzer.html index c20446fa5..dada8235f 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/CPEAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/CPEAnalyzer.html @@ -53,762 +53,773 @@ 45 import org.owasp.dependencycheck.dependency.EvidenceCollection; 46 import org.owasp.dependencycheck.dependency.Identifier; 47 import org.owasp.dependencycheck.dependency.VulnerableSoftware; -48 import org.owasp.dependencycheck.utils.DependencyVersion; -49 import org.owasp.dependencycheck.utils.DependencyVersionUtil; -50 import org.slf4j.Logger; -51 import org.slf4j.LoggerFactory; -52 -53 /** -54 * CPEAnalyzer is a utility class that takes a project dependency and attempts -55 * to discern if there is an associated CPE. It uses the evidence contained -56 * within the dependency to search the Lucene index. -57 * -58 * @author Jeremy Long -59 */ -60 public class CPEAnalyzer implements Analyzer { -61 -62 /** -63 * The Logger. -64 */ -65 private static final Logger LOGGER = LoggerFactory.getLogger(CPEAnalyzer.class); -66 /** -67 * The maximum number of query results to return. -68 */ -69 static final int MAX_QUERY_RESULTS = 25; -70 /** -71 * The weighting boost to give terms when constructing the Lucene query. -72 */ -73 static final String WEIGHTING_BOOST = "^5"; -74 /** -75 * A string representation of a regular expression defining characters -76 * utilized within the CPE Names. -77 */ -78 static final String CLEANSE_CHARACTER_RX = "[^A-Za-z0-9 ._-]"; -79 /** -80 * A string representation of a regular expression used to remove all but -81 * alpha characters. -82 */ -83 static final String CLEANSE_NONALPHA_RX = "[^A-Za-z]*"; -84 /** -85 * The additional size to add to a new StringBuilder to account for extra -86 * data that will be written into the string. -87 */ -88 static final int STRING_BUILDER_BUFFER = 20; -89 /** -90 * The CPE in memory index. -91 */ -92 private CpeMemoryIndex cpe; -93 /** -94 * The CVE Database. -95 */ -96 private CveDB cve; -97 -98 /** -99 * The URL to perform a search of the NVD CVE data at NIST. -100 */ -101 public static final String NVD_SEARCH_URL = "https://web.nvd.nist.gov/view/vuln/search-results?adv_search=true&cves=on&cpe_version=%s"; -102 -103 /** -104 * Returns the name of this analyzer. -105 * -106 * @return the name of this analyzer. -107 */ -108 @Override -109 public String getName() { -110 return "CPE Analyzer"; -111 } -112 -113 /** -114 * Returns the analysis phase that this analyzer should run in. -115 * -116 * @return the analysis phase that this analyzer should run in. -117 */ -118 @Override -119 public AnalysisPhase getAnalysisPhase() { -120 return AnalysisPhase.IDENTIFIER_ANALYSIS; -121 } -122 -123 /** -124 * Creates the CPE Lucene Index. -125 * -126 * @throws Exception is thrown if there is an issue opening the index. -127 */ -128 @Override -129 public void initialize() throws Exception { -130 this.open(); -131 } -132 -133 /** -134 * Opens the data source. -135 * -136 * @throws IOException when the Lucene directory to be queried does not -137 * exist or is corrupt. -138 * @throws DatabaseException when the database throws an exception. This -139 * usually occurs when the database is in use by another process. -140 */ -141 public void open() throws IOException, DatabaseException { -142 if (!isOpen()) { -143 cve = new CveDB(); -144 cve.open(); -145 cpe = CpeMemoryIndex.getInstance(); -146 try { -147 LOGGER.info("Creating the CPE Index"); -148 final long creationStart = System.currentTimeMillis(); -149 cpe.open(cve); -150 LOGGER.info("CPE Index Created ({} ms)", System.currentTimeMillis() - creationStart); -151 } catch (IndexException ex) { -152 LOGGER.debug("IndexException", ex); -153 throw new DatabaseException(ex); -154 } -155 } -156 } -157 -158 /** -159 * Closes the data sources. -160 */ -161 @Override -162 public void close() { -163 if (cpe != null) { -164 cpe.close(); -165 cpe = null; -166 } -167 if (cve != null) { -168 cve.close(); -169 cve = null; -170 } -171 } -172 -173 public boolean isOpen() { -174 return cpe != null && cpe.isOpen(); -175 } -176 -177 /** -178 * Searches the data store of CPE entries, trying to identify the CPE for -179 * the given dependency based on the evidence contained within. The -180 * dependency passed in is updated with any identified CPE values. -181 * -182 * @param dependency the dependency to search for CPE entries on. -183 * @throws CorruptIndexException is thrown when the Lucene index is corrupt. -184 * @throws IOException is thrown when an IOException occurs. -185 * @throws ParseException is thrown when the Lucene query cannot be parsed. -186 */ -187 protected void determineCPE(Dependency dependency) throws CorruptIndexException, IOException, ParseException { -188 //TODO test dojo-war against this. we shold get dojo-toolkit:dojo-toolkit AND dojo-toolkit:toolkit -189 String vendors = ""; -190 String products = ""; -191 for (Confidence confidence : Confidence.values()) { -192 if (dependency.getVendorEvidence().contains(confidence)) { -193 vendors = addEvidenceWithoutDuplicateTerms(vendors, dependency.getVendorEvidence(), confidence); -194 LOGGER.debug("vendor search: {}", vendors); -195 } -196 if (dependency.getProductEvidence().contains(confidence)) { -197 products = addEvidenceWithoutDuplicateTerms(products, dependency.getProductEvidence(), confidence); -198 LOGGER.debug("product search: {}", products); -199 } -200 if (!vendors.isEmpty() && !products.isEmpty()) { -201 final List<IndexEntry> entries = searchCPE(vendors, products, dependency.getVendorEvidence().getWeighting(), -202 dependency.getProductEvidence().getWeighting()); -203 if (entries == null) { -204 continue; -205 } -206 boolean identifierAdded = false; -207 for (IndexEntry e : entries) { -208 LOGGER.debug("Verifying entry: {}", e); -209 if (verifyEntry(e, dependency)) { -210 final String vendor = e.getVendor(); -211 final String product = e.getProduct(); -212 LOGGER.debug("identified vendor/product: {}/{}", vendor, product); -213 identifierAdded |= determineIdentifiers(dependency, vendor, product, confidence); -214 } +48 import org.owasp.dependencycheck.exception.InitializationException; +49 import org.owasp.dependencycheck.utils.DependencyVersion; +50 import org.owasp.dependencycheck.utils.DependencyVersionUtil; +51 import org.slf4j.Logger; +52 import org.slf4j.LoggerFactory; +53 +54 /** +55 * CPEAnalyzer is a utility class that takes a project dependency and attempts +56 * to discern if there is an associated CPE. It uses the evidence contained +57 * within the dependency to search the Lucene index. +58 * +59 * @author Jeremy Long +60 */ +61 public class CPEAnalyzer implements Analyzer { +62 +63 /** +64 * The Logger. +65 */ +66 private static final Logger LOGGER = LoggerFactory.getLogger(CPEAnalyzer.class); +67 /** +68 * The maximum number of query results to return. +69 */ +70 static final int MAX_QUERY_RESULTS = 25; +71 /** +72 * The weighting boost to give terms when constructing the Lucene query. +73 */ +74 static final String WEIGHTING_BOOST = "^5"; +75 /** +76 * A string representation of a regular expression defining characters +77 * utilized within the CPE Names. +78 */ +79 static final String CLEANSE_CHARACTER_RX = "[^A-Za-z0-9 ._-]"; +80 /** +81 * A string representation of a regular expression used to remove all but +82 * alpha characters. +83 */ +84 static final String CLEANSE_NONALPHA_RX = "[^A-Za-z]*"; +85 /** +86 * The additional size to add to a new StringBuilder to account for extra +87 * data that will be written into the string. +88 */ +89 static final int STRING_BUILDER_BUFFER = 20; +90 /** +91 * The CPE in memory index. +92 */ +93 private CpeMemoryIndex cpe; +94 /** +95 * The CVE Database. +96 */ +97 private CveDB cve; +98 +99 /** +100 * The URL to perform a search of the NVD CVE data at NIST. +101 */ +102 public static final String NVD_SEARCH_URL = "https://web.nvd.nist.gov/view/vuln/search-results?adv_search=true&cves=on&cpe_version=%s"; +103 +104 /** +105 * Returns the name of this analyzer. +106 * +107 * @return the name of this analyzer. +108 */ +109 @Override +110 public String getName() { +111 return "CPE Analyzer"; +112 } +113 +114 /** +115 * Returns the analysis phase that this analyzer should run in. +116 * +117 * @return the analysis phase that this analyzer should run in. +118 */ +119 @Override +120 public AnalysisPhase getAnalysisPhase() { +121 return AnalysisPhase.IDENTIFIER_ANALYSIS; +122 } +123 +124 /** +125 * Creates the CPE Lucene Index. +126 * +127 * @throws InitializationException is thrown if there is an issue opening +128 * the index. +129 */ +130 @Override +131 public void initialize() throws InitializationException { +132 try { +133 this.open(); +134 } catch (IOException ex) { +135 LOGGER.debug("Exception initializing the Lucene Index", ex); +136 throw new InitializationException("An exception occurred initializing the Lucene Index", ex); +137 } catch (DatabaseException ex) { +138 LOGGER.debug("Exception accessing the database", ex); +139 throw new InitializationException("An exception occurred accessing the database", ex); +140 } +141 } +142 +143 /** +144 * Opens the data source. +145 * +146 * @throws IOException when the Lucene directory to be queried does not +147 * exist or is corrupt. +148 * @throws DatabaseException when the database throws an exception. This +149 * usually occurs when the database is in use by another process. +150 */ +151 public void open() throws IOException, DatabaseException { +152 if (!isOpen()) { +153 cve = new CveDB(); +154 cve.open(); +155 cpe = CpeMemoryIndex.getInstance(); +156 try { +157 LOGGER.info("Creating the CPE Index"); +158 final long creationStart = System.currentTimeMillis(); +159 cpe.open(cve); +160 LOGGER.info("CPE Index Created ({} ms)", System.currentTimeMillis() - creationStart); +161 } catch (IndexException ex) { +162 LOGGER.debug("IndexException", ex); +163 throw new DatabaseException(ex); +164 } +165 } +166 } +167 +168 /** +169 * Closes the data sources. +170 */ +171 @Override +172 public void close() { +173 if (cpe != null) { +174 cpe.close(); +175 cpe = null; +176 } +177 if (cve != null) { +178 cve.close(); +179 cve = null; +180 } +181 } +182 +183 public boolean isOpen() { +184 return cpe != null && cpe.isOpen(); +185 } +186 +187 /** +188 * Searches the data store of CPE entries, trying to identify the CPE for +189 * the given dependency based on the evidence contained within. The +190 * dependency passed in is updated with any identified CPE values. +191 * +192 * @param dependency the dependency to search for CPE entries on. +193 * @throws CorruptIndexException is thrown when the Lucene index is corrupt. +194 * @throws IOException is thrown when an IOException occurs. +195 * @throws ParseException is thrown when the Lucene query cannot be parsed. +196 */ +197 protected void determineCPE(Dependency dependency) throws CorruptIndexException, IOException, ParseException { +198 //TODO test dojo-war against this. we shold get dojo-toolkit:dojo-toolkit AND dojo-toolkit:toolkit +199 String vendors = ""; +200 String products = ""; +201 for (Confidence confidence : Confidence.values()) { +202 if (dependency.getVendorEvidence().contains(confidence)) { +203 vendors = addEvidenceWithoutDuplicateTerms(vendors, dependency.getVendorEvidence(), confidence); +204 LOGGER.debug("vendor search: {}", vendors); +205 } +206 if (dependency.getProductEvidence().contains(confidence)) { +207 products = addEvidenceWithoutDuplicateTerms(products, dependency.getProductEvidence(), confidence); +208 LOGGER.debug("product search: {}", products); +209 } +210 if (!vendors.isEmpty() && !products.isEmpty()) { +211 final List<IndexEntry> entries = searchCPE(vendors, products, dependency.getVendorEvidence().getWeighting(), +212 dependency.getProductEvidence().getWeighting()); +213 if (entries == null) { +214 continue; 215 } -216 if (identifierAdded) { -217 break; -218 } -219 } -220 } -221 } -222 -223 /** -224 * Returns the text created by concatenating the text and the values from -225 * the EvidenceCollection (filtered for a specific confidence). This -226 * attempts to prevent duplicate terms from being added.<br/<br/> Note, if -227 * the evidence is longer then 200 characters it will be truncated. -228 * -229 * @param text the base text. -230 * @param ec an EvidenceCollection -231 * @param confidenceFilter a Confidence level to filter the evidence by. -232 * @return the new evidence text -233 */ -234 private String addEvidenceWithoutDuplicateTerms(final String text, final EvidenceCollection ec, Confidence confidenceFilter) { -235 final String txt = (text == null) ? "" : text; -236 final StringBuilder sb = new StringBuilder(txt.length() + (20 * ec.size())); -237 sb.append(' ').append(txt).append(' '); -238 for (Evidence e : ec.iterator(confidenceFilter)) { -239 String value = e.getValue(); -240 -241 //hack to get around the fact that lucene does a really good job of recognizing domains and not -242 // splitting them. TODO - put together a better lucene analyzer specific to the domain. -243 if (value.startsWith("http://")) { -244 value = value.substring(7).replaceAll("\\.", " "); -245 } -246 if (value.startsWith("https://")) { -247 value = value.substring(8).replaceAll("\\.", " "); -248 } -249 if (sb.indexOf(" " + value + " ") < 0) { -250 sb.append(value).append(' '); -251 } -252 } -253 return sb.toString().trim(); -254 } -255 -256 /** -257 * <p> -258 * Searches the Lucene CPE index to identify possible CPE entries associated -259 * with the supplied vendor, product, and version.</p> -260 * -261 * <p> -262 * If either the vendorWeightings or productWeightings lists have been -263 * populated this data is used to add weighting factors to the search.</p> -264 * -265 * @param vendor the text used to search the vendor field -266 * @param product the text used to search the product field -267 * @param vendorWeightings a list of strings to use to add weighting factors -268 * to the vendor field -269 * @param productWeightings Adds a list of strings that will be used to add -270 * weighting factors to the product search -271 * @return a list of possible CPE values -272 */ -273 protected List<IndexEntry> searchCPE(String vendor, String product, -274 Set<String> vendorWeightings, Set<String> productWeightings) { -275 -276 final List<IndexEntry> ret = new ArrayList<IndexEntry>(MAX_QUERY_RESULTS); -277 -278 final String searchString = buildSearch(vendor, product, vendorWeightings, productWeightings); -279 if (searchString == null) { -280 return ret; -281 } -282 try { -283 final TopDocs docs = cpe.search(searchString, MAX_QUERY_RESULTS); -284 for (ScoreDoc d : docs.scoreDocs) { -285 if (d.score >= 0.08) { -286 final Document doc = cpe.getDocument(d.doc); -287 final IndexEntry entry = new IndexEntry(); -288 entry.setVendor(doc.get(Fields.VENDOR)); -289 entry.setProduct(doc.get(Fields.PRODUCT)); -290 entry.setSearchScore(d.score); -291 if (!ret.contains(entry)) { -292 ret.add(entry); -293 } -294 } -295 } -296 return ret; -297 } catch (ParseException ex) { -298 LOGGER.warn("An error occurred querying the CPE data. See the log for more details."); -299 LOGGER.info("Unable to parse: {}", searchString, ex); -300 } catch (IOException ex) { -301 LOGGER.warn("An error occurred reading CPE data. See the log for more details."); -302 LOGGER.info("IO Error with search string: {}", searchString, ex); -303 } -304 return null; -305 } -306 -307 /** -308 * <p> -309 * Builds a Lucene search string by properly escaping data and constructing -310 * a valid search query.</p> -311 * -312 * <p> -313 * If either the possibleVendor or possibleProducts lists have been -314 * populated this data is used to add weighting factors to the search string -315 * generated.</p> -316 * -317 * @param vendor text to search the vendor field -318 * @param product text to search the product field -319 * @param vendorWeighting a list of strings to apply to the vendor to boost -320 * the terms weight -321 * @param productWeightings a list of strings to apply to the product to -322 * boost the terms weight -323 * @return the Lucene query -324 */ -325 protected String buildSearch(String vendor, String product, -326 Set<String> vendorWeighting, Set<String> productWeightings) { -327 final String v = vendor; //.replaceAll("[^\\w\\d]", " "); -328 final String p = product; //.replaceAll("[^\\w\\d]", " "); -329 final StringBuilder sb = new StringBuilder(v.length() + p.length() -330 + Fields.PRODUCT.length() + Fields.VENDOR.length() + STRING_BUILDER_BUFFER); -331 -332 if (!appendWeightedSearch(sb, Fields.PRODUCT, p, productWeightings)) { -333 return null; -334 } -335 sb.append(" AND "); -336 if (!appendWeightedSearch(sb, Fields.VENDOR, v, vendorWeighting)) { -337 return null; -338 } -339 return sb.toString(); -340 } +216 boolean identifierAdded = false; +217 for (IndexEntry e : entries) { +218 LOGGER.debug("Verifying entry: {}", e); +219 if (verifyEntry(e, dependency)) { +220 final String vendor = e.getVendor(); +221 final String product = e.getProduct(); +222 LOGGER.debug("identified vendor/product: {}/{}", vendor, product); +223 identifierAdded |= determineIdentifiers(dependency, vendor, product, confidence); +224 } +225 } +226 if (identifierAdded) { +227 break; +228 } +229 } +230 } +231 } +232 +233 /** +234 * Returns the text created by concatenating the text and the values from +235 * the EvidenceCollection (filtered for a specific confidence). This +236 * attempts to prevent duplicate terms from being added.<br/<br/> Note, if +237 * the evidence is longer then 200 characters it will be truncated. +238 * +239 * @param text the base text. +240 * @param ec an EvidenceCollection +241 * @param confidenceFilter a Confidence level to filter the evidence by. +242 * @return the new evidence text +243 */ +244 private String addEvidenceWithoutDuplicateTerms(final String text, final EvidenceCollection ec, Confidence confidenceFilter) { +245 final String txt = (text == null) ? "" : text; +246 final StringBuilder sb = new StringBuilder(txt.length() + (20 * ec.size())); +247 sb.append(' ').append(txt).append(' '); +248 for (Evidence e : ec.iterator(confidenceFilter)) { +249 String value = e.getValue(); +250 +251 //hack to get around the fact that lucene does a really good job of recognizing domains and not +252 // splitting them. TODO - put together a better lucene analyzer specific to the domain. +253 if (value.startsWith("http://")) { +254 value = value.substring(7).replaceAll("\\.", " "); +255 } +256 if (value.startsWith("https://")) { +257 value = value.substring(8).replaceAll("\\.", " "); +258 } +259 if (sb.indexOf(" " + value + " ") < 0) { +260 sb.append(value).append(' '); +261 } +262 } +263 return sb.toString().trim(); +264 } +265 +266 /** +267 * <p> +268 * Searches the Lucene CPE index to identify possible CPE entries associated +269 * with the supplied vendor, product, and version.</p> +270 * +271 * <p> +272 * If either the vendorWeightings or productWeightings lists have been +273 * populated this data is used to add weighting factors to the search.</p> +274 * +275 * @param vendor the text used to search the vendor field +276 * @param product the text used to search the product field +277 * @param vendorWeightings a list of strings to use to add weighting factors +278 * to the vendor field +279 * @param productWeightings Adds a list of strings that will be used to add +280 * weighting factors to the product search +281 * @return a list of possible CPE values +282 */ +283 protected List<IndexEntry> searchCPE(String vendor, String product, +284 Set<String> vendorWeightings, Set<String> productWeightings) { +285 +286 final List<IndexEntry> ret = new ArrayList<IndexEntry>(MAX_QUERY_RESULTS); +287 +288 final String searchString = buildSearch(vendor, product, vendorWeightings, productWeightings); +289 if (searchString == null) { +290 return ret; +291 } +292 try { +293 final TopDocs docs = cpe.search(searchString, MAX_QUERY_RESULTS); +294 for (ScoreDoc d : docs.scoreDocs) { +295 if (d.score >= 0.08) { +296 final Document doc = cpe.getDocument(d.doc); +297 final IndexEntry entry = new IndexEntry(); +298 entry.setVendor(doc.get(Fields.VENDOR)); +299 entry.setProduct(doc.get(Fields.PRODUCT)); +300 entry.setSearchScore(d.score); +301 if (!ret.contains(entry)) { +302 ret.add(entry); +303 } +304 } +305 } +306 return ret; +307 } catch (ParseException ex) { +308 LOGGER.warn("An error occurred querying the CPE data. See the log for more details."); +309 LOGGER.info("Unable to parse: {}", searchString, ex); +310 } catch (IOException ex) { +311 LOGGER.warn("An error occurred reading CPE data. See the log for more details."); +312 LOGGER.info("IO Error with search string: {}", searchString, ex); +313 } +314 return null; +315 } +316 +317 /** +318 * <p> +319 * Builds a Lucene search string by properly escaping data and constructing +320 * a valid search query.</p> +321 * +322 * <p> +323 * If either the possibleVendor or possibleProducts lists have been +324 * populated this data is used to add weighting factors to the search string +325 * generated.</p> +326 * +327 * @param vendor text to search the vendor field +328 * @param product text to search the product field +329 * @param vendorWeighting a list of strings to apply to the vendor to boost +330 * the terms weight +331 * @param productWeightings a list of strings to apply to the product to +332 * boost the terms weight +333 * @return the Lucene query +334 */ +335 protected String buildSearch(String vendor, String product, +336 Set<String> vendorWeighting, Set<String> productWeightings) { +337 final String v = vendor; //.replaceAll("[^\\w\\d]", " "); +338 final String p = product; //.replaceAll("[^\\w\\d]", " "); +339 final StringBuilder sb = new StringBuilder(v.length() + p.length() +340 + Fields.PRODUCT.length() + Fields.VENDOR.length() + STRING_BUILDER_BUFFER); 341 -342 /** -343 * This method constructs a Lucene query for a given field. The searchText -344 * is split into separate words and if the word is within the list of -345 * weighted words then an additional weighting is applied to the term as it -346 * is appended into the query. -347 * -348 * @param sb a StringBuilder that the query text will be appended to. -349 * @param field the field within the Lucene index that the query is -350 * searching. -351 * @param searchText text used to construct the query. -352 * @param weightedText a list of terms that will be considered higher -353 * importance when searching. -354 * @return if the append was successful. -355 */ -356 private boolean appendWeightedSearch(StringBuilder sb, String field, String searchText, Set<String> weightedText) { -357 sb.append(' ').append(field).append(":( "); -358 -359 final String cleanText = cleanseText(searchText); -360 -361 if (cleanText.isEmpty()) { -362 return false; -363 } -364 -365 if (weightedText == null || weightedText.isEmpty()) { -366 LuceneUtils.appendEscapedLuceneQuery(sb, cleanText); -367 } else { -368 final StringTokenizer tokens = new StringTokenizer(cleanText); -369 while (tokens.hasMoreElements()) { -370 final String word = tokens.nextToken(); -371 StringBuilder temp = null; -372 for (String weighted : weightedText) { -373 final String weightedStr = cleanseText(weighted); -374 if (equalsIgnoreCaseAndNonAlpha(word, weightedStr)) { -375 temp = new StringBuilder(word.length() + 2); -376 LuceneUtils.appendEscapedLuceneQuery(temp, word); -377 temp.append(WEIGHTING_BOOST); -378 if (!word.equalsIgnoreCase(weightedStr)) { -379 temp.append(' '); -380 LuceneUtils.appendEscapedLuceneQuery(temp, weightedStr); -381 temp.append(WEIGHTING_BOOST); -382 } -383 break; -384 } -385 } -386 sb.append(' '); -387 if (temp == null) { -388 LuceneUtils.appendEscapedLuceneQuery(sb, word); -389 } else { -390 sb.append(temp); -391 } -392 } -393 } -394 sb.append(" ) "); -395 return true; -396 } -397 -398 /** -399 * Removes characters from the input text that are not used within the CPE -400 * index. -401 * -402 * @param text is the text to remove the characters from. -403 * @return the text having removed some characters. -404 */ -405 private String cleanseText(String text) { -406 return text.replaceAll(CLEANSE_CHARACTER_RX, " "); -407 } -408 -409 /** -410 * Compares two strings after lower casing them and removing the non-alpha -411 * characters. -412 * -413 * @param l string one to compare. -414 * @param r string two to compare. -415 * @return whether or not the two strings are similar. -416 */ -417 private boolean equalsIgnoreCaseAndNonAlpha(String l, String r) { -418 if (l == null || r == null) { -419 return false; -420 } -421 -422 final String left = l.replaceAll(CLEANSE_NONALPHA_RX, ""); -423 final String right = r.replaceAll(CLEANSE_NONALPHA_RX, ""); -424 return left.equalsIgnoreCase(right); -425 } -426 -427 /** -428 * Ensures that the CPE Identified matches the dependency. This validates -429 * that the product, vendor, and version information for the CPE are -430 * contained within the dependencies evidence. -431 * -432 * @param entry a CPE entry. -433 * @param dependency the dependency that the CPE entries could be for. -434 * @return whether or not the entry is valid. -435 */ -436 private boolean verifyEntry(final IndexEntry entry, final Dependency dependency) { -437 boolean isValid = false; -438 -439 //TODO - does this nullify some of the fuzzy matching that happens in the lucene search? -440 // for instance CPE some-component and in the evidence we have SomeComponent. -441 if (collectionContainsString(dependency.getProductEvidence(), entry.getProduct()) -442 && collectionContainsString(dependency.getVendorEvidence(), entry.getVendor())) { -443 //&& collectionContainsVersion(dependency.getVersionEvidence(), entry.getVersion()) -444 isValid = true; -445 } -446 return isValid; -447 } +342 if (!appendWeightedSearch(sb, Fields.PRODUCT, p, productWeightings)) { +343 return null; +344 } +345 sb.append(" AND "); +346 if (!appendWeightedSearch(sb, Fields.VENDOR, v, vendorWeighting)) { +347 return null; +348 } +349 return sb.toString(); +350 } +351 +352 /** +353 * This method constructs a Lucene query for a given field. The searchText +354 * is split into separate words and if the word is within the list of +355 * weighted words then an additional weighting is applied to the term as it +356 * is appended into the query. +357 * +358 * @param sb a StringBuilder that the query text will be appended to. +359 * @param field the field within the Lucene index that the query is +360 * searching. +361 * @param searchText text used to construct the query. +362 * @param weightedText a list of terms that will be considered higher +363 * importance when searching. +364 * @return if the append was successful. +365 */ +366 private boolean appendWeightedSearch(StringBuilder sb, String field, String searchText, Set<String> weightedText) { +367 sb.append(' ').append(field).append(":( "); +368 +369 final String cleanText = cleanseText(searchText); +370 +371 if (cleanText.isEmpty()) { +372 return false; +373 } +374 +375 if (weightedText == null || weightedText.isEmpty()) { +376 LuceneUtils.appendEscapedLuceneQuery(sb, cleanText); +377 } else { +378 final StringTokenizer tokens = new StringTokenizer(cleanText); +379 while (tokens.hasMoreElements()) { +380 final String word = tokens.nextToken(); +381 StringBuilder temp = null; +382 for (String weighted : weightedText) { +383 final String weightedStr = cleanseText(weighted); +384 if (equalsIgnoreCaseAndNonAlpha(word, weightedStr)) { +385 temp = new StringBuilder(word.length() + 2); +386 LuceneUtils.appendEscapedLuceneQuery(temp, word); +387 temp.append(WEIGHTING_BOOST); +388 if (!word.equalsIgnoreCase(weightedStr)) { +389 temp.append(' '); +390 LuceneUtils.appendEscapedLuceneQuery(temp, weightedStr); +391 temp.append(WEIGHTING_BOOST); +392 } +393 break; +394 } +395 } +396 sb.append(' '); +397 if (temp == null) { +398 LuceneUtils.appendEscapedLuceneQuery(sb, word); +399 } else { +400 sb.append(temp); +401 } +402 } +403 } +404 sb.append(" ) "); +405 return true; +406 } +407 +408 /** +409 * Removes characters from the input text that are not used within the CPE +410 * index. +411 * +412 * @param text is the text to remove the characters from. +413 * @return the text having removed some characters. +414 */ +415 private String cleanseText(String text) { +416 return text.replaceAll(CLEANSE_CHARACTER_RX, " "); +417 } +418 +419 /** +420 * Compares two strings after lower casing them and removing the non-alpha +421 * characters. +422 * +423 * @param l string one to compare. +424 * @param r string two to compare. +425 * @return whether or not the two strings are similar. +426 */ +427 private boolean equalsIgnoreCaseAndNonAlpha(String l, String r) { +428 if (l == null || r == null) { +429 return false; +430 } +431 +432 final String left = l.replaceAll(CLEANSE_NONALPHA_RX, ""); +433 final String right = r.replaceAll(CLEANSE_NONALPHA_RX, ""); +434 return left.equalsIgnoreCase(right); +435 } +436 +437 /** +438 * Ensures that the CPE Identified matches the dependency. This validates +439 * that the product, vendor, and version information for the CPE are +440 * contained within the dependencies evidence. +441 * +442 * @param entry a CPE entry. +443 * @param dependency the dependency that the CPE entries could be for. +444 * @return whether or not the entry is valid. +445 */ +446 private boolean verifyEntry(final IndexEntry entry, final Dependency dependency) { +447 boolean isValid = false; 448 -449 /** -450 * Used to determine if the EvidenceCollection contains a specific string. -451 * -452 * @param ec an EvidenceCollection -453 * @param text the text to search for -454 * @return whether or not the EvidenceCollection contains the string -455 */ -456 private boolean collectionContainsString(EvidenceCollection ec, String text) { -457 //TODO - likely need to change the split... not sure if this will work for CPE with special chars -458 if (text == null) { -459 return false; -460 } -461 final String[] words = text.split("[\\s_-]"); -462 final List<String> list = new ArrayList<String>(); -463 String tempWord = null; -464 for (String word : words) { -465 /* -466 single letter words should be concatenated with the next word. -467 so { "m", "core", "sample" } -> { "mcore", "sample" } -468 */ -469 if (tempWord != null) { -470 list.add(tempWord + word); -471 tempWord = null; -472 } else if (word.length() <= 2) { -473 tempWord = word; -474 } else { -475 list.add(word); -476 } -477 } -478 if (tempWord != null) { -479 if (!list.isEmpty()) { -480 final String tmp = list.get(list.size() - 1) + tempWord; -481 list.add(tmp); -482 } else { -483 list.add(tempWord); -484 } -485 } -486 if (list.isEmpty()) { -487 return false; -488 } -489 boolean contains = true; -490 for (String word : list) { -491 contains &= ec.containsUsedString(word); -492 } -493 return contains; -494 } -495 -496 /** -497 * Analyzes a dependency and attempts to determine if there are any CPE -498 * identifiers for this dependency. -499 * -500 * @param dependency The Dependency to analyze. -501 * @param engine The analysis engine -502 * @throws AnalysisException is thrown if there is an issue analyzing the -503 * dependency. -504 */ -505 @Override -506 public synchronized void analyze(Dependency dependency, Engine engine) throws AnalysisException { -507 try { -508 determineCPE(dependency); -509 } catch (CorruptIndexException ex) { -510 throw new AnalysisException("CPE Index is corrupt.", ex); -511 } catch (IOException ex) { -512 throw new AnalysisException("Failure opening the CPE Index.", ex); -513 } catch (ParseException ex) { -514 throw new AnalysisException("Unable to parse the generated Lucene query for this dependency.", ex); -515 } -516 } -517 -518 /** -519 * Retrieves a list of CPE values from the CveDB based on the vendor and -520 * product passed in. The list is then validated to find only CPEs that are -521 * valid for the given dependency. It is possible that the CPE identified is -522 * a best effort "guess" based on the vendor, product, and version -523 * information. -524 * -525 * @param dependency the Dependency being analyzed -526 * @param vendor the vendor for the CPE being analyzed -527 * @param product the product for the CPE being analyzed -528 * @param currentConfidence the current confidence being used during -529 * analysis -530 * @return <code>true</code> if an identifier was added to the dependency; -531 * otherwise <code>false</code> -532 * @throws UnsupportedEncodingException is thrown if UTF-8 is not supported -533 */ -534 protected boolean determineIdentifiers(Dependency dependency, String vendor, String product, -535 Confidence currentConfidence) throws UnsupportedEncodingException { -536 final Set<VulnerableSoftware> cpes = cve.getCPEs(vendor, product); -537 DependencyVersion bestGuess = new DependencyVersion("-"); -538 Confidence bestGuessConf = null; -539 boolean hasBroadMatch = false; -540 final List<IdentifierMatch> collected = new ArrayList<IdentifierMatch>(); -541 -542 //TODO the following algorithm incorrectly identifies things as a lower version -543 // if there lower confidence evidence when the current (highest) version number -544 // is newer then anything in the NVD. -545 for (Confidence conf : Confidence.values()) { -546 for (Evidence evidence : dependency.getVersionEvidence().iterator(conf)) { -547 final DependencyVersion evVer = DependencyVersionUtil.parseVersion(evidence.getValue()); -548 if (evVer == null) { -549 continue; -550 } -551 for (VulnerableSoftware vs : cpes) { -552 DependencyVersion dbVer; -553 if (vs.getUpdate() != null && !vs.getUpdate().isEmpty()) { -554 dbVer = DependencyVersionUtil.parseVersion(vs.getVersion() + '.' + vs.getUpdate()); -555 } else { -556 dbVer = DependencyVersionUtil.parseVersion(vs.getVersion()); -557 } -558 if (dbVer == null) { //special case, no version specified - everything is vulnerable -559 hasBroadMatch = true; -560 final String url = String.format(NVD_SEARCH_URL, URLEncoder.encode(vs.getName(), "UTF-8")); -561 final IdentifierMatch match = new IdentifierMatch("cpe", vs.getName(), url, IdentifierConfidence.BROAD_MATCH, conf); -562 collected.add(match); -563 } else if (evVer.equals(dbVer)) { //yeah! exact match -564 final String url = String.format(NVD_SEARCH_URL, URLEncoder.encode(vs.getName(), "UTF-8")); -565 final IdentifierMatch match = new IdentifierMatch("cpe", vs.getName(), url, IdentifierConfidence.EXACT_MATCH, conf); -566 collected.add(match); -567 } else //TODO the following isn't quite right is it? need to think about this guessing game a bit more. -568 if (evVer.getVersionParts().size() <= dbVer.getVersionParts().size() -569 && evVer.matchesAtLeastThreeLevels(dbVer)) { -570 if (bestGuessConf == null || bestGuessConf.compareTo(conf) > 0) { -571 if (bestGuess.getVersionParts().size() < dbVer.getVersionParts().size()) { -572 bestGuess = dbVer; -573 bestGuessConf = conf; -574 } -575 } -576 } -577 } -578 if (bestGuessConf == null || bestGuessConf.compareTo(conf) > 0) { -579 if (bestGuess.getVersionParts().size() < evVer.getVersionParts().size()) { -580 bestGuess = evVer; -581 bestGuessConf = conf; -582 } -583 } -584 } -585 } -586 final String cpeName = String.format("cpe:/a:%s:%s:%s", vendor, product, bestGuess.toString()); -587 String url = null; -588 if (hasBroadMatch) { //if we have a broad match we can add the URL to the best guess. -589 final String cpeUrlName = String.format("cpe:/a:%s:%s", vendor, product); -590 url = String.format(NVD_SEARCH_URL, URLEncoder.encode(cpeUrlName, "UTF-8")); -591 } -592 if (bestGuessConf == null) { -593 bestGuessConf = Confidence.LOW; -594 } -595 final IdentifierMatch match = new IdentifierMatch("cpe", cpeName, url, IdentifierConfidence.BEST_GUESS, bestGuessConf); -596 collected.add(match); -597 -598 Collections.sort(collected); -599 final IdentifierConfidence bestIdentifierQuality = collected.get(0).getConfidence(); -600 final Confidence bestEvidenceQuality = collected.get(0).getEvidenceConfidence(); -601 boolean identifierAdded = false; -602 for (IdentifierMatch m : collected) { -603 if (bestIdentifierQuality.equals(m.getConfidence()) -604 && bestEvidenceQuality.equals(m.getEvidenceConfidence())) { -605 final Identifier i = m.getIdentifier(); -606 if (bestIdentifierQuality == IdentifierConfidence.BEST_GUESS) { -607 i.setConfidence(Confidence.LOW); -608 } else { -609 i.setConfidence(bestEvidenceQuality); -610 } -611 dependency.addIdentifier(i); -612 identifierAdded = true; -613 } -614 } -615 return identifierAdded; -616 } -617 -618 /** -619 * The confidence whether the identifier is an exact match, or a best guess. -620 */ -621 private enum IdentifierConfidence { -622 -623 /** -624 * An exact match for the CPE. -625 */ -626 EXACT_MATCH, -627 /** -628 * A best guess for the CPE. -629 */ -630 BEST_GUESS, -631 /** -632 * The entire vendor/product group must be added (without a guess at -633 * version) because there is a CVE with a VS that only specifies -634 * vendor/product. -635 */ -636 BROAD_MATCH -637 } -638 -639 /** -640 * A simple object to hold an identifier and carry information about the -641 * confidence in the identifier. -642 */ -643 private static class IdentifierMatch implements Comparable<IdentifierMatch> { -644 -645 /** -646 * Constructs an IdentifierMatch. -647 * -648 * @param type the type of identifier (such as CPE) -649 * @param value the value of the identifier -650 * @param url the URL of the identifier -651 * @param identifierConfidence the confidence in the identifier: best -652 * guess or exact match -653 * @param evidenceConfidence the confidence of the evidence used to find -654 * the identifier -655 */ -656 IdentifierMatch(String type, String value, String url, IdentifierConfidence identifierConfidence, Confidence evidenceConfidence) { -657 this.identifier = new Identifier(type, value, url); -658 this.confidence = identifierConfidence; -659 this.evidenceConfidence = evidenceConfidence; -660 } -661 //<editor-fold defaultstate="collapsed" desc="Property implementations: evidenceConfidence, confidence, identifier"> -662 /** -663 * The confidence in the evidence used to identify this match. -664 */ -665 private Confidence evidenceConfidence; -666 -667 /** -668 * Get the value of evidenceConfidence -669 * -670 * @return the value of evidenceConfidence -671 */ -672 public Confidence getEvidenceConfidence() { -673 return evidenceConfidence; -674 } -675 -676 /** -677 * Set the value of evidenceConfidence -678 * -679 * @param evidenceConfidence new value of evidenceConfidence -680 */ -681 public void setEvidenceConfidence(Confidence evidenceConfidence) { -682 this.evidenceConfidence = evidenceConfidence; -683 } -684 /** -685 * The confidence whether this is an exact match, or a best guess. -686 */ -687 private IdentifierConfidence confidence; -688 -689 /** -690 * Get the value of confidence. -691 * -692 * @return the value of confidence -693 */ -694 public IdentifierConfidence getConfidence() { -695 return confidence; -696 } -697 -698 /** -699 * Set the value of confidence. -700 * -701 * @param confidence new value of confidence -702 */ -703 public void setConfidence(IdentifierConfidence confidence) { -704 this.confidence = confidence; -705 } -706 /** -707 * The CPE identifier. -708 */ -709 private Identifier identifier; -710 -711 /** -712 * Get the value of identifier. -713 * -714 * @return the value of identifier -715 */ -716 public Identifier getIdentifier() { -717 return identifier; -718 } -719 -720 /** -721 * Set the value of identifier. -722 * -723 * @param identifier new value of identifier -724 */ -725 public void setIdentifier(Identifier identifier) { -726 this.identifier = identifier; -727 } -728 //</editor-fold> -729 //<editor-fold defaultstate="collapsed" desc="Standard implementations of toString, hashCode, and equals"> +449 //TODO - does this nullify some of the fuzzy matching that happens in the lucene search? +450 // for instance CPE some-component and in the evidence we have SomeComponent. +451 if (collectionContainsString(dependency.getProductEvidence(), entry.getProduct()) +452 && collectionContainsString(dependency.getVendorEvidence(), entry.getVendor())) { +453 //&& collectionContainsVersion(dependency.getVersionEvidence(), entry.getVersion()) +454 isValid = true; +455 } +456 return isValid; +457 } +458 +459 /** +460 * Used to determine if the EvidenceCollection contains a specific string. +461 * +462 * @param ec an EvidenceCollection +463 * @param text the text to search for +464 * @return whether or not the EvidenceCollection contains the string +465 */ +466 private boolean collectionContainsString(EvidenceCollection ec, String text) { +467 //TODO - likely need to change the split... not sure if this will work for CPE with special chars +468 if (text == null) { +469 return false; +470 } +471 final String[] words = text.split("[\\s_-]"); +472 final List<String> list = new ArrayList<String>(); +473 String tempWord = null; +474 for (String word : words) { +475 /* +476 single letter words should be concatenated with the next word. +477 so { "m", "core", "sample" } -> { "mcore", "sample" } +478 */ +479 if (tempWord != null) { +480 list.add(tempWord + word); +481 tempWord = null; +482 } else if (word.length() <= 2) { +483 tempWord = word; +484 } else { +485 list.add(word); +486 } +487 } +488 if (tempWord != null) { +489 if (!list.isEmpty()) { +490 final String tmp = list.get(list.size() - 1) + tempWord; +491 list.add(tmp); +492 } else { +493 list.add(tempWord); +494 } +495 } +496 if (list.isEmpty()) { +497 return false; +498 } +499 boolean contains = true; +500 for (String word : list) { +501 contains &= ec.containsUsedString(word); +502 } +503 return contains; +504 } +505 +506 /** +507 * Analyzes a dependency and attempts to determine if there are any CPE +508 * identifiers for this dependency. +509 * +510 * @param dependency The Dependency to analyze. +511 * @param engine The analysis engine +512 * @throws AnalysisException is thrown if there is an issue analyzing the +513 * dependency. +514 */ +515 @Override +516 public synchronized void analyze(Dependency dependency, Engine engine) throws AnalysisException { +517 try { +518 determineCPE(dependency); +519 } catch (CorruptIndexException ex) { +520 throw new AnalysisException("CPE Index is corrupt.", ex); +521 } catch (IOException ex) { +522 throw new AnalysisException("Failure opening the CPE Index.", ex); +523 } catch (ParseException ex) { +524 throw new AnalysisException("Unable to parse the generated Lucene query for this dependency.", ex); +525 } +526 } +527 +528 /** +529 * Retrieves a list of CPE values from the CveDB based on the vendor and +530 * product passed in. The list is then validated to find only CPEs that are +531 * valid for the given dependency. It is possible that the CPE identified is +532 * a best effort "guess" based on the vendor, product, and version +533 * information. +534 * +535 * @param dependency the Dependency being analyzed +536 * @param vendor the vendor for the CPE being analyzed +537 * @param product the product for the CPE being analyzed +538 * @param currentConfidence the current confidence being used during +539 * analysis +540 * @return <code>true</code> if an identifier was added to the dependency; +541 * otherwise <code>false</code> +542 * @throws UnsupportedEncodingException is thrown if UTF-8 is not supported +543 */ +544 protected boolean determineIdentifiers(Dependency dependency, String vendor, String product, +545 Confidence currentConfidence) throws UnsupportedEncodingException { +546 final Set<VulnerableSoftware> cpes = cve.getCPEs(vendor, product); +547 DependencyVersion bestGuess = new DependencyVersion("-"); +548 Confidence bestGuessConf = null; +549 boolean hasBroadMatch = false; +550 final List<IdentifierMatch> collected = new ArrayList<IdentifierMatch>(); +551 +552 //TODO the following algorithm incorrectly identifies things as a lower version +553 // if there lower confidence evidence when the current (highest) version number +554 // is newer then anything in the NVD. +555 for (Confidence conf : Confidence.values()) { +556 for (Evidence evidence : dependency.getVersionEvidence().iterator(conf)) { +557 final DependencyVersion evVer = DependencyVersionUtil.parseVersion(evidence.getValue()); +558 if (evVer == null) { +559 continue; +560 } +561 for (VulnerableSoftware vs : cpes) { +562 DependencyVersion dbVer; +563 if (vs.getUpdate() != null && !vs.getUpdate().isEmpty()) { +564 dbVer = DependencyVersionUtil.parseVersion(vs.getVersion() + '.' + vs.getUpdate()); +565 } else { +566 dbVer = DependencyVersionUtil.parseVersion(vs.getVersion()); +567 } +568 if (dbVer == null) { //special case, no version specified - everything is vulnerable +569 hasBroadMatch = true; +570 final String url = String.format(NVD_SEARCH_URL, URLEncoder.encode(vs.getName(), "UTF-8")); +571 final IdentifierMatch match = new IdentifierMatch("cpe", vs.getName(), url, IdentifierConfidence.BROAD_MATCH, conf); +572 collected.add(match); +573 } else if (evVer.equals(dbVer)) { //yeah! exact match +574 final String url = String.format(NVD_SEARCH_URL, URLEncoder.encode(vs.getName(), "UTF-8")); +575 final IdentifierMatch match = new IdentifierMatch("cpe", vs.getName(), url, IdentifierConfidence.EXACT_MATCH, conf); +576 collected.add(match); +577 +578 //TODO the following isn't quite right is it? need to think about this guessing game a bit more. +579 } else if (evVer.getVersionParts().size() <= dbVer.getVersionParts().size() +580 && evVer.matchesAtLeastThreeLevels(dbVer)) { +581 if (bestGuessConf == null || bestGuessConf.compareTo(conf) > 0) { +582 if (bestGuess.getVersionParts().size() < dbVer.getVersionParts().size()) { +583 bestGuess = dbVer; +584 bestGuessConf = conf; +585 } +586 } +587 } +588 } +589 if (bestGuessConf == null || bestGuessConf.compareTo(conf) > 0) { +590 if (bestGuess.getVersionParts().size() < evVer.getVersionParts().size()) { +591 bestGuess = evVer; +592 bestGuessConf = conf; +593 } +594 } +595 } +596 } +597 final String cpeName = String.format("cpe:/a:%s:%s:%s", vendor, product, bestGuess.toString()); +598 String url = null; +599 if (hasBroadMatch) { //if we have a broad match we can add the URL to the best guess. +600 final String cpeUrlName = String.format("cpe:/a:%s:%s", vendor, product); +601 url = String.format(NVD_SEARCH_URL, URLEncoder.encode(cpeUrlName, "UTF-8")); +602 } +603 if (bestGuessConf == null) { +604 bestGuessConf = Confidence.LOW; +605 } +606 final IdentifierMatch match = new IdentifierMatch("cpe", cpeName, url, IdentifierConfidence.BEST_GUESS, bestGuessConf); +607 collected.add(match); +608 +609 Collections.sort(collected); +610 final IdentifierConfidence bestIdentifierQuality = collected.get(0).getConfidence(); +611 final Confidence bestEvidenceQuality = collected.get(0).getEvidenceConfidence(); +612 boolean identifierAdded = false; +613 for (IdentifierMatch m : collected) { +614 if (bestIdentifierQuality.equals(m.getConfidence()) +615 && bestEvidenceQuality.equals(m.getEvidenceConfidence())) { +616 final Identifier i = m.getIdentifier(); +617 if (bestIdentifierQuality == IdentifierConfidence.BEST_GUESS) { +618 i.setConfidence(Confidence.LOW); +619 } else { +620 i.setConfidence(bestEvidenceQuality); +621 } +622 dependency.addIdentifier(i); +623 identifierAdded = true; +624 } +625 } +626 return identifierAdded; +627 } +628 +629 /** +630 * The confidence whether the identifier is an exact match, or a best guess. +631 */ +632 private enum IdentifierConfidence { +633 +634 /** +635 * An exact match for the CPE. +636 */ +637 EXACT_MATCH, +638 /** +639 * A best guess for the CPE. +640 */ +641 BEST_GUESS, +642 /** +643 * The entire vendor/product group must be added (without a guess at +644 * version) because there is a CVE with a VS that only specifies +645 * vendor/product. +646 */ +647 BROAD_MATCH +648 } +649 +650 /** +651 * A simple object to hold an identifier and carry information about the +652 * confidence in the identifier. +653 */ +654 private static class IdentifierMatch implements Comparable<IdentifierMatch> { +655 +656 /** +657 * Constructs an IdentifierMatch. +658 * +659 * @param type the type of identifier (such as CPE) +660 * @param value the value of the identifier +661 * @param url the URL of the identifier +662 * @param identifierConfidence the confidence in the identifier: best +663 * guess or exact match +664 * @param evidenceConfidence the confidence of the evidence used to find +665 * the identifier +666 */ +667 IdentifierMatch(String type, String value, String url, IdentifierConfidence identifierConfidence, Confidence evidenceConfidence) { +668 this.identifier = new Identifier(type, value, url); +669 this.confidence = identifierConfidence; +670 this.evidenceConfidence = evidenceConfidence; +671 } +672 //<editor-fold defaultstate="collapsed" desc="Property implementations: evidenceConfidence, confidence, identifier"> +673 /** +674 * The confidence in the evidence used to identify this match. +675 */ +676 private Confidence evidenceConfidence; +677 +678 /** +679 * Get the value of evidenceConfidence +680 * +681 * @return the value of evidenceConfidence +682 */ +683 public Confidence getEvidenceConfidence() { +684 return evidenceConfidence; +685 } +686 +687 /** +688 * Set the value of evidenceConfidence +689 * +690 * @param evidenceConfidence new value of evidenceConfidence +691 */ +692 public void setEvidenceConfidence(Confidence evidenceConfidence) { +693 this.evidenceConfidence = evidenceConfidence; +694 } +695 /** +696 * The confidence whether this is an exact match, or a best guess. +697 */ +698 private IdentifierConfidence confidence; +699 +700 /** +701 * Get the value of confidence. +702 * +703 * @return the value of confidence +704 */ +705 public IdentifierConfidence getConfidence() { +706 return confidence; +707 } +708 +709 /** +710 * Set the value of confidence. +711 * +712 * @param confidence new value of confidence +713 */ +714 public void setConfidence(IdentifierConfidence confidence) { +715 this.confidence = confidence; +716 } +717 /** +718 * The CPE identifier. +719 */ +720 private Identifier identifier; +721 +722 /** +723 * Get the value of identifier. +724 * +725 * @return the value of identifier +726 */ +727 public Identifier getIdentifier() { +728 return identifier; +729 } 730 731 /** -732 * Standard toString() implementation. +732 * Set the value of identifier. 733 * -734 * @return the string representation of the object +734 * @param identifier new value of identifier 735 */ -736 @Override -737 public String toString() { -738 return "IdentifierMatch{" + "evidenceConfidence=" + evidenceConfidence -739 + ", confidence=" + confidence + ", identifier=" + identifier + '}'; -740 } +736 public void setIdentifier(Identifier identifier) { +737 this.identifier = identifier; +738 } +739 //</editor-fold> +740 //<editor-fold defaultstate="collapsed" desc="Standard implementations of toString, hashCode, and equals"> 741 742 /** -743 * Standard hashCode() implementation. +743 * Standard toString() implementation. 744 * -745 * @return the hashCode +745 * @return the string representation of the object 746 */ 747 @Override -748 public int hashCode() { -749 int hash = 5; -750 hash = 97 * hash + (this.evidenceConfidence != null ? this.evidenceConfidence.hashCode() : 0); -751 hash = 97 * hash + (this.confidence != null ? this.confidence.hashCode() : 0); -752 hash = 97 * hash + (this.identifier != null ? this.identifier.hashCode() : 0); -753 return hash; -754 } -755 -756 /** -757 * Standard equals implementation. -758 * -759 * @param obj the object to compare -760 * @return true if the objects are equal, otherwise false -761 */ -762 @Override -763 public boolean equals(Object obj) { -764 if (obj == null) { -765 return false; -766 } -767 if (getClass() != obj.getClass()) { -768 return false; -769 } -770 final IdentifierMatch other = (IdentifierMatch) obj; -771 if (this.evidenceConfidence != other.evidenceConfidence) { -772 return false; -773 } -774 if (this.confidence != other.confidence) { -775 return false; -776 } -777 if (this.identifier != other.identifier && (this.identifier == null || !this.identifier.equals(other.identifier))) { -778 return false; -779 } -780 return true; -781 } -782 //</editor-fold> -783 -784 /** -785 * Standard implementation of compareTo that compares identifier -786 * confidence, evidence confidence, and then the identifier. -787 * -788 * @param o the IdentifierMatch to compare to -789 * @return the natural ordering of IdentifierMatch -790 */ -791 @Override -792 public int compareTo(IdentifierMatch o) { -793 int conf = this.confidence.compareTo(o.confidence); -794 if (conf == 0) { -795 conf = this.evidenceConfidence.compareTo(o.evidenceConfidence); -796 if (conf == 0) { -797 conf = identifier.compareTo(o.identifier); -798 } -799 } -800 return conf; -801 } -802 } -803 } +748 public String toString() { +749 return "IdentifierMatch{" + "evidenceConfidence=" + evidenceConfidence +750 + ", confidence=" + confidence + ", identifier=" + identifier + '}'; +751 } +752 +753 /** +754 * Standard hashCode() implementation. +755 * +756 * @return the hashCode +757 */ +758 @Override +759 public int hashCode() { +760 int hash = 5; +761 hash = 97 * hash + (this.evidenceConfidence != null ? this.evidenceConfidence.hashCode() : 0); +762 hash = 97 * hash + (this.confidence != null ? this.confidence.hashCode() : 0); +763 hash = 97 * hash + (this.identifier != null ? this.identifier.hashCode() : 0); +764 return hash; +765 } +766 +767 /** +768 * Standard equals implementation. +769 * +770 * @param obj the object to compare +771 * @return true if the objects are equal, otherwise false +772 */ +773 @Override +774 public boolean equals(Object obj) { +775 if (obj == null) { +776 return false; +777 } +778 if (getClass() != obj.getClass()) { +779 return false; +780 } +781 final IdentifierMatch other = (IdentifierMatch) obj; +782 if (this.evidenceConfidence != other.evidenceConfidence) { +783 return false; +784 } +785 if (this.confidence != other.confidence) { +786 return false; +787 } +788 if (this.identifier != other.identifier && (this.identifier == null || !this.identifier.equals(other.identifier))) { +789 return false; +790 } +791 return true; +792 } +793 //</editor-fold> +794 +795 /** +796 * Standard implementation of compareTo that compares identifier +797 * confidence, evidence confidence, and then the identifier. +798 * +799 * @param o the IdentifierMatch to compare to +800 * @return the natural ordering of IdentifierMatch +801 */ +802 @Override +803 public int compareTo(IdentifierMatch o) { +804 int conf = this.confidence.compareTo(o.confidence); +805 if (conf == 0) { +806 conf = this.evidenceConfidence.compareTo(o.evidenceConfidence); +807 if (conf == 0) { +808 conf = identifier.compareTo(o.identifier); +809 } +810 } +811 return conf; +812 } +813 } +814 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/CentralAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/CentralAnalyzer.html index 39a71f5b4..3fc3de35e 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/CentralAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/CentralAnalyzer.html @@ -41,209 +41,219 @@ 33 import java.io.FileFilter; 34 import java.io.FileNotFoundException; 35 import java.io.IOException; -36 import java.net.URL; -37 import java.util.List; -38 import org.owasp.dependencycheck.utils.DownloadFailedException; -39 import org.owasp.dependencycheck.utils.Downloader; -40 import org.owasp.dependencycheck.utils.FileFilterBuilder; -41 import org.owasp.dependencycheck.utils.InvalidSettingException; -42 import org.owasp.dependencycheck.utils.Settings; -43 -44 /** -45 * Analyzer which will attempt to locate a dependency, and the GAV information, by querying Central for the dependency's SHA-1 -46 * digest. -47 * -48 * @author colezlaw -49 */ -50 public class CentralAnalyzer extends AbstractFileTypeAnalyzer { -51 -52 /** -53 * The logger. -54 */ -55 private static final Logger LOGGER = LoggerFactory.getLogger(CentralAnalyzer.class); -56 -57 /** -58 * The name of the analyzer. -59 */ -60 private static final String ANALYZER_NAME = "Central Analyzer"; -61 -62 /** -63 * The phase in which this analyzer runs. -64 */ -65 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; -66 -67 /** -68 * The types of files on which this will work. -69 */ -70 private static final String SUPPORTED_EXTENSIONS = "jar"; -71 -72 /** -73 * The analyzer should be disabled if there are errors, so this is a flag to determine if such an error has occurred. -74 */ -75 private boolean errorFlag = false; -76 -77 /** -78 * The searcher itself. -79 */ -80 private CentralSearch searcher; -81 /** -82 * Field indicating if the analyzer is enabled. -83 */ -84 private final boolean enabled = checkEnabled(); -85 -86 /** -87 * Determine whether to enable this analyzer or not. -88 * -89 * @return whether the analyzer should be enabled -90 */ -91 @Override -92 public boolean isEnabled() { -93 return enabled; -94 } -95 -96 /** -97 * Determines if this analyzer is enabled. -98 * -99 * @return <code>true</code> if the analyzer is enabled; otherwise <code>false</code> -100 */ -101 private boolean checkEnabled() { -102 boolean retval = false; -103 -104 try { -105 if (Settings.getBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED)) { -106 if (!Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED) -107 || NexusAnalyzer.DEFAULT_URL.equals(Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL))) { -108 LOGGER.debug("Enabling the Central analyzer"); -109 retval = true; -110 } else { -111 LOGGER.info("Nexus analyzer is enabled, disabling the Central Analyzer"); -112 } -113 } else { -114 LOGGER.info("Central analyzer disabled"); -115 } -116 } catch (InvalidSettingException ise) { -117 LOGGER.warn("Invalid setting. Disabling the Central analyzer"); -118 } -119 return retval; -120 } -121 -122 /** -123 * Initializes the analyzer once before any analysis is performed. -124 * -125 * @throws Exception if there's an error during initialization -126 */ -127 @Override -128 public void initializeFileTypeAnalyzer() throws Exception { -129 LOGGER.debug("Initializing Central analyzer"); -130 LOGGER.debug("Central analyzer enabled: {}", isEnabled()); -131 if (isEnabled()) { -132 final String searchUrl = Settings.getString(Settings.KEYS.ANALYZER_CENTRAL_URL); -133 LOGGER.debug("Central Analyzer URL: {}", searchUrl); -134 searcher = new CentralSearch(new URL(searchUrl)); -135 } -136 } -137 -138 /** -139 * Returns the analyzer's name. -140 * -141 * @return the name of the analyzer -142 */ -143 @Override -144 public String getName() { -145 return ANALYZER_NAME; -146 } -147 -148 /** -149 * Returns the key used in the properties file to to reference the analyzer's enabled property. -150 * -151 * @return the analyzer's enabled property setting key. -152 */ -153 @Override -154 protected String getAnalyzerEnabledSettingKey() { -155 return Settings.KEYS.ANALYZER_CENTRAL_ENABLED; -156 } -157 -158 /** -159 * Returns the analysis phase under which the analyzer runs. +36 import java.net.MalformedURLException; +37 import java.net.URL; +38 import java.util.List; +39 import org.owasp.dependencycheck.exception.InitializationException; +40 import org.owasp.dependencycheck.utils.DownloadFailedException; +41 import org.owasp.dependencycheck.utils.Downloader; +42 import org.owasp.dependencycheck.utils.FileFilterBuilder; +43 import org.owasp.dependencycheck.utils.InvalidSettingException; +44 import org.owasp.dependencycheck.utils.Settings; +45 +46 /** +47 * Analyzer which will attempt to locate a dependency, and the GAV information, +48 * by querying Central for the dependency's SHA-1 digest. +49 * +50 * @author colezlaw +51 */ +52 public class CentralAnalyzer extends AbstractFileTypeAnalyzer { +53 +54 /** +55 * The logger. +56 */ +57 private static final Logger LOGGER = LoggerFactory.getLogger(CentralAnalyzer.class); +58 +59 /** +60 * The name of the analyzer. +61 */ +62 private static final String ANALYZER_NAME = "Central Analyzer"; +63 +64 /** +65 * The phase in which this analyzer runs. +66 */ +67 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; +68 +69 /** +70 * The types of files on which this will work. +71 */ +72 private static final String SUPPORTED_EXTENSIONS = "jar"; +73 +74 /** +75 * The analyzer should be disabled if there are errors, so this is a flag to +76 * determine if such an error has occurred. +77 */ +78 private boolean errorFlag = false; +79 +80 /** +81 * The searcher itself. +82 */ +83 private CentralSearch searcher; +84 /** +85 * Field indicating if the analyzer is enabled. +86 */ +87 private final boolean enabled = checkEnabled(); +88 +89 /** +90 * Determine whether to enable this analyzer or not. +91 * +92 * @return whether the analyzer should be enabled +93 */ +94 @Override +95 public boolean isEnabled() { +96 return enabled; +97 } +98 +99 /** +100 * Determines if this analyzer is enabled. +101 * +102 * @return <code>true</code> if the analyzer is enabled; otherwise +103 * <code>false</code> +104 */ +105 private boolean checkEnabled() { +106 boolean retval = false; +107 +108 try { +109 if (Settings.getBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED)) { +110 if (!Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED) +111 || NexusAnalyzer.DEFAULT_URL.equals(Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL))) { +112 LOGGER.debug("Enabling the Central analyzer"); +113 retval = true; +114 } else { +115 LOGGER.info("Nexus analyzer is enabled, disabling the Central Analyzer"); +116 } +117 } else { +118 LOGGER.info("Central analyzer disabled"); +119 } +120 } catch (InvalidSettingException ise) { +121 LOGGER.warn("Invalid setting. Disabling the Central analyzer"); +122 } +123 return retval; +124 } +125 +126 /** +127 * Initializes the analyzer once before any analysis is performed. +128 * +129 * @throws InitializationException if there's an error during initialization +130 */ +131 @Override +132 public void initializeFileTypeAnalyzer() throws InitializationException { +133 LOGGER.debug("Initializing Central analyzer"); +134 LOGGER.debug("Central analyzer enabled: {}", isEnabled()); +135 if (isEnabled()) { +136 final String searchUrl = Settings.getString(Settings.KEYS.ANALYZER_CENTRAL_URL); +137 LOGGER.debug("Central Analyzer URL: {}", searchUrl); +138 try { +139 searcher = new CentralSearch(new URL(searchUrl)); +140 } catch (MalformedURLException ex) { +141 setEnabled(false); +142 throw new InitializationException("The configured URL to Maven Central is malformed: " + searchUrl, ex); +143 } +144 } +145 } +146 +147 /** +148 * Returns the analyzer's name. +149 * +150 * @return the name of the analyzer +151 */ +152 @Override +153 public String getName() { +154 return ANALYZER_NAME; +155 } +156 +157 /** +158 * Returns the key used in the properties file to to reference the +159 * analyzer's enabled property. 160 * -161 * @return the phase under which the analyzer runs +161 * @return the analyzer's enabled property setting key. 162 */ 163 @Override -164 public AnalysisPhase getAnalysisPhase() { -165 return ANALYSIS_PHASE; +164 protected String getAnalyzerEnabledSettingKey() { +165 return Settings.KEYS.ANALYZER_CENTRAL_ENABLED; 166 } 167 168 /** -169 * The file filter used to determine which files this analyzer supports. -170 */ -171 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(SUPPORTED_EXTENSIONS).build(); -172 +169 * Returns the analysis phase under which the analyzer runs. +170 * +171 * @return the phase under which the analyzer runs +172 */ 173 @Override -174 protected FileFilter getFileFilter() { -175 return FILTER; +174 public AnalysisPhase getAnalysisPhase() { +175 return ANALYSIS_PHASE; 176 } 177 178 /** -179 * Performs the analysis. -180 * -181 * @param dependency the dependency to analyze -182 * @param engine the engine -183 * @throws AnalysisException when there's an exception during analysis -184 */ -185 @Override -186 public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { -187 if (errorFlag || !isEnabled()) { -188 return; -189 } -190 -191 try { -192 final List<MavenArtifact> mas = searcher.searchSha1(dependency.getSha1sum()); -193 final Confidence confidence = mas.size() > 1 ? Confidence.HIGH : Confidence.HIGHEST; -194 for (MavenArtifact ma : mas) { -195 LOGGER.debug("Central analyzer found artifact ({}) for dependency ({})", ma, dependency.getFileName()); -196 dependency.addAsEvidence("central", ma, confidence); -197 boolean pomAnalyzed = false; -198 for (Evidence e : dependency.getVendorEvidence()) { -199 if ("pom".equals(e.getSource())) { -200 pomAnalyzed = true; -201 break; -202 } -203 } -204 if (!pomAnalyzed && ma.getPomUrl() != null) { -205 File pomFile = null; -206 try { -207 final File baseDir = Settings.getTempDirectory(); -208 pomFile = File.createTempFile("pom", ".xml", baseDir); -209 if (!pomFile.delete()) { -210 LOGGER.warn("Unable to fetch pom.xml for {} from Central; " -211 + "this could result in undetected CPE/CVEs.", dependency.getFileName()); -212 LOGGER.debug("Unable to delete temp file"); -213 } -214 LOGGER.debug("Downloading {}", ma.getPomUrl()); -215 Downloader.fetchFile(new URL(ma.getPomUrl()), pomFile); -216 PomUtils.analyzePOM(dependency, pomFile); -217 -218 } catch (DownloadFailedException ex) { -219 LOGGER.warn("Unable to download pom.xml for {} from Central; " -220 + "this could result in undetected CPE/CVEs.", dependency.getFileName()); -221 } finally { -222 if (pomFile != null && !FileUtils.deleteQuietly(pomFile)) { -223 pomFile.deleteOnExit(); -224 } -225 } -226 } +179 * The file filter used to determine which files this analyzer supports. +180 */ +181 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(SUPPORTED_EXTENSIONS).build(); +182 +183 @Override +184 protected FileFilter getFileFilter() { +185 return FILTER; +186 } +187 +188 /** +189 * Performs the analysis. +190 * +191 * @param dependency the dependency to analyze +192 * @param engine the engine +193 * @throws AnalysisException when there's an exception during analysis +194 */ +195 @Override +196 public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { +197 if (errorFlag || !isEnabled()) { +198 return; +199 } +200 +201 try { +202 final List<MavenArtifact> mas = searcher.searchSha1(dependency.getSha1sum()); +203 final Confidence confidence = mas.size() > 1 ? Confidence.HIGH : Confidence.HIGHEST; +204 for (MavenArtifact ma : mas) { +205 LOGGER.debug("Central analyzer found artifact ({}) for dependency ({})", ma, dependency.getFileName()); +206 dependency.addAsEvidence("central", ma, confidence); +207 boolean pomAnalyzed = false; +208 for (Evidence e : dependency.getVendorEvidence()) { +209 if ("pom".equals(e.getSource())) { +210 pomAnalyzed = true; +211 break; +212 } +213 } +214 if (!pomAnalyzed && ma.getPomUrl() != null) { +215 File pomFile = null; +216 try { +217 final File baseDir = Settings.getTempDirectory(); +218 pomFile = File.createTempFile("pom", ".xml", baseDir); +219 if (!pomFile.delete()) { +220 LOGGER.warn("Unable to fetch pom.xml for {} from Central; " +221 + "this could result in undetected CPE/CVEs.", dependency.getFileName()); +222 LOGGER.debug("Unable to delete temp file"); +223 } +224 LOGGER.debug("Downloading {}", ma.getPomUrl()); +225 Downloader.fetchFile(new URL(ma.getPomUrl()), pomFile); +226 PomUtils.analyzePOM(dependency, pomFile); 227 -228 } -229 } catch (IllegalArgumentException iae) { -230 LOGGER.info("invalid sha1-hash on {}", dependency.getFileName()); -231 } catch (FileNotFoundException fnfe) { -232 LOGGER.debug("Artifact not found in repository: '{}", dependency.getFileName()); -233 } catch (IOException ioe) { -234 LOGGER.debug("Could not connect to Central search", ioe); -235 errorFlag = true; -236 } -237 } -238 } +228 } catch (DownloadFailedException ex) { +229 LOGGER.warn("Unable to download pom.xml for {} from Central; " +230 + "this could result in undetected CPE/CVEs.", dependency.getFileName()); +231 } finally { +232 if (pomFile != null && !FileUtils.deleteQuietly(pomFile)) { +233 pomFile.deleteOnExit(); +234 } +235 } +236 } +237 +238 } +239 } catch (IllegalArgumentException iae) { +240 LOGGER.info("invalid sha1-hash on {}", dependency.getFileName()); +241 } catch (FileNotFoundException fnfe) { +242 LOGGER.debug("Artifact not found in repository: '{}", dependency.getFileName()); +243 } catch (IOException ioe) { +244 LOGGER.debug("Could not connect to Central search", ioe); +245 errorFlag = true; +246 } +247 } +248 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzer.html index 81b4a7155..4fd93c80a 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzer.html @@ -43,132 +43,141 @@ 35 import java.io.FileNotFoundException; 36 import java.nio.charset.Charset; 37 import java.security.MessageDigest; -38 -39 /** -40 * Used to analyze a composer.lock file for a composer PHP app. -41 * -42 * @author colezlaw -43 */ -44 @Experimental -45 public class ComposerLockAnalyzer extends AbstractFileTypeAnalyzer { -46 -47 /** -48 * The logger. -49 */ -50 private static final Logger LOGGER = LoggerFactory.getLogger(ComposerLockAnalyzer.class); -51 -52 /** -53 * The analyzer name. -54 */ -55 private static final String ANALYZER_NAME = "Composer.lock analyzer"; -56 -57 /** -58 * composer.json. -59 */ -60 private static final String COMPOSER_LOCK = "composer.lock"; -61 -62 /** -63 * The FileFilter. -64 */ -65 private static final FileFilter FILE_FILTER = FileFilterBuilder.newInstance().addFilenames(COMPOSER_LOCK).build(); -66 -67 /** -68 * Returns the FileFilter. -69 * -70 * @return the FileFilter -71 */ -72 @Override -73 protected FileFilter getFileFilter() { -74 return FILE_FILTER; -75 } -76 -77 /** -78 * Initializes the analyzer. -79 * -80 * @throws Exception thrown if an exception occurs getting an instance of SHA1 -81 */ -82 @Override -83 protected void initializeFileTypeAnalyzer() throws Exception { -84 sha1 = MessageDigest.getInstance("SHA1"); -85 } -86 -87 /** -88 * The MessageDigest for calculating a new digest for the new dependencies added. -89 */ -90 private MessageDigest sha1 = null; -91 -92 /** -93 * Entry point for the analyzer. -94 * -95 * @param dependency the dependency to analyze -96 * @param engine the engine scanning -97 * @throws AnalysisException if there's a failure during analysis +38 import java.security.NoSuchAlgorithmException; +39 import org.owasp.dependencycheck.exception.InitializationException; +40 +41 /** +42 * Used to analyze a composer.lock file for a composer PHP app. +43 * +44 * @author colezlaw +45 */ +46 @Experimental +47 public class ComposerLockAnalyzer extends AbstractFileTypeAnalyzer { +48 +49 /** +50 * The logger. +51 */ +52 private static final Logger LOGGER = LoggerFactory.getLogger(ComposerLockAnalyzer.class); +53 +54 /** +55 * The analyzer name. +56 */ +57 private static final String ANALYZER_NAME = "Composer.lock analyzer"; +58 +59 /** +60 * composer.json. +61 */ +62 private static final String COMPOSER_LOCK = "composer.lock"; +63 +64 /** +65 * The FileFilter. +66 */ +67 private static final FileFilter FILE_FILTER = FileFilterBuilder.newInstance().addFilenames(COMPOSER_LOCK).build(); +68 +69 /** +70 * Returns the FileFilter. +71 * +72 * @return the FileFilter +73 */ +74 @Override +75 protected FileFilter getFileFilter() { +76 return FILE_FILTER; +77 } +78 +79 /** +80 * Initializes the analyzer. +81 * +82 * @throws InitializationException thrown if an exception occurs getting an +83 * instance of SHA1 +84 */ +85 @Override +86 protected void initializeFileTypeAnalyzer() throws InitializationException { +87 try { +88 sha1 = MessageDigest.getInstance("SHA1"); +89 } catch (NoSuchAlgorithmException ex) { +90 setEnabled(false); +91 throw new InitializationException("Unable to create SHA1 MmessageDigest", ex); +92 } +93 } +94 +95 /** +96 * The MessageDigest for calculating a new digest for the new dependencies +97 * added. 98 */ -99 @Override -100 protected void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { -101 FileInputStream fis = null; -102 try { -103 fis = new FileInputStream(dependency.getActualFile()); -104 final ComposerLockParser clp = new ComposerLockParser(fis); -105 LOGGER.info("Checking composer.lock file {}", dependency.getActualFilePath()); -106 clp.process(); -107 for (ComposerDependency dep : clp.getDependencies()) { -108 final Dependency d = new Dependency(dependency.getActualFile()); -109 d.setDisplayFileName(String.format("%s:%s/%s", dependency.getDisplayFileName(), dep.getGroup(), dep.getProject())); -110 final String filePath = String.format("%s:%s/%s", dependency.getFilePath(), dep.getGroup(), dep.getProject()); -111 d.setFilePath(filePath); -112 d.setSha1sum(Checksum.getHex(sha1.digest(filePath.getBytes(Charset.defaultCharset())))); -113 d.getVendorEvidence().addEvidence(COMPOSER_LOCK, "vendor", dep.getGroup(), Confidence.HIGHEST); -114 d.getProductEvidence().addEvidence(COMPOSER_LOCK, "product", dep.getProject(), Confidence.HIGHEST); -115 d.getVersionEvidence().addEvidence(COMPOSER_LOCK, "version", dep.getVersion(), Confidence.HIGHEST); -116 LOGGER.info("Adding dependency {}", d); -117 engine.getDependencies().add(d); -118 } -119 } catch (FileNotFoundException fnfe) { -120 LOGGER.warn("Error opening dependency {}", dependency.getActualFilePath()); -121 } catch (ComposerException ce) { -122 LOGGER.warn("Error parsing composer.json {}", dependency.getActualFilePath(), ce); -123 } finally { -124 if (fis != null) { -125 try { -126 fis.close(); -127 } catch (Exception e) { -128 LOGGER.debug("Unable to close file", e); -129 } -130 } -131 } -132 } -133 -134 /** -135 * Gets the key to determine whether the analyzer is enabled. -136 * -137 * @return the key specifying whether the analyzer is enabled -138 */ -139 @Override -140 protected String getAnalyzerEnabledSettingKey() { -141 return Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED; -142 } -143 -144 /** -145 * Returns the analyzer's name. -146 * -147 * @return the analyzer's name -148 */ -149 @Override -150 public String getName() { -151 return ANALYZER_NAME; -152 } -153 -154 /** -155 * Returns the phase this analyzer should run under. -156 * -157 * @return the analysis phase -158 */ -159 @Override -160 public AnalysisPhase getAnalysisPhase() { -161 return AnalysisPhase.INFORMATION_COLLECTION; -162 } -163 } +99 private MessageDigest sha1 = null; +100 +101 /** +102 * Entry point for the analyzer. +103 * +104 * @param dependency the dependency to analyze +105 * @param engine the engine scanning +106 * @throws AnalysisException if there's a failure during analysis +107 */ +108 @Override +109 protected void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { +110 FileInputStream fis = null; +111 try { +112 fis = new FileInputStream(dependency.getActualFile()); +113 final ComposerLockParser clp = new ComposerLockParser(fis); +114 LOGGER.info("Checking composer.lock file {}", dependency.getActualFilePath()); +115 clp.process(); +116 for (ComposerDependency dep : clp.getDependencies()) { +117 final Dependency d = new Dependency(dependency.getActualFile()); +118 d.setDisplayFileName(String.format("%s:%s/%s", dependency.getDisplayFileName(), dep.getGroup(), dep.getProject())); +119 final String filePath = String.format("%s:%s/%s", dependency.getFilePath(), dep.getGroup(), dep.getProject()); +120 d.setFilePath(filePath); +121 d.setSha1sum(Checksum.getHex(sha1.digest(filePath.getBytes(Charset.defaultCharset())))); +122 d.getVendorEvidence().addEvidence(COMPOSER_LOCK, "vendor", dep.getGroup(), Confidence.HIGHEST); +123 d.getProductEvidence().addEvidence(COMPOSER_LOCK, "product", dep.getProject(), Confidence.HIGHEST); +124 d.getVersionEvidence().addEvidence(COMPOSER_LOCK, "version", dep.getVersion(), Confidence.HIGHEST); +125 LOGGER.info("Adding dependency {}", d); +126 engine.getDependencies().add(d); +127 } +128 } catch (FileNotFoundException fnfe) { +129 LOGGER.warn("Error opening dependency {}", dependency.getActualFilePath()); +130 } catch (ComposerException ce) { +131 LOGGER.warn("Error parsing composer.json {}", dependency.getActualFilePath(), ce); +132 } finally { +133 if (fis != null) { +134 try { +135 fis.close(); +136 } catch (Exception e) { +137 LOGGER.debug("Unable to close file", e); +138 } +139 } +140 } +141 } +142 +143 /** +144 * Gets the key to determine whether the analyzer is enabled. +145 * +146 * @return the key specifying whether the analyzer is enabled +147 */ +148 @Override +149 protected String getAnalyzerEnabledSettingKey() { +150 return Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED; +151 } +152 +153 /** +154 * Returns the analyzer's name. +155 * +156 * @return the analyzer's name +157 */ +158 @Override +159 public String getName() { +160 return ANALYZER_NAME; +161 } +162 +163 /** +164 * Returns the phase this analyzer should run under. +165 * +166 * @return the analysis phase +167 */ +168 @Override +169 public AnalysisPhase getAnalysisPhase() { +170 return AnalysisPhase.INFORMATION_COLLECTION; +171 } +172 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/CpeSuppressionAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/CpeSuppressionAnalyzer.html index 91803c5fc..69344012e 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/CpeSuppressionAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/CpeSuppressionAnalyzer.html @@ -28,7 +28,7 @@ 20 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; 21 import org.owasp.dependencycheck.Engine; 22 import org.owasp.dependencycheck.dependency.Dependency; -23 import org.owasp.dependencycheck.suppression.SuppressionRule; +23 import org.owasp.dependencycheck.xml.suppression.SuppressionRule; 24 25 /** 26 * The suppression analyzer processes an externally defined XML document that complies with the suppressions.xsd schema. diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/HintAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/HintAnalyzer.html index 6b5626c04..3cd496f97 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/HintAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/HintAnalyzer.html @@ -25,163 +25,340 @@ 17 */ 18 package org.owasp.dependencycheck.analyzer; 19 -20 import java.util.ArrayList; -21 import java.util.Iterator; -22 import java.util.List; -23 import java.util.Set; -24 import org.owasp.dependencycheck.Engine; -25 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; -26 import org.owasp.dependencycheck.dependency.Confidence; -27 import org.owasp.dependencycheck.dependency.Dependency; -28 import org.owasp.dependencycheck.dependency.Evidence; -29 -30 /** -31 * -32 * @author Jeremy Long -33 */ -34 public class HintAnalyzer extends AbstractAnalyzer implements Analyzer { -35 -36 //<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer"> -37 /** -38 * The name of the analyzer. -39 */ -40 private static final String ANALYZER_NAME = "Hint Analyzer"; -41 /** -42 * The phase that this analyzer is intended to run in. -43 */ -44 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_IDENTIFIER_ANALYSIS; -45 -46 /** -47 * Returns the name of the analyzer. -48 * -49 * @return the name of the analyzer. -50 */ -51 @Override -52 public String getName() { -53 return ANALYZER_NAME; -54 } +20 import java.io.File; +21 import java.io.IOException; +22 import java.io.InputStream; +23 import java.net.MalformedURLException; +24 import java.net.URL; +25 import java.util.ArrayList; +26 import java.util.Iterator; +27 import java.util.List; +28 import java.util.regex.Pattern; +29 import org.owasp.dependencycheck.Engine; +30 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; +31 import org.owasp.dependencycheck.dependency.Dependency; +32 import org.owasp.dependencycheck.dependency.Evidence; +33 import org.owasp.dependencycheck.exception.InitializationException; +34 import org.owasp.dependencycheck.xml.suppression.PropertyType; +35 import org.owasp.dependencycheck.utils.DownloadFailedException; +36 import org.owasp.dependencycheck.utils.Downloader; +37 import org.owasp.dependencycheck.utils.FileUtils; +38 import org.owasp.dependencycheck.utils.Settings; +39 import org.owasp.dependencycheck.xml.hints.VendorDuplicatingHintRule; +40 import org.owasp.dependencycheck.xml.hints.HintParseException; +41 import org.owasp.dependencycheck.xml.hints.HintParser; +42 import org.owasp.dependencycheck.xml.hints.HintRule; +43 import org.owasp.dependencycheck.xml.hints.Hints; +44 import org.slf4j.Logger; +45 import org.slf4j.LoggerFactory; +46 import org.xml.sax.SAXException; +47 +48 /** +49 * This analyzer adds evidence to dependencies to enhance the accuracy of +50 * library identification. +51 * +52 * @author Jeremy Long +53 */ +54 public class HintAnalyzer extends AbstractAnalyzer implements Analyzer { 55 -56 /** -57 * Returns the phase that the analyzer is intended to run in. -58 * -59 * @return the phase that the analyzer is intended to run in. -60 */ -61 @Override -62 public AnalysisPhase getAnalysisPhase() { -63 return ANALYSIS_PHASE; -64 } -65 //</editor-fold> -66 -67 /** -68 * The HintAnalyzer uses knowledge about a dependency to add additional information to help in identification of identifiers -69 * or vulnerabilities. -70 * -71 * @param dependency The dependency being analyzed -72 * @param engine The scanning engine -73 * @throws AnalysisException is thrown if there is an exception analyzing the dependency. -74 */ -75 @Override -76 public void analyze(Dependency dependency, Engine engine) throws AnalysisException { -77 final Evidence springTest1 = new Evidence("Manifest", -78 "Implementation-Title", -79 "Spring Framework", -80 Confidence.HIGH); -81 -82 final Evidence springTest2 = new Evidence("Manifest", -83 "Implementation-Title", -84 "org.springframework.core", -85 Confidence.HIGH); -86 -87 final Evidence springTest3 = new Evidence("Manifest", -88 "Implementation-Title", -89 "spring-core", -90 Confidence.HIGH); -91 -92 final Evidence springTest4 = new Evidence("jar", -93 "package name", -94 "springframework", -95 Confidence.LOW); -96 -97 final Evidence springSecurityTest1 = new Evidence("Manifest", -98 "Bundle-Name", -99 "Spring Security Core", -100 Confidence.MEDIUM); -101 -102 final Evidence springSecurityTest2 = new Evidence("pom", -103 "artifactid", -104 "spring-security-core", -105 Confidence.HIGH); -106 -107 final Evidence symfony = new Evidence("composer.lock", -108 "vendor", -109 "symfony", -110 Confidence.HIGHEST); -111 -112 final Evidence zendframeworkVendor = new Evidence("composer.lock", -113 "vendor", -114 "zendframework", -115 Confidence.HIGHEST); -116 -117 final Evidence zendframeworkProduct = new Evidence("composer.lock", -118 "product", -119 "zendframework", -120 Confidence.HIGHEST); -121 -122 //springsource/vware problem -123 final Set<Evidence> product = dependency.getProductEvidence().getEvidence(); -124 final Set<Evidence> vendor = dependency.getVendorEvidence().getEvidence(); -125 -126 if (product.contains(springTest1) || product.contains(springTest2) || product.contains(springTest3) -127 || (dependency.getFileName().contains("spring") && product.contains(springTest4))) { -128 dependency.getProductEvidence().addEvidence("hint analyzer", "product", "springsource spring framework", Confidence.HIGH); -129 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "SpringSource", Confidence.HIGH); -130 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "vmware", Confidence.HIGH); -131 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "pivotal", Confidence.HIGH); -132 } -133 -134 if (vendor.contains(springTest4)) { -135 dependency.getProductEvidence().addEvidence("hint analyzer", "product", "springsource_spring_framework", Confidence.HIGH); -136 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "vmware", Confidence.HIGH); -137 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "pivotal", Confidence.HIGH); -138 } -139 -140 if (product.contains(springSecurityTest1) || product.contains(springSecurityTest2)) { -141 dependency.getProductEvidence().addEvidence("hint analyzer", "product", "springsource_spring_security", Confidence.HIGH); -142 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "SpringSource", Confidence.HIGH); -143 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "vmware", Confidence.HIGH); -144 } -145 -146 if (vendor.contains(symfony)) { -147 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "sensiolabs", Confidence.HIGHEST); -148 } -149 -150 if (vendor.contains(zendframeworkVendor)) { -151 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "zend", Confidence.HIGHEST); -152 } -153 -154 if (product.contains(zendframeworkProduct)) { -155 dependency.getProductEvidence().addEvidence("hint analyzer", "vendor", "zend_framework", Confidence.HIGHEST); -156 } -157 -158 //sun/oracle problem -159 final Iterator<Evidence> itr = dependency.getVendorEvidence().iterator(); -160 final List<Evidence> newEntries = new ArrayList<Evidence>(); -161 while (itr.hasNext()) { -162 final Evidence e = itr.next(); -163 if ("sun".equalsIgnoreCase(e.getValue(false))) { -164 final Evidence newEvidence = new Evidence(e.getSource() + " (hint)", e.getName(), "oracle", e.getConfidence()); -165 newEntries.add(newEvidence); -166 } else if ("oracle".equalsIgnoreCase(e.getValue(false))) { -167 final Evidence newEvidence = new Evidence(e.getSource() + " (hint)", e.getName(), "sun", e.getConfidence()); -168 newEntries.add(newEvidence); +56 //<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer"> +57 /** +58 * The name of the analyzer. +59 */ +60 private static final String ANALYZER_NAME = "Hint Analyzer"; +61 /** +62 * The phase that this analyzer is intended to run in. +63 */ +64 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_IDENTIFIER_ANALYSIS; +65 +66 /** +67 * Returns the name of the analyzer. +68 * +69 * @return the name of the analyzer. +70 */ +71 @Override +72 public String getName() { +73 return ANALYZER_NAME; +74 } +75 +76 /** +77 * Returns the phase that the analyzer is intended to run in. +78 * +79 * @return the phase that the analyzer is intended to run in. +80 */ +81 @Override +82 public AnalysisPhase getAnalysisPhase() { +83 return ANALYSIS_PHASE; +84 } +85 +86 /** +87 * The initialize method does nothing for this Analyzer. +88 * +89 * @throws InitializationException thrown if there is an exception +90 */ +91 @Override +92 public void initialize() throws InitializationException { +93 try { +94 super.initialize(); +95 loadHintRules(); +96 } catch (HintParseException ex) { +97 LOGGER.debug("Unable to parse hint file", ex); +98 throw new InitializationException("Unable to parse the hint file", ex); +99 } +100 } +101 //</editor-fold> +102 +103 /** +104 * The Logger for use throughout the class +105 */ +106 private static final Logger LOGGER = LoggerFactory.getLogger(HintAnalyzer.class); +107 /** +108 * The name of the hint rule file +109 */ +110 private static final String HINT_RULE_FILE_NAME = "dependencycheck-base-hint.xml"; +111 /** +112 * The collection of hints. +113 */ +114 private Hints hints; +115 +116 /** +117 * The HintAnalyzer uses knowledge about a dependency to add additional +118 * information to help in identification of identifiers or vulnerabilities. +119 * +120 * @param dependency The dependency being analyzed +121 * @param engine The scanning engine +122 * @throws AnalysisException is thrown if there is an exception analyzing +123 * the dependency. +124 */ +125 @Override +126 public void analyze(Dependency dependency, Engine engine) throws AnalysisException { +127 for (HintRule hint : hints.getHintRules()) { +128 boolean shouldAdd = false; +129 for (Evidence given : hint.getGivenVendor()) { +130 if (dependency.getVendorEvidence().getEvidence().contains(given)) { +131 shouldAdd = true; +132 break; +133 } +134 } +135 if (!shouldAdd) { +136 for (Evidence given : hint.getGivenProduct()) { +137 if (dependency.getProductEvidence().getEvidence().contains(given)) { +138 shouldAdd = true; +139 break; +140 } +141 } +142 } +143 if (!shouldAdd) { +144 for (PropertyType pt : hint.getFilenames()) { +145 if (pt.matches(dependency.getFileName())) { +146 shouldAdd = true; +147 } +148 } +149 } +150 if (shouldAdd) { +151 for (Evidence e : hint.getAddVendor()) { +152 dependency.getVendorEvidence().addEvidence(e); +153 } +154 for (Evidence e : hint.getAddProduct()) { +155 dependency.getProductEvidence().addEvidence(e); +156 } +157 } +158 } +159 +160 final Iterator<Evidence> itr = dependency.getVendorEvidence().iterator(); +161 final List<Evidence> newEntries = new ArrayList<Evidence>(); +162 while (itr.hasNext()) { +163 final Evidence e = itr.next(); +164 for (VendorDuplicatingHintRule dhr : hints.getVendorDuplicatingHintRules()) { +165 if (dhr.getValue().equalsIgnoreCase(e.getValue(false))) { +166 newEntries.add(new Evidence(e.getSource() + " (hint)", +167 e.getName(), dhr.getDuplicate(), e.getConfidence())); +168 } 169 } 170 } 171 for (Evidence e : newEntries) { 172 dependency.getVendorEvidence().addEvidence(e); 173 } 174 -175 } -176 } +175 //<editor-fold defaultstate="collapsed" desc="Old implementation"> +176 /* +177 final Evidence springTest1 = new Evidence("Manifest", +178 "Implementation-Title", +179 "Spring Framework", +180 Confidence.HIGH); +181 +182 final Evidence springTest2 = new Evidence("Manifest", +183 "Implementation-Title", +184 "org.springframework.core", +185 Confidence.HIGH); +186 +187 final Evidence springTest3 = new Evidence("Manifest", +188 "Implementation-Title", +189 "spring-core", +190 Confidence.HIGH); +191 +192 final Evidence springTest4 = new Evidence("jar", +193 "package name", +194 "springframework", +195 Confidence.LOW); +196 +197 final Evidence springSecurityTest1 = new Evidence("Manifest", +198 "Bundle-Name", +199 "Spring Security Core", +200 Confidence.MEDIUM); +201 +202 final Evidence springSecurityTest2 = new Evidence("pom", +203 "artifactid", +204 "spring-security-core", +205 Confidence.HIGH); +206 +207 final Evidence symfony = new Evidence("composer.lock", +208 "vendor", +209 "symfony", +210 Confidence.HIGHEST); +211 +212 final Evidence zendframeworkVendor = new Evidence("composer.lock", +213 "vendor", +214 "zendframework", +215 Confidence.HIGHEST); +216 +217 final Evidence zendframeworkProduct = new Evidence("composer.lock", +218 "product", +219 "zendframework", +220 Confidence.HIGHEST); +221 +222 //springsource/vware problem +223 final Set<Evidence> product = dependency.getProductEvidence().getEvidence(); +224 final Set<Evidence> vendor = dependency.getVendorEvidence().getEvidence(); +225 +226 if (product.contains(springTest1) || product.contains(springTest2) || product.contains(springTest3) +227 || (dependency.getFileName().contains("spring") && product.contains(springTest4))) { +228 dependency.getProductEvidence().addEvidence("hint analyzer", "product", "springsource spring framework", Confidence.HIGH); +229 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "SpringSource", Confidence.HIGH); +230 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "vmware", Confidence.HIGH); +231 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "pivotal", Confidence.HIGH); +232 } +233 +234 if (vendor.contains(springTest4)) { +235 dependency.getProductEvidence().addEvidence("hint analyzer", "product", "springsource_spring_framework", Confidence.HIGH); +236 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "vmware", Confidence.HIGH); +237 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "pivotal", Confidence.HIGH); +238 } +239 +240 if (product.contains(springSecurityTest1) || product.contains(springSecurityTest2)) { +241 dependency.getProductEvidence().addEvidence("hint analyzer", "product", "springsource_spring_security", Confidence.HIGH); +242 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "SpringSource", Confidence.HIGH); +243 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "vmware", Confidence.HIGH); +244 } +245 +246 if (vendor.contains(symfony)) { +247 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "sensiolabs", Confidence.HIGHEST); +248 } +249 +250 if (vendor.contains(zendframeworkVendor)) { +251 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "zend", Confidence.HIGHEST); +252 } +253 +254 if (product.contains(zendframeworkProduct)) { +255 dependency.getProductEvidence().addEvidence("hint analyzer", "vendor", "zend_framework", Confidence.HIGHEST); +256 } +257 +258 //sun/oracle problem +259 final Iterator<Evidence> itr = dependency.getVendorEvidence().iterator(); +260 final List<Evidence> newEntries = new ArrayList<Evidence>(); +261 while (itr.hasNext()) { +262 final Evidence e = itr.next(); +263 if ("sun".equalsIgnoreCase(e.getValue(false))) { +264 final Evidence newEvidence = new Evidence(e.getSource() + " (hint)", e.getName(), "oracle", e.getConfidence()); +265 newEntries.add(newEvidence); +266 } else if ("oracle".equalsIgnoreCase(e.getValue(false))) { +267 final Evidence newEvidence = new Evidence(e.getSource() + " (hint)", e.getName(), "sun", e.getConfidence()); +268 newEntries.add(newEvidence); +269 } +270 } +271 for (Evidence e : newEntries) { +272 dependency.getVendorEvidence().addEvidence(e); +273 } +274 */ +275 //</editor-fold> +276 } +277 +278 /** +279 * Loads the hint rules file. +280 * +281 * @throws HintParseException thrown if the XML cannot be parsed. +282 */ +283 private void loadHintRules() throws HintParseException { +284 final HintParser parser = new HintParser(); +285 File file = null; +286 try { +287 hints = parser.parseHints(this.getClass().getClassLoader().getResourceAsStream(HINT_RULE_FILE_NAME)); +288 } catch (HintParseException ex) { +289 LOGGER.error("Unable to parse the base hint data file"); +290 LOGGER.debug("Unable to parse the base hint data file", ex); +291 } catch (SAXException ex) { +292 LOGGER.error("Unable to parse the base hint data file"); +293 LOGGER.debug("Unable to parse the base hint data file", ex); +294 } +295 final String filePath = Settings.getString(Settings.KEYS.HINTS_FILE); +296 if (filePath == null) { +297 return; +298 } +299 boolean deleteTempFile = false; +300 try { +301 final Pattern uriRx = Pattern.compile("^(https?|file)\\:.*", Pattern.CASE_INSENSITIVE); +302 if (uriRx.matcher(filePath).matches()) { +303 deleteTempFile = true; +304 file = FileUtils.getTempFile("hint", "xml"); +305 final URL url = new URL(filePath); +306 try { +307 Downloader.fetchFile(url, file, false); +308 } catch (DownloadFailedException ex) { +309 Downloader.fetchFile(url, file, true); +310 } +311 } else { +312 file = new File(filePath); +313 if (!file.exists()) { +314 final InputStream fromClasspath = this.getClass().getClassLoader().getResourceAsStream(filePath); +315 if (fromClasspath != null) { +316 deleteTempFile = true; +317 file = FileUtils.getTempFile("hint", "xml"); +318 try { +319 org.apache.commons.io.FileUtils.copyInputStreamToFile(fromClasspath, file); +320 } catch (IOException ex) { +321 throw new HintParseException("Unable to locate suppressions file in classpath", ex); +322 } +323 } +324 } +325 } +326 +327 if (file != null) { +328 try { +329 final Hints newHints = parser.parseHints(file); +330 hints.getHintRules().addAll(newHints.getHintRules()); +331 hints.getVendorDuplicatingHintRules().addAll(newHints.getVendorDuplicatingHintRules()); +332 LOGGER.debug("{} hint rules were loaded.", hints.getHintRules().size()); +333 LOGGER.debug("{} duplicating hint rules were loaded.", hints.getVendorDuplicatingHintRules().size()); +334 } catch (HintParseException ex) { +335 LOGGER.warn("Unable to parse hint rule xml file '{}'", file.getPath()); +336 LOGGER.warn(ex.getMessage()); +337 LOGGER.debug("", ex); +338 throw ex; +339 } +340 } +341 } catch (DownloadFailedException ex) { +342 throw new HintParseException("Unable to fetch the configured hint file", ex); +343 } catch (MalformedURLException ex) { +344 throw new HintParseException("Configured hint file has an invalid URL", ex); +345 } catch (IOException ex) { +346 throw new HintParseException("Unable to create temp file for hints", ex); +347 } finally { +348 if (deleteTempFile && file != null) { +349 FileUtils.delete(file); +350 } +351 } +352 } +353 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/JarAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/JarAnalyzer.html index 973da820f..197720596 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/JarAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/JarAnalyzer.html @@ -57,1184 +57,1188 @@ 49 import org.owasp.dependencycheck.dependency.Confidence; 50 import org.owasp.dependencycheck.dependency.Dependency; 51 import org.owasp.dependencycheck.dependency.EvidenceCollection; -52 import org.owasp.dependencycheck.utils.FileFilterBuilder; -53 import org.owasp.dependencycheck.xml.pom.License; -54 import org.owasp.dependencycheck.xml.pom.PomUtils; -55 import org.owasp.dependencycheck.xml.pom.Model; -56 import org.owasp.dependencycheck.utils.FileUtils; -57 import org.owasp.dependencycheck.utils.Settings; -58 import org.slf4j.Logger; -59 import org.slf4j.LoggerFactory; -60 -61 /** -62 * Used to load a JAR file and collect information that can be used to determine -63 * the associated CPE. -64 * -65 * @author Jeremy Long -66 */ -67 public class JarAnalyzer extends AbstractFileTypeAnalyzer { -68 -69 //<editor-fold defaultstate="collapsed" desc="Constants and Member Variables"> -70 /** -71 * The logger. -72 */ -73 private static final Logger LOGGER = LoggerFactory.getLogger(JarAnalyzer.class); -74 /** -75 * The count of directories created during analysis. This is used for -76 * creating temporary directories. -77 */ -78 private static int dirCount = 0; -79 /** -80 * The system independent newline character. -81 */ -82 private static final String NEWLINE = System.getProperty("line.separator"); -83 /** -84 * A list of values in the manifest to ignore as they only result in false -85 * positives. -86 */ -87 private static final Set<String> IGNORE_VALUES = newHashSet( -88 "Sun Java System Application Server"); -89 /** -90 * A list of elements in the manifest to ignore. -91 */ -92 private static final Set<String> IGNORE_KEYS = newHashSet( -93 "built-by", -94 "created-by", -95 "builtby", -96 "createdby", -97 "build-jdk", -98 "buildjdk", -99 "ant-version", -100 "antversion", -101 "dynamicimportpackage", -102 "dynamicimport-package", -103 "dynamic-importpackage", -104 "dynamic-import-package", -105 "import-package", -106 "ignore-package", -107 "export-package", -108 "importpackage", -109 "ignorepackage", -110 "exportpackage", -111 "sealed", -112 "manifest-version", -113 "archiver-version", -114 "manifestversion", -115 "archiverversion", -116 "classpath", -117 "class-path", -118 "tool", -119 "bundle-manifestversion", -120 "bundlemanifestversion", -121 "bundle-vendor", -122 "include-resource", -123 "embed-dependency", -124 "ipojo-components", -125 "ipojo-extension", -126 "eclipse-sourcereferences"); -127 /** -128 * Deprecated Jar manifest attribute, that is, nonetheless, useful for -129 * analysis. -130 */ -131 @SuppressWarnings("deprecation") -132 private static final String IMPLEMENTATION_VENDOR_ID = Attributes.Name.IMPLEMENTATION_VENDOR_ID -133 .toString(); -134 /** -135 * item in some manifest, should be considered medium confidence. -136 */ -137 private static final String BUNDLE_VERSION = "Bundle-Version"; //: 2.1.2 -138 /** -139 * item in some manifest, should be considered medium confidence. -140 */ -141 private static final String BUNDLE_DESCRIPTION = "Bundle-Description"; //: Apache Struts 2 -142 /** -143 * item in some manifest, should be considered medium confidence. -144 */ -145 private static final String BUNDLE_NAME = "Bundle-Name"; //: Struts 2 Core -146 /** -147 * A pattern to detect HTML within text. -148 */ -149 private static final Pattern HTML_DETECTION_PATTERN = Pattern.compile("\\<[a-z]+.*/?\\>", Pattern.CASE_INSENSITIVE); -150 -151 //</editor-fold> -152 /** -153 * Constructs a new JarAnalyzer. -154 */ -155 public JarAnalyzer() { -156 } -157 -158 //<editor-fold defaultstate="collapsed" desc="All standard implmentation details of Analyzer"> -159 /** -160 * The name of the analyzer. -161 */ -162 private static final String ANALYZER_NAME = "Jar Analyzer"; -163 /** -164 * The phase that this analyzer is intended to run in. -165 */ -166 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; -167 /** -168 * The set of file extensions supported by this analyzer. -169 */ -170 private static final String[] EXTENSIONS = {"jar", "war"}; -171 -172 /** -173 * The file filter used to determine which files this analyzer supports. -174 */ -175 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(EXTENSIONS).build(); -176 -177 /** -178 * Returns the FileFilter. -179 * -180 * @return the FileFilter -181 */ -182 @Override -183 protected FileFilter getFileFilter() { -184 return FILTER; -185 } -186 -187 /** -188 * Returns the name of the analyzer. -189 * -190 * @return the name of the analyzer. -191 */ -192 @Override -193 public String getName() { -194 return ANALYZER_NAME; -195 } -196 -197 /** -198 * Returns the phase that the analyzer is intended to run in. -199 * -200 * @return the phase that the analyzer is intended to run in. -201 */ -202 @Override -203 public AnalysisPhase getAnalysisPhase() { -204 return ANALYSIS_PHASE; -205 } -206 //</editor-fold> -207 -208 /** -209 * Returns the key used in the properties file to reference the analyzer's -210 * enabled property. -211 * -212 * @return the analyzer's enabled property setting key -213 */ -214 @Override -215 protected String getAnalyzerEnabledSettingKey() { -216 return Settings.KEYS.ANALYZER_JAR_ENABLED; -217 } -218 -219 /** -220 * Loads a specified JAR file and collects information from the manifest and -221 * checksums to identify the correct CPE information. -222 * -223 * @param dependency the dependency to analyze. -224 * @param engine the engine that is scanning the dependencies -225 * @throws AnalysisException is thrown if there is an error reading the JAR -226 * file. -227 */ -228 @Override -229 public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { -230 try { -231 final List<ClassNameInformation> classNames = collectClassNames(dependency); -232 final String fileName = dependency.getFileName().toLowerCase(); -233 if (classNames.isEmpty() -234 && (fileName.endsWith("-sources.jar") -235 || fileName.endsWith("-javadoc.jar") -236 || fileName.endsWith("-src.jar") -237 || fileName.endsWith("-doc.jar"))) { -238 engine.getDependencies().remove(dependency); -239 } -240 final boolean hasManifest = parseManifest(dependency, classNames); -241 final boolean hasPOM = analyzePOM(dependency, classNames, engine); -242 final boolean addPackagesAsEvidence = !(hasManifest && hasPOM); -243 analyzePackageNames(classNames, dependency, addPackagesAsEvidence); -244 } catch (IOException ex) { -245 throw new AnalysisException("Exception occurred reading the JAR file.", ex); -246 } -247 } -248 -249 /** -250 * Attempts to find a pom.xml within the JAR file. If found it extracts -251 * information and adds it to the evidence. This will attempt to interpolate -252 * the strings contained within the pom.properties if one exists. -253 * -254 * @param dependency the dependency being analyzed -255 * @param classes a collection of class name information -256 * @param engine the analysis engine, used to add additional dependencies -257 * @throws AnalysisException is thrown if there is an exception parsing the -258 * pom -259 * @return whether or not evidence was added to the dependency -260 */ -261 protected boolean analyzePOM(Dependency dependency, List<ClassNameInformation> classes, Engine engine) throws AnalysisException { -262 boolean foundSomething = false; -263 final JarFile jar; -264 try { -265 jar = new JarFile(dependency.getActualFilePath()); -266 } catch (IOException ex) { -267 LOGGER.warn("Unable to read JarFile '{}'.", dependency.getActualFilePath()); -268 LOGGER.trace("", ex); -269 return false; -270 } -271 List<String> pomEntries; -272 try { -273 pomEntries = retrievePomListing(jar); -274 } catch (IOException ex) { -275 LOGGER.warn("Unable to read Jar file entries in '{}'.", dependency.getActualFilePath()); -276 LOGGER.trace("", ex); -277 return false; -278 } -279 File externalPom = null; -280 if (pomEntries.isEmpty()) { -281 final String pomPath = FilenameUtils.removeExtension(dependency.getActualFilePath()) + ".pom"; -282 externalPom = new File(pomPath); -283 if (externalPom.isFile()) { -284 pomEntries.add(pomPath); -285 } else { -286 return false; -287 } -288 } -289 for (String path : pomEntries) { -290 LOGGER.debug("Reading pom entry: {}", path); -291 Properties pomProperties = null; -292 try { -293 if (externalPom == null) { -294 pomProperties = retrievePomProperties(path, jar); -295 } -296 } catch (IOException ex) { -297 LOGGER.trace("ignore this, failed reading a non-existent pom.properties", ex); -298 } -299 Model pom = null; -300 try { -301 if (pomEntries.size() > 1) { -302 //extract POM to its own directory and add it as its own dependency -303 final Dependency newDependency = new Dependency(); -304 pom = extractPom(path, jar, newDependency); -305 -306 final String displayPath = String.format("%s%s%s", -307 dependency.getFilePath(), -308 File.separator, -309 path); -310 final String displayName = String.format("%s%s%s", -311 dependency.getFileName(), -312 File.separator, -313 path); -314 -315 newDependency.setFileName(displayName); -316 newDependency.setFilePath(displayPath); -317 pom.processProperties(pomProperties); -318 setPomEvidence(newDependency, pom, null); -319 engine.getDependencies().add(newDependency); -320 Collections.sort(engine.getDependencies()); -321 } else { -322 if (externalPom == null) { -323 pom = PomUtils.readPom(path, jar); -324 } else { -325 pom = PomUtils.readPom(externalPom); -326 } -327 pom.processProperties(pomProperties); -328 foundSomething |= setPomEvidence(dependency, pom, classes); -329 } -330 } catch (AnalysisException ex) { -331 LOGGER.warn("An error occurred while analyzing '{}'.", dependency.getActualFilePath()); -332 LOGGER.trace("", ex); -333 } -334 } -335 return foundSomething; -336 } -337 -338 /** -339 * Given a path to a pom.xml within a JarFile, this method attempts to load -340 * a sibling pom.properties if one exists. -341 * -342 * @param path the path to the pom.xml within the JarFile -343 * @param jar the JarFile to load the pom.properties from -344 * @return a Properties object or null if no pom.properties was found -345 * @throws IOException thrown if there is an exception reading the -346 * pom.properties -347 */ -348 private Properties retrievePomProperties(String path, final JarFile jar) throws IOException { -349 Properties pomProperties = null; -350 final String propPath = path.substring(0, path.length() - 7) + "pom.properies"; -351 final ZipEntry propEntry = jar.getEntry(propPath); -352 if (propEntry != null) { -353 Reader reader = null; -354 try { -355 reader = new InputStreamReader(jar.getInputStream(propEntry), "UTF-8"); -356 pomProperties = new Properties(); -357 pomProperties.load(reader); -358 LOGGER.debug("Read pom.properties: {}", propPath); -359 } finally { -360 if (reader != null) { -361 try { -362 reader.close(); -363 } catch (IOException ex) { -364 LOGGER.trace("close error", ex); -365 } -366 } -367 } -368 } -369 return pomProperties; -370 } -371 -372 /** -373 * Searches a JarFile for pom.xml entries and returns a listing of these -374 * entries. -375 * -376 * @param jar the JarFile to search -377 * @return a list of pom.xml entries -378 * @throws IOException thrown if there is an exception reading a JarEntry -379 */ -380 private List<String> retrievePomListing(final JarFile jar) throws IOException { -381 final List<String> pomEntries = new ArrayList<String>(); -382 final Enumeration<JarEntry> entries = jar.entries(); -383 while (entries.hasMoreElements()) { -384 final JarEntry entry = entries.nextElement(); -385 final String entryName = (new File(entry.getName())).getName().toLowerCase(); -386 if (!entry.isDirectory() && "pom.xml".equals(entryName)) { -387 LOGGER.trace("POM Entry found: {}", entry.getName()); -388 pomEntries.add(entry.getName()); -389 } -390 } -391 return pomEntries; -392 } -393 -394 /** -395 * Retrieves the specified POM from a jar file and converts it to a Model. -396 * -397 * @param path the path to the pom.xml file within the jar file -398 * @param jar the jar file to extract the pom from -399 * @param dependency the dependency being analyzed -400 * @return returns the POM object -401 * @throws AnalysisException is thrown if there is an exception extracting -402 * or parsing the POM {@link org.owasp.dependencycheck.xml.pom.Model} object -403 */ -404 private Model extractPom(String path, JarFile jar, Dependency dependency) throws AnalysisException { -405 InputStream input = null; -406 FileOutputStream fos = null; -407 final File tmpDir = getNextTempDirectory(); -408 final File file = new File(tmpDir, "pom.xml"); -409 try { -410 final ZipEntry entry = jar.getEntry(path); -411 input = jar.getInputStream(entry); -412 fos = new FileOutputStream(file); -413 IOUtils.copy(input, fos); -414 dependency.setActualFilePath(file.getAbsolutePath()); -415 } catch (IOException ex) { -416 LOGGER.warn("An error occurred reading '{}' from '{}'.", path, dependency.getFilePath()); -417 LOGGER.error("", ex); -418 } finally { -419 closeStream(fos); -420 closeStream(input); -421 } -422 return PomUtils.readPom(file); -423 } -424 -425 /** -426 * Silently closes an input stream ignoring errors. -427 * -428 * @param stream an input stream to close -429 */ -430 private void closeStream(InputStream stream) { -431 if (stream != null) { -432 try { -433 stream.close(); -434 } catch (IOException ex) { -435 LOGGER.trace("", ex); -436 } -437 } -438 } -439 -440 /** -441 * Silently closes an output stream ignoring errors. -442 * -443 * @param stream an output stream to close -444 */ -445 private void closeStream(OutputStream stream) { -446 if (stream != null) { -447 try { -448 stream.close(); -449 } catch (IOException ex) { -450 LOGGER.trace("", ex); -451 } -452 } -453 } -454 -455 /** -456 * Sets evidence from the pom on the supplied dependency. -457 * -458 * @param dependency the dependency to set data on -459 * @param pom the information from the pom -460 * @param classes a collection of ClassNameInformation - containing data -461 * about the fully qualified class names within the JAR file being analyzed -462 * @return true if there was evidence within the pom that we could use; -463 * otherwise false -464 */ -465 public static boolean setPomEvidence(Dependency dependency, Model pom, List<ClassNameInformation> classes) { -466 boolean foundSomething = false; -467 boolean addAsIdentifier = true; -468 if (pom == null) { -469 return foundSomething; -470 } -471 String groupid = pom.getGroupId(); -472 String parentGroupId = pom.getParentGroupId(); -473 String artifactid = pom.getArtifactId(); -474 String parentArtifactId = pom.getParentArtifactId(); -475 String version = pom.getVersion(); -476 String parentVersion = pom.getParentVersion(); -477 -478 if ("org.sonatype.oss".equals(parentGroupId) && "oss-parent".equals(parentArtifactId)) { -479 parentGroupId = null; -480 parentArtifactId = null; -481 parentVersion = null; -482 } -483 -484 if ((groupid == null || groupid.isEmpty()) && parentGroupId != null && !parentGroupId.isEmpty()) { -485 groupid = parentGroupId; -486 } -487 -488 final String originalGroupID = groupid; -489 if (groupid.startsWith("org.") || groupid.startsWith("com.")) { -490 groupid = groupid.substring(4); -491 } -492 -493 if ((artifactid == null || artifactid.isEmpty()) && parentArtifactId != null && !parentArtifactId.isEmpty()) { -494 artifactid = parentArtifactId; -495 } -496 -497 final String originalArtifactID = artifactid; -498 if (artifactid.startsWith("org.") || artifactid.startsWith("com.")) { -499 artifactid = artifactid.substring(4); -500 } -501 -502 if ((version == null || version.isEmpty()) && parentVersion != null && !parentVersion.isEmpty()) { -503 version = parentVersion; -504 } -505 -506 if (groupid != null && !groupid.isEmpty()) { -507 foundSomething = true; -508 dependency.getVendorEvidence().addEvidence("pom", "groupid", groupid, Confidence.HIGHEST); -509 dependency.getProductEvidence().addEvidence("pom", "groupid", groupid, Confidence.LOW); -510 addMatchingValues(classes, groupid, dependency.getVendorEvidence()); -511 addMatchingValues(classes, groupid, dependency.getProductEvidence()); -512 if (parentGroupId != null && !parentGroupId.isEmpty() && !parentGroupId.equals(groupid)) { -513 dependency.getVendorEvidence().addEvidence("pom", "parent-groupid", parentGroupId, Confidence.MEDIUM); -514 dependency.getProductEvidence().addEvidence("pom", "parent-groupid", parentGroupId, Confidence.LOW); -515 addMatchingValues(classes, parentGroupId, dependency.getVendorEvidence()); -516 addMatchingValues(classes, parentGroupId, dependency.getProductEvidence()); -517 } -518 } else { -519 addAsIdentifier = false; -520 } -521 -522 if (artifactid != null && !artifactid.isEmpty()) { -523 foundSomething = true; -524 dependency.getProductEvidence().addEvidence("pom", "artifactid", artifactid, Confidence.HIGHEST); -525 dependency.getVendorEvidence().addEvidence("pom", "artifactid", artifactid, Confidence.LOW); -526 addMatchingValues(classes, artifactid, dependency.getVendorEvidence()); -527 addMatchingValues(classes, artifactid, dependency.getProductEvidence()); -528 if (parentArtifactId != null && !parentArtifactId.isEmpty() && !parentArtifactId.equals(artifactid)) { -529 dependency.getProductEvidence().addEvidence("pom", "parent-artifactid", parentArtifactId, Confidence.MEDIUM); -530 dependency.getVendorEvidence().addEvidence("pom", "parent-artifactid", parentArtifactId, Confidence.LOW); -531 addMatchingValues(classes, parentArtifactId, dependency.getVendorEvidence()); -532 addMatchingValues(classes, parentArtifactId, dependency.getProductEvidence()); -533 } -534 } else { -535 addAsIdentifier = false; -536 } -537 -538 if (version != null && !version.isEmpty()) { -539 foundSomething = true; -540 dependency.getVersionEvidence().addEvidence("pom", "version", version, Confidence.HIGHEST); -541 if (parentVersion != null && !parentVersion.isEmpty() && !parentVersion.equals(version)) { -542 dependency.getVersionEvidence().addEvidence("pom", "parent-version", version, Confidence.LOW); -543 } -544 } else { -545 addAsIdentifier = false; -546 } -547 -548 if (addAsIdentifier) { -549 dependency.addIdentifier("maven", String.format("%s:%s:%s", originalGroupID, originalArtifactID, version), null, Confidence.HIGH); -550 } -551 -552 // org name -553 final String org = pom.getOrganization(); -554 if (org != null && !org.isEmpty()) { -555 dependency.getVendorEvidence().addEvidence("pom", "organization name", org, Confidence.HIGH); -556 dependency.getProductEvidence().addEvidence("pom", "organization name", org, Confidence.LOW); -557 addMatchingValues(classes, org, dependency.getVendorEvidence()); -558 addMatchingValues(classes, org, dependency.getProductEvidence()); -559 } -560 //pom name -561 final String pomName = pom.getName(); -562 if (pomName -563 != null && !pomName.isEmpty()) { -564 foundSomething = true; -565 dependency.getProductEvidence().addEvidence("pom", "name", pomName, Confidence.HIGH); -566 dependency.getVendorEvidence().addEvidence("pom", "name", pomName, Confidence.HIGH); -567 addMatchingValues(classes, pomName, dependency.getVendorEvidence()); -568 addMatchingValues(classes, pomName, dependency.getProductEvidence()); -569 } -570 -571 //Description -572 final String description = pom.getDescription(); -573 if (description != null && !description.isEmpty() && !description.startsWith("POM was created by")) { -574 foundSomething = true; -575 final String trimmedDescription = addDescription(dependency, description, "pom", "description"); -576 addMatchingValues(classes, trimmedDescription, dependency.getVendorEvidence()); -577 addMatchingValues(classes, trimmedDescription, dependency.getProductEvidence()); -578 } -579 -580 final String projectURL = pom.getProjectURL(); -581 if (projectURL != null && !projectURL.trim().isEmpty()) { -582 dependency.getVendorEvidence().addEvidence("pom", "url", projectURL, Confidence.HIGHEST); -583 } -584 -585 extractLicense(pom, dependency); -586 return foundSomething; -587 } -588 -589 /** -590 * Analyzes the path information of the classes contained within the -591 * JarAnalyzer to try and determine possible vendor or product names. If any -592 * are found they are stored in the packageVendor and packageProduct -593 * hashSets. -594 * -595 * @param classNames a list of class names -596 * @param dependency a dependency to analyze -597 * @param addPackagesAsEvidence a flag indicating whether or not package -598 * names should be added as evidence. -599 */ -600 protected void analyzePackageNames(List<ClassNameInformation> classNames, -601 Dependency dependency, boolean addPackagesAsEvidence) { -602 final Map<String, Integer> vendorIdentifiers = new HashMap<String, Integer>(); -603 final Map<String, Integer> productIdentifiers = new HashMap<String, Integer>(); -604 analyzeFullyQualifiedClassNames(classNames, vendorIdentifiers, productIdentifiers); -605 -606 final int classCount = classNames.size(); -607 final EvidenceCollection vendor = dependency.getVendorEvidence(); -608 final EvidenceCollection product = dependency.getProductEvidence(); -609 -610 for (Map.Entry<String, Integer> entry : vendorIdentifiers.entrySet()) { -611 final float ratio = entry.getValue() / (float) classCount; -612 if (ratio > 0.5) { -613 //TODO remove weighting -614 vendor.addWeighting(entry.getKey()); -615 if (addPackagesAsEvidence && entry.getKey().length() > 1) { -616 vendor.addEvidence("jar", "package name", entry.getKey(), Confidence.LOW); -617 } -618 } -619 } -620 for (Map.Entry<String, Integer> entry : productIdentifiers.entrySet()) { -621 final float ratio = entry.getValue() / (float) classCount; -622 if (ratio > 0.5) { -623 product.addWeighting(entry.getKey()); -624 if (addPackagesAsEvidence && entry.getKey().length() > 1) { -625 product.addEvidence("jar", "package name", entry.getKey(), Confidence.LOW); -626 } -627 } -628 } -629 } -630 -631 /** -632 * <p> -633 * Reads the manifest from the JAR file and collects the entries. Some -634 * vendorKey entries are:</p> -635 * <ul><li>Implementation Title</li> -636 * <li>Implementation Version</li> <li>Implementation Vendor</li> -637 * <li>Implementation VendorId</li> <li>Bundle Name</li> <li>Bundle -638 * Version</li> <li>Bundle Vendor</li> <li>Bundle Description</li> <li>Main -639 * Class</li> </ul> -640 * However, all but a handful of specific entries are read in. -641 * -642 * @param dependency A reference to the dependency -643 * @param classInformation a collection of class information -644 * @return whether evidence was identified parsing the manifest -645 * @throws IOException if there is an issue reading the JAR file -646 */ -647 protected boolean parseManifest(Dependency dependency, -648 List<ClassNameInformation> classInformation) -649 throws IOException { -650 boolean foundSomething = false; -651 JarFile jar = null; -652 try { -653 jar = new JarFile(dependency.getActualFilePath()); -654 final Manifest manifest = jar.getManifest(); -655 if (manifest == null) { -656 if (!dependency.getFileName().toLowerCase().endsWith("-sources.jar") -657 && !dependency.getFileName().toLowerCase().endsWith("-javadoc.jar") -658 && !dependency.getFileName().toLowerCase().endsWith("-src.jar") -659 && !dependency.getFileName().toLowerCase().endsWith("-doc.jar")) { -660 LOGGER.debug("Jar file '{}' does not contain a manifest.", -661 dependency.getFileName()); -662 } -663 return false; -664 } -665 final EvidenceCollection vendorEvidence = dependency.getVendorEvidence(); -666 final EvidenceCollection productEvidence = dependency.getProductEvidence(); -667 final EvidenceCollection versionEvidence = dependency.getVersionEvidence(); -668 -669 String source = "Manifest"; -670 String specificationVersion = null; -671 boolean hasImplementationVersion = false; -672 Attributes atts = manifest.getMainAttributes(); -673 for (Entry<Object, Object> entry : atts.entrySet()) { -674 String key = entry.getKey().toString(); -675 String value = atts.getValue(key); -676 if (HTML_DETECTION_PATTERN.matcher(value).find()) { -677 value = Jsoup.parse(value).text(); -678 } -679 if (IGNORE_VALUES.contains(value)) { -680 continue; -681 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_TITLE.toString())) { -682 foundSomething = true; -683 productEvidence.addEvidence(source, key, value, Confidence.HIGH); -684 addMatchingValues(classInformation, value, productEvidence); -685 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VERSION.toString())) { -686 hasImplementationVersion = true; -687 foundSomething = true; -688 versionEvidence.addEvidence(source, key, value, Confidence.HIGH); -689 } else if ("specification-version".equalsIgnoreCase(key)) { -690 specificationVersion = key; -691 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VENDOR.toString())) { -692 foundSomething = true; -693 vendorEvidence.addEvidence(source, key, value, Confidence.HIGH); -694 addMatchingValues(classInformation, value, vendorEvidence); -695 } else if (key.equalsIgnoreCase(IMPLEMENTATION_VENDOR_ID)) { -696 foundSomething = true; -697 vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -698 addMatchingValues(classInformation, value, vendorEvidence); -699 } else if (key.equalsIgnoreCase(BUNDLE_DESCRIPTION)) { -700 foundSomething = true; -701 addDescription(dependency, value, "manifest", key); -702 addMatchingValues(classInformation, value, productEvidence); -703 } else if (key.equalsIgnoreCase(BUNDLE_NAME)) { -704 foundSomething = true; -705 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -706 addMatchingValues(classInformation, value, productEvidence); -707 // //the following caused false positives. -708 // } else if (key.equalsIgnoreCase(BUNDLE_VENDOR)) { -709 // foundSomething = true; -710 // vendorEvidence.addEvidence(source, key, value, Confidence.HIGH); -711 // addMatchingValues(classInformation, value, vendorEvidence); -712 } else if (key.equalsIgnoreCase(BUNDLE_VERSION)) { -713 foundSomething = true; -714 versionEvidence.addEvidence(source, key, value, Confidence.HIGH); -715 } else if (key.equalsIgnoreCase(Attributes.Name.MAIN_CLASS.toString())) { -716 continue; -717 //skipping main class as if this has important information to add -718 // it will be added during class name analysis... if other fields -719 // have the information from the class name then they will get added... -720 } else { -721 key = key.toLowerCase(); -722 if (!IGNORE_KEYS.contains(key) -723 && !key.endsWith("jdk") -724 && !key.contains("lastmodified") -725 && !key.endsWith("package") -726 && !key.endsWith("classpath") -727 && !key.endsWith("class-path") -728 && !key.endsWith("-scm") //todo change this to a regex? -729 && !key.startsWith("scm-") -730 && !value.trim().startsWith("scm:") -731 && !isImportPackage(key, value) -732 && !isPackage(key, value)) { -733 foundSomething = true; -734 if (key.contains("version")) { -735 if (!key.contains("specification")) { -736 versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -737 } -738 } else if ("build-id".equals(key)) { -739 int pos = value.indexOf('('); -740 if (pos >= 0) { -741 value = value.substring(0, pos - 1); -742 } -743 pos = value.indexOf('['); -744 if (pos >= 0) { -745 value = value.substring(0, pos - 1); -746 } -747 versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -748 } else if (key.contains("title")) { -749 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -750 addMatchingValues(classInformation, value, productEvidence); -751 } else if (key.contains("vendor")) { -752 if (key.contains("specification")) { -753 vendorEvidence.addEvidence(source, key, value, Confidence.LOW); -754 } else { -755 vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -756 addMatchingValues(classInformation, value, vendorEvidence); -757 } -758 } else if (key.contains("name")) { -759 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -760 vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -761 addMatchingValues(classInformation, value, vendorEvidence); -762 addMatchingValues(classInformation, value, productEvidence); -763 } else if (key.contains("license")) { -764 addLicense(dependency, value); -765 } else if (key.contains("description")) { -766 addDescription(dependency, value, "manifest", key); -767 } else { -768 productEvidence.addEvidence(source, key, value, Confidence.LOW); -769 vendorEvidence.addEvidence(source, key, value, Confidence.LOW); -770 addMatchingValues(classInformation, value, vendorEvidence); -771 addMatchingValues(classInformation, value, productEvidence); -772 if (value.matches(".*\\d.*")) { -773 final StringTokenizer tokenizer = new StringTokenizer(value, " "); -774 while (tokenizer.hasMoreElements()) { -775 final String s = tokenizer.nextToken(); -776 if (s.matches("^[0-9.]+$")) { -777 versionEvidence.addEvidence(source, key, s, Confidence.LOW); -778 } -779 } -780 } -781 } -782 } -783 } -784 } -785 -786 for (Map.Entry<String, Attributes> item : manifest.getEntries().entrySet()) { -787 final String name = item.getKey(); -788 source = "manifest: " + name; -789 atts = item.getValue(); -790 for (Entry<Object, Object> entry : atts.entrySet()) { -791 final String key = entry.getKey().toString(); -792 final String value = atts.getValue(key); -793 if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_TITLE.toString())) { -794 foundSomething = true; -795 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -796 addMatchingValues(classInformation, value, productEvidence); -797 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VERSION.toString())) { +52 import org.owasp.dependencycheck.exception.InitializationException; +53 import org.owasp.dependencycheck.utils.FileFilterBuilder; +54 import org.owasp.dependencycheck.xml.pom.License; +55 import org.owasp.dependencycheck.xml.pom.PomUtils; +56 import org.owasp.dependencycheck.xml.pom.Model; +57 import org.owasp.dependencycheck.utils.FileUtils; +58 import org.owasp.dependencycheck.utils.Settings; +59 import org.slf4j.Logger; +60 import org.slf4j.LoggerFactory; +61 +62 /** +63 * Used to load a JAR file and collect information that can be used to determine +64 * the associated CPE. +65 * +66 * @author Jeremy Long +67 */ +68 public class JarAnalyzer extends AbstractFileTypeAnalyzer { +69 +70 //<editor-fold defaultstate="collapsed" desc="Constants and Member Variables"> +71 /** +72 * The logger. +73 */ +74 private static final Logger LOGGER = LoggerFactory.getLogger(JarAnalyzer.class); +75 /** +76 * The count of directories created during analysis. This is used for +77 * creating temporary directories. +78 */ +79 private static int dirCount = 0; +80 /** +81 * The system independent newline character. +82 */ +83 private static final String NEWLINE = System.getProperty("line.separator"); +84 /** +85 * A list of values in the manifest to ignore as they only result in false +86 * positives. +87 */ +88 private static final Set<String> IGNORE_VALUES = newHashSet( +89 "Sun Java System Application Server"); +90 /** +91 * A list of elements in the manifest to ignore. +92 */ +93 private static final Set<String> IGNORE_KEYS = newHashSet( +94 "built-by", +95 "created-by", +96 "builtby", +97 "createdby", +98 "build-jdk", +99 "buildjdk", +100 "ant-version", +101 "antversion", +102 "dynamicimportpackage", +103 "dynamicimport-package", +104 "dynamic-importpackage", +105 "dynamic-import-package", +106 "import-package", +107 "ignore-package", +108 "export-package", +109 "importpackage", +110 "ignorepackage", +111 "exportpackage", +112 "sealed", +113 "manifest-version", +114 "archiver-version", +115 "manifestversion", +116 "archiverversion", +117 "classpath", +118 "class-path", +119 "tool", +120 "bundle-manifestversion", +121 "bundlemanifestversion", +122 "bundle-vendor", +123 "include-resource", +124 "embed-dependency", +125 "ipojo-components", +126 "ipojo-extension", +127 "eclipse-sourcereferences"); +128 /** +129 * Deprecated Jar manifest attribute, that is, nonetheless, useful for +130 * analysis. +131 */ +132 @SuppressWarnings("deprecation") +133 private static final String IMPLEMENTATION_VENDOR_ID = Attributes.Name.IMPLEMENTATION_VENDOR_ID +134 .toString(); +135 /** +136 * item in some manifest, should be considered medium confidence. +137 */ +138 private static final String BUNDLE_VERSION = "Bundle-Version"; //: 2.1.2 +139 /** +140 * item in some manifest, should be considered medium confidence. +141 */ +142 private static final String BUNDLE_DESCRIPTION = "Bundle-Description"; //: Apache Struts 2 +143 /** +144 * item in some manifest, should be considered medium confidence. +145 */ +146 private static final String BUNDLE_NAME = "Bundle-Name"; //: Struts 2 Core +147 /** +148 * A pattern to detect HTML within text. +149 */ +150 private static final Pattern HTML_DETECTION_PATTERN = Pattern.compile("\\<[a-z]+.*/?\\>", Pattern.CASE_INSENSITIVE); +151 +152 //</editor-fold> +153 /** +154 * Constructs a new JarAnalyzer. +155 */ +156 public JarAnalyzer() { +157 } +158 +159 //<editor-fold defaultstate="collapsed" desc="All standard implmentation details of Analyzer"> +160 /** +161 * The name of the analyzer. +162 */ +163 private static final String ANALYZER_NAME = "Jar Analyzer"; +164 /** +165 * The phase that this analyzer is intended to run in. +166 */ +167 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; +168 /** +169 * The set of file extensions supported by this analyzer. +170 */ +171 private static final String[] EXTENSIONS = {"jar", "war"}; +172 +173 /** +174 * The file filter used to determine which files this analyzer supports. +175 */ +176 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(EXTENSIONS).build(); +177 +178 /** +179 * Returns the FileFilter. +180 * +181 * @return the FileFilter +182 */ +183 @Override +184 protected FileFilter getFileFilter() { +185 return FILTER; +186 } +187 +188 /** +189 * Returns the name of the analyzer. +190 * +191 * @return the name of the analyzer. +192 */ +193 @Override +194 public String getName() { +195 return ANALYZER_NAME; +196 } +197 +198 /** +199 * Returns the phase that the analyzer is intended to run in. +200 * +201 * @return the phase that the analyzer is intended to run in. +202 */ +203 @Override +204 public AnalysisPhase getAnalysisPhase() { +205 return ANALYSIS_PHASE; +206 } +207 //</editor-fold> +208 +209 /** +210 * Returns the key used in the properties file to reference the analyzer's +211 * enabled property. +212 * +213 * @return the analyzer's enabled property setting key +214 */ +215 @Override +216 protected String getAnalyzerEnabledSettingKey() { +217 return Settings.KEYS.ANALYZER_JAR_ENABLED; +218 } +219 +220 /** +221 * Loads a specified JAR file and collects information from the manifest and +222 * checksums to identify the correct CPE information. +223 * +224 * @param dependency the dependency to analyze. +225 * @param engine the engine that is scanning the dependencies +226 * @throws AnalysisException is thrown if there is an error reading the JAR +227 * file. +228 */ +229 @Override +230 public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { +231 try { +232 final List<ClassNameInformation> classNames = collectClassNames(dependency); +233 final String fileName = dependency.getFileName().toLowerCase(); +234 if (classNames.isEmpty() +235 && (fileName.endsWith("-sources.jar") +236 || fileName.endsWith("-javadoc.jar") +237 || fileName.endsWith("-src.jar") +238 || fileName.endsWith("-doc.jar"))) { +239 engine.getDependencies().remove(dependency); +240 } +241 final boolean hasManifest = parseManifest(dependency, classNames); +242 final boolean hasPOM = analyzePOM(dependency, classNames, engine); +243 final boolean addPackagesAsEvidence = !(hasManifest && hasPOM); +244 analyzePackageNames(classNames, dependency, addPackagesAsEvidence); +245 } catch (IOException ex) { +246 throw new AnalysisException("Exception occurred reading the JAR file.", ex); +247 } +248 } +249 +250 /** +251 * Attempts to find a pom.xml within the JAR file. If found it extracts +252 * information and adds it to the evidence. This will attempt to interpolate +253 * the strings contained within the pom.properties if one exists. +254 * +255 * @param dependency the dependency being analyzed +256 * @param classes a collection of class name information +257 * @param engine the analysis engine, used to add additional dependencies +258 * @throws AnalysisException is thrown if there is an exception parsing the +259 * pom +260 * @return whether or not evidence was added to the dependency +261 */ +262 protected boolean analyzePOM(Dependency dependency, List<ClassNameInformation> classes, Engine engine) throws AnalysisException { +263 boolean foundSomething = false; +264 final JarFile jar; +265 try { +266 jar = new JarFile(dependency.getActualFilePath()); +267 } catch (IOException ex) { +268 LOGGER.warn("Unable to read JarFile '{}'.", dependency.getActualFilePath()); +269 LOGGER.trace("", ex); +270 return false; +271 } +272 List<String> pomEntries; +273 try { +274 pomEntries = retrievePomListing(jar); +275 } catch (IOException ex) { +276 LOGGER.warn("Unable to read Jar file entries in '{}'.", dependency.getActualFilePath()); +277 LOGGER.trace("", ex); +278 return false; +279 } +280 File externalPom = null; +281 if (pomEntries.isEmpty()) { +282 final String pomPath = FilenameUtils.removeExtension(dependency.getActualFilePath()) + ".pom"; +283 externalPom = new File(pomPath); +284 if (externalPom.isFile()) { +285 pomEntries.add(pomPath); +286 } else { +287 return false; +288 } +289 } +290 for (String path : pomEntries) { +291 LOGGER.debug("Reading pom entry: {}", path); +292 Properties pomProperties = null; +293 try { +294 if (externalPom == null) { +295 pomProperties = retrievePomProperties(path, jar); +296 } +297 } catch (IOException ex) { +298 LOGGER.trace("ignore this, failed reading a non-existent pom.properties", ex); +299 } +300 Model pom = null; +301 try { +302 if (pomEntries.size() > 1) { +303 //extract POM to its own directory and add it as its own dependency +304 final Dependency newDependency = new Dependency(); +305 pom = extractPom(path, jar, newDependency); +306 +307 final String displayPath = String.format("%s%s%s", +308 dependency.getFilePath(), +309 File.separator, +310 path); +311 final String displayName = String.format("%s%s%s", +312 dependency.getFileName(), +313 File.separator, +314 path); +315 +316 newDependency.setFileName(displayName); +317 newDependency.setFilePath(displayPath); +318 pom.processProperties(pomProperties); +319 setPomEvidence(newDependency, pom, null); +320 engine.getDependencies().add(newDependency); +321 Collections.sort(engine.getDependencies()); +322 } else { +323 if (externalPom == null) { +324 pom = PomUtils.readPom(path, jar); +325 } else { +326 pom = PomUtils.readPom(externalPom); +327 } +328 pom.processProperties(pomProperties); +329 foundSomething |= setPomEvidence(dependency, pom, classes); +330 } +331 } catch (AnalysisException ex) { +332 LOGGER.warn("An error occurred while analyzing '{}'.", dependency.getActualFilePath()); +333 LOGGER.trace("", ex); +334 } +335 } +336 return foundSomething; +337 } +338 +339 /** +340 * Given a path to a pom.xml within a JarFile, this method attempts to load +341 * a sibling pom.properties if one exists. +342 * +343 * @param path the path to the pom.xml within the JarFile +344 * @param jar the JarFile to load the pom.properties from +345 * @return a Properties object or null if no pom.properties was found +346 * @throws IOException thrown if there is an exception reading the +347 * pom.properties +348 */ +349 private Properties retrievePomProperties(String path, final JarFile jar) throws IOException { +350 Properties pomProperties = null; +351 final String propPath = path.substring(0, path.length() - 7) + "pom.properies"; +352 final ZipEntry propEntry = jar.getEntry(propPath); +353 if (propEntry != null) { +354 Reader reader = null; +355 try { +356 reader = new InputStreamReader(jar.getInputStream(propEntry), "UTF-8"); +357 pomProperties = new Properties(); +358 pomProperties.load(reader); +359 LOGGER.debug("Read pom.properties: {}", propPath); +360 } finally { +361 if (reader != null) { +362 try { +363 reader.close(); +364 } catch (IOException ex) { +365 LOGGER.trace("close error", ex); +366 } +367 } +368 } +369 } +370 return pomProperties; +371 } +372 +373 /** +374 * Searches a JarFile for pom.xml entries and returns a listing of these +375 * entries. +376 * +377 * @param jar the JarFile to search +378 * @return a list of pom.xml entries +379 * @throws IOException thrown if there is an exception reading a JarEntry +380 */ +381 private List<String> retrievePomListing(final JarFile jar) throws IOException { +382 final List<String> pomEntries = new ArrayList<String>(); +383 final Enumeration<JarEntry> entries = jar.entries(); +384 while (entries.hasMoreElements()) { +385 final JarEntry entry = entries.nextElement(); +386 final String entryName = (new File(entry.getName())).getName().toLowerCase(); +387 if (!entry.isDirectory() && "pom.xml".equals(entryName)) { +388 LOGGER.trace("POM Entry found: {}", entry.getName()); +389 pomEntries.add(entry.getName()); +390 } +391 } +392 return pomEntries; +393 } +394 +395 /** +396 * Retrieves the specified POM from a jar file and converts it to a Model. +397 * +398 * @param path the path to the pom.xml file within the jar file +399 * @param jar the jar file to extract the pom from +400 * @param dependency the dependency being analyzed +401 * @return returns the POM object +402 * @throws AnalysisException is thrown if there is an exception extracting +403 * or parsing the POM {@link org.owasp.dependencycheck.xml.pom.Model} object +404 */ +405 private Model extractPom(String path, JarFile jar, Dependency dependency) throws AnalysisException { +406 InputStream input = null; +407 FileOutputStream fos = null; +408 final File tmpDir = getNextTempDirectory(); +409 final File file = new File(tmpDir, "pom.xml"); +410 try { +411 final ZipEntry entry = jar.getEntry(path); +412 input = jar.getInputStream(entry); +413 fos = new FileOutputStream(file); +414 IOUtils.copy(input, fos); +415 dependency.setActualFilePath(file.getAbsolutePath()); +416 } catch (IOException ex) { +417 LOGGER.warn("An error occurred reading '{}' from '{}'.", path, dependency.getFilePath()); +418 LOGGER.error("", ex); +419 } finally { +420 closeStream(fos); +421 closeStream(input); +422 } +423 return PomUtils.readPom(file); +424 } +425 +426 /** +427 * Silently closes an input stream ignoring errors. +428 * +429 * @param stream an input stream to close +430 */ +431 private void closeStream(InputStream stream) { +432 if (stream != null) { +433 try { +434 stream.close(); +435 } catch (IOException ex) { +436 LOGGER.trace("", ex); +437 } +438 } +439 } +440 +441 /** +442 * Silently closes an output stream ignoring errors. +443 * +444 * @param stream an output stream to close +445 */ +446 private void closeStream(OutputStream stream) { +447 if (stream != null) { +448 try { +449 stream.close(); +450 } catch (IOException ex) { +451 LOGGER.trace("", ex); +452 } +453 } +454 } +455 +456 /** +457 * Sets evidence from the pom on the supplied dependency. +458 * +459 * @param dependency the dependency to set data on +460 * @param pom the information from the pom +461 * @param classes a collection of ClassNameInformation - containing data +462 * about the fully qualified class names within the JAR file being analyzed +463 * @return true if there was evidence within the pom that we could use; +464 * otherwise false +465 */ +466 public static boolean setPomEvidence(Dependency dependency, Model pom, List<ClassNameInformation> classes) { +467 boolean foundSomething = false; +468 boolean addAsIdentifier = true; +469 if (pom == null) { +470 return foundSomething; +471 } +472 String groupid = pom.getGroupId(); +473 String parentGroupId = pom.getParentGroupId(); +474 String artifactid = pom.getArtifactId(); +475 String parentArtifactId = pom.getParentArtifactId(); +476 String version = pom.getVersion(); +477 String parentVersion = pom.getParentVersion(); +478 +479 if ("org.sonatype.oss".equals(parentGroupId) && "oss-parent".equals(parentArtifactId)) { +480 parentGroupId = null; +481 parentArtifactId = null; +482 parentVersion = null; +483 } +484 +485 if ((groupid == null || groupid.isEmpty()) && parentGroupId != null && !parentGroupId.isEmpty()) { +486 groupid = parentGroupId; +487 } +488 +489 final String originalGroupID = groupid; +490 if (groupid.startsWith("org.") || groupid.startsWith("com.")) { +491 groupid = groupid.substring(4); +492 } +493 +494 if ((artifactid == null || artifactid.isEmpty()) && parentArtifactId != null && !parentArtifactId.isEmpty()) { +495 artifactid = parentArtifactId; +496 } +497 +498 final String originalArtifactID = artifactid; +499 if (artifactid.startsWith("org.") || artifactid.startsWith("com.")) { +500 artifactid = artifactid.substring(4); +501 } +502 +503 if ((version == null || version.isEmpty()) && parentVersion != null && !parentVersion.isEmpty()) { +504 version = parentVersion; +505 } +506 +507 if (groupid != null && !groupid.isEmpty()) { +508 foundSomething = true; +509 dependency.getVendorEvidence().addEvidence("pom", "groupid", groupid, Confidence.HIGHEST); +510 dependency.getProductEvidence().addEvidence("pom", "groupid", groupid, Confidence.LOW); +511 addMatchingValues(classes, groupid, dependency.getVendorEvidence()); +512 addMatchingValues(classes, groupid, dependency.getProductEvidence()); +513 if (parentGroupId != null && !parentGroupId.isEmpty() && !parentGroupId.equals(groupid)) { +514 dependency.getVendorEvidence().addEvidence("pom", "parent-groupid", parentGroupId, Confidence.MEDIUM); +515 dependency.getProductEvidence().addEvidence("pom", "parent-groupid", parentGroupId, Confidence.LOW); +516 addMatchingValues(classes, parentGroupId, dependency.getVendorEvidence()); +517 addMatchingValues(classes, parentGroupId, dependency.getProductEvidence()); +518 } +519 } else { +520 addAsIdentifier = false; +521 } +522 +523 if (artifactid != null && !artifactid.isEmpty()) { +524 foundSomething = true; +525 dependency.getProductEvidence().addEvidence("pom", "artifactid", artifactid, Confidence.HIGHEST); +526 dependency.getVendorEvidence().addEvidence("pom", "artifactid", artifactid, Confidence.LOW); +527 addMatchingValues(classes, artifactid, dependency.getVendorEvidence()); +528 addMatchingValues(classes, artifactid, dependency.getProductEvidence()); +529 if (parentArtifactId != null && !parentArtifactId.isEmpty() && !parentArtifactId.equals(artifactid)) { +530 dependency.getProductEvidence().addEvidence("pom", "parent-artifactid", parentArtifactId, Confidence.MEDIUM); +531 dependency.getVendorEvidence().addEvidence("pom", "parent-artifactid", parentArtifactId, Confidence.LOW); +532 addMatchingValues(classes, parentArtifactId, dependency.getVendorEvidence()); +533 addMatchingValues(classes, parentArtifactId, dependency.getProductEvidence()); +534 } +535 } else { +536 addAsIdentifier = false; +537 } +538 +539 if (version != null && !version.isEmpty()) { +540 foundSomething = true; +541 dependency.getVersionEvidence().addEvidence("pom", "version", version, Confidence.HIGHEST); +542 if (parentVersion != null && !parentVersion.isEmpty() && !parentVersion.equals(version)) { +543 dependency.getVersionEvidence().addEvidence("pom", "parent-version", version, Confidence.LOW); +544 } +545 } else { +546 addAsIdentifier = false; +547 } +548 +549 if (addAsIdentifier) { +550 dependency.addIdentifier("maven", String.format("%s:%s:%s", originalGroupID, originalArtifactID, version), null, Confidence.HIGH); +551 } +552 +553 // org name +554 final String org = pom.getOrganization(); +555 if (org != null && !org.isEmpty()) { +556 dependency.getVendorEvidence().addEvidence("pom", "organization name", org, Confidence.HIGH); +557 dependency.getProductEvidence().addEvidence("pom", "organization name", org, Confidence.LOW); +558 addMatchingValues(classes, org, dependency.getVendorEvidence()); +559 addMatchingValues(classes, org, dependency.getProductEvidence()); +560 } +561 //pom name +562 final String pomName = pom.getName(); +563 if (pomName +564 != null && !pomName.isEmpty()) { +565 foundSomething = true; +566 dependency.getProductEvidence().addEvidence("pom", "name", pomName, Confidence.HIGH); +567 dependency.getVendorEvidence().addEvidence("pom", "name", pomName, Confidence.HIGH); +568 addMatchingValues(classes, pomName, dependency.getVendorEvidence()); +569 addMatchingValues(classes, pomName, dependency.getProductEvidence()); +570 } +571 +572 //Description +573 final String description = pom.getDescription(); +574 if (description != null && !description.isEmpty() && !description.startsWith("POM was created by")) { +575 foundSomething = true; +576 final String trimmedDescription = addDescription(dependency, description, "pom", "description"); +577 addMatchingValues(classes, trimmedDescription, dependency.getVendorEvidence()); +578 addMatchingValues(classes, trimmedDescription, dependency.getProductEvidence()); +579 } +580 +581 final String projectURL = pom.getProjectURL(); +582 if (projectURL != null && !projectURL.trim().isEmpty()) { +583 dependency.getVendorEvidence().addEvidence("pom", "url", projectURL, Confidence.HIGHEST); +584 } +585 +586 extractLicense(pom, dependency); +587 return foundSomething; +588 } +589 +590 /** +591 * Analyzes the path information of the classes contained within the +592 * JarAnalyzer to try and determine possible vendor or product names. If any +593 * are found they are stored in the packageVendor and packageProduct +594 * hashSets. +595 * +596 * @param classNames a list of class names +597 * @param dependency a dependency to analyze +598 * @param addPackagesAsEvidence a flag indicating whether or not package +599 * names should be added as evidence. +600 */ +601 protected void analyzePackageNames(List<ClassNameInformation> classNames, +602 Dependency dependency, boolean addPackagesAsEvidence) { +603 final Map<String, Integer> vendorIdentifiers = new HashMap<String, Integer>(); +604 final Map<String, Integer> productIdentifiers = new HashMap<String, Integer>(); +605 analyzeFullyQualifiedClassNames(classNames, vendorIdentifiers, productIdentifiers); +606 +607 final int classCount = classNames.size(); +608 final EvidenceCollection vendor = dependency.getVendorEvidence(); +609 final EvidenceCollection product = dependency.getProductEvidence(); +610 +611 for (Map.Entry<String, Integer> entry : vendorIdentifiers.entrySet()) { +612 final float ratio = entry.getValue() / (float) classCount; +613 if (ratio > 0.5) { +614 //TODO remove weighting +615 vendor.addWeighting(entry.getKey()); +616 if (addPackagesAsEvidence && entry.getKey().length() > 1) { +617 vendor.addEvidence("jar", "package name", entry.getKey(), Confidence.LOW); +618 } +619 } +620 } +621 for (Map.Entry<String, Integer> entry : productIdentifiers.entrySet()) { +622 final float ratio = entry.getValue() / (float) classCount; +623 if (ratio > 0.5) { +624 product.addWeighting(entry.getKey()); +625 if (addPackagesAsEvidence && entry.getKey().length() > 1) { +626 product.addEvidence("jar", "package name", entry.getKey(), Confidence.LOW); +627 } +628 } +629 } +630 } +631 +632 /** +633 * <p> +634 * Reads the manifest from the JAR file and collects the entries. Some +635 * vendorKey entries are:</p> +636 * <ul><li>Implementation Title</li> +637 * <li>Implementation Version</li> <li>Implementation Vendor</li> +638 * <li>Implementation VendorId</li> <li>Bundle Name</li> <li>Bundle +639 * Version</li> <li>Bundle Vendor</li> <li>Bundle Description</li> <li>Main +640 * Class</li> </ul> +641 * However, all but a handful of specific entries are read in. +642 * +643 * @param dependency A reference to the dependency +644 * @param classInformation a collection of class information +645 * @return whether evidence was identified parsing the manifest +646 * @throws IOException if there is an issue reading the JAR file +647 */ +648 protected boolean parseManifest(Dependency dependency, List<ClassNameInformation> classInformation) throws IOException { +649 boolean foundSomething = false; +650 JarFile jar = null; +651 try { +652 jar = new JarFile(dependency.getActualFilePath()); +653 final Manifest manifest = jar.getManifest(); +654 if (manifest == null) { +655 if (!dependency.getFileName().toLowerCase().endsWith("-sources.jar") +656 && !dependency.getFileName().toLowerCase().endsWith("-javadoc.jar") +657 && !dependency.getFileName().toLowerCase().endsWith("-src.jar") +658 && !dependency.getFileName().toLowerCase().endsWith("-doc.jar")) { +659 LOGGER.debug("Jar file '{}' does not contain a manifest.", +660 dependency.getFileName()); +661 } +662 return false; +663 } +664 final EvidenceCollection vendorEvidence = dependency.getVendorEvidence(); +665 final EvidenceCollection productEvidence = dependency.getProductEvidence(); +666 final EvidenceCollection versionEvidence = dependency.getVersionEvidence(); +667 String source = "Manifest"; +668 String specificationVersion = null; +669 boolean hasImplementationVersion = false; +670 Attributes atts = manifest.getMainAttributes(); +671 for (Entry<Object, Object> entry : atts.entrySet()) { +672 String key = entry.getKey().toString(); +673 String value = atts.getValue(key); +674 if (HTML_DETECTION_PATTERN.matcher(value).find()) { +675 value = Jsoup.parse(value).text(); +676 } +677 if (IGNORE_VALUES.contains(value)) { +678 continue; +679 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_TITLE.toString())) { +680 foundSomething = true; +681 productEvidence.addEvidence(source, key, value, Confidence.HIGH); +682 addMatchingValues(classInformation, value, productEvidence); +683 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VERSION.toString())) { +684 hasImplementationVersion = true; +685 foundSomething = true; +686 versionEvidence.addEvidence(source, key, value, Confidence.HIGH); +687 } else if ("specification-version".equalsIgnoreCase(key)) { +688 specificationVersion = key; +689 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VENDOR.toString())) { +690 foundSomething = true; +691 vendorEvidence.addEvidence(source, key, value, Confidence.HIGH); +692 addMatchingValues(classInformation, value, vendorEvidence); +693 } else if (key.equalsIgnoreCase(IMPLEMENTATION_VENDOR_ID)) { +694 foundSomething = true; +695 vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +696 addMatchingValues(classInformation, value, vendorEvidence); +697 } else if (key.equalsIgnoreCase(BUNDLE_DESCRIPTION)) { +698 foundSomething = true; +699 addDescription(dependency, value, "manifest", key); +700 addMatchingValues(classInformation, value, productEvidence); +701 } else if (key.equalsIgnoreCase(BUNDLE_NAME)) { +702 foundSomething = true; +703 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +704 addMatchingValues(classInformation, value, productEvidence); +705 // //the following caused false positives. +706 // } else if (key.equalsIgnoreCase(BUNDLE_VENDOR)) { +707 // foundSomething = true; +708 // vendorEvidence.addEvidence(source, key, value, Confidence.HIGH); +709 // addMatchingValues(classInformation, value, vendorEvidence); +710 } else if (key.equalsIgnoreCase(BUNDLE_VERSION)) { +711 foundSomething = true; +712 versionEvidence.addEvidence(source, key, value, Confidence.HIGH); +713 } else if (key.equalsIgnoreCase(Attributes.Name.MAIN_CLASS.toString())) { +714 continue; +715 //skipping main class as if this has important information to add +716 // it will be added during class name analysis... if other fields +717 // have the information from the class name then they will get added... +718 } else { +719 key = key.toLowerCase(); +720 if (!IGNORE_KEYS.contains(key) +721 && !key.endsWith("jdk") +722 && !key.contains("lastmodified") +723 && !key.endsWith("package") +724 && !key.endsWith("classpath") +725 && !key.endsWith("class-path") +726 && !key.endsWith("-scm") //todo change this to a regex? +727 && !key.startsWith("scm-") +728 && !value.trim().startsWith("scm:") +729 && !isImportPackage(key, value) +730 && !isPackage(key, value)) { +731 foundSomething = true; +732 if (key.contains("version")) { +733 if (!key.contains("specification")) { +734 versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +735 } +736 } else if ("build-id".equals(key)) { +737 int pos = value.indexOf('('); +738 if (pos >= 0) { +739 value = value.substring(0, pos - 1); +740 } +741 pos = value.indexOf('['); +742 if (pos >= 0) { +743 value = value.substring(0, pos - 1); +744 } +745 versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +746 } else if (key.contains("title")) { +747 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +748 addMatchingValues(classInformation, value, productEvidence); +749 } else if (key.contains("vendor")) { +750 if (key.contains("specification")) { +751 vendorEvidence.addEvidence(source, key, value, Confidence.LOW); +752 } else { +753 vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +754 addMatchingValues(classInformation, value, vendorEvidence); +755 } +756 } else if (key.contains("name")) { +757 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +758 vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +759 addMatchingValues(classInformation, value, vendorEvidence); +760 addMatchingValues(classInformation, value, productEvidence); +761 } else if (key.contains("license")) { +762 addLicense(dependency, value); +763 } else if (key.contains("description")) { +764 addDescription(dependency, value, "manifest", key); +765 } else { +766 productEvidence.addEvidence(source, key, value, Confidence.LOW); +767 vendorEvidence.addEvidence(source, key, value, Confidence.LOW); +768 addMatchingValues(classInformation, value, vendorEvidence); +769 addMatchingValues(classInformation, value, productEvidence); +770 if (value.matches(".*\\d.*")) { +771 final StringTokenizer tokenizer = new StringTokenizer(value, " "); +772 while (tokenizer.hasMoreElements()) { +773 final String s = tokenizer.nextToken(); +774 if (s.matches("^[0-9.]+$")) { +775 versionEvidence.addEvidence(source, key, s, Confidence.LOW); +776 } +777 } +778 } +779 } +780 } +781 } +782 } +783 for (Map.Entry<String, Attributes> item : manifest.getEntries().entrySet()) { +784 final String name = item.getKey(); +785 source = "manifest: " + name; +786 atts = item.getValue(); +787 for (Entry<Object, Object> entry : atts.entrySet()) { +788 final String key = entry.getKey().toString(); +789 final String value = atts.getValue(key); +790 if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_TITLE.toString())) { +791 foundSomething = true; +792 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +793 addMatchingValues(classInformation, value, productEvidence); +794 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VERSION.toString())) { +795 foundSomething = true; +796 versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +797 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VENDOR.toString())) { 798 foundSomething = true; -799 versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -800 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VENDOR.toString())) { -801 foundSomething = true; -802 vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -803 addMatchingValues(classInformation, value, vendorEvidence); -804 } else if (key.equalsIgnoreCase(Attributes.Name.SPECIFICATION_TITLE.toString())) { -805 foundSomething = true; -806 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -807 addMatchingValues(classInformation, value, productEvidence); -808 } -809 } -810 } -811 if (specificationVersion != null && !hasImplementationVersion) { -812 foundSomething = true; -813 versionEvidence.addEvidence(source, "specification-version", specificationVersion, Confidence.HIGH); -814 } -815 } finally { -816 if (jar != null) { -817 jar.close(); -818 } -819 } -820 return foundSomething; -821 } -822 -823 /** -824 * Adds a description to the given dependency. If the description contains -825 * one of the following strings beyond 100 characters, then the description -826 * used will be trimmed to that position: -827 * <ul><li>"such as"</li><li>"like "</li><li>"will use "</li><li>"* uses -828 * "</li></ul> -829 * -830 * @param dependency a dependency -831 * @param description the description -832 * @param source the source of the evidence -833 * @param key the "name" of the evidence -834 * @return if the description is trimmed, the trimmed version is returned; -835 * otherwise the original description is returned -836 */ -837 public static String addDescription(Dependency dependency, String description, String source, String key) { -838 if (dependency.getDescription() == null) { -839 dependency.setDescription(description); -840 } -841 String desc; -842 if (HTML_DETECTION_PATTERN.matcher(description).find()) { -843 desc = Jsoup.parse(description).text(); -844 } else { -845 desc = description; -846 } -847 dependency.setDescription(desc); -848 if (desc.length() > 100) { -849 desc = desc.replaceAll("\\s\\s+", " "); -850 final int posSuchAs = desc.toLowerCase().indexOf("such as ", 100); -851 final int posLike = desc.toLowerCase().indexOf("like ", 100); -852 final int posWillUse = desc.toLowerCase().indexOf("will use ", 100); -853 final int posUses = desc.toLowerCase().indexOf(" uses ", 100); -854 int pos = -1; -855 pos = Math.max(pos, posSuchAs); -856 if (pos >= 0 && posLike >= 0) { -857 pos = Math.min(pos, posLike); -858 } else { -859 pos = Math.max(pos, posLike); -860 } -861 if (pos >= 0 && posWillUse >= 0) { -862 pos = Math.min(pos, posWillUse); -863 } else { -864 pos = Math.max(pos, posWillUse); -865 } -866 if (pos >= 0 && posUses >= 0) { -867 pos = Math.min(pos, posUses); -868 } else { -869 pos = Math.max(pos, posUses); -870 } -871 -872 if (pos > 0) { -873 desc = desc.substring(0, pos) + "..."; -874 } -875 dependency.getProductEvidence().addEvidence(source, key, desc, Confidence.LOW); -876 dependency.getVendorEvidence().addEvidence(source, key, desc, Confidence.LOW); -877 } else { -878 dependency.getProductEvidence().addEvidence(source, key, desc, Confidence.MEDIUM); -879 dependency.getVendorEvidence().addEvidence(source, key, desc, Confidence.MEDIUM); -880 } -881 return desc; -882 } -883 -884 /** -885 * Adds a license to the given dependency. -886 * -887 * @param d a dependency -888 * @param license the license -889 */ -890 private void addLicense(Dependency d, String license) { -891 if (d.getLicense() == null) { -892 d.setLicense(license); -893 } else if (!d.getLicense().contains(license)) { -894 d.setLicense(d.getLicense() + NEWLINE + license); -895 } -896 } -897 -898 /** -899 * The parent directory for the individual directories per archive. -900 */ -901 private File tempFileLocation = null; -902 -903 /** -904 * Initializes the JarAnalyzer. -905 * -906 * @throws Exception is thrown if there is an exception creating a temporary -907 * directory -908 */ -909 @Override -910 public void initializeFileTypeAnalyzer() throws Exception { -911 final File baseDir = Settings.getTempDirectory(); -912 tempFileLocation = File.createTempFile("check", "tmp", baseDir); -913 if (!tempFileLocation.delete()) { -914 final String msg = String.format("Unable to delete temporary file '%s'.", tempFileLocation.getAbsolutePath()); -915 throw new AnalysisException(msg); -916 } -917 if (!tempFileLocation.mkdirs()) { -918 final String msg = String.format("Unable to create directory '%s'.", tempFileLocation.getAbsolutePath()); -919 throw new AnalysisException(msg); -920 } -921 } -922 -923 /** -924 * Deletes any files extracted from the JAR during analysis. -925 */ -926 @Override -927 public void close() { -928 if (tempFileLocation != null && tempFileLocation.exists()) { -929 LOGGER.debug("Attempting to delete temporary files"); -930 final boolean success = FileUtils.delete(tempFileLocation); -931 if (!success) { -932 LOGGER.warn("Failed to delete some temporary files, see the log for more details"); -933 } -934 } -935 } -936 -937 /** -938 * Determines if the key value pair from the manifest is for an "import" -939 * type entry for package names. -940 * -941 * @param key the key from the manifest -942 * @param value the value from the manifest -943 * @return true or false depending on if it is believed the entry is an -944 * "import" entry -945 */ -946 private boolean isImportPackage(String key, String value) { -947 final Pattern packageRx = Pattern.compile("^([a-zA-Z0-9_#\\$\\*\\.]+\\s*[,;]\\s*)+([a-zA-Z0-9_#\\$\\*\\.]+\\s*)?$"); -948 final boolean matches = packageRx.matcher(value).matches(); -949 return matches && (key.contains("import") || key.contains("include") || value.length() > 10); -950 } -951 -952 /** -953 * Cycles through an enumeration of JarEntries, contained within the -954 * dependency, and returns a list of the class names. This does not include -955 * core Java package names (i.e. java.* or javax.*). -956 * -957 * @param dependency the dependency being analyzed -958 * @return an list of fully qualified class names -959 */ -960 private List<ClassNameInformation> collectClassNames(Dependency dependency) { -961 final List<ClassNameInformation> classNames = new ArrayList<ClassNameInformation>(); -962 JarFile jar = null; -963 try { -964 jar = new JarFile(dependency.getActualFilePath()); -965 final Enumeration<JarEntry> entries = jar.entries(); -966 while (entries.hasMoreElements()) { -967 final JarEntry entry = entries.nextElement(); -968 final String name = entry.getName().toLowerCase(); -969 //no longer stripping "|com\\.sun" - there are some com.sun jar files with CVEs. -970 if (name.endsWith(".class") && !name.matches("^javax?\\..*$")) { -971 final ClassNameInformation className = new ClassNameInformation(name.substring(0, name.length() - 6)); -972 classNames.add(className); -973 } -974 } -975 } catch (IOException ex) { -976 LOGGER.warn("Unable to open jar file '{}'.", dependency.getFileName()); -977 LOGGER.debug("", ex); -978 } finally { -979 if (jar != null) { -980 try { -981 jar.close(); -982 } catch (IOException ex) { -983 LOGGER.trace("", ex); -984 } -985 } -986 } -987 return classNames; -988 } -989 -990 /** -991 * Cycles through the list of class names and places the package levels 0-3 -992 * into the provided maps for vendor and product. This is helpful when -993 * analyzing vendor/product as many times this is included in the package -994 * name. -995 * -996 * @param classNames a list of class names -997 * @param vendor HashMap of possible vendor names from package names (e.g. -998 * owasp) -999 * @param product HashMap of possible product names from package names (e.g. -1000 * dependencycheck) -1001 */ -1002 private void analyzeFullyQualifiedClassNames(List<ClassNameInformation> classNames, -1003 Map<String, Integer> vendor, Map<String, Integer> product) { -1004 for (ClassNameInformation entry : classNames) { -1005 final List<String> list = entry.getPackageStructure(); -1006 addEntry(vendor, list.get(0)); -1007 -1008 if (list.size() == 2) { -1009 addEntry(product, list.get(1)); -1010 } -1011 if (list.size() == 3) { -1012 addEntry(vendor, list.get(1)); +799 vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +800 addMatchingValues(classInformation, value, vendorEvidence); +801 } else if (key.equalsIgnoreCase(Attributes.Name.SPECIFICATION_TITLE.toString())) { +802 foundSomething = true; +803 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +804 addMatchingValues(classInformation, value, productEvidence); +805 } +806 } +807 } +808 if (specificationVersion != null && !hasImplementationVersion) { +809 foundSomething = true; +810 versionEvidence.addEvidence(source, "specification-version", specificationVersion, Confidence.HIGH); +811 } +812 } finally { +813 if (jar != null) { +814 jar.close(); +815 } +816 } +817 return foundSomething; +818 } +819 +820 /** +821 * Adds a description to the given dependency. If the description contains +822 * one of the following strings beyond 100 characters, then the description +823 * used will be trimmed to that position: +824 * <ul><li>"such as"</li><li>"like "</li><li>"will use "</li><li>"* uses +825 * "</li></ul> +826 * +827 * @param dependency a dependency +828 * @param description the description +829 * @param source the source of the evidence +830 * @param key the "name" of the evidence +831 * @return if the description is trimmed, the trimmed version is returned; +832 * otherwise the original description is returned +833 */ +834 public static String addDescription(Dependency dependency, String description, String source, String key) { +835 if (dependency.getDescription() == null) { +836 dependency.setDescription(description); +837 } +838 String desc; +839 if (HTML_DETECTION_PATTERN.matcher(description).find()) { +840 desc = Jsoup.parse(description).text(); +841 } else { +842 desc = description; +843 } +844 dependency.setDescription(desc); +845 if (desc.length() > 100) { +846 desc = desc.replaceAll("\\s\\s+", " "); +847 final int posSuchAs = desc.toLowerCase().indexOf("such as ", 100); +848 final int posLike = desc.toLowerCase().indexOf("like ", 100); +849 final int posWillUse = desc.toLowerCase().indexOf("will use ", 100); +850 final int posUses = desc.toLowerCase().indexOf(" uses ", 100); +851 int pos = -1; +852 pos = Math.max(pos, posSuchAs); +853 if (pos >= 0 && posLike >= 0) { +854 pos = Math.min(pos, posLike); +855 } else { +856 pos = Math.max(pos, posLike); +857 } +858 if (pos >= 0 && posWillUse >= 0) { +859 pos = Math.min(pos, posWillUse); +860 } else { +861 pos = Math.max(pos, posWillUse); +862 } +863 if (pos >= 0 && posUses >= 0) { +864 pos = Math.min(pos, posUses); +865 } else { +866 pos = Math.max(pos, posUses); +867 } +868 +869 if (pos > 0) { +870 desc = desc.substring(0, pos) + "..."; +871 } +872 dependency.getProductEvidence().addEvidence(source, key, desc, Confidence.LOW); +873 dependency.getVendorEvidence().addEvidence(source, key, desc, Confidence.LOW); +874 } else { +875 dependency.getProductEvidence().addEvidence(source, key, desc, Confidence.MEDIUM); +876 dependency.getVendorEvidence().addEvidence(source, key, desc, Confidence.MEDIUM); +877 } +878 return desc; +879 } +880 +881 /** +882 * Adds a license to the given dependency. +883 * +884 * @param d a dependency +885 * @param license the license +886 */ +887 private void addLicense(Dependency d, String license) { +888 if (d.getLicense() == null) { +889 d.setLicense(license); +890 } else if (!d.getLicense().contains(license)) { +891 d.setLicense(d.getLicense() + NEWLINE + license); +892 } +893 } +894 +895 /** +896 * The parent directory for the individual directories per archive. +897 */ +898 private File tempFileLocation = null; +899 +900 /** +901 * Initializes the JarAnalyzer. +902 * +903 * @throws InitializationException is thrown if there is an exception +904 * creating a temporary directory +905 */ +906 @Override +907 public void initializeFileTypeAnalyzer() throws InitializationException { +908 try { +909 final File baseDir = Settings.getTempDirectory(); +910 tempFileLocation = File.createTempFile("check", "tmp", baseDir); +911 if (!tempFileLocation.delete()) { +912 final String msg = String.format("Unable to delete temporary file '%s'.", tempFileLocation.getAbsolutePath()); +913 setEnabled(false); +914 throw new InitializationException(msg); +915 } +916 if (!tempFileLocation.mkdirs()) { +917 final String msg = String.format("Unable to create directory '%s'.", tempFileLocation.getAbsolutePath()); +918 setEnabled(false); +919 throw new InitializationException(msg); +920 } +921 } catch (IOException ex) { +922 setEnabled(false); +923 throw new InitializationException("Unable to create a temporary file", ex); +924 } +925 } +926 +927 /** +928 * Deletes any files extracted from the JAR during analysis. +929 */ +930 @Override +931 public void close() { +932 if (tempFileLocation != null && tempFileLocation.exists()) { +933 LOGGER.debug("Attempting to delete temporary files"); +934 final boolean success = FileUtils.delete(tempFileLocation); +935 if (!success) { +936 LOGGER.warn("Failed to delete some temporary files, see the log for more details"); +937 } +938 } +939 } +940 +941 /** +942 * Determines if the key value pair from the manifest is for an "import" +943 * type entry for package names. +944 * +945 * @param key the key from the manifest +946 * @param value the value from the manifest +947 * @return true or false depending on if it is believed the entry is an +948 * "import" entry +949 */ +950 private boolean isImportPackage(String key, String value) { +951 final Pattern packageRx = Pattern.compile("^([a-zA-Z0-9_#\\$\\*\\.]+\\s*[,;]\\s*)+([a-zA-Z0-9_#\\$\\*\\.]+\\s*)?$"); +952 final boolean matches = packageRx.matcher(value).matches(); +953 return matches && (key.contains("import") || key.contains("include") || value.length() > 10); +954 } +955 +956 /** +957 * Cycles through an enumeration of JarEntries, contained within the +958 * dependency, and returns a list of the class names. This does not include +959 * core Java package names (i.e. java.* or javax.*). +960 * +961 * @param dependency the dependency being analyzed +962 * @return an list of fully qualified class names +963 */ +964 private List<ClassNameInformation> collectClassNames(Dependency dependency) { +965 final List<ClassNameInformation> classNames = new ArrayList<ClassNameInformation>(); +966 JarFile jar = null; +967 try { +968 jar = new JarFile(dependency.getActualFilePath()); +969 final Enumeration<JarEntry> entries = jar.entries(); +970 while (entries.hasMoreElements()) { +971 final JarEntry entry = entries.nextElement(); +972 final String name = entry.getName().toLowerCase(); +973 //no longer stripping "|com\\.sun" - there are some com.sun jar files with CVEs. +974 if (name.endsWith(".class") && !name.matches("^javax?\\..*$")) { +975 final ClassNameInformation className = new ClassNameInformation(name.substring(0, name.length() - 6)); +976 classNames.add(className); +977 } +978 } +979 } catch (IOException ex) { +980 LOGGER.warn("Unable to open jar file '{}'.", dependency.getFileName()); +981 LOGGER.debug("", ex); +982 } finally { +983 if (jar != null) { +984 try { +985 jar.close(); +986 } catch (IOException ex) { +987 LOGGER.trace("", ex); +988 } +989 } +990 } +991 return classNames; +992 } +993 +994 /** +995 * Cycles through the list of class names and places the package levels 0-3 +996 * into the provided maps for vendor and product. This is helpful when +997 * analyzing vendor/product as many times this is included in the package +998 * name. +999 * +1000 * @param classNames a list of class names +1001 * @param vendor HashMap of possible vendor names from package names (e.g. +1002 * owasp) +1003 * @param product HashMap of possible product names from package names (e.g. +1004 * dependencycheck) +1005 */ +1006 private void analyzeFullyQualifiedClassNames(List<ClassNameInformation> classNames, +1007 Map<String, Integer> vendor, Map<String, Integer> product) { +1008 for (ClassNameInformation entry : classNames) { +1009 final List<String> list = entry.getPackageStructure(); +1010 addEntry(vendor, list.get(0)); +1011 +1012 if (list.size() == 2) { 1013 addEntry(product, list.get(1)); -1014 addEntry(product, list.get(2)); -1015 } -1016 if (list.size() >= 4) { -1017 addEntry(vendor, list.get(1)); -1018 addEntry(vendor, list.get(2)); -1019 addEntry(product, list.get(1)); -1020 addEntry(product, list.get(2)); -1021 addEntry(product, list.get(3)); -1022 } -1023 } -1024 } -1025 -1026 /** -1027 * Adds an entry to the specified collection and sets the Integer (e.g. the -1028 * count) to 1. If the entry already exists in the collection then the -1029 * Integer is incremented by 1. -1030 * -1031 * @param collection a collection of strings and their occurrence count -1032 * @param key the key to add to the collection -1033 */ -1034 private void addEntry(Map<String, Integer> collection, String key) { -1035 if (collection.containsKey(key)) { -1036 collection.put(key, collection.get(key) + 1); -1037 } else { -1038 collection.put(key, 1); -1039 } -1040 } -1041 -1042 /** -1043 * Cycles through the collection of class name information to see if parts -1044 * of the package names are contained in the provided value. If found, it -1045 * will be added as the HIGHEST confidence evidence because we have more -1046 * then one source corroborating the value. -1047 * -1048 * @param classes a collection of class name information -1049 * @param value the value to check to see if it contains a package name -1050 * @param evidence the evidence collection to add new entries too -1051 */ -1052 private static void addMatchingValues(List<ClassNameInformation> classes, String value, EvidenceCollection evidence) { -1053 if (value == null || value.isEmpty() || classes == null || classes.isEmpty()) { -1054 return; -1055 } -1056 final String text = value.toLowerCase(); -1057 for (ClassNameInformation cni : classes) { -1058 for (String key : cni.getPackageStructure()) { -1059 final Pattern p = Pattern.compile("\b" + key + "\b"); -1060 if (p.matcher(text).find()) { -1061 //if (text.contains(key)) { //note, package structure elements are already lowercase. -1062 evidence.addEvidence("jar", "package name", key, Confidence.HIGHEST); -1063 } -1064 } -1065 } -1066 } -1067 -1068 /** -1069 * Simple check to see if the attribute from a manifest is just a package -1070 * name. -1071 * -1072 * @param key the key of the value to check -1073 * @param value the value to check -1074 * @return true if the value looks like a java package name, otherwise false -1075 */ -1076 private boolean isPackage(String key, String value) { -1077 -1078 return !key.matches(".*(version|title|vendor|name|license|description).*") -1079 && value.matches("^([a-zA-Z_][a-zA-Z0-9_\\$]*(\\.[a-zA-Z_][a-zA-Z0-9_\\$]*)*)?$"); -1080 -1081 } -1082 -1083 /** -1084 * Extracts the license information from the pom and adds it to the -1085 * dependency. -1086 * -1087 * @param pom the pom object -1088 * @param dependency the dependency to add license information too -1089 */ -1090 public static void extractLicense(Model pom, Dependency dependency) { -1091 //license -1092 if (pom.getLicenses() != null) { -1093 String license = null; -1094 for (License lic : pom.getLicenses()) { -1095 String tmp = null; -1096 if (lic.getName() != null) { -1097 tmp = lic.getName(); -1098 } -1099 if (lic.getUrl() != null) { -1100 if (tmp == null) { -1101 tmp = lic.getUrl(); -1102 } else { -1103 tmp += ": " + lic.getUrl(); -1104 } -1105 } -1106 if (tmp == null) { -1107 continue; -1108 } -1109 if (HTML_DETECTION_PATTERN.matcher(tmp).find()) { -1110 tmp = Jsoup.parse(tmp).text(); -1111 } -1112 if (license == null) { -1113 license = tmp; -1114 } else { -1115 license += "\n" + tmp; -1116 } -1117 } -1118 if (license != null) { -1119 dependency.setLicense(license); -1120 +1014 } +1015 if (list.size() == 3) { +1016 addEntry(vendor, list.get(1)); +1017 addEntry(product, list.get(1)); +1018 addEntry(product, list.get(2)); +1019 } +1020 if (list.size() >= 4) { +1021 addEntry(vendor, list.get(1)); +1022 addEntry(vendor, list.get(2)); +1023 addEntry(product, list.get(1)); +1024 addEntry(product, list.get(2)); +1025 addEntry(product, list.get(3)); +1026 } +1027 } +1028 } +1029 +1030 /** +1031 * Adds an entry to the specified collection and sets the Integer (e.g. the +1032 * count) to 1. If the entry already exists in the collection then the +1033 * Integer is incremented by 1. +1034 * +1035 * @param collection a collection of strings and their occurrence count +1036 * @param key the key to add to the collection +1037 */ +1038 private void addEntry(Map<String, Integer> collection, String key) { +1039 if (collection.containsKey(key)) { +1040 collection.put(key, collection.get(key) + 1); +1041 } else { +1042 collection.put(key, 1); +1043 } +1044 } +1045 +1046 /** +1047 * Cycles through the collection of class name information to see if parts +1048 * of the package names are contained in the provided value. If found, it +1049 * will be added as the HIGHEST confidence evidence because we have more +1050 * then one source corroborating the value. +1051 * +1052 * @param classes a collection of class name information +1053 * @param value the value to check to see if it contains a package name +1054 * @param evidence the evidence collection to add new entries too +1055 */ +1056 private static void addMatchingValues(List<ClassNameInformation> classes, String value, EvidenceCollection evidence) { +1057 if (value == null || value.isEmpty() || classes == null || classes.isEmpty()) { +1058 return; +1059 } +1060 final String text = value.toLowerCase(); +1061 for (ClassNameInformation cni : classes) { +1062 for (String key : cni.getPackageStructure()) { +1063 final Pattern p = Pattern.compile("\b" + key + "\b"); +1064 if (p.matcher(text).find()) { +1065 //if (text.contains(key)) { //note, package structure elements are already lowercase. +1066 evidence.addEvidence("jar", "package name", key, Confidence.HIGHEST); +1067 } +1068 } +1069 } +1070 } +1071 +1072 /** +1073 * Simple check to see if the attribute from a manifest is just a package +1074 * name. +1075 * +1076 * @param key the key of the value to check +1077 * @param value the value to check +1078 * @return true if the value looks like a java package name, otherwise false +1079 */ +1080 private boolean isPackage(String key, String value) { +1081 +1082 return !key.matches(".*(version|title|vendor|name|license|description).*") +1083 && value.matches("^([a-zA-Z_][a-zA-Z0-9_\\$]*(\\.[a-zA-Z_][a-zA-Z0-9_\\$]*)*)?$"); +1084 +1085 } +1086 +1087 /** +1088 * Extracts the license information from the pom and adds it to the +1089 * dependency. +1090 * +1091 * @param pom the pom object +1092 * @param dependency the dependency to add license information too +1093 */ +1094 public static void extractLicense(Model pom, Dependency dependency) { +1095 //license +1096 if (pom.getLicenses() != null) { +1097 String license = null; +1098 for (License lic : pom.getLicenses()) { +1099 String tmp = null; +1100 if (lic.getName() != null) { +1101 tmp = lic.getName(); +1102 } +1103 if (lic.getUrl() != null) { +1104 if (tmp == null) { +1105 tmp = lic.getUrl(); +1106 } else { +1107 tmp += ": " + lic.getUrl(); +1108 } +1109 } +1110 if (tmp == null) { +1111 continue; +1112 } +1113 if (HTML_DETECTION_PATTERN.matcher(tmp).find()) { +1114 tmp = Jsoup.parse(tmp).text(); +1115 } +1116 if (license == null) { +1117 license = tmp; +1118 } else { +1119 license += "\n" + tmp; +1120 } 1121 } -1122 } -1123 } +1122 if (license != null) { +1123 dependency.setLicense(license); 1124 -1125 /** -1126 * Stores information about a class name. -1127 */ -1128 protected static class ClassNameInformation { -1129 -1130 /** -1131 * <p> -1132 * Stores information about a given class name. This class will keep the -1133 * fully qualified class name and a list of the important parts of the -1134 * package structure. Up to the first four levels of the package -1135 * structure are stored, excluding a leading "org" or "com". -1136 * Example:</p> -1137 * <code>ClassNameInformation obj = new ClassNameInformation("org.owasp.dependencycheck.analyzer.JarAnalyzer"); -1138 * System.out.println(obj.getName()); -1139 * for (String p : obj.getPackageStructure()) -1140 * System.out.println(p); -1141 * </code> -1142 * <p> -1143 * Would result in:</p> -1144 * <code>org.owasp.dependencycheck.analyzer.JarAnalyzer -1145 * owasp -1146 * dependencycheck -1147 * analyzer -1148 * jaranalyzer</code> -1149 * -1150 * @param className a fully qualified class name -1151 */ -1152 ClassNameInformation(String className) { -1153 name = className; -1154 if (name.contains("/")) { -1155 final String[] tmp = className.toLowerCase().split("/"); -1156 int start = 0; -1157 int end = 3; -1158 if ("com".equals(tmp[0]) || "org".equals(tmp[0])) { -1159 start = 1; -1160 end = 4; -1161 } -1162 if (tmp.length <= end) { -1163 end = tmp.length - 1; -1164 } -1165 for (int i = start; i <= end; i++) { -1166 packageStructure.add(tmp[i]); -1167 } -1168 } else { -1169 packageStructure.add(name); -1170 } -1171 } -1172 /** -1173 * The fully qualified class name. -1174 */ -1175 private String name; -1176 -1177 /** -1178 * Get the value of name -1179 * -1180 * @return the value of name -1181 */ -1182 public String getName() { -1183 return name; -1184 } -1185 -1186 /** -1187 * Set the value of name -1188 * -1189 * @param name new value of name -1190 */ -1191 public void setName(String name) { -1192 this.name = name; -1193 } -1194 /** -1195 * Up to the first four levels of the package structure, excluding a -1196 * leading "org" or "com". -1197 */ -1198 private final ArrayList<String> packageStructure = new ArrayList<String>(); -1199 -1200 /** -1201 * Get the value of packageStructure -1202 * -1203 * @return the value of packageStructure -1204 */ -1205 public ArrayList<String> getPackageStructure() { -1206 return packageStructure; -1207 } -1208 } -1209 -1210 /** -1211 * Retrieves the next temporary directory to extract an archive too. -1212 * -1213 * @return a directory -1214 * @throws AnalysisException thrown if unable to create temporary directory -1215 */ -1216 private File getNextTempDirectory() throws AnalysisException { -1217 dirCount += 1; -1218 final File directory = new File(tempFileLocation, String.valueOf(dirCount)); -1219 //getting an exception for some directories not being able to be created; might be because the directory already exists? -1220 if (directory.exists()) { -1221 return getNextTempDirectory(); -1222 } -1223 if (!directory.mkdirs()) { -1224 final String msg = String.format("Unable to create temp directory '%s'.", directory.getAbsolutePath()); -1225 throw new AnalysisException(msg); +1125 } +1126 } +1127 } +1128 +1129 /** +1130 * Stores information about a class name. +1131 */ +1132 protected static class ClassNameInformation { +1133 +1134 /** +1135 * <p> +1136 * Stores information about a given class name. This class will keep the +1137 * fully qualified class name and a list of the important parts of the +1138 * package structure. Up to the first four levels of the package +1139 * structure are stored, excluding a leading "org" or "com". +1140 * Example:</p> +1141 * <code>ClassNameInformation obj = new ClassNameInformation("org.owasp.dependencycheck.analyzer.JarAnalyzer"); +1142 * System.out.println(obj.getName()); +1143 * for (String p : obj.getPackageStructure()) +1144 * System.out.println(p); +1145 * </code> +1146 * <p> +1147 * Would result in:</p> +1148 * <code>org.owasp.dependencycheck.analyzer.JarAnalyzer +1149 * owasp +1150 * dependencycheck +1151 * analyzer +1152 * jaranalyzer</code> +1153 * +1154 * @param className a fully qualified class name +1155 */ +1156 ClassNameInformation(String className) { +1157 name = className; +1158 if (name.contains("/")) { +1159 final String[] tmp = className.toLowerCase().split("/"); +1160 int start = 0; +1161 int end = 3; +1162 if ("com".equals(tmp[0]) || "org".equals(tmp[0])) { +1163 start = 1; +1164 end = 4; +1165 } +1166 if (tmp.length <= end) { +1167 end = tmp.length - 1; +1168 } +1169 for (int i = start; i <= end; i++) { +1170 packageStructure.add(tmp[i]); +1171 } +1172 } else { +1173 packageStructure.add(name); +1174 } +1175 } +1176 /** +1177 * The fully qualified class name. +1178 */ +1179 private String name; +1180 +1181 /** +1182 * Get the value of name +1183 * +1184 * @return the value of name +1185 */ +1186 public String getName() { +1187 return name; +1188 } +1189 +1190 /** +1191 * Set the value of name +1192 * +1193 * @param name new value of name +1194 */ +1195 public void setName(String name) { +1196 this.name = name; +1197 } +1198 /** +1199 * Up to the first four levels of the package structure, excluding a +1200 * leading "org" or "com". +1201 */ +1202 private final ArrayList<String> packageStructure = new ArrayList<String>(); +1203 +1204 /** +1205 * Get the value of packageStructure +1206 * +1207 * @return the value of packageStructure +1208 */ +1209 public ArrayList<String> getPackageStructure() { +1210 return packageStructure; +1211 } +1212 } +1213 +1214 /** +1215 * Retrieves the next temporary directory to extract an archive too. +1216 * +1217 * @return a directory +1218 * @throws AnalysisException thrown if unable to create temporary directory +1219 */ +1220 private File getNextTempDirectory() throws AnalysisException { +1221 dirCount += 1; +1222 final File directory = new File(tempFileLocation, String.valueOf(dirCount)); +1223 //getting an exception for some directories not being able to be created; might be because the directory already exists? +1224 if (directory.exists()) { +1225 return getNextTempDirectory(); 1226 } -1227 return directory; -1228 } -1229 } +1227 if (!directory.mkdirs()) { +1228 final String msg = String.format("Unable to create temp directory '%s'.", directory.getAbsolutePath()); +1229 throw new AnalysisException(msg); +1230 } +1231 return directory; +1232 } +1233 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/NexusAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/NexusAnalyzer.html index 28b6703c4..423630215 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/NexusAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/NexusAnalyzer.html @@ -43,229 +43,234 @@ 35 import java.io.IOException; 36 import java.net.MalformedURLException; 37 import java.net.URL; -38 import org.owasp.dependencycheck.utils.DownloadFailedException; -39 import org.owasp.dependencycheck.utils.Downloader; -40 import org.owasp.dependencycheck.utils.FileFilterBuilder; -41 import org.owasp.dependencycheck.utils.InvalidSettingException; -42 import org.owasp.dependencycheck.utils.Settings; -43 -44 /** -45 * Analyzer which will attempt to locate a dependency on a Nexus service by SHA-1 digest of the dependency. -46 * -47 * There are two settings which govern this behavior: +38 import org.owasp.dependencycheck.exception.InitializationException; +39 import org.owasp.dependencycheck.utils.DownloadFailedException; +40 import org.owasp.dependencycheck.utils.Downloader; +41 import org.owasp.dependencycheck.utils.FileFilterBuilder; +42 import org.owasp.dependencycheck.utils.InvalidSettingException; +43 import org.owasp.dependencycheck.utils.Settings; +44 +45 /** +46 * Analyzer which will attempt to locate a dependency on a Nexus service by +47 * SHA-1 digest of the dependency. 48 * -49 * <ul> -50 * <li>{@link org.owasp.dependencycheck.utils.Settings.KEYS#ANALYZER_NEXUS_ENABLED} determines whether this analyzer is even -51 * enabled. This can be overridden by setting the system property.</li> -52 * <li>{@link org.owasp.dependencycheck.utils.Settings.KEYS#ANALYZER_NEXUS_URL} the URL to a Nexus service to search by SHA-1. -53 * There is an expected <code>%s</code> in this where the SHA-1 will get entered.</li> -54 * </ul> -55 * -56 * @author colezlaw -57 */ -58 public class NexusAnalyzer extends AbstractFileTypeAnalyzer { -59 -60 /** -61 * The default URL - this will be used by the CentralAnalyzer to determine whether to enable this. -62 */ -63 public static final String DEFAULT_URL = "https://repository.sonatype.org/service/local/"; -64 -65 /** -66 * The logger. +49 * There are two settings which govern this behavior: +50 * +51 * <ul> +52 * <li>{@link org.owasp.dependencycheck.utils.Settings.KEYS#ANALYZER_NEXUS_ENABLED} +53 * determines whether this analyzer is even enabled. This can be overridden by +54 * setting the system property.</li> +55 * <li>{@link org.owasp.dependencycheck.utils.Settings.KEYS#ANALYZER_NEXUS_URL} +56 * the URL to a Nexus service to search by SHA-1. There is an expected +57 * <code>%s</code> in this where the SHA-1 will get entered.</li> +58 * </ul> +59 * +60 * @author colezlaw +61 */ +62 public class NexusAnalyzer extends AbstractFileTypeAnalyzer { +63 +64 /** +65 * The default URL - this will be used by the CentralAnalyzer to determine +66 * whether to enable this. 67 */ -68 private static final Logger LOGGER = LoggerFactory.getLogger(NexusAnalyzer.class); +68 public static final String DEFAULT_URL = "https://repository.sonatype.org/service/local/"; 69 70 /** -71 * The name of the analyzer. +71 * The logger. 72 */ -73 private static final String ANALYZER_NAME = "Nexus Analyzer"; +73 private static final Logger LOGGER = LoggerFactory.getLogger(NexusAnalyzer.class); 74 75 /** -76 * The phase in which the analyzer runs. +76 * The name of the analyzer. 77 */ -78 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; +78 private static final String ANALYZER_NAME = "Nexus Analyzer"; 79 80 /** -81 * The types of files on which this will work. +81 * The phase in which the analyzer runs. 82 */ -83 private static final String SUPPORTED_EXTENSIONS = "jar"; +83 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; 84 85 /** -86 * The Nexus Search to be set up for this analyzer. +86 * The types of files on which this will work. 87 */ -88 private NexusSearch searcher; +88 private static final String SUPPORTED_EXTENSIONS = "jar"; 89 90 /** -91 * Field indicating if the analyzer is enabled. +91 * The Nexus Search to be set up for this analyzer. 92 */ -93 private final boolean enabled = checkEnabled(); +93 private NexusSearch searcher; 94 95 /** -96 * Determines if this analyzer is enabled -97 * -98 * @return <code>true</code> if the analyzer is enabled; otherwise <code>false</code> -99 */ -100 private boolean checkEnabled() { -101 /* Enable this analyzer ONLY if the Nexus URL has been set to something -102 other than the default one (if it's the default one, we'll use the -103 central one) and it's enabled by the user. -104 */ -105 boolean retval = false; -106 try { -107 if (!DEFAULT_URL.equals(Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL)) -108 && Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED)) { -109 LOGGER.info("Enabling Nexus analyzer"); -110 retval = true; -111 } else { -112 LOGGER.debug("Nexus analyzer disabled, using Central instead"); -113 } -114 } catch (InvalidSettingException ise) { -115 LOGGER.warn("Invalid setting. Disabling Nexus analyzer"); -116 } -117 -118 return retval; -119 } -120 -121 /** -122 * Determine whether to enable this analyzer or not. -123 * -124 * @return whether the analyzer should be enabled -125 */ -126 @Override -127 public boolean isEnabled() { -128 return enabled; -129 } -130 -131 /** -132 * Initializes the analyzer once before any analysis is performed. -133 * -134 * @throws Exception if there's an error during initialization -135 */ -136 @Override -137 public void initializeFileTypeAnalyzer() throws Exception { -138 LOGGER.debug("Initializing Nexus Analyzer"); -139 LOGGER.debug("Nexus Analyzer enabled: {}", isEnabled()); -140 if (isEnabled()) { -141 final String searchUrl = Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL); -142 LOGGER.debug("Nexus Analyzer URL: {}", searchUrl); -143 try { -144 searcher = new NexusSearch(new URL(searchUrl)); -145 if (!searcher.preflightRequest()) { -146 LOGGER.warn("There was an issue getting Nexus status. Disabling analyzer."); -147 setEnabled(false); -148 } -149 } catch (MalformedURLException mue) { -150 // I know that initialize can throw an exception, but we'll -151 // just disable the analyzer if the URL isn't valid -152 LOGGER.warn("Property {} not a valid URL. Nexus Analyzer disabled", searchUrl); -153 setEnabled(false); -154 } -155 } -156 } -157 -158 /** -159 * Returns the analyzer's name. -160 * -161 * @return the name of the analyzer -162 */ -163 @Override -164 public String getName() { -165 return ANALYZER_NAME; -166 } -167 -168 /** -169 * Returns the key used in the properties file to reference the analyzer's enabled property. -170 * -171 * @return the analyzer's enabled property setting key -172 */ -173 @Override -174 protected String getAnalyzerEnabledSettingKey() { -175 return Settings.KEYS.ANALYZER_NEXUS_ENABLED; -176 } -177 -178 /** -179 * Returns the analysis phase under which the analyzer runs. -180 * -181 * @return the phase under which this analyzer runs -182 */ -183 @Override -184 public AnalysisPhase getAnalysisPhase() { -185 return ANALYSIS_PHASE; -186 } -187 -188 /** -189 * The file filter used to determine which files this analyzer supports. -190 */ -191 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(SUPPORTED_EXTENSIONS).build(); +96 * Field indicating if the analyzer is enabled. +97 */ +98 private final boolean enabled = checkEnabled(); +99 +100 /** +101 * Determines if this analyzer is enabled +102 * +103 * @return <code>true</code> if the analyzer is enabled; otherwise +104 * <code>false</code> +105 */ +106 private boolean checkEnabled() { +107 /* Enable this analyzer ONLY if the Nexus URL has been set to something +108 other than the default one (if it's the default one, we'll use the +109 central one) and it's enabled by the user. +110 */ +111 boolean retval = false; +112 try { +113 if (!DEFAULT_URL.equals(Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL)) +114 && Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED)) { +115 LOGGER.info("Enabling Nexus analyzer"); +116 retval = true; +117 } else { +118 LOGGER.debug("Nexus analyzer disabled, using Central instead"); +119 } +120 } catch (InvalidSettingException ise) { +121 LOGGER.warn("Invalid setting. Disabling Nexus analyzer"); +122 } +123 +124 return retval; +125 } +126 +127 /** +128 * Determine whether to enable this analyzer or not. +129 * +130 * @return whether the analyzer should be enabled +131 */ +132 @Override +133 public boolean isEnabled() { +134 return enabled; +135 } +136 +137 /** +138 * Initializes the analyzer once before any analysis is performed. +139 * +140 * @throws InitializationException if there's an error during initialization +141 */ +142 @Override +143 public void initializeFileTypeAnalyzer() throws InitializationException { +144 LOGGER.debug("Initializing Nexus Analyzer"); +145 LOGGER.debug("Nexus Analyzer enabled: {}", isEnabled()); +146 if (isEnabled()) { +147 final String searchUrl = Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL); +148 LOGGER.debug("Nexus Analyzer URL: {}", searchUrl); +149 try { +150 searcher = new NexusSearch(new URL(searchUrl)); +151 if (!searcher.preflightRequest()) { +152 setEnabled(false); +153 throw new InitializationException("There was an issue getting Nexus status. Disabling analyzer."); +154 } +155 } catch (MalformedURLException mue) { +156 setEnabled(false); +157 throw new InitializationException("Malformed URL to Nexus: " + searchUrl, mue); +158 } +159 } +160 } +161 +162 /** +163 * Returns the analyzer's name. +164 * +165 * @return the name of the analyzer +166 */ +167 @Override +168 public String getName() { +169 return ANALYZER_NAME; +170 } +171 +172 /** +173 * Returns the key used in the properties file to reference the analyzer's +174 * enabled property. +175 * +176 * @return the analyzer's enabled property setting key +177 */ +178 @Override +179 protected String getAnalyzerEnabledSettingKey() { +180 return Settings.KEYS.ANALYZER_NEXUS_ENABLED; +181 } +182 +183 /** +184 * Returns the analysis phase under which the analyzer runs. +185 * +186 * @return the phase under which this analyzer runs +187 */ +188 @Override +189 public AnalysisPhase getAnalysisPhase() { +190 return ANALYSIS_PHASE; +191 } 192 193 /** -194 * Returns the FileFilter -195 * -196 * @return the FileFilter -197 */ -198 @Override -199 protected FileFilter getFileFilter() { -200 return FILTER; -201 } -202 -203 /** -204 * Performs the analysis. -205 * -206 * @param dependency the dependency to analyze -207 * @param engine the engine -208 * @throws AnalysisException when there's an exception during analysis -209 */ -210 @Override -211 public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { -212 if (!isEnabled()) { -213 return; -214 } -215 try { -216 final MavenArtifact ma = searcher.searchSha1(dependency.getSha1sum()); -217 dependency.addAsEvidence("nexus", ma, Confidence.HIGH); -218 boolean pomAnalyzed = false; -219 LOGGER.debug("POM URL {}", ma.getPomUrl()); -220 for (Evidence e : dependency.getVendorEvidence()) { -221 if ("pom".equals(e.getSource())) { -222 pomAnalyzed = true; -223 break; -224 } -225 } -226 if (!pomAnalyzed && ma.getPomUrl() != null) { -227 File pomFile = null; -228 try { -229 final File baseDir = Settings.getTempDirectory(); -230 pomFile = File.createTempFile("pom", ".xml", baseDir); -231 if (!pomFile.delete()) { -232 LOGGER.warn("Unable to fetch pom.xml for {} from Nexus repository; " -233 + "this could result in undetected CPE/CVEs.", dependency.getFileName()); -234 LOGGER.debug("Unable to delete temp file"); -235 } -236 LOGGER.debug("Downloading {}", ma.getPomUrl()); -237 Downloader.fetchFile(new URL(ma.getPomUrl()), pomFile); -238 PomUtils.analyzePOM(dependency, pomFile); -239 } catch (DownloadFailedException ex) { -240 LOGGER.warn("Unable to download pom.xml for {} from Nexus repository; " -241 + "this could result in undetected CPE/CVEs.", dependency.getFileName()); -242 } finally { -243 if (pomFile != null && !FileUtils.deleteQuietly(pomFile)) { -244 pomFile.deleteOnExit(); -245 } -246 } -247 } -248 } catch (IllegalArgumentException iae) { -249 //dependency.addAnalysisException(new AnalysisException("Invalid SHA-1")); -250 LOGGER.info("invalid sha-1 hash on {}", dependency.getFileName()); -251 } catch (FileNotFoundException fnfe) { -252 //dependency.addAnalysisException(new AnalysisException("Artifact not found on repository")); -253 LOGGER.debug("Artifact not found in repository '{}'", dependency.getFileName()); -254 LOGGER.debug(fnfe.getMessage(), fnfe); -255 } catch (IOException ioe) { -256 //dependency.addAnalysisException(new AnalysisException("Could not connect to repository", ioe)); -257 LOGGER.debug("Could not connect to nexus repository", ioe); -258 } -259 } -260 } +194 * The file filter used to determine which files this analyzer supports. +195 */ +196 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(SUPPORTED_EXTENSIONS).build(); +197 +198 /** +199 * Returns the FileFilter +200 * +201 * @return the FileFilter +202 */ +203 @Override +204 protected FileFilter getFileFilter() { +205 return FILTER; +206 } +207 +208 /** +209 * Performs the analysis. +210 * +211 * @param dependency the dependency to analyze +212 * @param engine the engine +213 * @throws AnalysisException when there's an exception during analysis +214 */ +215 @Override +216 public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { +217 if (!isEnabled()) { +218 return; +219 } +220 try { +221 final MavenArtifact ma = searcher.searchSha1(dependency.getSha1sum()); +222 dependency.addAsEvidence("nexus", ma, Confidence.HIGH); +223 boolean pomAnalyzed = false; +224 LOGGER.debug("POM URL {}", ma.getPomUrl()); +225 for (Evidence e : dependency.getVendorEvidence()) { +226 if ("pom".equals(e.getSource())) { +227 pomAnalyzed = true; +228 break; +229 } +230 } +231 if (!pomAnalyzed && ma.getPomUrl() != null) { +232 File pomFile = null; +233 try { +234 final File baseDir = Settings.getTempDirectory(); +235 pomFile = File.createTempFile("pom", ".xml", baseDir); +236 if (!pomFile.delete()) { +237 LOGGER.warn("Unable to fetch pom.xml for {} from Nexus repository; " +238 + "this could result in undetected CPE/CVEs.", dependency.getFileName()); +239 LOGGER.debug("Unable to delete temp file"); +240 } +241 LOGGER.debug("Downloading {}", ma.getPomUrl()); +242 Downloader.fetchFile(new URL(ma.getPomUrl()), pomFile); +243 PomUtils.analyzePOM(dependency, pomFile); +244 } catch (DownloadFailedException ex) { +245 LOGGER.warn("Unable to download pom.xml for {} from Nexus repository; " +246 + "this could result in undetected CPE/CVEs.", dependency.getFileName()); +247 } finally { +248 if (pomFile != null && !FileUtils.deleteQuietly(pomFile)) { +249 pomFile.deleteOnExit(); +250 } +251 } +252 } +253 } catch (IllegalArgumentException iae) { +254 //dependency.addAnalysisException(new AnalysisException("Invalid SHA-1")); +255 LOGGER.info("invalid sha-1 hash on {}", dependency.getFileName()); +256 } catch (FileNotFoundException fnfe) { +257 //dependency.addAnalysisException(new AnalysisException("Artifact not found on repository")); +258 LOGGER.debug("Artifact not found in repository '{}'", dependency.getFileName()); +259 LOGGER.debug(fnfe.getMessage(), fnfe); +260 } catch (IOException ioe) { +261 //dependency.addAnalysisException(new AnalysisException("Could not connect to repository", ioe)); +262 LOGGER.debug("Could not connect to nexus repository", ioe); +263 } +264 } +265 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/NodePackageAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/NodePackageAnalyzer.html index ebd893860..e4fbd96db 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/NodePackageAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/NodePackageAnalyzer.html @@ -46,154 +46,157 @@ 38 import javax.json.JsonReader; 39 import javax.json.JsonString; 40 import javax.json.JsonValue; -41 -42 /** -43 * Used to analyze Node Package Manager (npm) package.json files, and collect information that can be used to determine the -44 * associated CPE. -45 * -46 * @author Dale Visser -47 */ -48 @Experimental -49 public class NodePackageAnalyzer extends AbstractFileTypeAnalyzer { -50 -51 /** -52 * The logger. -53 */ -54 private static final Logger LOGGER = LoggerFactory.getLogger(NodePackageAnalyzer.class); -55 -56 /** -57 * The name of the analyzer. -58 */ -59 private static final String ANALYZER_NAME = "Node.js Package Analyzer"; -60 -61 /** -62 * The phase that this analyzer is intended to run in. -63 */ -64 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; -65 -66 /** -67 * The file name to scan. -68 */ -69 public static final String PACKAGE_JSON = "package.json"; -70 /** -71 * Filter that detects files named "package.json". -72 */ -73 private static final FileFilter PACKAGE_JSON_FILTER = FileFilterBuilder.newInstance() -74 .addFilenames(PACKAGE_JSON).build(); -75 -76 /** -77 * Returns the FileFilter -78 * -79 * @return the FileFilter -80 */ -81 @Override -82 protected FileFilter getFileFilter() { -83 return PACKAGE_JSON_FILTER; -84 } -85 -86 @Override -87 protected void initializeFileTypeAnalyzer() throws Exception { -88 // NO-OP -89 } -90 -91 /** -92 * Returns the name of the analyzer. -93 * -94 * @return the name of the analyzer. -95 */ -96 @Override -97 public String getName() { -98 return ANALYZER_NAME; -99 } -100 -101 /** -102 * Returns the phase that the analyzer is intended to run in. -103 * -104 * @return the phase that the analyzer is intended to run in. -105 */ -106 @Override -107 public AnalysisPhase getAnalysisPhase() { -108 return ANALYSIS_PHASE; -109 } -110 -111 /** -112 * Returns the key used in the properties file to reference the analyzer's enabled property. -113 * -114 * @return the analyzer's enabled property setting key -115 */ -116 @Override -117 protected String getAnalyzerEnabledSettingKey() { -118 return Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED; -119 } -120 -121 @Override -122 protected void analyzeFileType(Dependency dependency, Engine engine) -123 throws AnalysisException { -124 final File file = dependency.getActualFile(); -125 JsonReader jsonReader; -126 try { -127 jsonReader = Json.createReader(FileUtils.openInputStream(file)); -128 } catch (IOException e) { -129 throw new AnalysisException( -130 "Problem occurred while reading dependency file.", e); -131 } -132 try { -133 final JsonObject json = jsonReader.readObject(); -134 final EvidenceCollection productEvidence = dependency.getProductEvidence(); -135 final EvidenceCollection vendorEvidence = dependency.getVendorEvidence(); -136 if (json.containsKey("name")) { -137 final Object value = json.get("name"); -138 if (value instanceof JsonString) { -139 final String valueString = ((JsonString) value).getString(); -140 productEvidence.addEvidence(PACKAGE_JSON, "name", valueString, Confidence.HIGHEST); -141 vendorEvidence.addEvidence(PACKAGE_JSON, "name_project", String.format("%s_project", valueString), Confidence.LOW); -142 } else { -143 LOGGER.warn("JSON value not string as expected: {}", value); -144 } -145 } -146 addToEvidence(json, productEvidence, "description"); -147 addToEvidence(json, vendorEvidence, "author"); -148 addToEvidence(json, dependency.getVersionEvidence(), "version"); -149 dependency.setDisplayFileName(String.format("%s/%s", file.getParentFile().getName(), file.getName())); -150 } catch (JsonException e) { -151 LOGGER.warn("Failed to parse package.json file.", e); -152 } finally { -153 jsonReader.close(); -154 } -155 } -156 -157 /** -158 * Adds information to an evidence collection from the node json configuration. -159 * -160 * @param json information from node.js -161 * @param collection a set of evidence about a dependency -162 * @param key the key to obtain the data from the json information -163 */ -164 private void addToEvidence(JsonObject json, EvidenceCollection collection, String key) { -165 if (json.containsKey(key)) { -166 final JsonValue value = json.get(key); -167 if (value instanceof JsonString) { -168 collection.addEvidence(PACKAGE_JSON, key, ((JsonString) value).getString(), Confidence.HIGHEST); -169 } else if (value instanceof JsonObject) { -170 final JsonObject jsonObject = (JsonObject) value; -171 for (final Map.Entry<String, JsonValue> entry : jsonObject.entrySet()) { -172 final String property = entry.getKey(); -173 final JsonValue subValue = entry.getValue(); -174 if (subValue instanceof JsonString) { -175 collection.addEvidence(PACKAGE_JSON, -176 String.format("%s.%s", key, property), -177 ((JsonString) subValue).getString(), -178 Confidence.HIGHEST); -179 } else { -180 LOGGER.warn("JSON sub-value not string as expected: {}", subValue); -181 } -182 } -183 } else { -184 LOGGER.warn("JSON value not string or JSON object as expected: {}", value); -185 } -186 } -187 } -188 } +41 import org.owasp.dependencycheck.exception.InitializationException; +42 +43 /** +44 * Used to analyze Node Package Manager (npm) package.json files, and collect +45 * information that can be used to determine the associated CPE. +46 * +47 * @author Dale Visser +48 */ +49 @Experimental +50 public class NodePackageAnalyzer extends AbstractFileTypeAnalyzer { +51 +52 /** +53 * The logger. +54 */ +55 private static final Logger LOGGER = LoggerFactory.getLogger(NodePackageAnalyzer.class); +56 +57 /** +58 * The name of the analyzer. +59 */ +60 private static final String ANALYZER_NAME = "Node.js Package Analyzer"; +61 +62 /** +63 * The phase that this analyzer is intended to run in. +64 */ +65 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; +66 +67 /** +68 * The file name to scan. +69 */ +70 public static final String PACKAGE_JSON = "package.json"; +71 /** +72 * Filter that detects files named "package.json". +73 */ +74 private static final FileFilter PACKAGE_JSON_FILTER = FileFilterBuilder.newInstance() +75 .addFilenames(PACKAGE_JSON).build(); +76 +77 /** +78 * Returns the FileFilter +79 * +80 * @return the FileFilter +81 */ +82 @Override +83 protected FileFilter getFileFilter() { +84 return PACKAGE_JSON_FILTER; +85 } +86 +87 @Override +88 protected void initializeFileTypeAnalyzer() throws InitializationException { +89 // NO-OP +90 } +91 +92 /** +93 * Returns the name of the analyzer. +94 * +95 * @return the name of the analyzer. +96 */ +97 @Override +98 public String getName() { +99 return ANALYZER_NAME; +100 } +101 +102 /** +103 * Returns the phase that the analyzer is intended to run in. +104 * +105 * @return the phase that the analyzer is intended to run in. +106 */ +107 @Override +108 public AnalysisPhase getAnalysisPhase() { +109 return ANALYSIS_PHASE; +110 } +111 +112 /** +113 * Returns the key used in the properties file to reference the analyzer's +114 * enabled property. +115 * +116 * @return the analyzer's enabled property setting key +117 */ +118 @Override +119 protected String getAnalyzerEnabledSettingKey() { +120 return Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED; +121 } +122 +123 @Override +124 protected void analyzeFileType(Dependency dependency, Engine engine) +125 throws AnalysisException { +126 final File file = dependency.getActualFile(); +127 JsonReader jsonReader; +128 try { +129 jsonReader = Json.createReader(FileUtils.openInputStream(file)); +130 } catch (IOException e) { +131 throw new AnalysisException( +132 "Problem occurred while reading dependency file.", e); +133 } +134 try { +135 final JsonObject json = jsonReader.readObject(); +136 final EvidenceCollection productEvidence = dependency.getProductEvidence(); +137 final EvidenceCollection vendorEvidence = dependency.getVendorEvidence(); +138 if (json.containsKey("name")) { +139 final Object value = json.get("name"); +140 if (value instanceof JsonString) { +141 final String valueString = ((JsonString) value).getString(); +142 productEvidence.addEvidence(PACKAGE_JSON, "name", valueString, Confidence.HIGHEST); +143 vendorEvidence.addEvidence(PACKAGE_JSON, "name_project", String.format("%s_project", valueString), Confidence.LOW); +144 } else { +145 LOGGER.warn("JSON value not string as expected: {}", value); +146 } +147 } +148 addToEvidence(json, productEvidence, "description"); +149 addToEvidence(json, vendorEvidence, "author"); +150 addToEvidence(json, dependency.getVersionEvidence(), "version"); +151 dependency.setDisplayFileName(String.format("%s/%s", file.getParentFile().getName(), file.getName())); +152 } catch (JsonException e) { +153 LOGGER.warn("Failed to parse package.json file.", e); +154 } finally { +155 jsonReader.close(); +156 } +157 } +158 +159 /** +160 * Adds information to an evidence collection from the node json +161 * configuration. +162 * +163 * @param json information from node.js +164 * @param collection a set of evidence about a dependency +165 * @param key the key to obtain the data from the json information +166 */ +167 private void addToEvidence(JsonObject json, EvidenceCollection collection, String key) { +168 if (json.containsKey(key)) { +169 final JsonValue value = json.get(key); +170 if (value instanceof JsonString) { +171 collection.addEvidence(PACKAGE_JSON, key, ((JsonString) value).getString(), Confidence.HIGHEST); +172 } else if (value instanceof JsonObject) { +173 final JsonObject jsonObject = (JsonObject) value; +174 for (final Map.Entry<String, JsonValue> entry : jsonObject.entrySet()) { +175 final String property = entry.getKey(); +176 final JsonValue subValue = entry.getValue(); +177 if (subValue instanceof JsonString) { +178 collection.addEvidence(PACKAGE_JSON, +179 String.format("%s.%s", key, property), +180 ((JsonString) subValue).getString(), +181 Confidence.HIGHEST); +182 } else { +183 LOGGER.warn("JSON sub-value not string as expected: {}", subValue); +184 } +185 } +186 } else { +187 LOGGER.warn("JSON value not string or JSON object as expected: {}", value); +188 } +189 } +190 } +191 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/NuspecAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/NuspecAnalyzer.html index 115aa3ccc..d211926f5 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/NuspecAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/NuspecAnalyzer.html @@ -42,134 +42,136 @@ 34 import java.io.FileInputStream; 35 import java.io.FileNotFoundException; 36 import java.io.IOException; -37 -38 /** -39 * Analyzer which will parse a Nuspec file to gather module information. -40 * -41 * @author colezlaw -42 */ -43 public class NuspecAnalyzer extends AbstractFileTypeAnalyzer { -44 -45 /** -46 * The logger. -47 */ -48 private static final Logger LOGGER = LoggerFactory.getLogger(NuspecAnalyzer.class); -49 -50 /** -51 * The name of the analyzer. -52 */ -53 private static final String ANALYZER_NAME = "Nuspec Analyzer"; -54 -55 /** -56 * The phase in which the analyzer runs. -57 */ -58 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; -59 -60 /** -61 * The types of files on which this will work. -62 */ -63 private static final String SUPPORTED_EXTENSIONS = "nuspec"; -64 -65 /** -66 * Initializes the analyzer once before any analysis is performed. -67 * -68 * @throws Exception if there's an error during initialization -69 */ -70 @Override -71 public void initializeFileTypeAnalyzer() throws Exception { -72 } -73 -74 /** -75 * Returns the analyzer's name. -76 * -77 * @return the name of the analyzer -78 */ -79 @Override -80 public String getName() { -81 return ANALYZER_NAME; -82 } -83 -84 /** -85 * Returns the key used in the properties file to reference the analyzer's enabled property. -86 * -87 * @return the analyzer's enabled property setting key -88 */ -89 @Override -90 protected String getAnalyzerEnabledSettingKey() { -91 return Settings.KEYS.ANALYZER_NUSPEC_ENABLED; -92 } -93 -94 /** -95 * Returns the analysis phase under which the analyzer runs. -96 * -97 * @return the phase under which this analyzer runs -98 */ -99 @Override -100 public AnalysisPhase getAnalysisPhase() { -101 return ANALYSIS_PHASE; -102 } -103 -104 /** -105 * The file filter used to determine which files this analyzer supports. -106 */ -107 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions( -108 SUPPORTED_EXTENSIONS).build(); -109 -110 /** -111 * Returns the FileFilter -112 * -113 * @return the FileFilter -114 */ -115 @Override -116 protected FileFilter getFileFilter() { -117 return FILTER; -118 } -119 -120 /** -121 * Performs the analysis. -122 * -123 * @param dependency the dependency to analyze -124 * @param engine the engine -125 * @throws AnalysisException when there's an exception during analysis -126 */ -127 @Override -128 public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { -129 LOGGER.debug("Checking Nuspec file {}", dependency); -130 try { -131 final NuspecParser parser = new XPathNuspecParser(); -132 NugetPackage np = null; -133 FileInputStream fis = null; -134 try { -135 fis = new FileInputStream(dependency.getActualFilePath()); -136 np = parser.parse(fis); -137 } catch (NuspecParseException ex) { -138 throw new AnalysisException(ex); -139 } catch (FileNotFoundException ex) { +37 import org.owasp.dependencycheck.exception.InitializationException; +38 +39 /** +40 * Analyzer which will parse a Nuspec file to gather module information. +41 * +42 * @author colezlaw +43 */ +44 public class NuspecAnalyzer extends AbstractFileTypeAnalyzer { +45 +46 /** +47 * The logger. +48 */ +49 private static final Logger LOGGER = LoggerFactory.getLogger(NuspecAnalyzer.class); +50 +51 /** +52 * The name of the analyzer. +53 */ +54 private static final String ANALYZER_NAME = "Nuspec Analyzer"; +55 +56 /** +57 * The phase in which the analyzer runs. +58 */ +59 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; +60 +61 /** +62 * The types of files on which this will work. +63 */ +64 private static final String SUPPORTED_EXTENSIONS = "nuspec"; +65 +66 /** +67 * Initializes the analyzer once before any analysis is performed. +68 * +69 * @throws InitializationException if there's an error during initialization +70 */ +71 @Override +72 public void initializeFileTypeAnalyzer() throws InitializationException { +73 } +74 +75 /** +76 * Returns the analyzer's name. +77 * +78 * @return the name of the analyzer +79 */ +80 @Override +81 public String getName() { +82 return ANALYZER_NAME; +83 } +84 +85 /** +86 * Returns the key used in the properties file to reference the analyzer's +87 * enabled property. +88 * +89 * @return the analyzer's enabled property setting key +90 */ +91 @Override +92 protected String getAnalyzerEnabledSettingKey() { +93 return Settings.KEYS.ANALYZER_NUSPEC_ENABLED; +94 } +95 +96 /** +97 * Returns the analysis phase under which the analyzer runs. +98 * +99 * @return the phase under which this analyzer runs +100 */ +101 @Override +102 public AnalysisPhase getAnalysisPhase() { +103 return ANALYSIS_PHASE; +104 } +105 +106 /** +107 * The file filter used to determine which files this analyzer supports. +108 */ +109 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions( +110 SUPPORTED_EXTENSIONS).build(); +111 +112 /** +113 * Returns the FileFilter +114 * +115 * @return the FileFilter +116 */ +117 @Override +118 protected FileFilter getFileFilter() { +119 return FILTER; +120 } +121 +122 /** +123 * Performs the analysis. +124 * +125 * @param dependency the dependency to analyze +126 * @param engine the engine +127 * @throws AnalysisException when there's an exception during analysis +128 */ +129 @Override +130 public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { +131 LOGGER.debug("Checking Nuspec file {}", dependency); +132 try { +133 final NuspecParser parser = new XPathNuspecParser(); +134 NugetPackage np = null; +135 FileInputStream fis = null; +136 try { +137 fis = new FileInputStream(dependency.getActualFilePath()); +138 np = parser.parse(fis); +139 } catch (NuspecParseException ex) { 140 throw new AnalysisException(ex); -141 } finally { -142 if (fis != null) { -143 try { -144 fis.close(); -145 } catch (IOException e) { -146 LOGGER.debug("Error closing input stream"); -147 } -148 } -149 } -150 -151 if (np.getOwners() != null) { -152 dependency.getVendorEvidence().addEvidence("nuspec", "owners", np.getOwners(), Confidence.HIGHEST); -153 } -154 dependency.getVendorEvidence().addEvidence("nuspec", "authors", np.getAuthors(), Confidence.HIGH); -155 dependency.getVersionEvidence().addEvidence("nuspec", "version", np.getVersion(), Confidence.HIGHEST); -156 dependency.getProductEvidence().addEvidence("nuspec", "id", np.getId(), Confidence.HIGHEST); -157 if (np.getTitle() != null) { -158 dependency.getProductEvidence().addEvidence("nuspec", "title", np.getTitle(), Confidence.MEDIUM); -159 } -160 } catch (Throwable e) { -161 throw new AnalysisException(e); -162 } -163 } -164 } +141 } catch (FileNotFoundException ex) { +142 throw new AnalysisException(ex); +143 } finally { +144 if (fis != null) { +145 try { +146 fis.close(); +147 } catch (IOException e) { +148 LOGGER.debug("Error closing input stream"); +149 } +150 } +151 } +152 +153 if (np.getOwners() != null) { +154 dependency.getVendorEvidence().addEvidence("nuspec", "owners", np.getOwners(), Confidence.HIGHEST); +155 } +156 dependency.getVendorEvidence().addEvidence("nuspec", "authors", np.getAuthors(), Confidence.HIGH); +157 dependency.getVersionEvidence().addEvidence("nuspec", "version", np.getVersion(), Confidence.HIGHEST); +158 dependency.getProductEvidence().addEvidence("nuspec", "id", np.getId(), Confidence.HIGHEST); +159 if (np.getTitle() != null) { +160 dependency.getProductEvidence().addEvidence("nuspec", "title", np.getTitle(), Confidence.MEDIUM); +161 } +162 } catch (Throwable e) { +163 throw new AnalysisException(e); +164 } +165 } +166 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/NvdCveAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/NvdCveAnalyzer.html index 2a2c2c490..75128b17b 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/NvdCveAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/NvdCveAnalyzer.html @@ -35,131 +35,150 @@ 27 import org.owasp.dependencycheck.dependency.Dependency; 28 import org.owasp.dependencycheck.dependency.Identifier; 29 import org.owasp.dependencycheck.dependency.Vulnerability; -30 -31 /** -32 * NvdCveAnalyzer is a utility class that takes a project dependency and attempts to discern if there is an associated -33 * CVEs. It uses the the identifiers found by other analyzers to lookup the CVE data. -34 * -35 * @author Jeremy Long -36 */ -37 public class NvdCveAnalyzer implements Analyzer { -38 -39 /** -40 * The maximum number of query results to return. -41 */ -42 static final int MAX_QUERY_RESULTS = 100; -43 /** -44 * The CVE Index. -45 */ -46 private CveDB cveDB; -47 +30 import org.owasp.dependencycheck.exception.InitializationException; +31 import org.slf4j.LoggerFactory; +32 +33 /** +34 * NvdCveAnalyzer is a utility class that takes a project dependency and attempts to discern if there is an associated +35 * CVEs. It uses the the identifiers found by other analyzers to lookup the CVE data. +36 * +37 * @author Jeremy Long +38 */ +39 public class NvdCveAnalyzer implements Analyzer { +40 /** +41 * The Logger for use throughout the class +42 */ +43 private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(NvdCveAnalyzer.class); +44 /** +45 * The maximum number of query results to return. +46 */ +47 static final int MAX_QUERY_RESULTS = 100; 48 /** -49 * Opens the data source. -50 * -51 * @throws SQLException thrown when there is a SQL Exception -52 * @throws IOException thrown when there is an IO Exception -53 * @throws DatabaseException thrown when there is a database exceptions -54 * @throws ClassNotFoundException thrown if the h2 database driver cannot be loaded -55 */ -56 public void open() throws SQLException, IOException, DatabaseException, ClassNotFoundException { -57 cveDB = new CveDB(); -58 cveDB.open(); -59 } -60 -61 /** -62 * Closes the data source. -63 */ -64 @Override -65 public void close() { -66 cveDB.close(); -67 cveDB = null; -68 } -69 -70 /** -71 * Returns the status of the data source - is the database open. -72 * -73 * @return true or false. -74 */ -75 public boolean isOpen() { -76 return cveDB != null; -77 } -78 -79 /** -80 * Ensures that the CVE Database is closed. -81 * -82 * @throws Throwable when a throwable is thrown. -83 */ -84 @Override -85 protected void finalize() throws Throwable { -86 super.finalize(); -87 if (isOpen()) { -88 close(); -89 } -90 } -91 -92 /** -93 * Analyzes a dependency and attempts to determine if there are any CPE identifiers for this dependency. -94 * -95 * @param dependency The Dependency to analyze -96 * @param engine The analysis engine -97 * @throws AnalysisException is thrown if there is an issue analyzing the dependency -98 */ -99 @Override -100 public void analyze(Dependency dependency, Engine engine) throws AnalysisException { -101 for (Identifier id : dependency.getIdentifiers()) { -102 if ("cpe".equals(id.getType())) { -103 try { -104 final String value = id.getValue(); -105 final List<Vulnerability> vulns = cveDB.getVulnerabilities(value); -106 dependency.getVulnerabilities().addAll(vulns); -107 } catch (DatabaseException ex) { -108 throw new AnalysisException(ex); -109 } -110 } -111 } -112 for (Identifier id : dependency.getSuppressedIdentifiers()) { -113 if ("cpe".equals(id.getType())) { -114 try { -115 final String value = id.getValue(); -116 final List<Vulnerability> vulns = cveDB.getVulnerabilities(value); -117 dependency.getSuppressedVulnerabilities().addAll(vulns); -118 } catch (DatabaseException ex) { -119 throw new AnalysisException(ex); -120 } -121 } -122 } -123 } -124 -125 /** -126 * Returns the name of this analyzer. -127 * -128 * @return the name of this analyzer. -129 */ -130 @Override -131 public String getName() { -132 return "NVD CVE Analyzer"; -133 } -134 -135 /** -136 * Returns the analysis phase that this analyzer should run in. -137 * -138 * @return the analysis phase that this analyzer should run in. -139 */ -140 @Override -141 public AnalysisPhase getAnalysisPhase() { -142 return AnalysisPhase.FINDING_ANALYSIS; -143 } -144 -145 /** -146 * Opens the database used to gather NVD CVE data. -147 * -148 * @throws Exception is thrown if there is an issue opening the index. -149 */ -150 @Override -151 public void initialize() throws Exception { -152 this.open(); -153 } -154 } +49 * The CVE Index. +50 */ +51 private CveDB cveDB; +52 +53 /** +54 * Opens the data source. +55 * +56 * @throws SQLException thrown when there is a SQL Exception +57 * @throws IOException thrown when there is an IO Exception +58 * @throws DatabaseException thrown when there is a database exceptions +59 * @throws ClassNotFoundException thrown if the h2 database driver cannot be loaded +60 */ +61 public void open() throws SQLException, IOException, DatabaseException, ClassNotFoundException { +62 cveDB = new CveDB(); +63 cveDB.open(); +64 } +65 +66 /** +67 * Closes the data source. +68 */ +69 @Override +70 public void close() { +71 cveDB.close(); +72 cveDB = null; +73 } +74 +75 /** +76 * Returns the status of the data source - is the database open. +77 * +78 * @return true or false. +79 */ +80 public boolean isOpen() { +81 return cveDB != null; +82 } +83 +84 /** +85 * Ensures that the CVE Database is closed. +86 * +87 * @throws Throwable an exception raised by this method +88 */ +89 @Override +90 protected void finalize() throws Throwable { +91 super.finalize(); +92 if (isOpen()) { +93 close(); +94 } +95 } +96 +97 /** +98 * Analyzes a dependency and attempts to determine if there are any CPE identifiers for this dependency. +99 * +100 * @param dependency The Dependency to analyze +101 * @param engine The analysis engine +102 * @throws AnalysisException thrown if there is an issue analyzing the dependency +103 */ +104 @Override +105 public void analyze(Dependency dependency, Engine engine) throws AnalysisException { +106 for (Identifier id : dependency.getIdentifiers()) { +107 if ("cpe".equals(id.getType())) { +108 try { +109 final String value = id.getValue(); +110 final List<Vulnerability> vulns = cveDB.getVulnerabilities(value); +111 dependency.getVulnerabilities().addAll(vulns); +112 } catch (DatabaseException ex) { +113 throw new AnalysisException(ex); +114 } +115 } +116 } +117 for (Identifier id : dependency.getSuppressedIdentifiers()) { +118 if ("cpe".equals(id.getType())) { +119 try { +120 final String value = id.getValue(); +121 final List<Vulnerability> vulns = cveDB.getVulnerabilities(value); +122 dependency.getSuppressedVulnerabilities().addAll(vulns); +123 } catch (DatabaseException ex) { +124 throw new AnalysisException(ex); +125 } +126 } +127 } +128 } +129 +130 /** +131 * Returns the name of this analyzer. +132 * +133 * @return the name of this analyzer. +134 */ +135 @Override +136 public String getName() { +137 return "NVD CVE Analyzer"; +138 } +139 +140 /** +141 * Returns the analysis phase that this analyzer should run in. +142 * +143 * @return the analysis phase that this analyzer should run in. +144 */ +145 @Override +146 public AnalysisPhase getAnalysisPhase() { +147 return AnalysisPhase.FINDING_ANALYSIS; +148 } +149 +150 /** +151 * Opens the database used to gather NVD CVE data. +152 * +153 * @throws InitializationException is thrown if there is an issue opening the index. +154 */ +155 @Override +156 public void initialize() throws InitializationException { +157 try { +158 this.open(); +159 } catch (SQLException ex) { +160 LOGGER.debug("SQL Exception initializing NvdCveAnalyzer", ex); +161 throw new InitializationException(ex); +162 } catch (IOException ex) { +163 LOGGER.debug("IO Exception initializing NvdCveAnalyzer", ex); +164 throw new InitializationException(ex); +165 } catch (DatabaseException ex) { +166 LOGGER.debug("Database Exception initializing NvdCveAnalyzer", ex); +167 throw new InitializationException(ex); +168 } catch (ClassNotFoundException ex) { +169 LOGGER.debug("Exception initializing NvdCveAnalyzer", ex); +170 throw new InitializationException(ex); +171 } +172 } +173 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/OpenSSLAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/OpenSSLAnalyzer.html index e59ace550..eab8d7e8f 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/OpenSSLAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/OpenSSLAnalyzer.html @@ -39,186 +39,187 @@ 31 import java.nio.charset.Charset; 32 import java.util.regex.Matcher; 33 import java.util.regex.Pattern; -34 -35 /** -36 * Used to analyze OpenSSL source code present in the file system. -37 * -38 * @author Dale Visser -39 */ -40 public class OpenSSLAnalyzer extends AbstractFileTypeAnalyzer { -41 -42 /** -43 * Hexadecimal. -44 */ -45 private static final int HEXADECIMAL = 16; -46 /** -47 * Filename to analyze. All other .h files get removed from consideration. -48 */ -49 private static final String OPENSSLV_H = "opensslv.h"; -50 -51 /** -52 * Filter that detects files named "__init__.py". -53 */ -54 private static final FileFilter OPENSSLV_FILTER = FileFilterBuilder.newInstance().addFilenames(OPENSSLV_H).build(); -55 /** -56 * Open SSL Version number pattern. -57 */ -58 private static final Pattern VERSION_PATTERN = Pattern.compile( -59 "define\\s+OPENSSL_VERSION_NUMBER\\s+0x([0-9a-zA-Z]{8})L", Pattern.DOTALL -60 | Pattern.CASE_INSENSITIVE); -61 /** -62 * The offset of the major version number. -63 */ -64 private static final int MAJOR_OFFSET = 28; -65 /** -66 * The mask for the minor version number. -67 */ -68 private static final long MINOR_MASK = 0x0ff00000L; -69 /** -70 * The offset of the minor version number. -71 */ -72 private static final int MINOR_OFFSET = 20; -73 /** -74 * The max for the fix version. -75 */ -76 private static final long FIX_MASK = 0x000ff000L; -77 /** -78 * The offset for the fix version. -79 */ -80 private static final int FIX_OFFSET = 12; -81 /** -82 * The mask for the patch version. -83 */ -84 private static final long PATCH_MASK = 0x00000ff0L; -85 /** -86 * The offset for the patch version. -87 */ -88 private static final int PATCH_OFFSET = 4; -89 /** -90 * Number of letters. -91 */ -92 private static final int NUM_LETTERS = 26; -93 /** -94 * The status mask. -95 */ -96 private static final int STATUS_MASK = 0x0000000f; -97 -98 /** -99 * Returns the open SSL version as a string. -100 * -101 * @param openSSLVersionConstant The open SSL version -102 * @return the version of openssl -103 */ -104 static String getOpenSSLVersion(long openSSLVersionConstant) { -105 final long major = openSSLVersionConstant >>> MAJOR_OFFSET; -106 final long minor = (openSSLVersionConstant & MINOR_MASK) >>> MINOR_OFFSET; -107 final long fix = (openSSLVersionConstant & FIX_MASK) >>> FIX_OFFSET; -108 final long patchLevel = (openSSLVersionConstant & PATCH_MASK) >>> PATCH_OFFSET; -109 final String patch = 0 == patchLevel || patchLevel > NUM_LETTERS ? "" : String.valueOf((char) (patchLevel + 'a' - 1)); -110 final int statusCode = (int) (openSSLVersionConstant & STATUS_MASK); -111 final String status = 0xf == statusCode ? "" : (0 == statusCode ? "-dev" : "-beta" + statusCode); -112 return String.format("%d.%d.%d%s%s", major, minor, fix, patch, status); -113 } -114 -115 /** -116 * Returns the name of the Python Package Analyzer. -117 * -118 * @return the name of the analyzer -119 */ -120 @Override -121 public String getName() { -122 return "OpenSSL Source Analyzer"; -123 } -124 -125 /** -126 * Tell that we are used for information collection. -127 * -128 * @return INFORMATION_COLLECTION -129 */ -130 @Override -131 public AnalysisPhase getAnalysisPhase() { -132 return AnalysisPhase.INFORMATION_COLLECTION; -133 } -134 -135 /** -136 * Returns the set of supported file extensions. -137 * -138 * @return the set of supported file extensions -139 */ -140 @Override -141 protected FileFilter getFileFilter() { -142 return OPENSSLV_FILTER; -143 } -144 -145 /** -146 * No-op initializer implementation. -147 * -148 * @throws Exception never thrown -149 */ -150 @Override -151 protected void initializeFileTypeAnalyzer() throws Exception { -152 // Nothing to do here. -153 } -154 -155 /** -156 * Analyzes python packages and adds evidence to the dependency. -157 * -158 * @param dependency the dependency being analyzed -159 * @param engine the engine being used to perform the scan -160 * @throws AnalysisException thrown if there is an unrecoverable error -161 * analyzing the dependency -162 */ -163 @Override -164 protected void analyzeFileType(Dependency dependency, Engine engine) -165 throws AnalysisException { -166 final File file = dependency.getActualFile(); -167 final String parentName = file.getParentFile().getName(); -168 boolean found = false; -169 final String contents = getFileContents(file); -170 if (!contents.isEmpty()) { -171 final Matcher matcher = VERSION_PATTERN.matcher(contents); -172 if (matcher.find()) { -173 dependency.getVersionEvidence().addEvidence(OPENSSLV_H, "Version Constant", -174 getOpenSSLVersion(Long.parseLong(matcher.group(1), HEXADECIMAL)), Confidence.HIGH); -175 found = true; -176 } -177 } -178 if (found) { -179 dependency.setDisplayFileName(parentName + File.separatorChar + OPENSSLV_H); -180 dependency.getVendorEvidence().addEvidence(OPENSSLV_H, "Vendor", "OpenSSL", Confidence.HIGHEST); -181 dependency.getProductEvidence().addEvidence(OPENSSLV_H, "Product", "OpenSSL", Confidence.HIGHEST); -182 } else { -183 engine.getDependencies().remove(dependency); -184 } -185 } -186 -187 /** -188 * Retrieves the contents of a given file. -189 * -190 * @param actualFile the file to read -191 * @return the contents of the file -192 * @throws AnalysisException thrown if there is an IO Exception -193 */ -194 private String getFileContents(final File actualFile) -195 throws AnalysisException { -196 try { -197 return FileUtils.readFileToString(actualFile, Charset.defaultCharset()).trim(); -198 } catch (IOException e) { -199 throw new AnalysisException( -200 "Problem occurred while reading dependency file.", e); -201 } -202 } -203 -204 /** -205 * Returns the setting for the analyzer enabled setting key. -206 * -207 * @return the setting for the analyzer enabled setting key -208 */ -209 @Override -210 protected String getAnalyzerEnabledSettingKey() { -211 return Settings.KEYS.ANALYZER_OPENSSL_ENABLED; -212 } -213 } +34 import org.owasp.dependencycheck.exception.InitializationException; +35 +36 /** +37 * Used to analyze OpenSSL source code present in the file system. +38 * +39 * @author Dale Visser +40 */ +41 public class OpenSSLAnalyzer extends AbstractFileTypeAnalyzer { +42 +43 /** +44 * Hexadecimal. +45 */ +46 private static final int HEXADECIMAL = 16; +47 /** +48 * Filename to analyze. All other .h files get removed from consideration. +49 */ +50 private static final String OPENSSLV_H = "opensslv.h"; +51 +52 /** +53 * Filter that detects files named "__init__.py". +54 */ +55 private static final FileFilter OPENSSLV_FILTER = FileFilterBuilder.newInstance().addFilenames(OPENSSLV_H).build(); +56 /** +57 * Open SSL Version number pattern. +58 */ +59 private static final Pattern VERSION_PATTERN = Pattern.compile( +60 "define\\s+OPENSSL_VERSION_NUMBER\\s+0x([0-9a-zA-Z]{8})L", Pattern.DOTALL +61 | Pattern.CASE_INSENSITIVE); +62 /** +63 * The offset of the major version number. +64 */ +65 private static final int MAJOR_OFFSET = 28; +66 /** +67 * The mask for the minor version number. +68 */ +69 private static final long MINOR_MASK = 0x0ff00000L; +70 /** +71 * The offset of the minor version number. +72 */ +73 private static final int MINOR_OFFSET = 20; +74 /** +75 * The max for the fix version. +76 */ +77 private static final long FIX_MASK = 0x000ff000L; +78 /** +79 * The offset for the fix version. +80 */ +81 private static final int FIX_OFFSET = 12; +82 /** +83 * The mask for the patch version. +84 */ +85 private static final long PATCH_MASK = 0x00000ff0L; +86 /** +87 * The offset for the patch version. +88 */ +89 private static final int PATCH_OFFSET = 4; +90 /** +91 * Number of letters. +92 */ +93 private static final int NUM_LETTERS = 26; +94 /** +95 * The status mask. +96 */ +97 private static final int STATUS_MASK = 0x0000000f; +98 +99 /** +100 * Returns the open SSL version as a string. +101 * +102 * @param openSSLVersionConstant The open SSL version +103 * @return the version of openssl +104 */ +105 static String getOpenSSLVersion(long openSSLVersionConstant) { +106 final long major = openSSLVersionConstant >>> MAJOR_OFFSET; +107 final long minor = (openSSLVersionConstant & MINOR_MASK) >>> MINOR_OFFSET; +108 final long fix = (openSSLVersionConstant & FIX_MASK) >>> FIX_OFFSET; +109 final long patchLevel = (openSSLVersionConstant & PATCH_MASK) >>> PATCH_OFFSET; +110 final String patch = 0 == patchLevel || patchLevel > NUM_LETTERS ? "" : String.valueOf((char) (patchLevel + 'a' - 1)); +111 final int statusCode = (int) (openSSLVersionConstant & STATUS_MASK); +112 final String status = 0xf == statusCode ? "" : (0 == statusCode ? "-dev" : "-beta" + statusCode); +113 return String.format("%d.%d.%d%s%s", major, minor, fix, patch, status); +114 } +115 +116 /** +117 * Returns the name of the Python Package Analyzer. +118 * +119 * @return the name of the analyzer +120 */ +121 @Override +122 public String getName() { +123 return "OpenSSL Source Analyzer"; +124 } +125 +126 /** +127 * Tell that we are used for information collection. +128 * +129 * @return INFORMATION_COLLECTION +130 */ +131 @Override +132 public AnalysisPhase getAnalysisPhase() { +133 return AnalysisPhase.INFORMATION_COLLECTION; +134 } +135 +136 /** +137 * Returns the set of supported file extensions. +138 * +139 * @return the set of supported file extensions +140 */ +141 @Override +142 protected FileFilter getFileFilter() { +143 return OPENSSLV_FILTER; +144 } +145 +146 /** +147 * No-op initializer implementation. +148 * +149 * @throws InitializationException never thrown +150 */ +151 @Override +152 protected void initializeFileTypeAnalyzer() throws InitializationException { +153 // Nothing to do here. +154 } +155 +156 /** +157 * Analyzes python packages and adds evidence to the dependency. +158 * +159 * @param dependency the dependency being analyzed +160 * @param engine the engine being used to perform the scan +161 * @throws AnalysisException thrown if there is an unrecoverable error +162 * analyzing the dependency +163 */ +164 @Override +165 protected void analyzeFileType(Dependency dependency, Engine engine) +166 throws AnalysisException { +167 final File file = dependency.getActualFile(); +168 final String parentName = file.getParentFile().getName(); +169 boolean found = false; +170 final String contents = getFileContents(file); +171 if (!contents.isEmpty()) { +172 final Matcher matcher = VERSION_PATTERN.matcher(contents); +173 if (matcher.find()) { +174 dependency.getVersionEvidence().addEvidence(OPENSSLV_H, "Version Constant", +175 getOpenSSLVersion(Long.parseLong(matcher.group(1), HEXADECIMAL)), Confidence.HIGH); +176 found = true; +177 } +178 } +179 if (found) { +180 dependency.setDisplayFileName(parentName + File.separatorChar + OPENSSLV_H); +181 dependency.getVendorEvidence().addEvidence(OPENSSLV_H, "Vendor", "OpenSSL", Confidence.HIGHEST); +182 dependency.getProductEvidence().addEvidence(OPENSSLV_H, "Product", "OpenSSL", Confidence.HIGHEST); +183 } else { +184 engine.getDependencies().remove(dependency); +185 } +186 } +187 +188 /** +189 * Retrieves the contents of a given file. +190 * +191 * @param actualFile the file to read +192 * @return the contents of the file +193 * @throws AnalysisException thrown if there is an IO Exception +194 */ +195 private String getFileContents(final File actualFile) +196 throws AnalysisException { +197 try { +198 return FileUtils.readFileToString(actualFile, Charset.defaultCharset()).trim(); +199 } catch (IOException e) { +200 throw new AnalysisException( +201 "Problem occurred while reading dependency file.", e); +202 } +203 } +204 +205 /** +206 * Returns the setting for the analyzer enabled setting key. +207 * +208 * @return the setting for the analyzer enabled setting key +209 */ +210 @Override +211 protected String getAnalyzerEnabledSettingKey() { +212 return Settings.KEYS.ANALYZER_OPENSSL_ENABLED; +213 } +214 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/PythonDistributionAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/PythonDistributionAnalyzer.html index 0259a9aa0..e9aefa0d9 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/PythonDistributionAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/PythonDistributionAnalyzer.html @@ -31,356 +31,373 @@ 23 import java.io.FileInputStream; 24 import java.io.FileNotFoundException; 25 import java.io.FilenameFilter; -26 import org.apache.commons.io.filefilter.NameFileFilter; -27 import org.apache.commons.io.filefilter.SuffixFileFilter; -28 import org.apache.commons.io.input.AutoCloseInputStream; -29 import org.apache.commons.lang3.StringUtils; -30 import org.owasp.dependencycheck.Engine; -31 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; -32 import org.owasp.dependencycheck.dependency.Confidence; -33 import org.owasp.dependencycheck.dependency.Dependency; -34 import org.owasp.dependencycheck.dependency.EvidenceCollection; -35 import org.slf4j.Logger; -36 import org.slf4j.LoggerFactory; -37 -38 import javax.mail.MessagingException; -39 import javax.mail.internet.InternetHeaders; -40 import org.owasp.dependencycheck.utils.ExtractionException; -41 import org.owasp.dependencycheck.utils.ExtractionUtil; -42 import org.owasp.dependencycheck.utils.FileFilterBuilder; -43 import org.owasp.dependencycheck.utils.FileUtils; -44 import org.owasp.dependencycheck.utils.Settings; -45 import org.owasp.dependencycheck.utils.UrlStringUtils; -46 -47 /** -48 * Used to analyze a Wheel or egg distribution files, or their contents in unzipped form, and collect information that can be used -49 * to determine the associated CPE. -50 * -51 * @author Dale Visser -52 */ -53 @Experimental -54 public class PythonDistributionAnalyzer extends AbstractFileTypeAnalyzer { -55 -56 /** -57 * Name of egg metadata files to analyze. -58 */ -59 private static final String PKG_INFO = "PKG-INFO"; -60 -61 /** -62 * Name of wheel metadata files to analyze. -63 */ -64 private static final String METADATA = "METADATA"; -65 -66 /** -67 * The logger. -68 */ -69 private static final Logger LOGGER = LoggerFactory -70 .getLogger(PythonDistributionAnalyzer.class); -71 -72 /** -73 * The count of directories created during analysis. This is used for creating temporary directories. -74 */ -75 private static int dirCount = 0; -76 -77 /** -78 * The name of the analyzer. -79 */ -80 private static final String ANALYZER_NAME = "Python Distribution Analyzer"; +26 import java.io.IOException; +27 import org.apache.commons.io.filefilter.NameFileFilter; +28 import org.apache.commons.io.filefilter.SuffixFileFilter; +29 import org.apache.commons.io.input.AutoCloseInputStream; +30 import org.apache.commons.lang3.StringUtils; +31 import org.owasp.dependencycheck.Engine; +32 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; +33 import org.owasp.dependencycheck.dependency.Confidence; +34 import org.owasp.dependencycheck.dependency.Dependency; +35 import org.owasp.dependencycheck.dependency.EvidenceCollection; +36 import org.slf4j.Logger; +37 import org.slf4j.LoggerFactory; +38 +39 import javax.mail.MessagingException; +40 import javax.mail.internet.InternetHeaders; +41 import org.owasp.dependencycheck.exception.InitializationException; +42 import org.owasp.dependencycheck.utils.ExtractionException; +43 import org.owasp.dependencycheck.utils.ExtractionUtil; +44 import org.owasp.dependencycheck.utils.FileFilterBuilder; +45 import org.owasp.dependencycheck.utils.FileUtils; +46 import org.owasp.dependencycheck.utils.Settings; +47 import org.owasp.dependencycheck.utils.UrlStringUtils; +48 +49 /** +50 * Used to analyze a Wheel or egg distribution files, or their contents in +51 * unzipped form, and collect information that can be used to determine the +52 * associated CPE. +53 * +54 * @author Dale Visser +55 */ +56 @Experimental +57 public class PythonDistributionAnalyzer extends AbstractFileTypeAnalyzer { +58 +59 /** +60 * Name of egg metadata files to analyze. +61 */ +62 private static final String PKG_INFO = "PKG-INFO"; +63 +64 /** +65 * Name of wheel metadata files to analyze. +66 */ +67 private static final String METADATA = "METADATA"; +68 +69 /** +70 * The logger. +71 */ +72 private static final Logger LOGGER = LoggerFactory +73 .getLogger(PythonDistributionAnalyzer.class); +74 +75 /** +76 * The count of directories created during analysis. This is used for +77 * creating temporary directories. +78 */ +79 private static int dirCount = 0; +80 81 /** -82 * The phase that this analyzer is intended to run in. +82 * The name of the analyzer. 83 */ -84 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; -85 -86 /** -87 * The set of file extensions supported by this analyzer. -88 */ -89 private static final String[] EXTENSIONS = {"whl", "egg", "zip"}; -90 -91 /** -92 * Used to match on egg archive candidate extensions. -93 */ -94 private static final FileFilter EGG_OR_ZIP = FileFilterBuilder.newInstance().addExtensions("egg", "zip").build(); -95 -96 /** -97 * Used to detect files with a .whl extension. -98 */ -99 private static final FileFilter WHL_FILTER = FileFilterBuilder.newInstance().addExtensions("whl").build(); -100 -101 /** -102 * The parent directory for the individual directories per archive. -103 */ -104 private File tempFileLocation; -105 -106 /** -107 * Filter that detects *.dist-info files (but doesn't verify they are directories. -108 */ -109 private static final FilenameFilter DIST_INFO_FILTER = new SuffixFileFilter( -110 ".dist-info"); -111 -112 /** -113 * Filter that detects files named "METADATA". -114 */ -115 private static final FilenameFilter EGG_INFO_FILTER = new NameFileFilter( -116 "EGG-INFO"); -117 -118 /** -119 * Filter that detects files named "METADATA". -120 */ -121 private static final NameFileFilter METADATA_FILTER = new NameFileFilter( -122 METADATA); -123 -124 /** -125 * Filter that detects files named "PKG-INFO". -126 */ -127 private static final NameFileFilter PKG_INFO_FILTER = new NameFileFilter( -128 PKG_INFO); -129 -130 /** -131 * The file filter used to determine which files this analyzer supports. -132 */ -133 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addFileFilters( -134 METADATA_FILTER, PKG_INFO_FILTER).addExtensions(EXTENSIONS).build(); -135 -136 /** -137 * Returns the FileFilter -138 * -139 * @return the FileFilter -140 */ -141 @Override -142 protected FileFilter getFileFilter() { -143 return FILTER; -144 } -145 -146 /** -147 * Returns the name of the analyzer. -148 * -149 * @return the name of the analyzer. -150 */ -151 @Override -152 public String getName() { -153 return ANALYZER_NAME; -154 } -155 -156 /** -157 * Returns the phase that the analyzer is intended to run in. -158 * -159 * @return the phase that the analyzer is intended to run in. -160 */ -161 @Override -162 public AnalysisPhase getAnalysisPhase() { -163 return ANALYSIS_PHASE; -164 } -165 -166 /** -167 * Returns the key used in the properties file to reference the analyzer's enabled property. -168 * -169 * @return the analyzer's enabled property setting key -170 */ -171 @Override -172 protected String getAnalyzerEnabledSettingKey() { -173 return Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED; -174 } -175 -176 @Override -177 protected void analyzeFileType(Dependency dependency, Engine engine) -178 throws AnalysisException { -179 final File actualFile = dependency.getActualFile(); -180 if (WHL_FILTER.accept(actualFile)) { -181 collectMetadataFromArchiveFormat(dependency, DIST_INFO_FILTER, -182 METADATA_FILTER); -183 } else if (EGG_OR_ZIP.accept(actualFile)) { -184 collectMetadataFromArchiveFormat(dependency, EGG_INFO_FILTER, -185 PKG_INFO_FILTER); -186 } else { -187 final String name = actualFile.getName(); -188 final boolean metadata = METADATA.equals(name); -189 if (metadata || PKG_INFO.equals(name)) { -190 final File parent = actualFile.getParentFile(); -191 final String parentName = parent.getName(); -192 dependency.setDisplayFileName(parentName + "/" + name); -193 if (parent.isDirectory() -194 && (metadata && parentName.endsWith(".dist-info") -195 || parentName.endsWith(".egg-info") || "EGG-INFO" -196 .equals(parentName))) { -197 collectWheelMetadata(dependency, actualFile); -198 } -199 } -200 } -201 } -202 -203 /** -204 * Collects the meta data from an archive. -205 * -206 * @param dependency the archive being scanned -207 * @param folderFilter the filter to apply to the folder -208 * @param metadataFilter the filter to apply to the meta data -209 * @throws AnalysisException thrown when there is a problem analyzing the dependency -210 */ -211 private void collectMetadataFromArchiveFormat(Dependency dependency, -212 FilenameFilter folderFilter, FilenameFilter metadataFilter) -213 throws AnalysisException { -214 final File temp = getNextTempDirectory(); -215 LOGGER.debug("{} exists? {}", temp, temp.exists()); -216 try { -217 ExtractionUtil.extractFilesUsingFilter( -218 new File(dependency.getActualFilePath()), temp, -219 metadataFilter); -220 } catch (ExtractionException ex) { -221 throw new AnalysisException(ex); -222 } -223 -224 collectWheelMetadata( -225 dependency, -226 getMatchingFile(getMatchingFile(temp, folderFilter), -227 metadataFilter)); -228 } -229 -230 /** -231 * Makes sure a usable temporary directory is available. -232 * -233 * @throws Exception an AnalyzeException is thrown when the temp directory cannot be created -234 */ -235 @Override -236 protected void initializeFileTypeAnalyzer() throws Exception { -237 final File baseDir = Settings.getTempDirectory(); -238 tempFileLocation = File.createTempFile("check", "tmp", baseDir); -239 if (!tempFileLocation.delete()) { -240 final String msg = String.format( -241 "Unable to delete temporary file '%s'.", -242 tempFileLocation.getAbsolutePath()); -243 throw new AnalysisException(msg); -244 } -245 if (!tempFileLocation.mkdirs()) { -246 final String msg = String.format( -247 "Unable to create directory '%s'.", -248 tempFileLocation.getAbsolutePath()); -249 throw new AnalysisException(msg); -250 } -251 } -252 -253 /** -254 * Deletes any files extracted from the Wheel during analysis. -255 */ -256 @Override -257 public void close() { -258 if (tempFileLocation != null && tempFileLocation.exists()) { -259 LOGGER.debug("Attempting to delete temporary files"); -260 final boolean success = FileUtils.delete(tempFileLocation); -261 if (!success) { -262 LOGGER.warn( -263 "Failed to delete some temporary files, see the log for more details"); -264 } +84 private static final String ANALYZER_NAME = "Python Distribution Analyzer"; +85 /** +86 * The phase that this analyzer is intended to run in. +87 */ +88 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; +89 +90 /** +91 * The set of file extensions supported by this analyzer. +92 */ +93 private static final String[] EXTENSIONS = {"whl", "egg", "zip"}; +94 +95 /** +96 * Used to match on egg archive candidate extensions. +97 */ +98 private static final FileFilter EGG_OR_ZIP = FileFilterBuilder.newInstance().addExtensions("egg", "zip").build(); +99 +100 /** +101 * Used to detect files with a .whl extension. +102 */ +103 private static final FileFilter WHL_FILTER = FileFilterBuilder.newInstance().addExtensions("whl").build(); +104 +105 /** +106 * The parent directory for the individual directories per archive. +107 */ +108 private File tempFileLocation; +109 +110 /** +111 * Filter that detects *.dist-info files (but doesn't verify they are +112 * directories. +113 */ +114 private static final FilenameFilter DIST_INFO_FILTER = new SuffixFileFilter( +115 ".dist-info"); +116 +117 /** +118 * Filter that detects files named "METADATA". +119 */ +120 private static final FilenameFilter EGG_INFO_FILTER = new NameFileFilter( +121 "EGG-INFO"); +122 +123 /** +124 * Filter that detects files named "METADATA". +125 */ +126 private static final NameFileFilter METADATA_FILTER = new NameFileFilter( +127 METADATA); +128 +129 /** +130 * Filter that detects files named "PKG-INFO". +131 */ +132 private static final NameFileFilter PKG_INFO_FILTER = new NameFileFilter( +133 PKG_INFO); +134 +135 /** +136 * The file filter used to determine which files this analyzer supports. +137 */ +138 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addFileFilters( +139 METADATA_FILTER, PKG_INFO_FILTER).addExtensions(EXTENSIONS).build(); +140 +141 /** +142 * Returns the FileFilter +143 * +144 * @return the FileFilter +145 */ +146 @Override +147 protected FileFilter getFileFilter() { +148 return FILTER; +149 } +150 +151 /** +152 * Returns the name of the analyzer. +153 * +154 * @return the name of the analyzer. +155 */ +156 @Override +157 public String getName() { +158 return ANALYZER_NAME; +159 } +160 +161 /** +162 * Returns the phase that the analyzer is intended to run in. +163 * +164 * @return the phase that the analyzer is intended to run in. +165 */ +166 @Override +167 public AnalysisPhase getAnalysisPhase() { +168 return ANALYSIS_PHASE; +169 } +170 +171 /** +172 * Returns the key used in the properties file to reference the analyzer's +173 * enabled property. +174 * +175 * @return the analyzer's enabled property setting key +176 */ +177 @Override +178 protected String getAnalyzerEnabledSettingKey() { +179 return Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED; +180 } +181 +182 @Override +183 protected void analyzeFileType(Dependency dependency, Engine engine) +184 throws AnalysisException { +185 final File actualFile = dependency.getActualFile(); +186 if (WHL_FILTER.accept(actualFile)) { +187 collectMetadataFromArchiveFormat(dependency, DIST_INFO_FILTER, +188 METADATA_FILTER); +189 } else if (EGG_OR_ZIP.accept(actualFile)) { +190 collectMetadataFromArchiveFormat(dependency, EGG_INFO_FILTER, +191 PKG_INFO_FILTER); +192 } else { +193 final String name = actualFile.getName(); +194 final boolean metadata = METADATA.equals(name); +195 if (metadata || PKG_INFO.equals(name)) { +196 final File parent = actualFile.getParentFile(); +197 final String parentName = parent.getName(); +198 dependency.setDisplayFileName(parentName + "/" + name); +199 if (parent.isDirectory() +200 && (metadata && parentName.endsWith(".dist-info") +201 || parentName.endsWith(".egg-info") || "EGG-INFO" +202 .equals(parentName))) { +203 collectWheelMetadata(dependency, actualFile); +204 } +205 } +206 } +207 } +208 +209 /** +210 * Collects the meta data from an archive. +211 * +212 * @param dependency the archive being scanned +213 * @param folderFilter the filter to apply to the folder +214 * @param metadataFilter the filter to apply to the meta data +215 * @throws AnalysisException thrown when there is a problem analyzing the +216 * dependency +217 */ +218 private void collectMetadataFromArchiveFormat(Dependency dependency, +219 FilenameFilter folderFilter, FilenameFilter metadataFilter) +220 throws AnalysisException { +221 final File temp = getNextTempDirectory(); +222 LOGGER.debug("{} exists? {}", temp, temp.exists()); +223 try { +224 ExtractionUtil.extractFilesUsingFilter( +225 new File(dependency.getActualFilePath()), temp, +226 metadataFilter); +227 } catch (ExtractionException ex) { +228 throw new AnalysisException(ex); +229 } +230 +231 collectWheelMetadata( +232 dependency, +233 getMatchingFile(getMatchingFile(temp, folderFilter), +234 metadataFilter)); +235 } +236 +237 /** +238 * Makes sure a usable temporary directory is available. +239 * +240 * @throws InitializationException an AnalyzeException is thrown when the +241 * temp directory cannot be created +242 */ +243 @Override +244 protected void initializeFileTypeAnalyzer() throws InitializationException { +245 try { +246 final File baseDir = Settings.getTempDirectory(); +247 tempFileLocation = File.createTempFile("check", "tmp", baseDir); +248 if (!tempFileLocation.delete()) { +249 setEnabled(false); +250 final String msg = String.format( +251 "Unable to delete temporary file '%s'.", +252 tempFileLocation.getAbsolutePath()); +253 throw new InitializationException(msg); +254 } +255 if (!tempFileLocation.mkdirs()) { +256 setEnabled(false); +257 final String msg = String.format( +258 "Unable to create directory '%s'.", +259 tempFileLocation.getAbsolutePath()); +260 throw new InitializationException(msg); +261 } +262 } catch (IOException ex) { +263 setEnabled(false); +264 throw new InitializationException("Unable to create a temporary file", ex); 265 } 266 } 267 268 /** -269 * Gathers evidence from the METADATA file. -270 * -271 * @param dependency the dependency being analyzed -272 * @param file a reference to the manifest/properties file -273 */ -274 private static void collectWheelMetadata(Dependency dependency, File file) { -275 final InternetHeaders headers = getManifestProperties(file); -276 addPropertyToEvidence(headers, dependency.getVersionEvidence(), -277 "Version", Confidence.HIGHEST); -278 addPropertyToEvidence(headers, dependency.getProductEvidence(), "Name", -279 Confidence.HIGHEST); -280 final String url = headers.getHeader("Home-page", null); -281 final EvidenceCollection vendorEvidence = dependency -282 .getVendorEvidence(); -283 if (StringUtils.isNotBlank(url)) { -284 if (UrlStringUtils.isUrl(url)) { -285 vendorEvidence.addEvidence(METADATA, "vendor", url, -286 Confidence.MEDIUM); -287 } -288 } -289 addPropertyToEvidence(headers, vendorEvidence, "Author", Confidence.LOW); -290 final String summary = headers.getHeader("Summary", null); -291 if (StringUtils.isNotBlank(summary)) { -292 JarAnalyzer -293 .addDescription(dependency, summary, METADATA, "summary"); -294 } -295 } -296 -297 /** -298 * Adds a value to the evidence collection. -299 * -300 * @param headers the properties collection -301 * @param evidence the evidence collection to add the value -302 * @param property the property name -303 * @param confidence the confidence of the evidence -304 */ -305 private static void addPropertyToEvidence(InternetHeaders headers, -306 EvidenceCollection evidence, String property, Confidence confidence) { -307 final String value = headers.getHeader(property, null); -308 LOGGER.debug("Property: {}, Value: {}", property, value); -309 if (StringUtils.isNotBlank(value)) { -310 evidence.addEvidence(METADATA, property, value, confidence); -311 } -312 } -313 -314 /** -315 * Returns a list of files that match the given filter, this does not recursively scan the directory. -316 * -317 * @param folder the folder to filter -318 * @param filter the filter to apply to the files in the directory -319 * @return the list of Files in the directory that match the provided filter -320 */ -321 private static File getMatchingFile(File folder, FilenameFilter filter) { -322 File result = null; -323 final File[] matches = folder.listFiles(filter); -324 if (null != matches && 1 == matches.length) { -325 result = matches[0]; +269 * Deletes any files extracted from the Wheel during analysis. +270 */ +271 @Override +272 public void close() { +273 if (tempFileLocation != null && tempFileLocation.exists()) { +274 LOGGER.debug("Attempting to delete temporary files"); +275 final boolean success = FileUtils.delete(tempFileLocation); +276 if (!success) { +277 LOGGER.warn( +278 "Failed to delete some temporary files, see the log for more details"); +279 } +280 } +281 } +282 +283 /** +284 * Gathers evidence from the METADATA file. +285 * +286 * @param dependency the dependency being analyzed +287 * @param file a reference to the manifest/properties file +288 */ +289 private static void collectWheelMetadata(Dependency dependency, File file) { +290 final InternetHeaders headers = getManifestProperties(file); +291 addPropertyToEvidence(headers, dependency.getVersionEvidence(), +292 "Version", Confidence.HIGHEST); +293 addPropertyToEvidence(headers, dependency.getProductEvidence(), "Name", +294 Confidence.HIGHEST); +295 final String url = headers.getHeader("Home-page", null); +296 final EvidenceCollection vendorEvidence = dependency +297 .getVendorEvidence(); +298 if (StringUtils.isNotBlank(url)) { +299 if (UrlStringUtils.isUrl(url)) { +300 vendorEvidence.addEvidence(METADATA, "vendor", url, +301 Confidence.MEDIUM); +302 } +303 } +304 addPropertyToEvidence(headers, vendorEvidence, "Author", Confidence.LOW); +305 final String summary = headers.getHeader("Summary", null); +306 if (StringUtils.isNotBlank(summary)) { +307 JarAnalyzer +308 .addDescription(dependency, summary, METADATA, "summary"); +309 } +310 } +311 +312 /** +313 * Adds a value to the evidence collection. +314 * +315 * @param headers the properties collection +316 * @param evidence the evidence collection to add the value +317 * @param property the property name +318 * @param confidence the confidence of the evidence +319 */ +320 private static void addPropertyToEvidence(InternetHeaders headers, +321 EvidenceCollection evidence, String property, Confidence confidence) { +322 final String value = headers.getHeader(property, null); +323 LOGGER.debug("Property: {}, Value: {}", property, value); +324 if (StringUtils.isNotBlank(value)) { +325 evidence.addEvidence(METADATA, property, value, confidence); 326 } -327 return result; -328 } -329 -330 /** -331 * Reads the manifest entries from the provided file. +327 } +328 +329 /** +330 * Returns a list of files that match the given filter, this does not +331 * recursively scan the directory. 332 * -333 * @param manifest the manifest -334 * @return the manifest entries -335 */ -336 private static InternetHeaders getManifestProperties(File manifest) { -337 final InternetHeaders result = new InternetHeaders(); -338 if (null == manifest) { -339 LOGGER.debug("Manifest file not found."); -340 } else { -341 try { -342 result.load(new AutoCloseInputStream(new BufferedInputStream( -343 new FileInputStream(manifest)))); -344 } catch (MessagingException e) { -345 LOGGER.warn(e.getMessage(), e); -346 } catch (FileNotFoundException e) { -347 LOGGER.warn(e.getMessage(), e); -348 } -349 } -350 return result; -351 } -352 -353 /** -354 * Retrieves the next temporary destination directory for extracting an archive. -355 * -356 * @return a directory -357 * @throws AnalysisException thrown if unable to create temporary directory -358 */ -359 private File getNextTempDirectory() throws AnalysisException { -360 File directory; -361 -362 // getting an exception for some directories not being able to be -363 // created; might be because the directory already exists? -364 do { -365 dirCount += 1; -366 directory = new File(tempFileLocation, String.valueOf(dirCount)); -367 } while (directory.exists()); -368 if (!directory.mkdirs()) { -369 throw new AnalysisException(String.format( -370 "Unable to create temp directory '%s'.", -371 directory.getAbsolutePath())); -372 } -373 return directory; -374 } -375 } +333 * @param folder the folder to filter +334 * @param filter the filter to apply to the files in the directory +335 * @return the list of Files in the directory that match the provided filter +336 */ +337 private static File getMatchingFile(File folder, FilenameFilter filter) { +338 File result = null; +339 final File[] matches = folder.listFiles(filter); +340 if (null != matches && 1 == matches.length) { +341 result = matches[0]; +342 } +343 return result; +344 } +345 +346 /** +347 * Reads the manifest entries from the provided file. +348 * +349 * @param manifest the manifest +350 * @return the manifest entries +351 */ +352 private static InternetHeaders getManifestProperties(File manifest) { +353 final InternetHeaders result = new InternetHeaders(); +354 if (null == manifest) { +355 LOGGER.debug("Manifest file not found."); +356 } else { +357 try { +358 result.load(new AutoCloseInputStream(new BufferedInputStream( +359 new FileInputStream(manifest)))); +360 } catch (MessagingException e) { +361 LOGGER.warn(e.getMessage(), e); +362 } catch (FileNotFoundException e) { +363 LOGGER.warn(e.getMessage(), e); +364 } +365 } +366 return result; +367 } +368 +369 /** +370 * Retrieves the next temporary destination directory for extracting an +371 * archive. +372 * +373 * @return a directory +374 * @throws AnalysisException thrown if unable to create temporary directory +375 */ +376 private File getNextTempDirectory() throws AnalysisException { +377 File directory; +378 +379 // getting an exception for some directories not being able to be +380 // created; might be because the directory already exists? +381 do { +382 dirCount += 1; +383 directory = new File(tempFileLocation, String.valueOf(dirCount)); +384 } while (directory.exists()); +385 if (!directory.mkdirs()) { +386 throw new AnalysisException(String.format( +387 "Unable to create temp directory '%s'.", +388 directory.getAbsolutePath())); +389 } +390 return directory; +391 } +392 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/PythonPackageAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/PythonPackageAnalyzer.html index e87b494a2..847ae696f 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/PythonPackageAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/PythonPackageAnalyzer.html @@ -45,290 +45,291 @@ 37 import java.util.List; 38 import java.util.regex.Matcher; 39 import java.util.regex.Pattern; -40 -41 /** -42 * Used to analyze a Python package, and collect information that can be used to -43 * determine the associated CPE. -44 * -45 * @author Dale Visser -46 */ -47 @Experimental -48 public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer { -49 -50 /** -51 * Used when compiling file scanning regex patterns. -52 */ -53 private static final int REGEX_OPTIONS = Pattern.DOTALL -54 | Pattern.CASE_INSENSITIVE; -55 -56 /** -57 * Filename extensions for files to be analyzed. -58 */ -59 private static final String EXTENSIONS = "py"; -60 -61 /** -62 * Pattern for matching the module docstring in a source file. -63 */ -64 private static final Pattern MODULE_DOCSTRING = Pattern.compile( -65 "^(['\\\"]{3})(.*?)\\1", REGEX_OPTIONS); -66 -67 /** -68 * Matches assignments to version variables in Python source code. -69 */ -70 private static final Pattern VERSION_PATTERN = Pattern.compile( -71 "\\b(__)?version(__)? *= *(['\"]+)(\\d+\\.\\d+.*?)\\3", -72 REGEX_OPTIONS); -73 -74 /** -75 * Matches assignments to title variables in Python source code. -76 */ -77 private static final Pattern TITLE_PATTERN = compileAssignPattern("title"); -78 -79 /** -80 * Matches assignments to summary variables in Python source code. -81 */ -82 private static final Pattern SUMMARY_PATTERN = compileAssignPattern("summary"); -83 -84 /** -85 * Matches assignments to URL/URL variables in Python source code. -86 */ -87 private static final Pattern URI_PATTERN = compileAssignPattern("ur[il]"); -88 -89 /** -90 * Matches assignments to home page variables in Python source code. -91 */ -92 private static final Pattern HOMEPAGE_PATTERN = compileAssignPattern("home_?page"); -93 -94 /** -95 * Matches assignments to author variables in Python source code. -96 */ -97 private static final Pattern AUTHOR_PATTERN = compileAssignPattern("author"); -98 -99 /** -100 * Filter that detects files named "__init__.py". -101 */ -102 private static final FileFilter INIT_PY_FILTER = new NameFileFilter("__init__.py"); -103 -104 /** -105 * The file filter for python files. -106 */ -107 private static final FileFilter PY_FILTER = new SuffixFileFilter(".py"); -108 -109 /** -110 * Returns the name of the Python Package Analyzer. -111 * -112 * @return the name of the analyzer -113 */ -114 @Override -115 public String getName() { -116 return "Python Package Analyzer"; -117 } -118 -119 /** -120 * Tell that we are used for information collection. -121 * -122 * @return INFORMATION_COLLECTION -123 */ -124 @Override -125 public AnalysisPhase getAnalysisPhase() { -126 return AnalysisPhase.INFORMATION_COLLECTION; -127 } -128 -129 /** -130 * The file filter used to determine which files this analyzer supports. -131 */ -132 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(EXTENSIONS).build(); -133 -134 /** -135 * Returns the FileFilter -136 * -137 * @return the FileFilter -138 */ -139 @Override -140 protected FileFilter getFileFilter() { -141 return FILTER; -142 } -143 -144 /** -145 * No-op initializer implementation. -146 * -147 * @throws Exception never thrown -148 */ -149 @Override -150 protected void initializeFileTypeAnalyzer() throws Exception { -151 // Nothing to do here. -152 } -153 -154 /** -155 * Utility function to create a regex pattern matcher. -156 * -157 * @param name the value to use when constructing the assignment pattern -158 * @return the compiled Pattern -159 */ -160 private static Pattern compileAssignPattern(String name) { -161 return Pattern.compile( -162 String.format("\\b(__)?%s(__)?\\b *= *(['\"]+)(.*?)\\3", name), -163 REGEX_OPTIONS); -164 } -165 -166 /** -167 * Analyzes python packages and adds evidence to the dependency. -168 * -169 * @param dependency the dependency being analyzed -170 * @param engine the engine being used to perform the scan -171 * @throws AnalysisException thrown if there is an unrecoverable error -172 * analyzing the dependency -173 */ -174 @Override -175 protected void analyzeFileType(Dependency dependency, Engine engine) -176 throws AnalysisException { -177 final File file = dependency.getActualFile(); -178 final File parent = file.getParentFile(); -179 final String parentName = parent.getName(); -180 if (INIT_PY_FILTER.accept(file)) { -181 //by definition, the containing folder of __init__.py is considered the package, even the file is empty: -182 //"The __init__.py files are required to make Python treat the directories as containing packages" -183 //see section "6.4 Packages" from https://docs.python.org/2/tutorial/modules.html; -184 dependency.setDisplayFileName(parentName + "/__init__.py"); -185 dependency.getProductEvidence().addEvidence(file.getName(), -186 "PackageName", parentName, Confidence.HIGHEST); -187 -188 final File[] fileList = parent.listFiles(PY_FILTER); -189 if (fileList != null) { -190 for (final File sourceFile : fileList) { -191 analyzeFileContents(dependency, sourceFile); -192 } -193 } -194 } else { -195 // copy, alter and set in case some other thread is iterating over -196 final List<Dependency> dependencies = new ArrayList<Dependency>( -197 engine.getDependencies()); -198 dependencies.remove(dependency); -199 engine.setDependencies(dependencies); -200 } -201 } -202 -203 /** -204 * This should gather information from leading docstrings, file comments, -205 * and assignments to __version__, __title__, __summary__, __uri__, __url__, -206 * __home*page__, __author__, and their all caps equivalents. -207 * -208 * @param dependency the dependency being analyzed -209 * @param file the file name to analyze -210 * @return whether evidence was found -211 * @throws AnalysisException thrown if there is an unrecoverable error -212 */ -213 private boolean analyzeFileContents(Dependency dependency, File file) -214 throws AnalysisException { -215 String contents; -216 try { -217 contents = FileUtils.readFileToString(file, Charset.defaultCharset()).trim(); -218 } catch (IOException e) { -219 throw new AnalysisException( -220 "Problem occurred while reading dependency file.", e); -221 } -222 boolean found = false; -223 if (!contents.isEmpty()) { -224 final String source = file.getName(); -225 found = gatherEvidence(VERSION_PATTERN, contents, source, -226 dependency.getVersionEvidence(), "SourceVersion", -227 Confidence.MEDIUM); -228 found |= addSummaryInfo(dependency, SUMMARY_PATTERN, 4, contents, -229 source, "summary"); -230 if (INIT_PY_FILTER.accept(file)) { -231 found |= addSummaryInfo(dependency, MODULE_DOCSTRING, 2, -232 contents, source, "docstring"); -233 } -234 found |= gatherEvidence(TITLE_PATTERN, contents, source, -235 dependency.getProductEvidence(), "SourceTitle", -236 Confidence.LOW); -237 final EvidenceCollection vendorEvidence = dependency -238 .getVendorEvidence(); -239 found |= gatherEvidence(AUTHOR_PATTERN, contents, source, -240 vendorEvidence, "SourceAuthor", Confidence.MEDIUM); -241 found |= gatherHomePageEvidence(URI_PATTERN, vendorEvidence, -242 source, "URL", contents); -243 found |= gatherHomePageEvidence(HOMEPAGE_PATTERN, -244 vendorEvidence, source, "HomePage", contents); -245 } -246 return found; -247 } -248 -249 /** -250 * Adds summary information to the dependency -251 * -252 * @param dependency the dependency being analyzed -253 * @param pattern the pattern used to perform analysis -254 * @param group the group from the pattern that indicates the data to use -255 * @param contents the data being analyzed -256 * @param source the source name to use when recording the evidence -257 * @param key the key name to use when recording the evidence -258 * @return true if evidence was collected; otherwise false -259 */ -260 private boolean addSummaryInfo(Dependency dependency, Pattern pattern, -261 int group, String contents, String source, String key) { -262 final Matcher matcher = pattern.matcher(contents); -263 final boolean found = matcher.find(); -264 if (found) { -265 JarAnalyzer.addDescription(dependency, matcher.group(group), -266 source, key); -267 } -268 return found; -269 } -270 -271 /** -272 * Collects evidence from the home page URL. -273 * -274 * @param pattern the pattern to match -275 * @param evidence the evidence collection to add the evidence to -276 * @param source the source of the evidence -277 * @param name the name of the evidence -278 * @param contents the home page URL -279 * @return true if evidence was collected; otherwise false -280 */ -281 private boolean gatherHomePageEvidence(Pattern pattern, -282 EvidenceCollection evidence, String source, String name, -283 String contents) { -284 final Matcher matcher = pattern.matcher(contents); -285 boolean found = false; -286 if (matcher.find()) { -287 final String url = matcher.group(4); -288 if (UrlStringUtils.isUrl(url)) { -289 found = true; -290 evidence.addEvidence(source, name, url, Confidence.MEDIUM); -291 } -292 } -293 return found; -294 } -295 -296 /** -297 * Gather evidence from a Python source file using the given string -298 * assignment regex pattern. -299 * -300 * @param pattern to scan contents with -301 * @param contents of Python source file -302 * @param source for storing evidence -303 * @param evidence to store evidence in -304 * @param name of evidence -305 * @param confidence in evidence -306 * @return whether evidence was found -307 */ -308 private boolean gatherEvidence(Pattern pattern, String contents, -309 String source, EvidenceCollection evidence, String name, -310 Confidence confidence) { -311 final Matcher matcher = pattern.matcher(contents); -312 final boolean found = matcher.find(); -313 if (found) { -314 evidence.addEvidence(source, name, matcher.group(4), confidence); -315 } -316 return found; -317 } -318 -319 @Override -320 protected String getAnalyzerEnabledSettingKey() { -321 return Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED; -322 } -323 } +40 import org.owasp.dependencycheck.exception.InitializationException; +41 +42 /** +43 * Used to analyze a Python package, and collect information that can be used to +44 * determine the associated CPE. +45 * +46 * @author Dale Visser +47 */ +48 @Experimental +49 public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer { +50 +51 /** +52 * Used when compiling file scanning regex patterns. +53 */ +54 private static final int REGEX_OPTIONS = Pattern.DOTALL +55 | Pattern.CASE_INSENSITIVE; +56 +57 /** +58 * Filename extensions for files to be analyzed. +59 */ +60 private static final String EXTENSIONS = "py"; +61 +62 /** +63 * Pattern for matching the module docstring in a source file. +64 */ +65 private static final Pattern MODULE_DOCSTRING = Pattern.compile( +66 "^(['\\\"]{3})(.*?)\\1", REGEX_OPTIONS); +67 +68 /** +69 * Matches assignments to version variables in Python source code. +70 */ +71 private static final Pattern VERSION_PATTERN = Pattern.compile( +72 "\\b(__)?version(__)? *= *(['\"]+)(\\d+\\.\\d+.*?)\\3", +73 REGEX_OPTIONS); +74 +75 /** +76 * Matches assignments to title variables in Python source code. +77 */ +78 private static final Pattern TITLE_PATTERN = compileAssignPattern("title"); +79 +80 /** +81 * Matches assignments to summary variables in Python source code. +82 */ +83 private static final Pattern SUMMARY_PATTERN = compileAssignPattern("summary"); +84 +85 /** +86 * Matches assignments to URL/URL variables in Python source code. +87 */ +88 private static final Pattern URI_PATTERN = compileAssignPattern("ur[il]"); +89 +90 /** +91 * Matches assignments to home page variables in Python source code. +92 */ +93 private static final Pattern HOMEPAGE_PATTERN = compileAssignPattern("home_?page"); +94 +95 /** +96 * Matches assignments to author variables in Python source code. +97 */ +98 private static final Pattern AUTHOR_PATTERN = compileAssignPattern("author"); +99 +100 /** +101 * Filter that detects files named "__init__.py". +102 */ +103 private static final FileFilter INIT_PY_FILTER = new NameFileFilter("__init__.py"); +104 +105 /** +106 * The file filter for python files. +107 */ +108 private static final FileFilter PY_FILTER = new SuffixFileFilter(".py"); +109 +110 /** +111 * Returns the name of the Python Package Analyzer. +112 * +113 * @return the name of the analyzer +114 */ +115 @Override +116 public String getName() { +117 return "Python Package Analyzer"; +118 } +119 +120 /** +121 * Tell that we are used for information collection. +122 * +123 * @return INFORMATION_COLLECTION +124 */ +125 @Override +126 public AnalysisPhase getAnalysisPhase() { +127 return AnalysisPhase.INFORMATION_COLLECTION; +128 } +129 +130 /** +131 * The file filter used to determine which files this analyzer supports. +132 */ +133 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(EXTENSIONS).build(); +134 +135 /** +136 * Returns the FileFilter +137 * +138 * @return the FileFilter +139 */ +140 @Override +141 protected FileFilter getFileFilter() { +142 return FILTER; +143 } +144 +145 /** +146 * No-op initializer implementation. +147 * +148 * @throws InitializationException never thrown +149 */ +150 @Override +151 protected void initializeFileTypeAnalyzer() throws InitializationException { +152 // Nothing to do here. +153 } +154 +155 /** +156 * Utility function to create a regex pattern matcher. +157 * +158 * @param name the value to use when constructing the assignment pattern +159 * @return the compiled Pattern +160 */ +161 private static Pattern compileAssignPattern(String name) { +162 return Pattern.compile( +163 String.format("\\b(__)?%s(__)?\\b *= *(['\"]+)(.*?)\\3", name), +164 REGEX_OPTIONS); +165 } +166 +167 /** +168 * Analyzes python packages and adds evidence to the dependency. +169 * +170 * @param dependency the dependency being analyzed +171 * @param engine the engine being used to perform the scan +172 * @throws AnalysisException thrown if there is an unrecoverable error +173 * analyzing the dependency +174 */ +175 @Override +176 protected void analyzeFileType(Dependency dependency, Engine engine) +177 throws AnalysisException { +178 final File file = dependency.getActualFile(); +179 final File parent = file.getParentFile(); +180 final String parentName = parent.getName(); +181 if (INIT_PY_FILTER.accept(file)) { +182 //by definition, the containing folder of __init__.py is considered the package, even the file is empty: +183 //"The __init__.py files are required to make Python treat the directories as containing packages" +184 //see section "6.4 Packages" from https://docs.python.org/2/tutorial/modules.html; +185 dependency.setDisplayFileName(parentName + "/__init__.py"); +186 dependency.getProductEvidence().addEvidence(file.getName(), +187 "PackageName", parentName, Confidence.HIGHEST); +188 +189 final File[] fileList = parent.listFiles(PY_FILTER); +190 if (fileList != null) { +191 for (final File sourceFile : fileList) { +192 analyzeFileContents(dependency, sourceFile); +193 } +194 } +195 } else { +196 // copy, alter and set in case some other thread is iterating over +197 final List<Dependency> dependencies = new ArrayList<Dependency>( +198 engine.getDependencies()); +199 dependencies.remove(dependency); +200 engine.setDependencies(dependencies); +201 } +202 } +203 +204 /** +205 * This should gather information from leading docstrings, file comments, +206 * and assignments to __version__, __title__, __summary__, __uri__, __url__, +207 * __home*page__, __author__, and their all caps equivalents. +208 * +209 * @param dependency the dependency being analyzed +210 * @param file the file name to analyze +211 * @return whether evidence was found +212 * @throws AnalysisException thrown if there is an unrecoverable error +213 */ +214 private boolean analyzeFileContents(Dependency dependency, File file) +215 throws AnalysisException { +216 String contents; +217 try { +218 contents = FileUtils.readFileToString(file, Charset.defaultCharset()).trim(); +219 } catch (IOException e) { +220 throw new AnalysisException( +221 "Problem occurred while reading dependency file.", e); +222 } +223 boolean found = false; +224 if (!contents.isEmpty()) { +225 final String source = file.getName(); +226 found = gatherEvidence(VERSION_PATTERN, contents, source, +227 dependency.getVersionEvidence(), "SourceVersion", +228 Confidence.MEDIUM); +229 found |= addSummaryInfo(dependency, SUMMARY_PATTERN, 4, contents, +230 source, "summary"); +231 if (INIT_PY_FILTER.accept(file)) { +232 found |= addSummaryInfo(dependency, MODULE_DOCSTRING, 2, +233 contents, source, "docstring"); +234 } +235 found |= gatherEvidence(TITLE_PATTERN, contents, source, +236 dependency.getProductEvidence(), "SourceTitle", +237 Confidence.LOW); +238 final EvidenceCollection vendorEvidence = dependency +239 .getVendorEvidence(); +240 found |= gatherEvidence(AUTHOR_PATTERN, contents, source, +241 vendorEvidence, "SourceAuthor", Confidence.MEDIUM); +242 found |= gatherHomePageEvidence(URI_PATTERN, vendorEvidence, +243 source, "URL", contents); +244 found |= gatherHomePageEvidence(HOMEPAGE_PATTERN, +245 vendorEvidence, source, "HomePage", contents); +246 } +247 return found; +248 } +249 +250 /** +251 * Adds summary information to the dependency +252 * +253 * @param dependency the dependency being analyzed +254 * @param pattern the pattern used to perform analysis +255 * @param group the group from the pattern that indicates the data to use +256 * @param contents the data being analyzed +257 * @param source the source name to use when recording the evidence +258 * @param key the key name to use when recording the evidence +259 * @return true if evidence was collected; otherwise false +260 */ +261 private boolean addSummaryInfo(Dependency dependency, Pattern pattern, +262 int group, String contents, String source, String key) { +263 final Matcher matcher = pattern.matcher(contents); +264 final boolean found = matcher.find(); +265 if (found) { +266 JarAnalyzer.addDescription(dependency, matcher.group(group), +267 source, key); +268 } +269 return found; +270 } +271 +272 /** +273 * Collects evidence from the home page URL. +274 * +275 * @param pattern the pattern to match +276 * @param evidence the evidence collection to add the evidence to +277 * @param source the source of the evidence +278 * @param name the name of the evidence +279 * @param contents the home page URL +280 * @return true if evidence was collected; otherwise false +281 */ +282 private boolean gatherHomePageEvidence(Pattern pattern, +283 EvidenceCollection evidence, String source, String name, +284 String contents) { +285 final Matcher matcher = pattern.matcher(contents); +286 boolean found = false; +287 if (matcher.find()) { +288 final String url = matcher.group(4); +289 if (UrlStringUtils.isUrl(url)) { +290 found = true; +291 evidence.addEvidence(source, name, url, Confidence.MEDIUM); +292 } +293 } +294 return found; +295 } +296 +297 /** +298 * Gather evidence from a Python source file using the given string +299 * assignment regex pattern. +300 * +301 * @param pattern to scan contents with +302 * @param contents of Python source file +303 * @param source for storing evidence +304 * @param evidence to store evidence in +305 * @param name of evidence +306 * @param confidence in evidence +307 * @return whether evidence was found +308 */ +309 private boolean gatherEvidence(Pattern pattern, String contents, +310 String source, EvidenceCollection evidence, String name, +311 Confidence confidence) { +312 final Matcher matcher = pattern.matcher(contents); +313 final boolean found = matcher.find(); +314 if (found) { +315 evidence.addEvidence(source, name, matcher.group(4), confidence); +316 } +317 return found; +318 } +319 +320 @Override +321 protected String getAnalyzerEnabledSettingKey() { +322 return Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED; +323 } +324 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.html index d14417ea9..ac2dbd5cf 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.html @@ -30,453 +30,479 @@ 22 import java.io.FileFilter; 23 import java.io.IOException; 24 import java.io.InputStreamReader; -25 import java.util.ArrayList; -26 import java.util.HashMap; -27 import java.util.List; -28 import java.util.Map; -29 import java.nio.charset.Charset; -30 import org.apache.commons.io.FileUtils; -31 import org.owasp.dependencycheck.Engine; -32 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; -33 import org.owasp.dependencycheck.data.nvdcve.CveDB; -34 import org.owasp.dependencycheck.dependency.Confidence; -35 import org.owasp.dependencycheck.dependency.Dependency; -36 import org.owasp.dependencycheck.dependency.Reference; -37 import org.owasp.dependencycheck.dependency.Vulnerability; -38 import org.owasp.dependencycheck.utils.FileFilterBuilder; -39 import org.owasp.dependencycheck.utils.Settings; -40 import org.slf4j.Logger; -41 import org.slf4j.LoggerFactory; -42 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; -43 -44 /** -45 * Used to analyze Ruby Bundler Gemspec.lock files utilizing the 3rd party -46 * bundle-audit tool. -47 * -48 * @author Dale Visser -49 */ -50 @Experimental -51 public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { -52 -53 private static final Logger LOGGER = LoggerFactory.getLogger(RubyBundleAuditAnalyzer.class); +25 import java.io.UnsupportedEncodingException; +26 import java.util.ArrayList; +27 import java.util.HashMap; +28 import java.util.List; +29 import java.util.Map; +30 import java.nio.charset.Charset; +31 import org.apache.commons.io.FileUtils; +32 import org.owasp.dependencycheck.Engine; +33 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; +34 import org.owasp.dependencycheck.data.nvdcve.CveDB; +35 import org.owasp.dependencycheck.dependency.Confidence; +36 import org.owasp.dependencycheck.dependency.Dependency; +37 import org.owasp.dependencycheck.dependency.Reference; +38 import org.owasp.dependencycheck.dependency.Vulnerability; +39 import org.owasp.dependencycheck.utils.FileFilterBuilder; +40 import org.owasp.dependencycheck.utils.Settings; +41 import org.slf4j.Logger; +42 import org.slf4j.LoggerFactory; +43 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; +44 import org.owasp.dependencycheck.exception.InitializationException; +45 +46 /** +47 * Used to analyze Ruby Bundler Gemspec.lock files utilizing the 3rd party +48 * bundle-audit tool. +49 * +50 * @author Dale Visser +51 */ +52 @Experimental +53 public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { 54 55 /** -56 * The name of the analyzer. +56 * The logger. 57 */ -58 private static final String ANALYZER_NAME = "Ruby Bundle Audit Analyzer"; +58 private static final Logger LOGGER = LoggerFactory.getLogger(RubyBundleAuditAnalyzer.class); 59 60 /** -61 * The phase that this analyzer is intended to run in. +61 * The name of the analyzer. 62 */ -63 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_INFORMATION_COLLECTION; -64 /** -65 * The filter defining which files will be analyzed. -66 */ -67 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addFilenames("Gemfile.lock").build(); -68 /** -69 * Name. -70 */ -71 public static final String NAME = "Name: "; -72 /** -73 * Version. -74 */ -75 public static final String VERSION = "Version: "; -76 /** -77 * Advisory. -78 */ -79 public static final String ADVISORY = "Advisory: "; -80 /** -81 * Criticality. -82 */ -83 public static final String CRITICALITY = "Criticality: "; -84 +63 private static final String ANALYZER_NAME = "Ruby Bundle Audit Analyzer"; +64 +65 /** +66 * The phase that this analyzer is intended to run in. +67 */ +68 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_INFORMATION_COLLECTION; +69 /** +70 * The filter defining which files will be analyzed. +71 */ +72 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addFilenames("Gemfile.lock").build(); +73 /** +74 * Name. +75 */ +76 public static final String NAME = "Name: "; +77 /** +78 * Version. +79 */ +80 public static final String VERSION = "Version: "; +81 /** +82 * Advisory. +83 */ +84 public static final String ADVISORY = "Advisory: "; 85 /** -86 * The DAL. +86 * Criticality. 87 */ -88 private CveDB cvedb; +88 public static final String CRITICALITY = "Criticality: "; 89 90 /** -91 * @return a filter that accepts files named Gemfile.lock +91 * The DAL. 92 */ -93 @Override -94 protected FileFilter getFileFilter() { -95 return FILTER; -96 } -97 -98 /** -99 * Launch bundle-audit. -100 * -101 * @param folder directory that contains bundle audit -102 * @return a handle to the process -103 * @throws AnalysisException thrown when there is an issue launching bundle -104 * audit -105 */ -106 private Process launchBundleAudit(File folder) throws AnalysisException { -107 if (!folder.isDirectory()) { -108 throw new AnalysisException(String.format("%s should have been a directory.", folder.getAbsolutePath())); -109 } -110 final List<String> args = new ArrayList<String>(); -111 final String bundleAuditPath = Settings.getString(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH); -112 args.add(null == bundleAuditPath ? "bundle-audit" : bundleAuditPath); -113 args.add("check"); -114 args.add("--verbose"); -115 final ProcessBuilder builder = new ProcessBuilder(args); -116 builder.directory(folder); -117 try { -118 LOGGER.info("Launching: " + args + " from " + folder); -119 return builder.start(); -120 } catch (IOException ioe) { -121 throw new AnalysisException("bundle-audit failure", ioe); -122 } -123 } -124 -125 /** -126 * Initialize the analyzer. In this case, extract GrokAssembly.exe to a -127 * temporary location. -128 * -129 * @throws Exception if anything goes wrong -130 */ -131 @Override -132 public void initializeFileTypeAnalyzer() throws Exception { -133 try { -134 cvedb = new CveDB(); -135 cvedb.open(); -136 } catch (DatabaseException ex) { -137 LOGGER.warn("Exception opening the database"); -138 LOGGER.debug("error", ex); -139 setEnabled(false); -140 throw ex; -141 } -142 // Now, need to see if bundle-audit actually runs from this location. -143 Process process = null; -144 try { -145 process = launchBundleAudit(Settings.getTempDirectory()); -146 } catch (AnalysisException ae) { -147 LOGGER.warn("Exception from bundle-audit process: {}. Disabling {}", ae.getCause(), ANALYZER_NAME); -148 setEnabled(false); -149 cvedb.close(); -150 cvedb = null; -151 throw ae; -152 } -153 -154 final int exitValue = process.waitFor(); -155 if (0 == exitValue) { -156 LOGGER.warn("Unexpected exit code from bundle-audit process. Disabling {}: {}", ANALYZER_NAME, exitValue); -157 setEnabled(false); -158 throw new AnalysisException("Unexpected exit code from bundle-audit process."); -159 } else { -160 BufferedReader reader = null; -161 try { -162 reader = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8")); -163 if (!reader.ready()) { -164 LOGGER.warn("Bundle-audit error stream unexpectedly not ready. Disabling " + ANALYZER_NAME); -165 setEnabled(false); -166 throw new AnalysisException("Bundle-audit error stream unexpectedly not ready."); -167 } else { -168 final String line = reader.readLine(); -169 if (line == null || !line.contains("Errno::ENOENT")) { -170 LOGGER.warn("Unexpected bundle-audit output. Disabling {}: {}", ANALYZER_NAME, line); -171 setEnabled(false); -172 throw new AnalysisException("Unexpected bundle-audit output."); -173 } -174 } -175 } finally { -176 if (null != reader) { -177 reader.close(); -178 } -179 } -180 } -181 -182 if (isEnabled()) { -183 LOGGER.info(ANALYZER_NAME + " is enabled. It is necessary to manually run \"bundle-audit update\" " -184 + "occasionally to keep its database up to date."); -185 } -186 } -187 -188 /** -189 * Returns the name of the analyzer. -190 * -191 * @return the name of the analyzer. -192 */ -193 @Override -194 public String getName() { -195 return ANALYZER_NAME; -196 } -197 -198 /** -199 * Returns the phase that the analyzer is intended to run in. -200 * -201 * @return the phase that the analyzer is intended to run in. -202 */ -203 @Override -204 public AnalysisPhase getAnalysisPhase() { -205 return ANALYSIS_PHASE; -206 } +93 private CveDB cvedb; +94 +95 /** +96 * @return a filter that accepts files named Gemfile.lock +97 */ +98 @Override +99 protected FileFilter getFileFilter() { +100 return FILTER; +101 } +102 +103 /** +104 * Launch bundle-audit. +105 * +106 * @param folder directory that contains bundle audit +107 * @return a handle to the process +108 * @throws AnalysisException thrown when there is an issue launching bundle +109 * audit +110 */ +111 private Process launchBundleAudit(File folder) throws AnalysisException { +112 if (!folder.isDirectory()) { +113 throw new AnalysisException(String.format("%s should have been a directory.", folder.getAbsolutePath())); +114 } +115 final List<String> args = new ArrayList<String>(); +116 final String bundleAuditPath = Settings.getString(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH); +117 args.add(null == bundleAuditPath ? "bundle-audit" : bundleAuditPath); +118 args.add("check"); +119 args.add("--verbose"); +120 final ProcessBuilder builder = new ProcessBuilder(args); +121 builder.directory(folder); +122 try { +123 LOGGER.info("Launching: " + args + " from " + folder); +124 return builder.start(); +125 } catch (IOException ioe) { +126 throw new AnalysisException("bundle-audit failure", ioe); +127 } +128 } +129 +130 /** +131 * Initialize the analyzer. In this case, extract GrokAssembly.exe to a +132 * temporary location. +133 * +134 * @throws InitializationException if anything goes wrong +135 */ +136 @Override +137 public void initializeFileTypeAnalyzer() throws InitializationException { +138 try { +139 cvedb = new CveDB(); +140 cvedb.open(); +141 } catch (DatabaseException ex) { +142 LOGGER.warn("Exception opening the database"); +143 LOGGER.debug("error", ex); +144 setEnabled(false); +145 throw new InitializationException("Error connecting to the database", ex); +146 } +147 // Now, need to see if bundle-audit actually runs from this location. +148 Process process = null; +149 try { +150 process = launchBundleAudit(Settings.getTempDirectory()); +151 } catch (AnalysisException ae) { +152 +153 setEnabled(false); +154 cvedb.close(); +155 cvedb = null; +156 final String msg = String.format("Exception from bundle-audit process: %s. Disabling %s", ae.getCause(), ANALYZER_NAME); +157 throw new InitializationException(msg, ae); +158 } catch (IOException ex) { +159 setEnabled(false); +160 throw new InitializationException("Unable to create temporary file, the Ruby Bundle Audit Analyzer will be disabled", ex); +161 } +162 +163 final int exitValue; +164 try { +165 exitValue = process.waitFor(); +166 } catch (InterruptedException ex) { +167 setEnabled(false); +168 final String msg = String.format("Bundle-audit process was interupted. Disabling %s", ANALYZER_NAME); +169 throw new InitializationException(msg); +170 } +171 if (0 == exitValue) { +172 setEnabled(false); +173 final String msg = String.format("Unexpected exit code from bundle-audit process. Disabling %s: %s", ANALYZER_NAME, exitValue); +174 throw new InitializationException(msg); +175 } else { +176 BufferedReader reader = null; +177 try { +178 reader = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8")); +179 if (!reader.ready()) { +180 LOGGER.warn("Bundle-audit error stream unexpectedly not ready. Disabling " + ANALYZER_NAME); +181 setEnabled(false); +182 throw new InitializationException("Bundle-audit error stream unexpectedly not ready."); +183 } else { +184 final String line = reader.readLine(); +185 if (line == null || !line.contains("Errno::ENOENT")) { +186 LOGGER.warn("Unexpected bundle-audit output. Disabling {}: {}", ANALYZER_NAME, line); +187 setEnabled(false); +188 throw new InitializationException("Unexpected bundle-audit output."); +189 } +190 } +191 } catch (UnsupportedEncodingException ex) { +192 setEnabled(false); +193 throw new InitializationException("Unexpected bundle-audit encoding.", ex); +194 } catch (IOException ex) { +195 setEnabled(false); +196 throw new InitializationException("Unable to read bundle-audit output.", ex); +197 } finally { +198 if (null != reader) { +199 try { +200 reader.close(); +201 } catch (IOException ex) { +202 LOGGER.debug("Error closing reader", ex); +203 } +204 } +205 } +206 } 207 -208 /** -209 * Returns the key used in the properties file to reference the analyzer's -210 * enabled property. -211 * -212 * @return the analyzer's enabled property setting key -213 */ -214 @Override -215 protected String getAnalyzerEnabledSettingKey() { -216 return Settings.KEYS.ANALYZER_BUNDLE_AUDIT_ENABLED; -217 } -218 -219 /** -220 * If {@link #analyzeFileType(Dependency, Engine)} is called, then we have -221 * successfully initialized, and it will be necessary to disable -222 * {@link RubyGemspecAnalyzer}. -223 */ -224 private boolean needToDisableGemspecAnalyzer = true; -225 -226 /** -227 * Determines if the analyzer can analyze the given file type. -228 * -229 * @param dependency the dependency to determine if it can analyze -230 * @param engine the dependency-check engine -231 * @throws AnalysisException thrown if there is an analysis exception. -232 */ -233 @Override -234 protected void analyzeFileType(Dependency dependency, Engine engine) -235 throws AnalysisException { -236 if (needToDisableGemspecAnalyzer) { -237 boolean failed = true; -238 final String className = RubyGemspecAnalyzer.class.getName(); -239 for (FileTypeAnalyzer analyzer : engine.getFileTypeAnalyzers()) { -240 if (analyzer instanceof RubyBundlerAnalyzer) { -241 ((RubyBundlerAnalyzer) analyzer).setEnabled(false); -242 LOGGER.info("Disabled " + RubyBundlerAnalyzer.class.getName() + " to avoid noisy duplicate results."); -243 } else if (analyzer instanceof RubyGemspecAnalyzer) { -244 ((RubyGemspecAnalyzer) analyzer).setEnabled(false); -245 LOGGER.info("Disabled " + className + " to avoid noisy duplicate results."); -246 failed = false; -247 } -248 } -249 if (failed) { -250 LOGGER.warn("Did not find " + className + '.'); -251 } -252 needToDisableGemspecAnalyzer = false; -253 } -254 final File parentFile = dependency.getActualFile().getParentFile(); -255 final Process process = launchBundleAudit(parentFile); -256 try { -257 process.waitFor(); -258 } catch (InterruptedException ie) { -259 throw new AnalysisException("bundle-audit process interrupted", ie); -260 } -261 BufferedReader rdr = null; -262 BufferedReader errReader = null; -263 try { -264 errReader = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8")); -265 while (errReader.ready()) { -266 final String error = errReader.readLine(); -267 LOGGER.warn(error); -268 } -269 rdr = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8")); -270 processBundlerAuditOutput(dependency, engine, rdr); -271 } catch (IOException ioe) { -272 LOGGER.warn("bundle-audit failure", ioe); -273 } finally { -274 if (errReader != null) { -275 try { -276 errReader.close(); -277 } catch (IOException ioe) { -278 LOGGER.warn("bundle-audit close failure", ioe); -279 } -280 } -281 if (null != rdr) { -282 try { -283 rdr.close(); -284 } catch (IOException ioe) { -285 LOGGER.warn("bundle-audit close failure", ioe); -286 } -287 } -288 } -289 -290 } -291 -292 /** -293 * Processes the bundler audit output. -294 * -295 * @param original the dependency -296 * @param engine the dependency-check engine -297 * @param rdr the reader of the report -298 * @throws IOException thrown if the report cannot be read. -299 */ -300 private void processBundlerAuditOutput(Dependency original, Engine engine, BufferedReader rdr) throws IOException { -301 final String parentName = original.getActualFile().getParentFile().getName(); -302 final String fileName = original.getFileName(); -303 final String filePath = original.getFilePath(); -304 Dependency dependency = null; -305 Vulnerability vulnerability = null; -306 String gem = null; -307 final Map<String, Dependency> map = new HashMap<String, Dependency>(); -308 boolean appendToDescription = false; -309 while (rdr.ready()) { -310 final String nextLine = rdr.readLine(); -311 if (null == nextLine) { -312 break; -313 } else if (nextLine.startsWith(NAME)) { -314 appendToDescription = false; -315 gem = nextLine.substring(NAME.length()); -316 if (!map.containsKey(gem)) { -317 map.put(gem, createDependencyForGem(engine, parentName, fileName, filePath, gem)); -318 } -319 dependency = map.get(gem); -320 LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); -321 } else if (nextLine.startsWith(VERSION)) { -322 vulnerability = createVulnerability(parentName, dependency, gem, nextLine); -323 } else if (nextLine.startsWith(ADVISORY)) { -324 setVulnerabilityName(parentName, dependency, vulnerability, nextLine); -325 } else if (nextLine.startsWith(CRITICALITY)) { -326 addCriticalityToVulnerability(parentName, vulnerability, nextLine); -327 } else if (nextLine.startsWith("URL: ")) { -328 addReferenceToVulnerability(parentName, vulnerability, nextLine); -329 } else if (nextLine.startsWith("Description:")) { -330 appendToDescription = true; -331 if (null != vulnerability) { -332 vulnerability.setDescription("*** Vulnerability obtained from bundle-audit verbose report. " -333 + "Title link may not work. CPE below is guessed. CVSS score is estimated (-1.0 " -334 + " indicates unknown). See link below for full details. *** "); -335 } -336 } else if (appendToDescription) { -337 if (null != vulnerability) { -338 vulnerability.setDescription(vulnerability.getDescription() + nextLine + "\n"); -339 } -340 } -341 } -342 } -343 -344 /** -345 * Sets the vulnerability name. -346 * -347 * @param parentName the parent name -348 * @param dependency the dependency -349 * @param vulnerability the vulnerability -350 * @param nextLine the line to parse -351 */ -352 private void setVulnerabilityName(String parentName, Dependency dependency, Vulnerability vulnerability, String nextLine) { -353 final String advisory = nextLine.substring((ADVISORY.length())); -354 if (null != vulnerability) { -355 vulnerability.setName(advisory); -356 } -357 if (null != dependency) { -358 dependency.getVulnerabilities().add(vulnerability); // needed to wait for vulnerability name to avoid NPE -359 } -360 LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); -361 } -362 -363 /** -364 * Adds a reference to the vulnerability. -365 * -366 * @param parentName the parent name -367 * @param vulnerability the vulnerability -368 * @param nextLine the line to parse -369 */ -370 private void addReferenceToVulnerability(String parentName, Vulnerability vulnerability, String nextLine) { -371 final String url = nextLine.substring(("URL: ").length()); -372 if (null != vulnerability) { -373 final Reference ref = new Reference(); -374 ref.setName(vulnerability.getName()); -375 ref.setSource("bundle-audit"); -376 ref.setUrl(url); -377 vulnerability.getReferences().add(ref); -378 } -379 LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); -380 } -381 -382 /** -383 * Adds the criticality to the vulnerability -384 * -385 * @param parentName the parent name -386 * @param vulnerability the vulnerability -387 * @param nextLine the line to parse -388 */ -389 private void addCriticalityToVulnerability(String parentName, Vulnerability vulnerability, String nextLine) { -390 if (null != vulnerability) { -391 final String criticality = nextLine.substring(CRITICALITY.length()).trim(); -392 float score = -1.0f; -393 Vulnerability v = null; -394 try { -395 v = cvedb.getVulnerability(vulnerability.getName()); -396 } catch (DatabaseException ex) { -397 LOGGER.debug("Unable to look up vulnerability {}", vulnerability.getName()); -398 } -399 if (v != null) { -400 score = v.getCvssScore(); -401 } else if ("High".equalsIgnoreCase(criticality)) { -402 score = 8.5f; -403 } else if ("Medium".equalsIgnoreCase(criticality)) { -404 score = 5.5f; -405 } else if ("Low".equalsIgnoreCase(criticality)) { -406 score = 2.0f; -407 } -408 vulnerability.setCvssScore(score); -409 } -410 LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); -411 } -412 -413 /** -414 * Creates a vulnerability. -415 * -416 * @param parentName the parent name -417 * @param dependency the dependency -418 * @param gem the gem name -419 * @param nextLine the line to parse -420 * @return the vulnerability -421 */ -422 private Vulnerability createVulnerability(String parentName, Dependency dependency, String gem, String nextLine) { -423 Vulnerability vulnerability = null; -424 if (null != dependency) { -425 final String version = nextLine.substring(VERSION.length()); -426 dependency.getVersionEvidence().addEvidence( -427 "bundler-audit", -428 "Version", -429 version, -430 Confidence.HIGHEST); -431 vulnerability = new Vulnerability(); // don't add to dependency until we have name set later -432 vulnerability.setMatchedCPE( -433 String.format("cpe:/a:%1$s_project:%1$s:%2$s::~~~ruby~~", gem, version), -434 null); -435 vulnerability.setCvssAccessVector("-"); -436 vulnerability.setCvssAccessComplexity("-"); -437 vulnerability.setCvssAuthentication("-"); -438 vulnerability.setCvssAvailabilityImpact("-"); -439 vulnerability.setCvssConfidentialityImpact("-"); -440 vulnerability.setCvssIntegrityImpact("-"); -441 } -442 LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); -443 return vulnerability; -444 } -445 -446 /** -447 * Creates the dependency based off of the gem. -448 * -449 * @param engine the engine used for scanning -450 * @param parentName the gem parent -451 * @param fileName the file name -452 * @param filePath the file path -453 * @param gem the gem name -454 * @return the dependency to add -455 * @throws IOException thrown if a temporary gem file could not be written -456 */ -457 private Dependency createDependencyForGem(Engine engine, String parentName, String fileName, String filePath, String gem) throws IOException { -458 final File gemFile = new File(Settings.getTempDirectory(), gem + "_Gemfile.lock"); -459 gemFile.createNewFile(); -460 final String displayFileName = String.format("%s%c%s:%s", parentName, File.separatorChar, fileName, gem); -461 -462 FileUtils.write(gemFile, displayFileName, Charset.defaultCharset()); // unique contents to avoid dependency bundling -463 final Dependency dependency = new Dependency(gemFile); -464 dependency.getProductEvidence().addEvidence("bundler-audit", "Name", gem, Confidence.HIGHEST); -465 dependency.setDisplayFileName(displayFileName); -466 dependency.setFileName(fileName); -467 dependency.setFilePath(filePath); -468 engine.getDependencies().add(dependency); -469 return dependency; +208 if (isEnabled()) { +209 LOGGER.info(ANALYZER_NAME + " is enabled. It is necessary to manually run \"bundle-audit update\" " +210 + "occasionally to keep its database up to date."); +211 } +212 } +213 +214 /** +215 * Returns the name of the analyzer. +216 * +217 * @return the name of the analyzer. +218 */ +219 @Override +220 public String getName() { +221 return ANALYZER_NAME; +222 } +223 +224 /** +225 * Returns the phase that the analyzer is intended to run in. +226 * +227 * @return the phase that the analyzer is intended to run in. +228 */ +229 @Override +230 public AnalysisPhase getAnalysisPhase() { +231 return ANALYSIS_PHASE; +232 } +233 +234 /** +235 * Returns the key used in the properties file to reference the analyzer's +236 * enabled property. +237 * +238 * @return the analyzer's enabled property setting key +239 */ +240 @Override +241 protected String getAnalyzerEnabledSettingKey() { +242 return Settings.KEYS.ANALYZER_BUNDLE_AUDIT_ENABLED; +243 } +244 +245 /** +246 * If {@link #analyzeFileType(Dependency, Engine)} is called, then we have +247 * successfully initialized, and it will be necessary to disable +248 * {@link RubyGemspecAnalyzer}. +249 */ +250 private boolean needToDisableGemspecAnalyzer = true; +251 +252 /** +253 * Determines if the analyzer can analyze the given file type. +254 * +255 * @param dependency the dependency to determine if it can analyze +256 * @param engine the dependency-check engine +257 * @throws AnalysisException thrown if there is an analysis exception. +258 */ +259 @Override +260 protected void analyzeFileType(Dependency dependency, Engine engine) +261 throws AnalysisException { +262 if (needToDisableGemspecAnalyzer) { +263 boolean failed = true; +264 final String className = RubyGemspecAnalyzer.class.getName(); +265 for (FileTypeAnalyzer analyzer : engine.getFileTypeAnalyzers()) { +266 if (analyzer instanceof RubyBundlerAnalyzer) { +267 ((RubyBundlerAnalyzer) analyzer).setEnabled(false); +268 LOGGER.info("Disabled " + RubyBundlerAnalyzer.class.getName() + " to avoid noisy duplicate results."); +269 } else if (analyzer instanceof RubyGemspecAnalyzer) { +270 ((RubyGemspecAnalyzer) analyzer).setEnabled(false); +271 LOGGER.info("Disabled " + className + " to avoid noisy duplicate results."); +272 failed = false; +273 } +274 } +275 if (failed) { +276 LOGGER.warn("Did not find " + className + '.'); +277 } +278 needToDisableGemspecAnalyzer = false; +279 } +280 final File parentFile = dependency.getActualFile().getParentFile(); +281 final Process process = launchBundleAudit(parentFile); +282 try { +283 process.waitFor(); +284 } catch (InterruptedException ie) { +285 throw new AnalysisException("bundle-audit process interrupted", ie); +286 } +287 BufferedReader rdr = null; +288 BufferedReader errReader = null; +289 try { +290 errReader = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8")); +291 while (errReader.ready()) { +292 final String error = errReader.readLine(); +293 LOGGER.warn(error); +294 } +295 rdr = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8")); +296 processBundlerAuditOutput(dependency, engine, rdr); +297 } catch (IOException ioe) { +298 LOGGER.warn("bundle-audit failure", ioe); +299 } finally { +300 if (errReader != null) { +301 try { +302 errReader.close(); +303 } catch (IOException ioe) { +304 LOGGER.warn("bundle-audit close failure", ioe); +305 } +306 } +307 if (null != rdr) { +308 try { +309 rdr.close(); +310 } catch (IOException ioe) { +311 LOGGER.warn("bundle-audit close failure", ioe); +312 } +313 } +314 } +315 +316 } +317 +318 /** +319 * Processes the bundler audit output. +320 * +321 * @param original the dependency +322 * @param engine the dependency-check engine +323 * @param rdr the reader of the report +324 * @throws IOException thrown if the report cannot be read. +325 */ +326 private void processBundlerAuditOutput(Dependency original, Engine engine, BufferedReader rdr) throws IOException { +327 final String parentName = original.getActualFile().getParentFile().getName(); +328 final String fileName = original.getFileName(); +329 final String filePath = original.getFilePath(); +330 Dependency dependency = null; +331 Vulnerability vulnerability = null; +332 String gem = null; +333 final Map<String, Dependency> map = new HashMap<String, Dependency>(); +334 boolean appendToDescription = false; +335 while (rdr.ready()) { +336 final String nextLine = rdr.readLine(); +337 if (null == nextLine) { +338 break; +339 } else if (nextLine.startsWith(NAME)) { +340 appendToDescription = false; +341 gem = nextLine.substring(NAME.length()); +342 if (!map.containsKey(gem)) { +343 map.put(gem, createDependencyForGem(engine, parentName, fileName, filePath, gem)); +344 } +345 dependency = map.get(gem); +346 LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); +347 } else if (nextLine.startsWith(VERSION)) { +348 vulnerability = createVulnerability(parentName, dependency, gem, nextLine); +349 } else if (nextLine.startsWith(ADVISORY)) { +350 setVulnerabilityName(parentName, dependency, vulnerability, nextLine); +351 } else if (nextLine.startsWith(CRITICALITY)) { +352 addCriticalityToVulnerability(parentName, vulnerability, nextLine); +353 } else if (nextLine.startsWith("URL: ")) { +354 addReferenceToVulnerability(parentName, vulnerability, nextLine); +355 } else if (nextLine.startsWith("Description:")) { +356 appendToDescription = true; +357 if (null != vulnerability) { +358 vulnerability.setDescription("*** Vulnerability obtained from bundle-audit verbose report. " +359 + "Title link may not work. CPE below is guessed. CVSS score is estimated (-1.0 " +360 + " indicates unknown). See link below for full details. *** "); +361 } +362 } else if (appendToDescription) { +363 if (null != vulnerability) { +364 vulnerability.setDescription(vulnerability.getDescription() + nextLine + "\n"); +365 } +366 } +367 } +368 } +369 +370 /** +371 * Sets the vulnerability name. +372 * +373 * @param parentName the parent name +374 * @param dependency the dependency +375 * @param vulnerability the vulnerability +376 * @param nextLine the line to parse +377 */ +378 private void setVulnerabilityName(String parentName, Dependency dependency, Vulnerability vulnerability, String nextLine) { +379 final String advisory = nextLine.substring((ADVISORY.length())); +380 if (null != vulnerability) { +381 vulnerability.setName(advisory); +382 } +383 if (null != dependency) { +384 dependency.getVulnerabilities().add(vulnerability); // needed to wait for vulnerability name to avoid NPE +385 } +386 LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); +387 } +388 +389 /** +390 * Adds a reference to the vulnerability. +391 * +392 * @param parentName the parent name +393 * @param vulnerability the vulnerability +394 * @param nextLine the line to parse +395 */ +396 private void addReferenceToVulnerability(String parentName, Vulnerability vulnerability, String nextLine) { +397 final String url = nextLine.substring(("URL: ").length()); +398 if (null != vulnerability) { +399 final Reference ref = new Reference(); +400 ref.setName(vulnerability.getName()); +401 ref.setSource("bundle-audit"); +402 ref.setUrl(url); +403 vulnerability.getReferences().add(ref); +404 } +405 LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); +406 } +407 +408 /** +409 * Adds the criticality to the vulnerability +410 * +411 * @param parentName the parent name +412 * @param vulnerability the vulnerability +413 * @param nextLine the line to parse +414 */ +415 private void addCriticalityToVulnerability(String parentName, Vulnerability vulnerability, String nextLine) { +416 if (null != vulnerability) { +417 final String criticality = nextLine.substring(CRITICALITY.length()).trim(); +418 float score = -1.0f; +419 Vulnerability v = null; +420 try { +421 v = cvedb.getVulnerability(vulnerability.getName()); +422 } catch (DatabaseException ex) { +423 LOGGER.debug("Unable to look up vulnerability {}", vulnerability.getName()); +424 } +425 if (v != null) { +426 score = v.getCvssScore(); +427 } else if ("High".equalsIgnoreCase(criticality)) { +428 score = 8.5f; +429 } else if ("Medium".equalsIgnoreCase(criticality)) { +430 score = 5.5f; +431 } else if ("Low".equalsIgnoreCase(criticality)) { +432 score = 2.0f; +433 } +434 vulnerability.setCvssScore(score); +435 } +436 LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); +437 } +438 +439 /** +440 * Creates a vulnerability. +441 * +442 * @param parentName the parent name +443 * @param dependency the dependency +444 * @param gem the gem name +445 * @param nextLine the line to parse +446 * @return the vulnerability +447 */ +448 private Vulnerability createVulnerability(String parentName, Dependency dependency, String gem, String nextLine) { +449 Vulnerability vulnerability = null; +450 if (null != dependency) { +451 final String version = nextLine.substring(VERSION.length()); +452 dependency.getVersionEvidence().addEvidence( +453 "bundler-audit", +454 "Version", +455 version, +456 Confidence.HIGHEST); +457 vulnerability = new Vulnerability(); // don't add to dependency until we have name set later +458 vulnerability.setMatchedCPE( +459 String.format("cpe:/a:%1$s_project:%1$s:%2$s::~~~ruby~~", gem, version), +460 null); +461 vulnerability.setCvssAccessVector("-"); +462 vulnerability.setCvssAccessComplexity("-"); +463 vulnerability.setCvssAuthentication("-"); +464 vulnerability.setCvssAvailabilityImpact("-"); +465 vulnerability.setCvssConfidentialityImpact("-"); +466 vulnerability.setCvssIntegrityImpact("-"); +467 } +468 LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); +469 return vulnerability; 470 } -471 } +471 +472 /** +473 * Creates the dependency based off of the gem. +474 * +475 * @param engine the engine used for scanning +476 * @param parentName the gem parent +477 * @param fileName the file name +478 * @param filePath the file path +479 * @param gem the gem name +480 * @return the dependency to add +481 * @throws IOException thrown if a temporary gem file could not be written +482 */ +483 private Dependency createDependencyForGem(Engine engine, String parentName, String fileName, String filePath, String gem) throws IOException { +484 final File gemFile = new File(Settings.getTempDirectory(), gem + "_Gemfile.lock"); +485 gemFile.createNewFile(); +486 final String displayFileName = String.format("%s%c%s:%s", parentName, File.separatorChar, fileName, gem); +487 +488 FileUtils.write(gemFile, displayFileName, Charset.defaultCharset()); // unique contents to avoid dependency bundling +489 final Dependency dependency = new Dependency(gemFile); +490 dependency.getProductEvidence().addEvidence("bundler-audit", "Name", gem, Confidence.HIGHEST); +491 dependency.setDisplayFileName(displayFileName); +492 dependency.setFileName(fileName); +493 dependency.setFilePath(filePath); +494 engine.getDependencies().add(dependency); +495 return dependency; +496 } +497 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/RubyBundlerAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/RubyBundlerAnalyzer.html index 127f09633..b461d876a 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/RubyBundlerAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/RubyBundlerAnalyzer.html @@ -116,35 +116,36 @@ 108 final File gemsDir = new File(parentDir, GEMS); 109 if (gemsDir.exists()) { 110 final File[] matchingFiles = gemsDir.listFiles(new FilenameFilter() { -111 public boolean accept(File dir, String name) { -112 return name.equals(gemName); -113 } -114 }); -115 -116 if (matchingFiles != null && matchingFiles.length > 0) { -117 final String gemPath = matchingFiles[0].getAbsolutePath(); -118 if (dependency.getActualFilePath().equals(dependency.getFilePath())) { -119 if (gemPath != null) { -120 dependency.setPackagePath(gemPath); -121 } -122 } else { -123 //.gemspec's actualFilePath and filePath are different when it's from a compressed file -124 //in which case actualFilePath is the temp directory used by decompression. -125 //packagePath should use the filePath of the identified gem file in "gems" folder -126 final File gemspecStub = new File(dependency.getFilePath()); -127 final File specDir = gemspecStub.getParentFile(); -128 if (specDir != null && specDir.getName().equals(SPECIFICATIONS)) { -129 final File gemsDir2 = new File(specDir.getParentFile(), GEMS); -130 final File packageDir = new File(gemsDir2, gemName); -131 dependency.setPackagePath(packageDir.getAbsolutePath()); -132 } -133 } -134 } -135 } -136 } -137 } -138 } -139 } +111 @Override +112 public boolean accept(File dir, String name) { +113 return name.equals(gemName); +114 } +115 }); +116 +117 if (matchingFiles != null && matchingFiles.length > 0) { +118 final String gemPath = matchingFiles[0].getAbsolutePath(); +119 if (dependency.getActualFilePath().equals(dependency.getFilePath())) { +120 if (gemPath != null) { +121 dependency.setPackagePath(gemPath); +122 } +123 } else { +124 //.gemspec's actualFilePath and filePath are different when it's from a compressed file +125 //in which case actualFilePath is the temp directory used by decompression. +126 //packagePath should use the filePath of the identified gem file in "gems" folder +127 final File gemspecStub = new File(dependency.getFilePath()); +128 final File specDir = gemspecStub.getParentFile(); +129 if (specDir != null && specDir.getName().equals(SPECIFICATIONS)) { +130 final File gemsDir2 = new File(specDir.getParentFile(), GEMS); +131 final File packageDir = new File(gemsDir2, gemName); +132 dependency.setPackagePath(packageDir.getAbsolutePath()); +133 } +134 } +135 } +136 } +137 } +138 } +139 } +140 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.html index df6c70dd1..c6a328761 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.html @@ -40,216 +40,218 @@ 32 import org.owasp.dependencycheck.dependency.Confidence; 33 import org.owasp.dependencycheck.dependency.Dependency; 34 import org.owasp.dependencycheck.dependency.EvidenceCollection; -35 import org.owasp.dependencycheck.utils.FileFilterBuilder; -36 import org.owasp.dependencycheck.utils.Settings; -37 import org.slf4j.Logger; -38 import org.slf4j.LoggerFactory; -39 -40 /** -41 * Used to analyze Ruby Gem specifications and collect information that can be -42 * used to determine the associated CPE. Regular expressions are used to parse -43 * the well-defined Ruby syntax that forms the specification. -44 * -45 * @author Dale Visser -46 */ -47 @Experimental -48 public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer { -49 -50 /** -51 * The logger. -52 */ -53 private static final Logger LOGGER = LoggerFactory.getLogger(RubyGemspecAnalyzer.class); -54 /** -55 * The name of the analyzer. -56 */ -57 private static final String ANALYZER_NAME = "Ruby Gemspec Analyzer"; -58 -59 /** -60 * The phase that this analyzer is intended to run in. -61 */ -62 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; -63 -64 /** -65 * The gemspec file extension. -66 */ -67 private static final String GEMSPEC = "gemspec"; -68 -69 /** -70 * The file filter containing the list of file extensions that can be -71 * analyzed. -72 */ -73 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(GEMSPEC).build(); -74 //TODO: support Rakefile -75 //= FileFilterBuilder.newInstance().addExtensions(GEMSPEC).addFilenames("Rakefile").build(); -76 -77 /** -78 * The name of the version file. -79 */ -80 private static final String VERSION_FILE_NAME = "VERSION"; -81 -82 /** -83 * @return a filter that accepts files matching the glob pattern, *.gemspec -84 */ -85 @Override -86 protected FileFilter getFileFilter() { -87 return FILTER; -88 } -89 -90 @Override -91 protected void initializeFileTypeAnalyzer() throws Exception { -92 // NO-OP -93 } -94 -95 /** -96 * Returns the name of the analyzer. -97 * -98 * @return the name of the analyzer. -99 */ -100 @Override -101 public String getName() { -102 return ANALYZER_NAME; -103 } -104 -105 /** -106 * Returns the phase that the analyzer is intended to run in. -107 * -108 * @return the phase that the analyzer is intended to run in. -109 */ -110 @Override -111 public AnalysisPhase getAnalysisPhase() { -112 return ANALYSIS_PHASE; -113 } -114 -115 /** -116 * Returns the key used in the properties file to reference the analyzer's -117 * enabled property. -118 * -119 * @return the analyzer's enabled property setting key -120 */ -121 @Override -122 protected String getAnalyzerEnabledSettingKey() { -123 return Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED; -124 } -125 -126 /** -127 * The capture group #1 is the block variable. -128 */ -129 private static final Pattern GEMSPEC_BLOCK_INIT = Pattern.compile("Gem::Specification\\.new\\s+?do\\s+?\\|(.+?)\\|"); -130 -131 @Override -132 protected void analyzeFileType(Dependency dependency, Engine engine) -133 throws AnalysisException { -134 String contents; -135 try { -136 contents = FileUtils.readFileToString(dependency.getActualFile(), Charset.defaultCharset()); -137 } catch (IOException e) { -138 throw new AnalysisException( -139 "Problem occurred while reading dependency file.", e); -140 } -141 final Matcher matcher = GEMSPEC_BLOCK_INIT.matcher(contents); -142 if (matcher.find()) { -143 contents = contents.substring(matcher.end()); -144 final String blockVariable = matcher.group(1); -145 -146 final EvidenceCollection vendor = dependency.getVendorEvidence(); -147 final EvidenceCollection product = dependency.getProductEvidence(); -148 final String name = addStringEvidence(product, contents, blockVariable, "name", "name", Confidence.HIGHEST); -149 if (!name.isEmpty()) { -150 vendor.addEvidence(GEMSPEC, "name_project", name + "_project", Confidence.LOW); -151 } -152 addStringEvidence(product, contents, blockVariable, "summary", "summary", Confidence.LOW); -153 -154 addStringEvidence(vendor, contents, blockVariable, "author", "authors?", Confidence.HIGHEST); -155 addStringEvidence(vendor, contents, blockVariable, "email", "emails?", Confidence.MEDIUM); -156 addStringEvidence(vendor, contents, blockVariable, "homepage", "homepage", Confidence.HIGHEST); -157 addStringEvidence(vendor, contents, blockVariable, "license", "licen[cs]es?", Confidence.HIGHEST); -158 -159 final String value = addStringEvidence(dependency.getVersionEvidence(), contents, -160 blockVariable, "version", "version", Confidence.HIGHEST); -161 if (value.length() < 1) { -162 addEvidenceFromVersionFile(dependency.getActualFile(), dependency.getVersionEvidence()); -163 } -164 } -165 -166 setPackagePath(dependency); -167 } -168 -169 /** -170 * Adds the specified evidence to the given evidence collection. -171 * -172 * @param evidences the collection to add the evidence to -173 * @param contents the evidence contents -174 * @param blockVariable the variable -175 * @param field the field -176 * @param fieldPattern the field pattern -177 * @param confidence the confidence of the evidence -178 * @return the evidence string value added -179 */ -180 private String addStringEvidence(EvidenceCollection evidences, String contents, -181 String blockVariable, String field, String fieldPattern, Confidence confidence) { -182 String value = ""; -183 -184 //capture array value between [ ] -185 final Matcher arrayMatcher = Pattern.compile( -186 String.format("\\s*?%s\\.%s\\s*?=\\s*?\\[(.*?)\\]", blockVariable, fieldPattern), Pattern.CASE_INSENSITIVE).matcher(contents); -187 if (arrayMatcher.find()) { -188 final String arrayValue = arrayMatcher.group(1); -189 value = arrayValue.replaceAll("['\"]", "").trim(); //strip quotes -190 } else { //capture single value between quotes -191 final Matcher matcher = Pattern.compile( -192 String.format("\\s*?%s\\.%s\\s*?=\\s*?(['\"])(.*?)\\1", blockVariable, fieldPattern), Pattern.CASE_INSENSITIVE).matcher(contents); -193 if (matcher.find()) { -194 value = matcher.group(2); -195 } -196 } -197 if (value.length() > 0) { -198 evidences.addEvidence(GEMSPEC, field, value, confidence); -199 } -200 -201 return value; -202 } -203 -204 /** -205 * Adds evidence from the version file. -206 * -207 * @param dependencyFile the dependency being analyzed -208 * @param versionEvidences the version evidence -209 */ -210 private void addEvidenceFromVersionFile(File dependencyFile, EvidenceCollection versionEvidences) { -211 final File parentDir = dependencyFile.getParentFile(); -212 if (parentDir != null) { -213 final File[] matchingFiles = parentDir.listFiles(new FilenameFilter() { -214 public boolean accept(File dir, String name) { -215 return name.contains(VERSION_FILE_NAME); -216 } -217 }); -218 for (File f : matchingFiles) { -219 try { -220 final List<String> lines = FileUtils.readLines(f, Charset.defaultCharset()); -221 if (lines.size() == 1) { //TODO other checking? -222 final String value = lines.get(0).trim(); -223 versionEvidences.addEvidence(GEMSPEC, "version", value, Confidence.HIGH); -224 } -225 } catch (IOException e) { -226 LOGGER.debug("Error reading gemspec", e); -227 } -228 } -229 } -230 } -231 -232 /** -233 * Sets the package path on the dependency. -234 * -235 * @param dep the dependency to alter -236 */ -237 private void setPackagePath(Dependency dep) { -238 final File file = new File(dep.getFilePath()); -239 final String parent = file.getParent(); -240 if (parent != null) { -241 dep.setPackagePath(parent); -242 } -243 } -244 } +35 import org.owasp.dependencycheck.exception.InitializationException; +36 import org.owasp.dependencycheck.utils.FileFilterBuilder; +37 import org.owasp.dependencycheck.utils.Settings; +38 import org.slf4j.Logger; +39 import org.slf4j.LoggerFactory; +40 +41 /** +42 * Used to analyze Ruby Gem specifications and collect information that can be +43 * used to determine the associated CPE. Regular expressions are used to parse +44 * the well-defined Ruby syntax that forms the specification. +45 * +46 * @author Dale Visser +47 */ +48 @Experimental +49 public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer { +50 +51 /** +52 * The logger. +53 */ +54 private static final Logger LOGGER = LoggerFactory.getLogger(RubyGemspecAnalyzer.class); +55 /** +56 * The name of the analyzer. +57 */ +58 private static final String ANALYZER_NAME = "Ruby Gemspec Analyzer"; +59 +60 /** +61 * The phase that this analyzer is intended to run in. +62 */ +63 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; +64 +65 /** +66 * The gemspec file extension. +67 */ +68 private static final String GEMSPEC = "gemspec"; +69 +70 /** +71 * The file filter containing the list of file extensions that can be +72 * analyzed. +73 */ +74 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(GEMSPEC).build(); +75 //TODO: support Rakefile +76 //= FileFilterBuilder.newInstance().addExtensions(GEMSPEC).addFilenames("Rakefile").build(); +77 +78 /** +79 * The name of the version file. +80 */ +81 private static final String VERSION_FILE_NAME = "VERSION"; +82 +83 /** +84 * @return a filter that accepts files matching the glob pattern, *.gemspec +85 */ +86 @Override +87 protected FileFilter getFileFilter() { +88 return FILTER; +89 } +90 +91 @Override +92 protected void initializeFileTypeAnalyzer() throws InitializationException { +93 // NO-OP +94 } +95 +96 /** +97 * Returns the name of the analyzer. +98 * +99 * @return the name of the analyzer. +100 */ +101 @Override +102 public String getName() { +103 return ANALYZER_NAME; +104 } +105 +106 /** +107 * Returns the phase that the analyzer is intended to run in. +108 * +109 * @return the phase that the analyzer is intended to run in. +110 */ +111 @Override +112 public AnalysisPhase getAnalysisPhase() { +113 return ANALYSIS_PHASE; +114 } +115 +116 /** +117 * Returns the key used in the properties file to reference the analyzer's +118 * enabled property. +119 * +120 * @return the analyzer's enabled property setting key +121 */ +122 @Override +123 protected String getAnalyzerEnabledSettingKey() { +124 return Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED; +125 } +126 +127 /** +128 * The capture group #1 is the block variable. +129 */ +130 private static final Pattern GEMSPEC_BLOCK_INIT = Pattern.compile("Gem::Specification\\.new\\s+?do\\s+?\\|(.+?)\\|"); +131 +132 @Override +133 protected void analyzeFileType(Dependency dependency, Engine engine) +134 throws AnalysisException { +135 String contents; +136 try { +137 contents = FileUtils.readFileToString(dependency.getActualFile(), Charset.defaultCharset()); +138 } catch (IOException e) { +139 throw new AnalysisException( +140 "Problem occurred while reading dependency file.", e); +141 } +142 final Matcher matcher = GEMSPEC_BLOCK_INIT.matcher(contents); +143 if (matcher.find()) { +144 contents = contents.substring(matcher.end()); +145 final String blockVariable = matcher.group(1); +146 +147 final EvidenceCollection vendor = dependency.getVendorEvidence(); +148 final EvidenceCollection product = dependency.getProductEvidence(); +149 final String name = addStringEvidence(product, contents, blockVariable, "name", "name", Confidence.HIGHEST); +150 if (!name.isEmpty()) { +151 vendor.addEvidence(GEMSPEC, "name_project", name + "_project", Confidence.LOW); +152 } +153 addStringEvidence(product, contents, blockVariable, "summary", "summary", Confidence.LOW); +154 +155 addStringEvidence(vendor, contents, blockVariable, "author", "authors?", Confidence.HIGHEST); +156 addStringEvidence(vendor, contents, blockVariable, "email", "emails?", Confidence.MEDIUM); +157 addStringEvidence(vendor, contents, blockVariable, "homepage", "homepage", Confidence.HIGHEST); +158 addStringEvidence(vendor, contents, blockVariable, "license", "licen[cs]es?", Confidence.HIGHEST); +159 +160 final String value = addStringEvidence(dependency.getVersionEvidence(), contents, +161 blockVariable, "version", "version", Confidence.HIGHEST); +162 if (value.length() < 1) { +163 addEvidenceFromVersionFile(dependency.getActualFile(), dependency.getVersionEvidence()); +164 } +165 } +166 +167 setPackagePath(dependency); +168 } +169 +170 /** +171 * Adds the specified evidence to the given evidence collection. +172 * +173 * @param evidences the collection to add the evidence to +174 * @param contents the evidence contents +175 * @param blockVariable the variable +176 * @param field the field +177 * @param fieldPattern the field pattern +178 * @param confidence the confidence of the evidence +179 * @return the evidence string value added +180 */ +181 private String addStringEvidence(EvidenceCollection evidences, String contents, +182 String blockVariable, String field, String fieldPattern, Confidence confidence) { +183 String value = ""; +184 +185 //capture array value between [ ] +186 final Matcher arrayMatcher = Pattern.compile( +187 String.format("\\s*?%s\\.%s\\s*?=\\s*?\\[(.*?)\\]", blockVariable, fieldPattern), Pattern.CASE_INSENSITIVE).matcher(contents); +188 if (arrayMatcher.find()) { +189 final String arrayValue = arrayMatcher.group(1); +190 value = arrayValue.replaceAll("['\"]", "").trim(); //strip quotes +191 } else { //capture single value between quotes +192 final Matcher matcher = Pattern.compile( +193 String.format("\\s*?%s\\.%s\\s*?=\\s*?(['\"])(.*?)\\1", blockVariable, fieldPattern), Pattern.CASE_INSENSITIVE).matcher(contents); +194 if (matcher.find()) { +195 value = matcher.group(2); +196 } +197 } +198 if (value.length() > 0) { +199 evidences.addEvidence(GEMSPEC, field, value, confidence); +200 } +201 +202 return value; +203 } +204 +205 /** +206 * Adds evidence from the version file. +207 * +208 * @param dependencyFile the dependency being analyzed +209 * @param versionEvidences the version evidence +210 */ +211 private void addEvidenceFromVersionFile(File dependencyFile, EvidenceCollection versionEvidences) { +212 final File parentDir = dependencyFile.getParentFile(); +213 if (parentDir != null) { +214 final File[] matchingFiles = parentDir.listFiles(new FilenameFilter() { +215 @Override +216 public boolean accept(File dir, String name) { +217 return name.contains(VERSION_FILE_NAME); +218 } +219 }); +220 for (File f : matchingFiles) { +221 try { +222 final List<String> lines = FileUtils.readLines(f, Charset.defaultCharset()); +223 if (lines.size() == 1) { //TODO other checking? +224 final String value = lines.get(0).trim(); +225 versionEvidences.addEvidence(GEMSPEC, "version", value, Confidence.HIGH); +226 } +227 } catch (IOException e) { +228 LOGGER.debug("Error reading gemspec", e); +229 } +230 } +231 } +232 } +233 +234 /** +235 * Sets the package path on the dependency. +236 * +237 * @param dep the dependency to alter +238 */ +239 private void setPackagePath(Dependency dep) { +240 final File file = new File(dep.getFilePath()); +241 final String parent = file.getParent(); +242 if (parent != null) { +243 dep.setPackagePath(parent); +244 } +245 } +246 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/VulnerabilitySuppressionAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/VulnerabilitySuppressionAnalyzer.html index 6ff5fddac..81854a4f9 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/VulnerabilitySuppressionAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/VulnerabilitySuppressionAnalyzer.html @@ -28,7 +28,7 @@ 20 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; 21 import org.owasp.dependencycheck.Engine; 22 import org.owasp.dependencycheck.dependency.Dependency; -23 import org.owasp.dependencycheck.suppression.SuppressionRule; +23 import org.owasp.dependencycheck.xml.suppression.SuppressionRule; 24 25 /** 26 * The suppression analyzer processes an externally defined XML document that complies with the suppressions.xsd schema. diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/exception/package-frame.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/exception/package-frame.html index 0ef1c1648..0974bb6db 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/exception/package-frame.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/exception/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.analyzer.exception + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.analyzer.exception diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/exception/package-summary.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/exception/package-summary.html index 6a647307f..260e8b673 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/exception/package-summary.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/exception/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.analyzer.exception + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.analyzer.exception diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/package-frame.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/package-frame.html index 4886b4567..e52763f9b 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/package-frame.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.analyzer + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.analyzer diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/package-summary.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/package-summary.html index 0246e91fd..aabc604f4 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/package-summary.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.analyzer + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.analyzer diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/central/package-frame.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/central/package-frame.html index 66473098d..be53e5492 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/central/package-frame.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/central/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.central + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.central diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/central/package-summary.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/central/package-summary.html index afa169c0c..cbc47bbf6 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/central/package-summary.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/central/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.central + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.central diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/composer/package-frame.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/composer/package-frame.html index 0cf703955..4c66e78c3 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/composer/package-frame.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/composer/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.composer + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.composer diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/composer/package-summary.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/composer/package-summary.html index 730cfe15a..46563a804 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/composer/package-summary.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/composer/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.composer + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.composer diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/cpe/CpeMemoryIndex.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/cpe/CpeMemoryIndex.html index 9eae9c864..ed2431682 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/cpe/CpeMemoryIndex.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/cpe/CpeMemoryIndex.html @@ -46,288 +46,278 @@ 38 import org.apache.lucene.search.Query; 39 import org.apache.lucene.search.TopDocs; 40 import org.apache.lucene.store.RAMDirectory; -41 import org.owasp.dependencycheck.data.lucene.FieldAnalyzer; -42 import org.owasp.dependencycheck.data.lucene.LuceneUtils; -43 import org.owasp.dependencycheck.data.lucene.SearchFieldAnalyzer; -44 import org.owasp.dependencycheck.data.nvdcve.CveDB; -45 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; -46 import org.owasp.dependencycheck.utils.Pair; -47 import org.slf4j.Logger; -48 import org.slf4j.LoggerFactory; -49 -50 /** -51 * An in memory lucene index that contains the vendor/product combinations from the CPE (application) identifiers within the NVD -52 * CVE data. -53 * -54 * @author Jeremy Long -55 */ -56 public final class CpeMemoryIndex { -57 -58 /** -59 * The logger. -60 */ -61 private static final Logger LOGGER = LoggerFactory.getLogger(CpeMemoryIndex.class); -62 /** -63 * singleton instance. -64 */ -65 private static final CpeMemoryIndex INSTANCE = new CpeMemoryIndex(); -66 -67 /** -68 * private constructor for singleton. -69 */ -70 private CpeMemoryIndex() { -71 } -72 -73 /** -74 * Gets the singleton instance of the CpeMemoryIndex. -75 * -76 * @return the instance of the CpeMemoryIndex -77 */ -78 public static CpeMemoryIndex getInstance() { -79 return INSTANCE; -80 } -81 /** -82 * The in memory Lucene index. -83 */ -84 private RAMDirectory index; -85 /** -86 * The Lucene IndexReader. -87 */ -88 private IndexReader indexReader; -89 /** -90 * The Lucene IndexSearcher. -91 */ -92 private IndexSearcher indexSearcher; -93 /** -94 * The Lucene Analyzer used for Searching. -95 */ -96 private Analyzer searchingAnalyzer; -97 /** -98 * The Lucene QueryParser used for Searching. -99 */ -100 private QueryParser queryParser; -101 /** -102 * The search field analyzer for the product field. -103 */ -104 private SearchFieldAnalyzer productSearchFieldAnalyzer; -105 /** -106 * The search field analyzer for the vendor field. -107 */ -108 private SearchFieldAnalyzer vendorSearchFieldAnalyzer; -109 -110 /** -111 * Creates and loads data into an in memory index. -112 * -113 * @param cve the data source to retrieve the cpe data -114 * @throws IndexException thrown if there is an error creating the index -115 */ -116 public void open(CveDB cve) throws IndexException { -117 synchronized (INSTANCE) { -118 if (!openState) { -119 index = new RAMDirectory(); -120 buildIndex(cve); -121 try { -122 indexReader = DirectoryReader.open(index); -123 } catch (IOException ex) { -124 throw new IndexException(ex); -125 } -126 indexSearcher = new IndexSearcher(indexReader); -127 searchingAnalyzer = createSearchingAnalyzer(); -128 queryParser = new QueryParser(LuceneUtils.CURRENT_VERSION, Fields.DOCUMENT_KEY, searchingAnalyzer); -129 openState = true; -130 } -131 } -132 } -133 /** -134 * A flag indicating whether or not the index is open. -135 */ -136 private boolean openState = false; -137 -138 /** -139 * returns whether or not the index is open. -140 * -141 * @return whether or not the index is open -142 */ -143 public boolean isOpen() { -144 return openState; -145 } -146 -147 /** -148 * Creates the indexing analyzer for the CPE Index. -149 * -150 * @return the CPE Analyzer. -151 */ -152 private Analyzer createIndexingAnalyzer() { -153 final Map<String, Analyzer> fieldAnalyzers = new HashMap<String, Analyzer>(); -154 fieldAnalyzers.put(Fields.DOCUMENT_KEY, new KeywordAnalyzer()); -155 return new PerFieldAnalyzerWrapper(new FieldAnalyzer(LuceneUtils.CURRENT_VERSION), fieldAnalyzers); -156 } -157 -158 /** -159 * Creates an Analyzer for searching the CPE Index. -160 * -161 * @return the CPE Analyzer. -162 */ -163 private Analyzer createSearchingAnalyzer() { -164 final Map<String, Analyzer> fieldAnalyzers = new HashMap<String, Analyzer>(); -165 fieldAnalyzers.put(Fields.DOCUMENT_KEY, new KeywordAnalyzer()); -166 productSearchFieldAnalyzer = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION); -167 vendorSearchFieldAnalyzer = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION); -168 fieldAnalyzers.put(Fields.PRODUCT, productSearchFieldAnalyzer); -169 fieldAnalyzers.put(Fields.VENDOR, vendorSearchFieldAnalyzer); -170 -171 return new PerFieldAnalyzerWrapper(new FieldAnalyzer(LuceneUtils.CURRENT_VERSION), fieldAnalyzers); -172 } -173 -174 /** -175 * Closes the CPE Index. -176 */ -177 public void close() { -178 if (searchingAnalyzer != null) { -179 searchingAnalyzer.close(); -180 searchingAnalyzer = null; -181 } -182 if (indexReader != null) { -183 try { -184 indexReader.close(); -185 } catch (IOException ex) { -186 LOGGER.trace("", ex); -187 } -188 indexReader = null; -189 } -190 queryParser = null; -191 indexSearcher = null; -192 if (index != null) { -193 index.close(); -194 index = null; -195 } -196 openState = false; -197 } -198 -199 /** -200 * Builds the CPE Lucene Index based off of the data within the CveDB. -201 * -202 * @param cve the data base containing the CPE data -203 * @throws IndexException thrown if there is an issue creating the index -204 */ -205 private void buildIndex(CveDB cve) throws IndexException { -206 Analyzer analyzer = null; -207 IndexWriter indexWriter = null; -208 try { -209 analyzer = createIndexingAnalyzer(); -210 final IndexWriterConfig conf = new IndexWriterConfig(LuceneUtils.CURRENT_VERSION, analyzer); -211 indexWriter = new IndexWriter(index, conf); -212 try { -213 // Tip: reuse the Document and Fields for performance... -214 // See "Re-use Document and Field instances" from -215 // http://wiki.apache.org/lucene-java/ImproveIndexingSpeed -216 final Document doc = new Document(); -217 final Field v = new TextField(Fields.VENDOR, Fields.VENDOR, Field.Store.YES); -218 final Field p = new TextField(Fields.PRODUCT, Fields.PRODUCT, Field.Store.YES); -219 doc.add(v); -220 doc.add(p); -221 -222 final Set<Pair<String, String>> data = cve.getVendorProductList(); -223 for (Pair<String, String> pair : data) { -224 v.setStringValue(pair.getLeft()); -225 p.setStringValue(pair.getRight()); -226 indexWriter.addDocument(doc); -227 } -228 } catch (DatabaseException ex) { -229 LOGGER.debug("", ex); -230 throw new IndexException("Error reading CPE data", ex); -231 } -232 } catch (CorruptIndexException ex) { -233 throw new IndexException("Unable to close an in-memory index", ex); -234 } catch (IOException ex) { -235 throw new IndexException("Unable to close an in-memory index", ex); -236 } finally { -237 if (indexWriter != null) { -238 try { -239 try { -240 indexWriter.commit(); -241 } finally { -242 indexWriter.close(true); -243 } -244 } catch (CorruptIndexException ex) { -245 throw new IndexException("Unable to close an in-memory index", ex); -246 } catch (IOException ex) { -247 throw new IndexException("Unable to close an in-memory index", ex); -248 } -249 if (analyzer != null) { -250 analyzer.close(); -251 } -252 } -253 } -254 } -255 -256 /** -257 * Resets the searching analyzers -258 */ -259 private void resetSearchingAnalyzer() { -260 if (productSearchFieldAnalyzer != null) { -261 productSearchFieldAnalyzer.clear(); -262 } -263 if (vendorSearchFieldAnalyzer != null) { -264 vendorSearchFieldAnalyzer.clear(); -265 } -266 } -267 -268 /** -269 * Searches the index using the given search string. -270 * -271 * @param searchString the query text -272 * @param maxQueryResults the maximum number of documents to return -273 * @return the TopDocs found by the search -274 * @throws ParseException thrown when the searchString is invalid -275 * @throws IOException is thrown if there is an issue with the underlying Index -276 */ -277 public TopDocs search(String searchString, int maxQueryResults) throws ParseException, IOException { -278 if (searchString == null || searchString.trim().isEmpty()) { -279 throw new ParseException("Query is null or empty"); -280 } -281 LOGGER.debug(searchString); -282 final Query query = queryParser.parse(searchString); -283 return search(query, maxQueryResults); -284 } -285 -286 /** -287 * Searches the index using the given query. -288 * -289 * @param query the query used to search the index -290 * @param maxQueryResults the max number of results to return -291 * @return the TopDocs found be the query -292 * @throws CorruptIndexException thrown if the Index is corrupt -293 * @throws IOException thrown if there is an IOException -294 */ -295 public TopDocs search(Query query, int maxQueryResults) throws CorruptIndexException, IOException { -296 resetSearchingAnalyzer(); -297 return indexSearcher.search(query, maxQueryResults); -298 } -299 -300 /** -301 * Retrieves a document from the Index. -302 * -303 * @param documentId the id of the document to retrieve -304 * @return the Document -305 * @throws IOException thrown if there is an IOException -306 */ -307 public Document getDocument(int documentId) throws IOException { -308 return indexSearcher.doc(documentId); -309 } -310 -311 /** -312 * Returns the number of CPE entries stored in the index. -313 * -314 * @return the number of CPE entries stored in the index -315 */ -316 public int numDocs() { -317 if (indexReader == null) { -318 return -1; -319 } -320 return indexReader.numDocs(); -321 } -322 } +41 import org.owasp.dependencycheck.data.lucene.LuceneUtils; +42 import org.owasp.dependencycheck.data.lucene.SearchFieldAnalyzer; +43 import org.owasp.dependencycheck.data.nvdcve.CveDB; +44 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; +45 import org.owasp.dependencycheck.utils.Pair; +46 import org.slf4j.Logger; +47 import org.slf4j.LoggerFactory; +48 +49 /** +50 * An in memory lucene index that contains the vendor/product combinations from +51 * the CPE (application) identifiers within the NVD CVE data. +52 * +53 * @author Jeremy Long +54 */ +55 public final class CpeMemoryIndex { +56 +57 /** +58 * The logger. +59 */ +60 private static final Logger LOGGER = LoggerFactory.getLogger(CpeMemoryIndex.class); +61 /** +62 * singleton instance. +63 */ +64 private static final CpeMemoryIndex INSTANCE = new CpeMemoryIndex(); +65 +66 /** +67 * private constructor for singleton. +68 */ +69 private CpeMemoryIndex() { +70 } +71 +72 /** +73 * Gets the singleton instance of the CpeMemoryIndex. +74 * +75 * @return the instance of the CpeMemoryIndex +76 */ +77 public static CpeMemoryIndex getInstance() { +78 return INSTANCE; +79 } +80 /** +81 * The in memory Lucene index. +82 */ +83 private RAMDirectory index; +84 /** +85 * The Lucene IndexReader. +86 */ +87 private IndexReader indexReader; +88 /** +89 * The Lucene IndexSearcher. +90 */ +91 private IndexSearcher indexSearcher; +92 /** +93 * The Lucene Analyzer used for Searching. +94 */ +95 private Analyzer searchingAnalyzer; +96 /** +97 * The Lucene QueryParser used for Searching. +98 */ +99 private QueryParser queryParser; +100 /** +101 * The search field analyzer for the product field. +102 */ +103 private SearchFieldAnalyzer productFieldAnalyzer; +104 /** +105 * The search field analyzer for the vendor field. +106 */ +107 private SearchFieldAnalyzer vendorFieldAnalyzer; +108 +109 /** +110 * Creates and loads data into an in memory index. +111 * +112 * @param cve the data source to retrieve the cpe data +113 * @throws IndexException thrown if there is an error creating the index +114 */ +115 public void open(CveDB cve) throws IndexException { +116 synchronized (INSTANCE) { +117 if (!openState) { +118 index = new RAMDirectory(); +119 buildIndex(cve); +120 try { +121 indexReader = DirectoryReader.open(index); +122 } catch (IOException ex) { +123 throw new IndexException(ex); +124 } +125 indexSearcher = new IndexSearcher(indexReader); +126 searchingAnalyzer = createSearchingAnalyzer(); +127 queryParser = new QueryParser(LuceneUtils.CURRENT_VERSION, Fields.DOCUMENT_KEY, searchingAnalyzer); +128 openState = true; +129 } +130 } +131 } +132 /** +133 * A flag indicating whether or not the index is open. +134 */ +135 private boolean openState = false; +136 +137 /** +138 * returns whether or not the index is open. +139 * +140 * @return whether or not the index is open +141 */ +142 public boolean isOpen() { +143 return openState; +144 } +145 +146 /** +147 * Creates an Analyzer for searching the CPE Index. +148 * +149 * @return the CPE Analyzer. +150 */ +151 private Analyzer createSearchingAnalyzer() { +152 final Map<String, Analyzer> fieldAnalyzers = new HashMap<String, Analyzer>(); +153 fieldAnalyzers.put(Fields.DOCUMENT_KEY, new KeywordAnalyzer()); +154 productFieldAnalyzer = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION); +155 vendorFieldAnalyzer = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION); +156 fieldAnalyzers.put(Fields.PRODUCT, productFieldAnalyzer); +157 fieldAnalyzers.put(Fields.VENDOR, vendorFieldAnalyzer); +158 +159 return new PerFieldAnalyzerWrapper(new KeywordAnalyzer(), fieldAnalyzers); +160 } +161 +162 /** +163 * Closes the CPE Index. +164 */ +165 public void close() { +166 if (searchingAnalyzer != null) { +167 searchingAnalyzer.close(); +168 searchingAnalyzer = null; +169 } +170 if (indexReader != null) { +171 try { +172 indexReader.close(); +173 } catch (IOException ex) { +174 LOGGER.trace("", ex); +175 } +176 indexReader = null; +177 } +178 queryParser = null; +179 indexSearcher = null; +180 if (index != null) { +181 index.close(); +182 index = null; +183 } +184 openState = false; +185 } +186 +187 /** +188 * Builds the CPE Lucene Index based off of the data within the CveDB. +189 * +190 * @param cve the data base containing the CPE data +191 * @throws IndexException thrown if there is an issue creating the index +192 */ +193 private void buildIndex(CveDB cve) throws IndexException { +194 Analyzer analyzer = null; +195 IndexWriter indexWriter = null; +196 try { +197 analyzer = createSearchingAnalyzer(); +198 final IndexWriterConfig conf = new IndexWriterConfig(LuceneUtils.CURRENT_VERSION, analyzer); +199 indexWriter = new IndexWriter(index, conf); +200 try { +201 // Tip: reuse the Document and Fields for performance... +202 // See "Re-use Document and Field instances" from +203 // http://wiki.apache.org/lucene-java/ImproveIndexingSpeed +204 final Document doc = new Document(); +205 final Field v = new TextField(Fields.VENDOR, Fields.VENDOR, Field.Store.YES); +206 final Field p = new TextField(Fields.PRODUCT, Fields.PRODUCT, Field.Store.YES); +207 doc.add(v); +208 doc.add(p); +209 +210 final Set<Pair<String, String>> data = cve.getVendorProductList(); +211 for (Pair<String, String> pair : data) { +212 v.setStringValue(pair.getLeft()); +213 p.setStringValue(pair.getRight()); +214 indexWriter.addDocument(doc); +215 resetFieldAnalyzer(); +216 } +217 } catch (DatabaseException ex) { +218 LOGGER.debug("", ex); +219 throw new IndexException("Error reading CPE data", ex); +220 } +221 } catch (CorruptIndexException ex) { +222 throw new IndexException("Unable to close an in-memory index", ex); +223 } catch (IOException ex) { +224 throw new IndexException("Unable to close an in-memory index", ex); +225 } finally { +226 if (indexWriter != null) { +227 try { +228 try { +229 indexWriter.commit(); +230 } finally { +231 indexWriter.close(true); +232 } +233 } catch (CorruptIndexException ex) { +234 throw new IndexException("Unable to close an in-memory index", ex); +235 } catch (IOException ex) { +236 throw new IndexException("Unable to close an in-memory index", ex); +237 } +238 if (analyzer != null) { +239 analyzer.close(); +240 } +241 } +242 } +243 } +244 +245 /** +246 * Resets the product and vendor field analyzers. +247 */ +248 private void resetFieldAnalyzer() { +249 if (productFieldAnalyzer != null) { +250 productFieldAnalyzer.clear(); +251 } +252 if (vendorFieldAnalyzer != null) { +253 vendorFieldAnalyzer.clear(); +254 } +255 } +256 +257 /** +258 * Searches the index using the given search string. +259 * +260 * @param searchString the query text +261 * @param maxQueryResults the maximum number of documents to return +262 * @return the TopDocs found by the search +263 * @throws ParseException thrown when the searchString is invalid +264 * @throws IOException is thrown if there is an issue with the underlying +265 * Index +266 */ +267 public TopDocs search(String searchString, int maxQueryResults) throws ParseException, IOException { +268 if (searchString == null || searchString.trim().isEmpty()) { +269 throw new ParseException("Query is null or empty"); +270 } +271 LOGGER.debug(searchString); +272 final Query query = queryParser.parse(searchString); +273 return search(query, maxQueryResults); +274 } +275 +276 /** +277 * Searches the index using the given query. +278 * +279 * @param query the query used to search the index +280 * @param maxQueryResults the max number of results to return +281 * @return the TopDocs found be the query +282 * @throws CorruptIndexException thrown if the Index is corrupt +283 * @throws IOException thrown if there is an IOException +284 */ +285 public TopDocs search(Query query, int maxQueryResults) throws CorruptIndexException, IOException { +286 resetFieldAnalyzer(); +287 return indexSearcher.search(query, maxQueryResults); +288 } +289 +290 /** +291 * Retrieves a document from the Index. +292 * +293 * @param documentId the id of the document to retrieve +294 * @return the Document +295 * @throws IOException thrown if there is an IOException +296 */ +297 public Document getDocument(int documentId) throws IOException { +298 return indexSearcher.doc(documentId); +299 } +300 +301 /** +302 * Returns the number of CPE entries stored in the index. +303 * +304 * @return the number of CPE entries stored in the index +305 */ +306 public int numDocs() { +307 if (indexReader == null) { +308 return -1; +309 } +310 return indexReader.numDocs(); +311 } +312 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/cpe/package-frame.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/cpe/package-frame.html index 5aed3dd6e..c8076f3ba 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/cpe/package-frame.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/cpe/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.cpe + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.cpe diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/cpe/package-summary.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/cpe/package-summary.html index c993f29ab..d4aaad8c6 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/cpe/package-summary.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/cpe/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.cpe + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.cpe diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/cwe/package-frame.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/cwe/package-frame.html index 053b3bf11..272bab8e0 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/cwe/package-frame.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/cwe/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.cwe + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.cwe diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/cwe/package-summary.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/cwe/package-summary.html index f270ed630..cd3d0ee09 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/cwe/package-summary.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/cwe/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.cwe + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.cwe diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/lucene/FieldAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/lucene/FieldAnalyzer.html index f49b8afe9..f5499e92c 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/lucene/FieldAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/lucene/FieldAnalyzer.html @@ -37,55 +37,59 @@ 29 30 /** 31 * <p> -32 * A Lucene Analyzer that utilizes the WhitespaceTokenizer, WordDelimiterFilter, LowerCaseFilter, and StopFilter. The intended -33 * purpose of this Analyzer is to index the CPE fields vendor and product.</p> -34 * -35 * @author Jeremy Long -36 */ -37 public class FieldAnalyzer extends Analyzer { -38 -39 /** -40 * The Lucene Version used. -41 */ -42 private final Version version; -43 -44 /** -45 * Creates a new FieldAnalyzer. -46 * -47 * @param version the Lucene version -48 */ -49 public FieldAnalyzer(Version version) { -50 this.version = version; -51 } -52 -53 /** -54 * Creates the TokenStreamComponents -55 * -56 * @param fieldName the field name being analyzed -57 * @param reader the reader containing the input -58 * @return the TokenStreamComponents -59 */ -60 @Override -61 protected TokenStreamComponents createComponents(String fieldName, Reader reader) { -62 final Tokenizer source = new AlphaNumericTokenizer(version, reader); -63 -64 TokenStream stream = source; -65 -66 stream = new WordDelimiterFilter(stream, -67 WordDelimiterFilter.CATENATE_WORDS -68 | WordDelimiterFilter.GENERATE_WORD_PARTS -69 | WordDelimiterFilter.GENERATE_NUMBER_PARTS -70 | WordDelimiterFilter.PRESERVE_ORIGINAL -71 | WordDelimiterFilter.SPLIT_ON_CASE_CHANGE -72 | WordDelimiterFilter.SPLIT_ON_NUMERICS -73 | WordDelimiterFilter.STEM_ENGLISH_POSSESSIVE, null); -74 -75 stream = new LowerCaseFilter(version, stream); -76 stream = new StopFilter(version, stream, StopAnalyzer.ENGLISH_STOP_WORDS_SET); -77 -78 return new TokenStreamComponents(source, stream); -79 } -80 } +32 * A Lucene Analyzer that utilizes the WhitespaceTokenizer, WordDelimiterFilter, +33 * LowerCaseFilter, and StopFilter. The intended purpose of this Analyzer is to +34 * index the CPE fields vendor and product.</p> +35 * +36 * @author Jeremy Long +37 * @deprecated the field analyzer should not be used, instead use the +38 * SearchFieldAnalyzer so that the token analyzing filter is used. +39 */ +40 @Deprecated +41 public class FieldAnalyzer extends Analyzer { +42 +43 /** +44 * The Lucene Version used. +45 */ +46 private final Version version; +47 +48 /** +49 * Creates a new FieldAnalyzer. +50 * +51 * @param version the Lucene version +52 */ +53 public FieldAnalyzer(Version version) { +54 this.version = version; +55 } +56 +57 /** +58 * Creates the TokenStreamComponents +59 * +60 * @param fieldName the field name being analyzed +61 * @param reader the reader containing the input +62 * @return the TokenStreamComponents +63 */ +64 @Override +65 protected TokenStreamComponents createComponents(String fieldName, Reader reader) { +66 final Tokenizer source = new AlphaNumericTokenizer(version, reader); +67 +68 TokenStream stream = source; +69 +70 stream = new WordDelimiterFilter(stream, +71 WordDelimiterFilter.CATENATE_WORDS +72 | WordDelimiterFilter.GENERATE_WORD_PARTS +73 | WordDelimiterFilter.GENERATE_NUMBER_PARTS +74 | WordDelimiterFilter.PRESERVE_ORIGINAL +75 | WordDelimiterFilter.SPLIT_ON_CASE_CHANGE +76 | WordDelimiterFilter.SPLIT_ON_NUMERICS +77 | WordDelimiterFilter.STEM_ENGLISH_POSSESSIVE, null); +78 +79 stream = new LowerCaseFilter(version, stream); +80 stream = new StopFilter(version, stream, StopAnalyzer.ENGLISH_STOP_WORDS_SET); +81 +82 return new TokenStreamComponents(source, stream); +83 } +84 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/lucene/package-frame.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/lucene/package-frame.html index 8194a67dd..4c22972e2 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/lucene/package-frame.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/lucene/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.lucene + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.lucene diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/lucene/package-summary.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/lucene/package-summary.html index 9f8ebb524..ebce5fc7a 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/lucene/package-summary.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/lucene/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.lucene + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.lucene diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/nexus/package-frame.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/nexus/package-frame.html index 8e76c076e..f9c98c17b 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/nexus/package-frame.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/nexus/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.nexus + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.nexus diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/nexus/package-summary.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/nexus/package-summary.html index 8c455c5b3..d78004e0b 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/nexus/package-summary.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/nexus/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.nexus + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.nexus diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/nuget/package-frame.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/nuget/package-frame.html index 3e6f62531..135425a5d 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/nuget/package-frame.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/nuget/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.nuget + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.nuget diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/nuget/package-summary.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/nuget/package-summary.html index ceb4dc04a..3443e1fbd 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/nuget/package-summary.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/nuget/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.nuget + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.nuget diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/ConnectionFactory.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/ConnectionFactory.html index 95edc3f11..ed37e7d2b 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/ConnectionFactory.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/ConnectionFactory.html @@ -28,7 +28,7 @@ 20 import java.io.File; 21 import java.io.IOException; 22 import java.io.InputStream; -23 import java.sql.CallableStatement; +23 import java.sql.PreparedStatement; 24 import java.sql.Connection; 25 import java.sql.Driver; 26 import java.sql.DriverManager; @@ -360,11 +360,11 @@ 352 */ 353 private static void ensureSchemaVersion(Connection conn) throws DatabaseException { 354 ResultSet rs = null; -355 CallableStatement cs = null; +355 PreparedStatement ps = null; 356 try { 357 //TODO convert this to use DatabaseProperties -358 cs = conn.prepareCall("SELECT value FROM properties WHERE id = 'version'"); -359 rs = cs.executeQuery(); +358 ps = conn.prepareStatement("SELECT value FROM properties WHERE id = 'version'"); +359 rs = ps.executeQuery(); 360 if (rs.next()) { 361 final DependencyVersion appDbVersion = DependencyVersionUtil.parseVersion(DB_SCHEMA_VERSION); 362 final DependencyVersion db = DependencyVersionUtil.parseVersion(rs.getString(1)); @@ -384,7 +384,7 @@ 376 throw new DatabaseException("Unable to check the database schema version"); 377 } finally { 378 DBUtils.closeResultSet(rs); -379 DBUtils.closeStatement(cs); +379 DBUtils.closeStatement(ps); 380 } 381 } 382 } diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/CveDB.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/CveDB.html index c9c5d0eef..9fae88f80 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/CveDB.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/CveDB.html @@ -27,836 +27,834 @@ 19 20 import java.io.IOException; 21 import java.io.UnsupportedEncodingException; -22 import java.sql.CallableStatement; -23 import java.sql.Connection; -24 import java.sql.PreparedStatement; -25 import java.sql.ResultSet; -26 import java.sql.SQLException; -27 import java.sql.Statement; -28 import java.util.ArrayList; -29 import java.util.HashMap; -30 import java.util.HashSet; -31 import java.util.List; -32 import java.util.Locale; -33 import java.util.Map; -34 import java.util.Map.Entry; -35 import java.util.MissingResourceException; -36 import java.util.Properties; -37 import java.util.ResourceBundle; -38 import java.util.Set; -39 import org.owasp.dependencycheck.data.cwe.CweDB; -40 import org.owasp.dependencycheck.dependency.Reference; -41 import org.owasp.dependencycheck.dependency.Vulnerability; -42 import org.owasp.dependencycheck.dependency.VulnerableSoftware; -43 import org.owasp.dependencycheck.utils.DBUtils; -44 import org.owasp.dependencycheck.utils.DependencyVersion; -45 import org.owasp.dependencycheck.utils.DependencyVersionUtil; -46 import org.owasp.dependencycheck.utils.Pair; -47 import org.owasp.dependencycheck.utils.Settings; -48 import org.slf4j.Logger; -49 import org.slf4j.LoggerFactory; -50 -51 /** -52 * The database holding information about the NVD CVE data. -53 * -54 * @author Jeremy Long -55 */ -56 public class CveDB { -57 -58 /** -59 * The logger. -60 */ -61 private static final Logger LOGGER = LoggerFactory.getLogger(CveDB.class); -62 /** -63 * Database connection -64 */ -65 private Connection conn; -66 /** -67 * The bundle of statements used when accessing the database. -68 */ -69 private ResourceBundle statementBundle = null; -70 -71 /** -72 * Creates a new CveDB object and opens the database -73 * connection. Note, the connection must be closed by the caller by calling -74 * the close method. ======= Does the underlying connection support batch -75 * operations? -76 */ -77 private boolean batchSupported; -78 -79 /** -80 * Creates a new CveDB object and opens the database connection. Note, the -81 * connection must be closed by the caller by calling the close method. -82 * -83 * @throws DatabaseException thrown if there is an exception opening the -84 * database. -85 */ -86 public CveDB() throws DatabaseException { -87 super(); -88 try { -89 open(); -90 try { -91 final String databaseProductName = conn.getMetaData().getDatabaseProductName(); -92 batchSupported = conn.getMetaData().supportsBatchUpdates(); -93 LOGGER.debug("Database dialect: {}", databaseProductName); -94 final Locale dbDialect = new Locale(databaseProductName); -95 statementBundle = ResourceBundle.getBundle("data/dbStatements", dbDialect); -96 } catch (SQLException se) { -97 LOGGER.warn("Problem loading database specific dialect!", se); -98 statementBundle = ResourceBundle.getBundle("data/dbStatements"); -99 } -100 databaseProperties = new DatabaseProperties(this); -101 } catch (DatabaseException ex) { -102 throw ex; -103 } -104 } -105 -106 /** -107 * Returns the database connection. -108 * -109 * @return the database connection -110 */ -111 protected Connection getConnection() { -112 return conn; -113 } -114 -115 /** -116 * Opens the database connection. If the database does not exist, it will -117 * create a new one. -118 * -119 * @throws DatabaseException thrown if there is an error opening the -120 * database connection -121 */ -122 public final void open() throws DatabaseException { -123 if (!isOpen()) { -124 conn = ConnectionFactory.getConnection(); -125 } -126 } -127 -128 /** -129 * Closes the DB4O database. Close should be called on this object when it -130 * is done being used. -131 */ -132 public void close() { -133 if (conn != null) { -134 try { -135 conn.close(); -136 } catch (SQLException ex) { -137 LOGGER.error("There was an error attempting to close the CveDB, see the log for more details."); -138 LOGGER.debug("", ex); -139 } catch (Throwable ex) { -140 LOGGER.error("There was an exception attempting to close the CveDB, see the log for more details."); -141 LOGGER.debug("", ex); -142 } -143 conn = null; -144 } -145 } -146 -147 /** -148 * Returns whether the database connection is open or closed. -149 * -150 * @return whether the database connection is open or closed -151 */ -152 public boolean isOpen() { -153 return conn != null; -154 } -155 -156 /** -157 * Commits all completed transactions. -158 * -159 * @throws SQLException thrown if a SQL Exception occurs -160 */ -161 public void commit() throws SQLException { -162 //temporary remove this as autocommit is on. -163 //if (conn != null) { -164 // conn.commit(); -165 //} -166 } -167 -168 /** -169 * Cleans up the object and ensures that "close" has been called. -170 * -171 * @throws Throwable thrown if there is a problem -172 */ -173 @Override -174 @SuppressWarnings("FinalizeDeclaration") -175 protected void finalize() throws Throwable { -176 LOGGER.debug("Entering finalize"); -177 close(); -178 super.finalize(); -179 } -180 /** -181 * Database properties object containing the 'properties' from the database -182 * table. -183 */ -184 private DatabaseProperties databaseProperties; -185 -186 /** -187 * Get the value of databaseProperties. -188 * -189 * @return the value of databaseProperties -190 */ -191 public DatabaseProperties getDatabaseProperties() { -192 return databaseProperties; -193 } -194 -195 /** -196 * Searches the CPE entries in the database and retrieves all entries for a -197 * given vendor and product combination. The returned list will include all -198 * versions of the product that are registered in the NVD CVE data. -199 * -200 * @param vendor the identified vendor name of the dependency being analyzed -201 * @param product the identified name of the product of the dependency being -202 * analyzed -203 * @return a set of vulnerable software -204 */ -205 public Set<VulnerableSoftware> getCPEs(String vendor, String product) { -206 final Set<VulnerableSoftware> cpe = new HashSet<VulnerableSoftware>(); -207 ResultSet rs = null; -208 PreparedStatement ps = null; -209 try { -210 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_CPE_ENTRIES")); -211 ps.setString(1, vendor); -212 ps.setString(2, product); -213 rs = ps.executeQuery(); -214 -215 while (rs.next()) { -216 final VulnerableSoftware vs = new VulnerableSoftware(); -217 vs.setCpe(rs.getString(1)); -218 cpe.add(vs); -219 } -220 } catch (SQLException ex) { -221 LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details."); -222 LOGGER.debug("", ex); -223 } finally { -224 DBUtils.closeResultSet(rs); -225 DBUtils.closeStatement(ps); -226 } -227 return cpe; -228 } -229 -230 /** -231 * Returns the entire list of vendor/product combinations. -232 * -233 * @return the entire list of vendor/product combinations -234 * @throws DatabaseException thrown when there is an error retrieving the -235 * data from the DB -236 */ -237 public Set<Pair<String, String>> getVendorProductList() throws DatabaseException { -238 final Set<Pair<String, String>> data = new HashSet<Pair<String, String>>(); -239 ResultSet rs = null; -240 PreparedStatement ps = null; -241 try { -242 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_VENDOR_PRODUCT_LIST")); -243 rs = ps.executeQuery(); -244 while (rs.next()) { -245 data.add(new Pair<String, String>(rs.getString(1), rs.getString(2))); -246 } -247 } catch (SQLException ex) { -248 final String msg = "An unexpected SQL Exception occurred; please see the verbose log for more details."; -249 throw new DatabaseException(msg, ex); -250 } finally { -251 DBUtils.closeResultSet(rs); -252 DBUtils.closeStatement(ps); -253 } -254 return data; -255 } -256 -257 /** -258 * Returns a set of properties. -259 * -260 * @return the properties from the database -261 */ -262 Properties getProperties() { -263 final Properties prop = new Properties(); -264 PreparedStatement ps = null; -265 ResultSet rs = null; -266 try { -267 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_PROPERTIES")); -268 rs = ps.executeQuery(); -269 while (rs.next()) { -270 prop.setProperty(rs.getString(1), rs.getString(2)); -271 } -272 } catch (SQLException ex) { -273 LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details."); -274 LOGGER.debug("", ex); -275 } finally { -276 DBUtils.closeStatement(ps); -277 DBUtils.closeResultSet(rs); -278 } -279 return prop; -280 } -281 -282 /** -283 * Saves a property to the database. -284 * -285 * @param key the property key -286 * @param value the property value -287 */ -288 void saveProperty(String key, String value) { -289 try { -290 try { -291 final PreparedStatement mergeProperty = getConnection().prepareStatement(statementBundle.getString("MERGE_PROPERTY")); -292 try { -293 mergeProperty.setString(1, key); -294 mergeProperty.setString(2, value); -295 mergeProperty.executeUpdate(); -296 } finally { -297 DBUtils.closeStatement(mergeProperty); -298 } -299 } catch (MissingResourceException mre) { -300 // No Merge statement, so doing an Update/Insert... -301 PreparedStatement updateProperty = null; -302 PreparedStatement insertProperty = null; -303 try { -304 updateProperty = getConnection().prepareStatement(statementBundle.getString("UPDATE_PROPERTY")); -305 updateProperty.setString(1, value); -306 updateProperty.setString(2, key); -307 if (updateProperty.executeUpdate() == 0) { -308 insertProperty = getConnection().prepareStatement(statementBundle.getString("INSERT_PROPERTY")); -309 insertProperty.setString(1, key); -310 insertProperty.setString(2, value); -311 insertProperty.executeUpdate(); -312 } -313 } finally { -314 DBUtils.closeStatement(updateProperty); -315 DBUtils.closeStatement(insertProperty); -316 } -317 } -318 } catch (SQLException ex) { -319 LOGGER.warn("Unable to save property '{}' with a value of '{}' to the database", key, value); -320 LOGGER.debug("", ex); -321 } -322 } -323 -324 /** -325 * Retrieves the vulnerabilities associated with the specified CPE. -326 * -327 * @param cpeStr the CPE name -328 * @return a list of Vulnerabilities -329 * @throws DatabaseException thrown if there is an exception retrieving data -330 */ -331 public List<Vulnerability> getVulnerabilities(String cpeStr) throws DatabaseException { -332 final VulnerableSoftware cpe = new VulnerableSoftware(); -333 try { -334 cpe.parseName(cpeStr); -335 } catch (UnsupportedEncodingException ex) { -336 LOGGER.trace("", ex); -337 } -338 final DependencyVersion detectedVersion = parseDependencyVersion(cpe); -339 final List<Vulnerability> vulnerabilities = new ArrayList<Vulnerability>(); -340 -341 PreparedStatement ps = null; -342 ResultSet rs = null; -343 try { -344 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_CVE_FROM_SOFTWARE")); -345 ps.setString(1, cpe.getVendor()); -346 ps.setString(2, cpe.getProduct()); -347 rs = ps.executeQuery(); -348 String currentCVE = ""; -349 -350 final Map<String, Boolean> vulnSoftware = new HashMap<String, Boolean>(); -351 while (rs.next()) { -352 final String cveId = rs.getString(1); -353 if (!currentCVE.equals(cveId)) { //check for match and add -354 final Entry<String, Boolean> matchedCPE = getMatchingSoftware(vulnSoftware, cpe.getVendor(), cpe.getProduct(), detectedVersion); -355 if (matchedCPE != null) { -356 final Vulnerability v = getVulnerability(currentCVE); -357 v.setMatchedCPE(matchedCPE.getKey(), matchedCPE.getValue() ? "Y" : null); -358 vulnerabilities.add(v); -359 } -360 vulnSoftware.clear(); -361 currentCVE = cveId; -362 } -363 -364 final String cpeId = rs.getString(2); -365 final String previous = rs.getString(3); -366 final Boolean p = previous != null && !previous.isEmpty(); -367 vulnSoftware.put(cpeId, p); -368 } -369 //remember to process the last set of CVE/CPE entries -370 final Entry<String, Boolean> matchedCPE = getMatchingSoftware(vulnSoftware, cpe.getVendor(), cpe.getProduct(), detectedVersion); -371 if (matchedCPE != null) { -372 final Vulnerability v = getVulnerability(currentCVE); -373 v.setMatchedCPE(matchedCPE.getKey(), matchedCPE.getValue() ? "Y" : null); -374 vulnerabilities.add(v); -375 } -376 } catch (SQLException ex) { -377 throw new DatabaseException("Exception retrieving vulnerability for " + cpeStr, ex); -378 } finally { -379 DBUtils.closeResultSet(rs); -380 DBUtils.closeStatement(ps); -381 } -382 return vulnerabilities; -383 } -384 -385 /** -386 * Gets a vulnerability for the provided CVE. -387 * -388 * @param cve the CVE to lookup -389 * @return a vulnerability object -390 * @throws DatabaseException if an exception occurs -391 */ -392 public Vulnerability getVulnerability(String cve) throws DatabaseException { -393 PreparedStatement psV = null; -394 PreparedStatement psR = null; -395 PreparedStatement psS = null; -396 ResultSet rsV = null; -397 ResultSet rsR = null; -398 ResultSet rsS = null; -399 Vulnerability vuln = null; -400 -401 try { -402 psV = getConnection().prepareStatement(statementBundle.getString("SELECT_VULNERABILITY")); -403 psV.setString(1, cve); -404 rsV = psV.executeQuery(); -405 if (rsV.next()) { -406 vuln = new Vulnerability(); -407 vuln.setName(cve); -408 vuln.setDescription(rsV.getString(2)); -409 String cwe = rsV.getString(3); -410 if (cwe != null) { -411 final String name = CweDB.getCweName(cwe); -412 if (name != null) { -413 cwe += ' ' + name; -414 } -415 } -416 final int cveId = rsV.getInt(1); -417 vuln.setCwe(cwe); -418 vuln.setCvssScore(rsV.getFloat(4)); -419 vuln.setCvssAccessVector(rsV.getString(5)); -420 vuln.setCvssAccessComplexity(rsV.getString(6)); -421 vuln.setCvssAuthentication(rsV.getString(7)); -422 vuln.setCvssConfidentialityImpact(rsV.getString(8)); -423 vuln.setCvssIntegrityImpact(rsV.getString(9)); -424 vuln.setCvssAvailabilityImpact(rsV.getString(10)); -425 -426 psR = getConnection().prepareStatement(statementBundle.getString("SELECT_REFERENCES")); -427 psR.setInt(1, cveId); -428 rsR = psR.executeQuery(); -429 while (rsR.next()) { -430 vuln.addReference(rsR.getString(1), rsR.getString(2), rsR.getString(3)); -431 } -432 psS = getConnection().prepareStatement(statementBundle.getString("SELECT_SOFTWARE")); -433 psS.setInt(1, cveId); -434 rsS = psS.executeQuery(); -435 while (rsS.next()) { -436 final String cpe = rsS.getString(1); -437 final String prevVersion = rsS.getString(2); -438 if (prevVersion == null) { -439 vuln.addVulnerableSoftware(cpe); -440 } else { -441 vuln.addVulnerableSoftware(cpe, prevVersion); -442 } -443 } -444 } -445 } catch (SQLException ex) { -446 throw new DatabaseException("Error retrieving " + cve, ex); -447 } finally { -448 DBUtils.closeResultSet(rsV); -449 DBUtils.closeResultSet(rsR); -450 DBUtils.closeResultSet(rsS); -451 DBUtils.closeStatement(psV); -452 DBUtils.closeStatement(psR); -453 DBUtils.closeStatement(psS); -454 } -455 return vuln; -456 } -457 -458 /** -459 * Updates the vulnerability within the database. If the vulnerability does -460 * not exist it will be added. -461 * -462 * @param vuln the vulnerability to add to the database -463 * @throws DatabaseException is thrown if the database -464 */ -465 public void updateVulnerability(Vulnerability vuln) throws DatabaseException { -466 PreparedStatement selectVulnerabilityId = null; -467 PreparedStatement deleteVulnerability = null; -468 PreparedStatement deleteReferences = null; -469 PreparedStatement deleteSoftware = null; -470 PreparedStatement updateVulnerability = null; -471 PreparedStatement insertVulnerability = null; -472 PreparedStatement insertReference = null; -473 PreparedStatement selectCpeId = null; -474 PreparedStatement insertCpe = null; -475 PreparedStatement insertSoftware = null; -476 -477 try { -478 selectVulnerabilityId = getConnection().prepareStatement(statementBundle.getString("SELECT_VULNERABILITY_ID")); -479 deleteVulnerability = getConnection().prepareStatement(statementBundle.getString("DELETE_VULNERABILITY")); -480 deleteReferences = getConnection().prepareStatement(statementBundle.getString("DELETE_REFERENCE")); -481 deleteSoftware = getConnection().prepareStatement(statementBundle.getString("DELETE_SOFTWARE")); -482 updateVulnerability = getConnection().prepareStatement(statementBundle.getString("UPDATE_VULNERABILITY")); -483 final String[] ids = {"id"}; -484 insertVulnerability = getConnection().prepareStatement(statementBundle.getString("INSERT_VULNERABILITY"), -485 //Statement.RETURN_GENERATED_KEYS); -486 ids); -487 insertReference = getConnection().prepareStatement(statementBundle.getString("INSERT_REFERENCE")); -488 selectCpeId = getConnection().prepareStatement(statementBundle.getString("SELECT_CPE_ID")); -489 insertCpe = getConnection().prepareStatement(statementBundle.getString("INSERT_CPE"), -490 //Statement.RETURN_GENERATED_KEYS); -491 ids); -492 insertSoftware = getConnection().prepareStatement(statementBundle.getString("INSERT_SOFTWARE")); -493 int vulnerabilityId = 0; -494 selectVulnerabilityId.setString(1, vuln.getName()); -495 ResultSet rs = selectVulnerabilityId.executeQuery(); -496 if (rs.next()) { -497 vulnerabilityId = rs.getInt(1); -498 // first delete any existing vulnerability info. We don't know what was updated. yes, slower but atm easier. -499 deleteReferences.setInt(1, vulnerabilityId); -500 deleteReferences.execute(); -501 deleteSoftware.setInt(1, vulnerabilityId); -502 deleteSoftware.execute(); -503 } -504 DBUtils.closeResultSet(rs); -505 rs = null; -506 -507 if (vulnerabilityId != 0) { -508 if (vuln.getDescription().contains("** REJECT **")) { -509 deleteVulnerability.setInt(1, vulnerabilityId); -510 deleteVulnerability.executeUpdate(); -511 } else { -512 updateVulnerability.setString(1, vuln.getDescription()); -513 updateVulnerability.setString(2, vuln.getCwe()); -514 updateVulnerability.setFloat(3, vuln.getCvssScore()); -515 updateVulnerability.setString(4, vuln.getCvssAccessVector()); -516 updateVulnerability.setString(5, vuln.getCvssAccessComplexity()); -517 updateVulnerability.setString(6, vuln.getCvssAuthentication()); -518 updateVulnerability.setString(7, vuln.getCvssConfidentialityImpact()); -519 updateVulnerability.setString(8, vuln.getCvssIntegrityImpact()); -520 updateVulnerability.setString(9, vuln.getCvssAvailabilityImpact()); -521 updateVulnerability.setInt(10, vulnerabilityId); -522 updateVulnerability.executeUpdate(); -523 } -524 } else { -525 insertVulnerability.setString(1, vuln.getName()); -526 insertVulnerability.setString(2, vuln.getDescription()); -527 insertVulnerability.setString(3, vuln.getCwe()); -528 insertVulnerability.setFloat(4, vuln.getCvssScore()); -529 insertVulnerability.setString(5, vuln.getCvssAccessVector()); -530 insertVulnerability.setString(6, vuln.getCvssAccessComplexity()); -531 insertVulnerability.setString(7, vuln.getCvssAuthentication()); -532 insertVulnerability.setString(8, vuln.getCvssConfidentialityImpact()); -533 insertVulnerability.setString(9, vuln.getCvssIntegrityImpact()); -534 insertVulnerability.setString(10, vuln.getCvssAvailabilityImpact()); -535 insertVulnerability.execute(); -536 try { -537 rs = insertVulnerability.getGeneratedKeys(); -538 rs.next(); -539 vulnerabilityId = rs.getInt(1); -540 } catch (SQLException ex) { -541 final String msg = String.format("Unable to retrieve id for new vulnerability for '%s'", vuln.getName()); -542 throw new DatabaseException(msg, ex); -543 } finally { -544 DBUtils.closeResultSet(rs); -545 rs = null; -546 } -547 } -548 -549 for (Reference r : vuln.getReferences()) { -550 insertReference.setInt(1, vulnerabilityId); -551 insertReference.setString(2, r.getName()); -552 insertReference.setString(3, r.getUrl()); -553 insertReference.setString(4, r.getSource()); -554 -555 if (batchSupported) { -556 insertReference.addBatch(); -557 } else { -558 insertReference.execute(); -559 } -560 } -561 -562 if (batchSupported) { -563 insertReference.executeBatch(); -564 } -565 -566 for (VulnerableSoftware s : vuln.getVulnerableSoftware()) { -567 int cpeProductId = 0; -568 selectCpeId.setString(1, s.getName()); -569 try { -570 rs = selectCpeId.executeQuery(); -571 if (rs.next()) { -572 cpeProductId = rs.getInt(1); -573 } -574 } catch (SQLException ex) { -575 throw new DatabaseException("Unable to get primary key for new cpe: " + s.getName(), ex); -576 } finally { -577 DBUtils.closeResultSet(rs); -578 rs = null; -579 } -580 -581 if (cpeProductId == 0) { -582 insertCpe.setString(1, s.getName()); -583 insertCpe.setString(2, s.getVendor()); -584 insertCpe.setString(3, s.getProduct()); -585 insertCpe.executeUpdate(); -586 cpeProductId = DBUtils.getGeneratedKey(insertCpe); -587 } -588 if (cpeProductId == 0) { -589 throw new DatabaseException("Unable to retrieve cpeProductId - no data returned"); -590 } -591 -592 insertSoftware.setInt(1, vulnerabilityId); -593 insertSoftware.setInt(2, cpeProductId); -594 -595 if (s.getPreviousVersion() == null) { -596 insertSoftware.setNull(3, java.sql.Types.VARCHAR); -597 } else { -598 insertSoftware.setString(3, s.getPreviousVersion()); -599 } -600 if (batchSupported) { -601 insertSoftware.addBatch(); -602 } else { -603 try { -604 insertSoftware.execute(); -605 } catch (SQLException ex) { -606 if (ex.getMessage().contains("Duplicate entry")) { -607 final String msg = String.format("Duplicate software key identified in '%s:%s'", vuln.getName(), s.getName()); -608 LOGGER.debug(msg, ex); -609 } else { -610 throw ex; -611 } -612 } -613 } -614 } -615 if (batchSupported) { -616 insertSoftware.executeBatch(); -617 } -618 } catch (SQLException ex) { -619 final String msg = String.format("Error updating '%s'", vuln.getName()); -620 LOGGER.debug(msg, ex); -621 throw new DatabaseException(msg, ex); -622 } finally { -623 DBUtils.closeStatement(selectVulnerabilityId); -624 DBUtils.closeStatement(deleteReferences); -625 DBUtils.closeStatement(deleteSoftware); -626 DBUtils.closeStatement(updateVulnerability); -627 DBUtils.closeStatement(deleteVulnerability); -628 DBUtils.closeStatement(insertVulnerability); -629 DBUtils.closeStatement(insertReference); -630 DBUtils.closeStatement(selectCpeId); -631 DBUtils.closeStatement(insertCpe); -632 DBUtils.closeStatement(insertSoftware); -633 } -634 } -635 -636 /** -637 * Checks to see if data exists so that analysis can be performed. -638 * -639 * @return <code>true</code> if data exists; otherwise <code>false</code> -640 */ -641 public boolean dataExists() { -642 Statement cs = null; -643 ResultSet rs = null; -644 try { -645 cs = conn.createStatement(); -646 rs = cs.executeQuery("SELECT COUNT(*) records FROM cpeEntry"); -647 if (rs.next()) { -648 if (rs.getInt(1) > 0) { -649 return true; -650 } -651 } -652 } catch (SQLException ex) { -653 String dd; -654 try { -655 dd = Settings.getDataDirectory().getAbsolutePath(); -656 } catch (IOException ex1) { -657 dd = Settings.getString(Settings.KEYS.DATA_DIRECTORY); -658 } -659 LOGGER.error("Unable to access the local database.\n\nEnsure that '{}' is a writable directory. " -660 + "If the problem persist try deleting the files in '{}' and running {} again. If the problem continues, please " -661 + "create a log file (see documentation at http://jeremylong.github.io/DependencyCheck/) and open a ticket at " -662 + "https://github.com/jeremylong/DependencyCheck/issues and include the log file.\n\n", -663 dd, dd, Settings.getString(Settings.KEYS.APPLICATION_VAME)); -664 LOGGER.debug("", ex); -665 } finally { -666 DBUtils.closeResultSet(rs); -667 DBUtils.closeStatement(cs); -668 } -669 return false; -670 } -671 -672 /** -673 * It is possible that orphaned rows may be generated during database -674 * updates. This should be called after all updates have been completed to -675 * ensure orphan entries are removed. -676 */ -677 public void cleanupDatabase() { -678 PreparedStatement ps = null; -679 try { -680 ps = getConnection().prepareStatement(statementBundle.getString("CLEANUP_ORPHANS")); -681 if (ps != null) { -682 ps.executeUpdate(); -683 } -684 } catch (SQLException ex) { -685 LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details."); -686 LOGGER.debug("", ex); -687 } finally { -688 DBUtils.closeStatement(ps); -689 } -690 } -691 -692 /** -693 * Determines if the given identifiedVersion is affected by the given cpeId -694 * and previous version flag. A non-null, non-empty string passed to the -695 * previous version argument indicates that all previous versions are -696 * affected. -697 * -698 * @param vendor the vendor of the dependency being analyzed -699 * @param product the product name of the dependency being analyzed -700 * @param vulnerableSoftware a map of the vulnerable software with a boolean -701 * indicating if all previous versions are affected -702 * @param identifiedVersion the identified version of the dependency being -703 * analyzed -704 * @return true if the identified version is affected, otherwise false -705 */ -706 Entry<String, Boolean> getMatchingSoftware(Map<String, Boolean> vulnerableSoftware, String vendor, String product, -707 DependencyVersion identifiedVersion) { +22 import java.sql.Connection; +23 import java.sql.PreparedStatement; +24 import java.sql.ResultSet; +25 import java.sql.SQLException; +26 import java.sql.Statement; +27 import java.util.ArrayList; +28 import java.util.HashMap; +29 import java.util.HashSet; +30 import java.util.List; +31 import java.util.Locale; +32 import java.util.Map; +33 import java.util.Map.Entry; +34 import java.util.MissingResourceException; +35 import java.util.Properties; +36 import java.util.ResourceBundle; +37 import java.util.Set; +38 import org.owasp.dependencycheck.data.cwe.CweDB; +39 import org.owasp.dependencycheck.dependency.Reference; +40 import org.owasp.dependencycheck.dependency.Vulnerability; +41 import org.owasp.dependencycheck.dependency.VulnerableSoftware; +42 import org.owasp.dependencycheck.utils.DBUtils; +43 import org.owasp.dependencycheck.utils.DependencyVersion; +44 import org.owasp.dependencycheck.utils.DependencyVersionUtil; +45 import org.owasp.dependencycheck.utils.Pair; +46 import org.owasp.dependencycheck.utils.Settings; +47 import org.slf4j.Logger; +48 import org.slf4j.LoggerFactory; +49 +50 /** +51 * The database holding information about the NVD CVE data. +52 * +53 * @author Jeremy Long +54 */ +55 public class CveDB { +56 +57 /** +58 * The logger. +59 */ +60 private static final Logger LOGGER = LoggerFactory.getLogger(CveDB.class); +61 /** +62 * Database connection +63 */ +64 private Connection conn; +65 /** +66 * The bundle of statements used when accessing the database. +67 */ +68 private ResourceBundle statementBundle = null; +69 +70 /** +71 * Creates a new CveDB object and opens the database connection. Note, the +72 * connection must be closed by the caller by calling the close method. +73 * ======= Does the underlying connection support batch operations? +74 */ +75 private boolean batchSupported; +76 +77 /** +78 * Creates a new CveDB object and opens the database connection. Note, the +79 * connection must be closed by the caller by calling the close method. +80 * +81 * @throws DatabaseException thrown if there is an exception opening the +82 * database. +83 */ +84 public CveDB() throws DatabaseException { +85 super(); +86 try { +87 open(); +88 try { +89 final String databaseProductName = conn.getMetaData().getDatabaseProductName(); +90 batchSupported = conn.getMetaData().supportsBatchUpdates(); +91 LOGGER.debug("Database dialect: {}", databaseProductName); +92 final Locale dbDialect = new Locale(databaseProductName); +93 statementBundle = ResourceBundle.getBundle("data/dbStatements", dbDialect); +94 } catch (SQLException se) { +95 LOGGER.warn("Problem loading database specific dialect!", se); +96 statementBundle = ResourceBundle.getBundle("data/dbStatements"); +97 } +98 databaseProperties = new DatabaseProperties(this); +99 } catch (DatabaseException ex) { +100 throw ex; +101 } +102 } +103 +104 /** +105 * Returns the database connection. +106 * +107 * @return the database connection +108 */ +109 protected Connection getConnection() { +110 return conn; +111 } +112 +113 /** +114 * Opens the database connection. If the database does not exist, it will +115 * create a new one. +116 * +117 * @throws DatabaseException thrown if there is an error opening the +118 * database connection +119 */ +120 public final void open() throws DatabaseException { +121 if (!isOpen()) { +122 conn = ConnectionFactory.getConnection(); +123 } +124 } +125 +126 /** +127 * Closes the DB4O database. Close should be called on this object when it +128 * is done being used. +129 */ +130 public void close() { +131 if (conn != null) { +132 try { +133 conn.close(); +134 } catch (SQLException ex) { +135 LOGGER.error("There was an error attempting to close the CveDB, see the log for more details."); +136 LOGGER.debug("", ex); +137 } catch (Throwable ex) { +138 LOGGER.error("There was an exception attempting to close the CveDB, see the log for more details."); +139 LOGGER.debug("", ex); +140 } +141 conn = null; +142 } +143 } +144 +145 /** +146 * Returns whether the database connection is open or closed. +147 * +148 * @return whether the database connection is open or closed +149 */ +150 public boolean isOpen() { +151 return conn != null; +152 } +153 +154 /** +155 * Commits all completed transactions. +156 * +157 * @throws SQLException thrown if a SQL Exception occurs +158 */ +159 public void commit() throws SQLException { +160 //temporary remove this as autocommit is on. +161 //if (conn != null) { +162 // conn.commit(); +163 //} +164 } +165 +166 /** +167 * Cleans up the object and ensures that "close" has been called. +168 * +169 * @throws Throwable thrown if there is a problem +170 */ +171 @Override +172 @SuppressWarnings("FinalizeDeclaration") +173 protected void finalize() throws Throwable { +174 LOGGER.debug("Entering finalize"); +175 close(); +176 super.finalize(); +177 } +178 /** +179 * Database properties object containing the 'properties' from the database +180 * table. +181 */ +182 private DatabaseProperties databaseProperties; +183 +184 /** +185 * Get the value of databaseProperties. +186 * +187 * @return the value of databaseProperties +188 */ +189 public DatabaseProperties getDatabaseProperties() { +190 return databaseProperties; +191 } +192 +193 /** +194 * Searches the CPE entries in the database and retrieves all entries for a +195 * given vendor and product combination. The returned list will include all +196 * versions of the product that are registered in the NVD CVE data. +197 * +198 * @param vendor the identified vendor name of the dependency being analyzed +199 * @param product the identified name of the product of the dependency being +200 * analyzed +201 * @return a set of vulnerable software +202 */ +203 public Set<VulnerableSoftware> getCPEs(String vendor, String product) { +204 final Set<VulnerableSoftware> cpe = new HashSet<VulnerableSoftware>(); +205 ResultSet rs = null; +206 PreparedStatement ps = null; +207 try { +208 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_CPE_ENTRIES")); +209 ps.setString(1, vendor); +210 ps.setString(2, product); +211 rs = ps.executeQuery(); +212 +213 while (rs.next()) { +214 final VulnerableSoftware vs = new VulnerableSoftware(); +215 vs.setCpe(rs.getString(1)); +216 cpe.add(vs); +217 } +218 } catch (SQLException ex) { +219 LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details."); +220 LOGGER.debug("", ex); +221 } finally { +222 DBUtils.closeResultSet(rs); +223 DBUtils.closeStatement(ps); +224 } +225 return cpe; +226 } +227 +228 /** +229 * Returns the entire list of vendor/product combinations. +230 * +231 * @return the entire list of vendor/product combinations +232 * @throws DatabaseException thrown when there is an error retrieving the +233 * data from the DB +234 */ +235 public Set<Pair<String, String>> getVendorProductList() throws DatabaseException { +236 final Set<Pair<String, String>> data = new HashSet<Pair<String, String>>(); +237 ResultSet rs = null; +238 PreparedStatement ps = null; +239 try { +240 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_VENDOR_PRODUCT_LIST")); +241 rs = ps.executeQuery(); +242 while (rs.next()) { +243 data.add(new Pair<String, String>(rs.getString(1), rs.getString(2))); +244 } +245 } catch (SQLException ex) { +246 final String msg = "An unexpected SQL Exception occurred; please see the verbose log for more details."; +247 throw new DatabaseException(msg, ex); +248 } finally { +249 DBUtils.closeResultSet(rs); +250 DBUtils.closeStatement(ps); +251 } +252 return data; +253 } +254 +255 /** +256 * Returns a set of properties. +257 * +258 * @return the properties from the database +259 */ +260 Properties getProperties() { +261 final Properties prop = new Properties(); +262 PreparedStatement ps = null; +263 ResultSet rs = null; +264 try { +265 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_PROPERTIES")); +266 rs = ps.executeQuery(); +267 while (rs.next()) { +268 prop.setProperty(rs.getString(1), rs.getString(2)); +269 } +270 } catch (SQLException ex) { +271 LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details."); +272 LOGGER.debug("", ex); +273 } finally { +274 DBUtils.closeStatement(ps); +275 DBUtils.closeResultSet(rs); +276 } +277 return prop; +278 } +279 +280 /** +281 * Saves a property to the database. +282 * +283 * @param key the property key +284 * @param value the property value +285 */ +286 void saveProperty(String key, String value) { +287 try { +288 try { +289 final PreparedStatement mergeProperty = getConnection().prepareStatement(statementBundle.getString("MERGE_PROPERTY")); +290 try { +291 mergeProperty.setString(1, key); +292 mergeProperty.setString(2, value); +293 mergeProperty.executeUpdate(); +294 } finally { +295 DBUtils.closeStatement(mergeProperty); +296 } +297 } catch (MissingResourceException mre) { +298 // No Merge statement, so doing an Update/Insert... +299 PreparedStatement updateProperty = null; +300 PreparedStatement insertProperty = null; +301 try { +302 updateProperty = getConnection().prepareStatement(statementBundle.getString("UPDATE_PROPERTY")); +303 updateProperty.setString(1, value); +304 updateProperty.setString(2, key); +305 if (updateProperty.executeUpdate() == 0) { +306 insertProperty = getConnection().prepareStatement(statementBundle.getString("INSERT_PROPERTY")); +307 insertProperty.setString(1, key); +308 insertProperty.setString(2, value); +309 insertProperty.executeUpdate(); +310 } +311 } finally { +312 DBUtils.closeStatement(updateProperty); +313 DBUtils.closeStatement(insertProperty); +314 } +315 } +316 } catch (SQLException ex) { +317 LOGGER.warn("Unable to save property '{}' with a value of '{}' to the database", key, value); +318 LOGGER.debug("", ex); +319 } +320 } +321 +322 /** +323 * Retrieves the vulnerabilities associated with the specified CPE. +324 * +325 * @param cpeStr the CPE name +326 * @return a list of Vulnerabilities +327 * @throws DatabaseException thrown if there is an exception retrieving data +328 */ +329 public List<Vulnerability> getVulnerabilities(String cpeStr) throws DatabaseException { +330 final VulnerableSoftware cpe = new VulnerableSoftware(); +331 try { +332 cpe.parseName(cpeStr); +333 } catch (UnsupportedEncodingException ex) { +334 LOGGER.trace("", ex); +335 } +336 final DependencyVersion detectedVersion = parseDependencyVersion(cpe); +337 final List<Vulnerability> vulnerabilities = new ArrayList<Vulnerability>(); +338 +339 PreparedStatement ps = null; +340 ResultSet rs = null; +341 try { +342 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_CVE_FROM_SOFTWARE")); +343 ps.setString(1, cpe.getVendor()); +344 ps.setString(2, cpe.getProduct()); +345 rs = ps.executeQuery(); +346 String currentCVE = ""; +347 +348 final Map<String, Boolean> vulnSoftware = new HashMap<String, Boolean>(); +349 while (rs.next()) { +350 final String cveId = rs.getString(1); +351 if (!currentCVE.equals(cveId)) { //check for match and add +352 final Entry<String, Boolean> matchedCPE = getMatchingSoftware(vulnSoftware, cpe.getVendor(), cpe.getProduct(), detectedVersion); +353 if (matchedCPE != null) { +354 final Vulnerability v = getVulnerability(currentCVE); +355 v.setMatchedCPE(matchedCPE.getKey(), matchedCPE.getValue() ? "Y" : null); +356 vulnerabilities.add(v); +357 } +358 vulnSoftware.clear(); +359 currentCVE = cveId; +360 } +361 +362 final String cpeId = rs.getString(2); +363 final String previous = rs.getString(3); +364 final Boolean p = previous != null && !previous.isEmpty(); +365 vulnSoftware.put(cpeId, p); +366 } +367 //remember to process the last set of CVE/CPE entries +368 final Entry<String, Boolean> matchedCPE = getMatchingSoftware(vulnSoftware, cpe.getVendor(), cpe.getProduct(), detectedVersion); +369 if (matchedCPE != null) { +370 final Vulnerability v = getVulnerability(currentCVE); +371 v.setMatchedCPE(matchedCPE.getKey(), matchedCPE.getValue() ? "Y" : null); +372 vulnerabilities.add(v); +373 } +374 } catch (SQLException ex) { +375 throw new DatabaseException("Exception retrieving vulnerability for " + cpeStr, ex); +376 } finally { +377 DBUtils.closeResultSet(rs); +378 DBUtils.closeStatement(ps); +379 } +380 return vulnerabilities; +381 } +382 +383 /** +384 * Gets a vulnerability for the provided CVE. +385 * +386 * @param cve the CVE to lookup +387 * @return a vulnerability object +388 * @throws DatabaseException if an exception occurs +389 */ +390 public Vulnerability getVulnerability(String cve) throws DatabaseException { +391 PreparedStatement psV = null; +392 PreparedStatement psR = null; +393 PreparedStatement psS = null; +394 ResultSet rsV = null; +395 ResultSet rsR = null; +396 ResultSet rsS = null; +397 Vulnerability vuln = null; +398 +399 try { +400 psV = getConnection().prepareStatement(statementBundle.getString("SELECT_VULNERABILITY")); +401 psV.setString(1, cve); +402 rsV = psV.executeQuery(); +403 if (rsV.next()) { +404 vuln = new Vulnerability(); +405 vuln.setName(cve); +406 vuln.setDescription(rsV.getString(2)); +407 String cwe = rsV.getString(3); +408 if (cwe != null) { +409 final String name = CweDB.getCweName(cwe); +410 if (name != null) { +411 cwe += ' ' + name; +412 } +413 } +414 final int cveId = rsV.getInt(1); +415 vuln.setCwe(cwe); +416 vuln.setCvssScore(rsV.getFloat(4)); +417 vuln.setCvssAccessVector(rsV.getString(5)); +418 vuln.setCvssAccessComplexity(rsV.getString(6)); +419 vuln.setCvssAuthentication(rsV.getString(7)); +420 vuln.setCvssConfidentialityImpact(rsV.getString(8)); +421 vuln.setCvssIntegrityImpact(rsV.getString(9)); +422 vuln.setCvssAvailabilityImpact(rsV.getString(10)); +423 +424 psR = getConnection().prepareStatement(statementBundle.getString("SELECT_REFERENCES")); +425 psR.setInt(1, cveId); +426 rsR = psR.executeQuery(); +427 while (rsR.next()) { +428 vuln.addReference(rsR.getString(1), rsR.getString(2), rsR.getString(3)); +429 } +430 psS = getConnection().prepareStatement(statementBundle.getString("SELECT_SOFTWARE")); +431 psS.setInt(1, cveId); +432 rsS = psS.executeQuery(); +433 while (rsS.next()) { +434 final String cpe = rsS.getString(1); +435 final String prevVersion = rsS.getString(2); +436 if (prevVersion == null) { +437 vuln.addVulnerableSoftware(cpe); +438 } else { +439 vuln.addVulnerableSoftware(cpe, prevVersion); +440 } +441 } +442 } +443 } catch (SQLException ex) { +444 throw new DatabaseException("Error retrieving " + cve, ex); +445 } finally { +446 DBUtils.closeResultSet(rsV); +447 DBUtils.closeResultSet(rsR); +448 DBUtils.closeResultSet(rsS); +449 DBUtils.closeStatement(psV); +450 DBUtils.closeStatement(psR); +451 DBUtils.closeStatement(psS); +452 } +453 return vuln; +454 } +455 +456 /** +457 * Updates the vulnerability within the database. If the vulnerability does +458 * not exist it will be added. +459 * +460 * @param vuln the vulnerability to add to the database +461 * @throws DatabaseException is thrown if the database +462 */ +463 public void updateVulnerability(Vulnerability vuln) throws DatabaseException { +464 PreparedStatement selectVulnerabilityId = null; +465 PreparedStatement deleteVulnerability = null; +466 PreparedStatement deleteReferences = null; +467 PreparedStatement deleteSoftware = null; +468 PreparedStatement updateVulnerability = null; +469 PreparedStatement insertVulnerability = null; +470 PreparedStatement insertReference = null; +471 PreparedStatement selectCpeId = null; +472 PreparedStatement insertCpe = null; +473 PreparedStatement insertSoftware = null; +474 +475 try { +476 selectVulnerabilityId = getConnection().prepareStatement(statementBundle.getString("SELECT_VULNERABILITY_ID")); +477 deleteVulnerability = getConnection().prepareStatement(statementBundle.getString("DELETE_VULNERABILITY")); +478 deleteReferences = getConnection().prepareStatement(statementBundle.getString("DELETE_REFERENCE")); +479 deleteSoftware = getConnection().prepareStatement(statementBundle.getString("DELETE_SOFTWARE")); +480 updateVulnerability = getConnection().prepareStatement(statementBundle.getString("UPDATE_VULNERABILITY")); +481 final String[] ids = {"id"}; +482 insertVulnerability = getConnection().prepareStatement(statementBundle.getString("INSERT_VULNERABILITY"), +483 //Statement.RETURN_GENERATED_KEYS); +484 ids); +485 insertReference = getConnection().prepareStatement(statementBundle.getString("INSERT_REFERENCE")); +486 selectCpeId = getConnection().prepareStatement(statementBundle.getString("SELECT_CPE_ID")); +487 insertCpe = getConnection().prepareStatement(statementBundle.getString("INSERT_CPE"), +488 //Statement.RETURN_GENERATED_KEYS); +489 ids); +490 insertSoftware = getConnection().prepareStatement(statementBundle.getString("INSERT_SOFTWARE")); +491 int vulnerabilityId = 0; +492 selectVulnerabilityId.setString(1, vuln.getName()); +493 ResultSet rs = selectVulnerabilityId.executeQuery(); +494 if (rs.next()) { +495 vulnerabilityId = rs.getInt(1); +496 // first delete any existing vulnerability info. We don't know what was updated. yes, slower but atm easier. +497 deleteReferences.setInt(1, vulnerabilityId); +498 deleteReferences.execute(); +499 deleteSoftware.setInt(1, vulnerabilityId); +500 deleteSoftware.execute(); +501 } +502 DBUtils.closeResultSet(rs); +503 rs = null; +504 +505 if (vulnerabilityId != 0) { +506 if (vuln.getDescription().contains("** REJECT **")) { +507 deleteVulnerability.setInt(1, vulnerabilityId); +508 deleteVulnerability.executeUpdate(); +509 } else { +510 updateVulnerability.setString(1, vuln.getDescription()); +511 updateVulnerability.setString(2, vuln.getCwe()); +512 updateVulnerability.setFloat(3, vuln.getCvssScore()); +513 updateVulnerability.setString(4, vuln.getCvssAccessVector()); +514 updateVulnerability.setString(5, vuln.getCvssAccessComplexity()); +515 updateVulnerability.setString(6, vuln.getCvssAuthentication()); +516 updateVulnerability.setString(7, vuln.getCvssConfidentialityImpact()); +517 updateVulnerability.setString(8, vuln.getCvssIntegrityImpact()); +518 updateVulnerability.setString(9, vuln.getCvssAvailabilityImpact()); +519 updateVulnerability.setInt(10, vulnerabilityId); +520 updateVulnerability.executeUpdate(); +521 } +522 } else { +523 insertVulnerability.setString(1, vuln.getName()); +524 insertVulnerability.setString(2, vuln.getDescription()); +525 insertVulnerability.setString(3, vuln.getCwe()); +526 insertVulnerability.setFloat(4, vuln.getCvssScore()); +527 insertVulnerability.setString(5, vuln.getCvssAccessVector()); +528 insertVulnerability.setString(6, vuln.getCvssAccessComplexity()); +529 insertVulnerability.setString(7, vuln.getCvssAuthentication()); +530 insertVulnerability.setString(8, vuln.getCvssConfidentialityImpact()); +531 insertVulnerability.setString(9, vuln.getCvssIntegrityImpact()); +532 insertVulnerability.setString(10, vuln.getCvssAvailabilityImpact()); +533 insertVulnerability.execute(); +534 try { +535 rs = insertVulnerability.getGeneratedKeys(); +536 rs.next(); +537 vulnerabilityId = rs.getInt(1); +538 } catch (SQLException ex) { +539 final String msg = String.format("Unable to retrieve id for new vulnerability for '%s'", vuln.getName()); +540 throw new DatabaseException(msg, ex); +541 } finally { +542 DBUtils.closeResultSet(rs); +543 rs = null; +544 } +545 } +546 +547 for (Reference r : vuln.getReferences()) { +548 insertReference.setInt(1, vulnerabilityId); +549 insertReference.setString(2, r.getName()); +550 insertReference.setString(3, r.getUrl()); +551 insertReference.setString(4, r.getSource()); +552 +553 if (batchSupported) { +554 insertReference.addBatch(); +555 } else { +556 insertReference.execute(); +557 } +558 } +559 +560 if (batchSupported) { +561 insertReference.executeBatch(); +562 } +563 +564 for (VulnerableSoftware s : vuln.getVulnerableSoftware()) { +565 int cpeProductId = 0; +566 selectCpeId.setString(1, s.getName()); +567 try { +568 rs = selectCpeId.executeQuery(); +569 if (rs.next()) { +570 cpeProductId = rs.getInt(1); +571 } +572 } catch (SQLException ex) { +573 throw new DatabaseException("Unable to get primary key for new cpe: " + s.getName(), ex); +574 } finally { +575 DBUtils.closeResultSet(rs); +576 rs = null; +577 } +578 +579 if (cpeProductId == 0) { +580 insertCpe.setString(1, s.getName()); +581 insertCpe.setString(2, s.getVendor()); +582 insertCpe.setString(3, s.getProduct()); +583 insertCpe.executeUpdate(); +584 cpeProductId = DBUtils.getGeneratedKey(insertCpe); +585 } +586 if (cpeProductId == 0) { +587 throw new DatabaseException("Unable to retrieve cpeProductId - no data returned"); +588 } +589 +590 insertSoftware.setInt(1, vulnerabilityId); +591 insertSoftware.setInt(2, cpeProductId); +592 +593 if (s.getPreviousVersion() == null) { +594 insertSoftware.setNull(3, java.sql.Types.VARCHAR); +595 } else { +596 insertSoftware.setString(3, s.getPreviousVersion()); +597 } +598 if (batchSupported) { +599 insertSoftware.addBatch(); +600 } else { +601 try { +602 insertSoftware.execute(); +603 } catch (SQLException ex) { +604 if (ex.getMessage().contains("Duplicate entry")) { +605 final String msg = String.format("Duplicate software key identified in '%s:%s'", vuln.getName(), s.getName()); +606 LOGGER.debug(msg, ex); +607 } else { +608 throw ex; +609 } +610 } +611 } +612 } +613 if (batchSupported) { +614 insertSoftware.executeBatch(); +615 } +616 } catch (SQLException ex) { +617 final String msg = String.format("Error updating '%s'", vuln.getName()); +618 LOGGER.debug(msg, ex); +619 throw new DatabaseException(msg, ex); +620 } finally { +621 DBUtils.closeStatement(selectVulnerabilityId); +622 DBUtils.closeStatement(deleteReferences); +623 DBUtils.closeStatement(deleteSoftware); +624 DBUtils.closeStatement(updateVulnerability); +625 DBUtils.closeStatement(deleteVulnerability); +626 DBUtils.closeStatement(insertVulnerability); +627 DBUtils.closeStatement(insertReference); +628 DBUtils.closeStatement(selectCpeId); +629 DBUtils.closeStatement(insertCpe); +630 DBUtils.closeStatement(insertSoftware); +631 } +632 } +633 +634 /** +635 * Checks to see if data exists so that analysis can be performed. +636 * +637 * @return <code>true</code> if data exists; otherwise <code>false</code> +638 */ +639 public boolean dataExists() { +640 Statement cs = null; +641 ResultSet rs = null; +642 try { +643 cs = conn.createStatement(); +644 rs = cs.executeQuery("SELECT COUNT(*) records FROM cpeEntry"); +645 if (rs.next()) { +646 if (rs.getInt(1) > 0) { +647 return true; +648 } +649 } +650 } catch (SQLException ex) { +651 String dd; +652 try { +653 dd = Settings.getDataDirectory().getAbsolutePath(); +654 } catch (IOException ex1) { +655 dd = Settings.getString(Settings.KEYS.DATA_DIRECTORY); +656 } +657 LOGGER.error("Unable to access the local database.\n\nEnsure that '{}' is a writable directory. " +658 + "If the problem persist try deleting the files in '{}' and running {} again. If the problem continues, please " +659 + "create a log file (see documentation at http://jeremylong.github.io/DependencyCheck/) and open a ticket at " +660 + "https://github.com/jeremylong/DependencyCheck/issues and include the log file.\n\n", +661 dd, dd, Settings.getString(Settings.KEYS.APPLICATION_VAME)); +662 LOGGER.debug("", ex); +663 } finally { +664 DBUtils.closeResultSet(rs); +665 DBUtils.closeStatement(cs); +666 } +667 return false; +668 } +669 +670 /** +671 * It is possible that orphaned rows may be generated during database +672 * updates. This should be called after all updates have been completed to +673 * ensure orphan entries are removed. +674 */ +675 public void cleanupDatabase() { +676 PreparedStatement ps = null; +677 try { +678 ps = getConnection().prepareStatement(statementBundle.getString("CLEANUP_ORPHANS")); +679 if (ps != null) { +680 ps.executeUpdate(); +681 } +682 } catch (SQLException ex) { +683 LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details."); +684 LOGGER.debug("", ex); +685 } finally { +686 DBUtils.closeStatement(ps); +687 } +688 } +689 +690 /** +691 * Determines if the given identifiedVersion is affected by the given cpeId +692 * and previous version flag. A non-null, non-empty string passed to the +693 * previous version argument indicates that all previous versions are +694 * affected. +695 * +696 * @param vendor the vendor of the dependency being analyzed +697 * @param product the product name of the dependency being analyzed +698 * @param vulnerableSoftware a map of the vulnerable software with a boolean +699 * indicating if all previous versions are affected +700 * @param identifiedVersion the identified version of the dependency being +701 * analyzed +702 * @return true if the identified version is affected, otherwise false +703 */ +704 Entry<String, Boolean> getMatchingSoftware(Map<String, Boolean> vulnerableSoftware, String vendor, String product, +705 DependencyVersion identifiedVersion) { +706 +707 final boolean isVersionTwoADifferentProduct = "apache".equals(vendor) && "struts".equals(product); 708 -709 final boolean isVersionTwoADifferentProduct = "apache".equals(vendor) && "struts".equals(product); -710 -711 final Set<String> majorVersionsAffectingAllPrevious = new HashSet<String>(); -712 final boolean matchesAnyPrevious = identifiedVersion == null || "-".equals(identifiedVersion.toString()); -713 String majorVersionMatch = null; -714 for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) { -715 final DependencyVersion v = parseDependencyVersion(entry.getKey()); -716 if (v == null || "-".equals(v.toString())) { //all versions -717 return entry; -718 } -719 if (entry.getValue()) { -720 if (matchesAnyPrevious) { -721 return entry; -722 } -723 if (identifiedVersion != null && identifiedVersion.getVersionParts().get(0).equals(v.getVersionParts().get(0))) { -724 majorVersionMatch = v.getVersionParts().get(0); -725 } -726 majorVersionsAffectingAllPrevious.add(v.getVersionParts().get(0)); -727 } -728 } -729 if (matchesAnyPrevious) { -730 return null; -731 } -732 -733 final boolean canSkipVersions = majorVersionMatch != null && majorVersionsAffectingAllPrevious.size() > 1; -734 //yes, we are iterating over this twice. The first time we are skipping versions those that affect all versions -735 //then later we process those that affect all versions. This could be done with sorting... -736 for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) { -737 if (!entry.getValue()) { -738 final DependencyVersion v = parseDependencyVersion(entry.getKey()); -739 //this can't dereference a null 'majorVersionMatch' as canSkipVersions accounts for this. -740 if (canSkipVersions && !majorVersionMatch.equals(v.getVersionParts().get(0))) { -741 continue; -742 } -743 //this can't dereference a null 'identifiedVersion' because if it was null we would have exited -744 //in the above loop or just after loop (if matchesAnyPrevious return null). -745 if (identifiedVersion.equals(v)) { -746 return entry; -747 } -748 } -749 } -750 for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) { -751 if (entry.getValue()) { -752 final DependencyVersion v = parseDependencyVersion(entry.getKey()); -753 //this can't dereference a null 'majorVersionMatch' as canSkipVersions accounts for this. -754 if (canSkipVersions && !majorVersionMatch.equals(v.getVersionParts().get(0))) { -755 continue; -756 } -757 //this can't dereference a null 'identifiedVersion' because if it was null we would have exited -758 //in the above loop or just after loop (if matchesAnyPrevious return null). -759 if (entry.getValue() && identifiedVersion.compareTo(v) <= 0) { -760 if (!(isVersionTwoADifferentProduct && !identifiedVersion.getVersionParts().get(0).equals(v.getVersionParts().get(0)))) { -761 return entry; -762 } -763 } -764 } -765 } -766 return null; -767 } -768 -769 /** -770 * Parses the version (including revision) from a CPE identifier. If no -771 * version is identified then a '-' is returned. -772 * -773 * @param cpeStr a cpe identifier -774 * @return a dependency version -775 */ -776 private DependencyVersion parseDependencyVersion(String cpeStr) { -777 final VulnerableSoftware cpe = new VulnerableSoftware(); -778 try { -779 cpe.parseName(cpeStr); -780 } catch (UnsupportedEncodingException ex) { -781 //never going to happen. -782 LOGGER.trace("", ex); -783 } -784 return parseDependencyVersion(cpe); -785 } -786 -787 /** -788 * Takes a CPE and parses out the version number. If no version is -789 * identified then a '-' is returned. -790 * -791 * @param cpe a cpe object -792 * @return a dependency version -793 */ -794 private DependencyVersion parseDependencyVersion(VulnerableSoftware cpe) { -795 final DependencyVersion cpeVersion; -796 if (cpe.getVersion() != null && !cpe.getVersion().isEmpty()) { -797 final String versionText; -798 if (cpe.getUpdate() != null && !cpe.getUpdate().isEmpty()) { -799 versionText = String.format("%s.%s", cpe.getVersion(), cpe.getUpdate()); -800 } else { -801 versionText = cpe.getVersion(); -802 } -803 cpeVersion = DependencyVersionUtil.parseVersion(versionText); -804 } else { -805 cpeVersion = new DependencyVersion("-"); -806 } -807 return cpeVersion; -808 } -809 -810 /** -811 * This method is only referenced in unused code. -812 * -813 * Deletes unused dictionary entries from the database. -814 */ -815 public void deleteUnusedCpe() { -816 CallableStatement cs = null; -817 try { -818 cs = getConnection().prepareCall(statementBundle.getString("DELETE_UNUSED_DICT_CPE")); -819 cs.executeUpdate(); -820 } catch (SQLException ex) { -821 LOGGER.error("Unable to delete CPE dictionary entries", ex); -822 } finally { -823 DBUtils.closeStatement(cs); -824 } -825 } -826 -827 /** -828 * This method is only referenced in unused code and will likely break on -829 * MySQL if ever used due to the MERGE statement. +709 final Set<String> majorVersionsAffectingAllPrevious = new HashSet<String>(); +710 final boolean matchesAnyPrevious = identifiedVersion == null || "-".equals(identifiedVersion.toString()); +711 String majorVersionMatch = null; +712 for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) { +713 final DependencyVersion v = parseDependencyVersion(entry.getKey()); +714 if (v == null || "-".equals(v.toString())) { //all versions +715 return entry; +716 } +717 if (entry.getValue()) { +718 if (matchesAnyPrevious) { +719 return entry; +720 } +721 if (identifiedVersion != null && identifiedVersion.getVersionParts().get(0).equals(v.getVersionParts().get(0))) { +722 majorVersionMatch = v.getVersionParts().get(0); +723 } +724 majorVersionsAffectingAllPrevious.add(v.getVersionParts().get(0)); +725 } +726 } +727 if (matchesAnyPrevious) { +728 return null; +729 } +730 +731 final boolean canSkipVersions = majorVersionMatch != null && majorVersionsAffectingAllPrevious.size() > 1; +732 //yes, we are iterating over this twice. The first time we are skipping versions those that affect all versions +733 //then later we process those that affect all versions. This could be done with sorting... +734 for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) { +735 if (!entry.getValue()) { +736 final DependencyVersion v = parseDependencyVersion(entry.getKey()); +737 //this can't dereference a null 'majorVersionMatch' as canSkipVersions accounts for this. +738 if (canSkipVersions && !majorVersionMatch.equals(v.getVersionParts().get(0))) { +739 continue; +740 } +741 //this can't dereference a null 'identifiedVersion' because if it was null we would have exited +742 //in the above loop or just after loop (if matchesAnyPrevious return null). +743 if (identifiedVersion.equals(v)) { +744 return entry; +745 } +746 } +747 } +748 for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) { +749 if (entry.getValue()) { +750 final DependencyVersion v = parseDependencyVersion(entry.getKey()); +751 //this can't dereference a null 'majorVersionMatch' as canSkipVersions accounts for this. +752 if (canSkipVersions && !majorVersionMatch.equals(v.getVersionParts().get(0))) { +753 continue; +754 } +755 //this can't dereference a null 'identifiedVersion' because if it was null we would have exited +756 //in the above loop or just after loop (if matchesAnyPrevious return null). +757 if (entry.getValue() && identifiedVersion.compareTo(v) <= 0) { +758 if (!(isVersionTwoADifferentProduct && !identifiedVersion.getVersionParts().get(0).equals(v.getVersionParts().get(0)))) { +759 return entry; +760 } +761 } +762 } +763 } +764 return null; +765 } +766 +767 /** +768 * Parses the version (including revision) from a CPE identifier. If no +769 * version is identified then a '-' is returned. +770 * +771 * @param cpeStr a cpe identifier +772 * @return a dependency version +773 */ +774 private DependencyVersion parseDependencyVersion(String cpeStr) { +775 final VulnerableSoftware cpe = new VulnerableSoftware(); +776 try { +777 cpe.parseName(cpeStr); +778 } catch (UnsupportedEncodingException ex) { +779 //never going to happen. +780 LOGGER.trace("", ex); +781 } +782 return parseDependencyVersion(cpe); +783 } +784 +785 /** +786 * Takes a CPE and parses out the version number. If no version is +787 * identified then a '-' is returned. +788 * +789 * @param cpe a cpe object +790 * @return a dependency version +791 */ +792 private DependencyVersion parseDependencyVersion(VulnerableSoftware cpe) { +793 final DependencyVersion cpeVersion; +794 if (cpe.getVersion() != null && !cpe.getVersion().isEmpty()) { +795 final String versionText; +796 if (cpe.getUpdate() != null && !cpe.getUpdate().isEmpty()) { +797 versionText = String.format("%s.%s", cpe.getVersion(), cpe.getUpdate()); +798 } else { +799 versionText = cpe.getVersion(); +800 } +801 cpeVersion = DependencyVersionUtil.parseVersion(versionText); +802 } else { +803 cpeVersion = new DependencyVersion("-"); +804 } +805 return cpeVersion; +806 } +807 +808 /** +809 * This method is only referenced in unused code. +810 * +811 * Deletes unused dictionary entries from the database. +812 */ +813 public void deleteUnusedCpe() { +814 PreparedStatement ps = null; +815 try { +816 ps = getConnection().prepareStatement(statementBundle.getString("DELETE_UNUSED_DICT_CPE")); +817 ps.executeUpdate(); +818 } catch (SQLException ex) { +819 LOGGER.error("Unable to delete CPE dictionary entries", ex); +820 } finally { +821 DBUtils.closeStatement(ps); +822 } +823 } +824 +825 /** +826 * This method is only referenced in unused code and will likely break on +827 * MySQL if ever used due to the MERGE statement. +828 * +829 * Merges CPE entries into the database. 830 * -831 * Merges CPE entries into the database. -832 * -833 * @param cpe the CPE identifier -834 * @param vendor the CPE vendor -835 * @param product the CPE product -836 */ -837 public void addCpe(String cpe, String vendor, String product) { -838 PreparedStatement ps = null; -839 try { -840 ps = getConnection().prepareCall(statementBundle.getString("ADD_DICT_CPE")); -841 ps.setString(1, cpe); -842 ps.setString(2, vendor); -843 ps.setString(3, product); -844 ps.executeUpdate(); -845 } catch (SQLException ex) { -846 LOGGER.error("Unable to add CPE dictionary entry", ex); -847 } finally { -848 DBUtils.closeStatement(ps); -849 } -850 } -851 } +831 * @param cpe the CPE identifier +832 * @param vendor the CPE vendor +833 * @param product the CPE product +834 */ +835 public void addCpe(String cpe, String vendor, String product) { +836 PreparedStatement ps = null; +837 try { +838 ps = getConnection().prepareStatement(statementBundle.getString("ADD_DICT_CPE")); +839 ps.setString(1, cpe); +840 ps.setString(2, vendor); +841 ps.setString(3, product); +842 ps.executeUpdate(); +843 } catch (SQLException ex) { +844 LOGGER.error("Unable to add CPE dictionary entry", ex); +845 } finally { +846 DBUtils.closeStatement(ps); +847 } +848 } +849 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/package-frame.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/package-frame.html index af0294bde..b0d2aecee 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/package-frame.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.nvdcve + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.nvdcve diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/package-summary.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/package-summary.html index a155a3353..2ca21ca60 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/package-summary.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.nvdcve + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.nvdcve diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/EngineVersionCheck.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/EngineVersionCheck.html index 819d97414..756ce7202 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/EngineVersionCheck.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/EngineVersionCheck.html @@ -44,187 +44,203 @@ 36 import org.slf4j.LoggerFactory; 37 38 /** -39 * -40 * @author Jeremy Long -41 */ -42 public class EngineVersionCheck implements CachedWebDataSource { -43 -44 /** -45 * Static logger. -46 */ -47 private static final Logger LOGGER = LoggerFactory.getLogger(EngineVersionCheck.class); +39 * Checks the gh-pages dependency-check site to determine the current released +40 * version number. If the released version number is greater then the running +41 * version number a warning is printed recommending that an upgrade be +42 * performed. +43 * +44 * @author Jeremy Long +45 */ +46 public class EngineVersionCheck implements CachedWebDataSource { +47 48 /** -49 * The property key indicating when the last version check occurred. +49 * Static logger. 50 */ -51 public static final String ENGINE_VERSION_CHECKED_ON = "VersionCheckOn"; +51 private static final Logger LOGGER = LoggerFactory.getLogger(EngineVersionCheck.class); 52 /** 53 * The property key indicating when the last version check occurred. 54 */ -55 public static final String CURRENT_ENGINE_RELEASE = "CurrentEngineRelease"; +55 public static final String ENGINE_VERSION_CHECKED_ON = "VersionCheckOn"; 56 /** -57 * Reference to the Cve Database. +57 * The property key indicating when the last version check occurred. 58 */ -59 private CveDB cveDB = null; -60 -61 /** -62 * The version retrieved from the database properties or web to check against. -63 */ -64 private String updateToVersion; -65 -66 /** -67 * Getter for updateToVersion - only used for testing. Represents the version retrieved from the database. -68 * -69 * @return the version to test -70 */ -71 protected String getUpdateToVersion() { -72 return updateToVersion; -73 } -74 -75 /** -76 * Setter for updateToVersion - only used for testing. Represents the version retrieved from the database. -77 * -78 * @param version the version to test -79 */ -80 protected void setUpdateToVersion(String version) { -81 updateToVersion = version; -82 } -83 -84 @Override -85 public void update() throws UpdateException { -86 -87 try { -88 if (Settings.getBoolean(Settings.KEYS.AUTO_UPDATE)) { -89 openDatabase(); -90 LOGGER.debug("Begin Engine Version Check"); -91 final DatabaseProperties properties = cveDB.getDatabaseProperties(); -92 final long lastChecked = Long.parseLong(properties.getProperty(ENGINE_VERSION_CHECKED_ON, "0")); -93 final long now = System.currentTimeMillis(); -94 updateToVersion = properties.getProperty(CURRENT_ENGINE_RELEASE, ""); -95 final String currentVersion = Settings.getString(Settings.KEYS.APPLICATION_VERSION, "0.0.0"); -96 LOGGER.debug("Last checked: {}", lastChecked); -97 LOGGER.debug("Now: {}", now); -98 LOGGER.debug("Current version: {}", currentVersion); -99 final boolean updateNeeded = shouldUpdate(lastChecked, now, properties, currentVersion); -100 if (updateNeeded) { -101 LOGGER.warn("A new version of dependency-check is available. Consider updating to version {}.", -102 updateToVersion); -103 } -104 } -105 } catch (DatabaseException ex) { -106 LOGGER.debug("Database Exception opening databases to retrieve properties", ex); -107 throw new UpdateException("Error occured updating database properties."); -108 } catch (InvalidSettingException ex) { -109 LOGGER.debug("Unable to determine if autoupdate is enabled", ex); -110 } finally { -111 closeDatabase(); -112 -113 } -114 } -115 -116 /** -117 * Determines if a new version of the dependency-check engine has been released. -118 * -119 * @param lastChecked the epoch time of the last version check -120 * @param now the current epoch time -121 * @param properties the database properties object -122 * @param currentVersion the current version of dependency-check -123 * @return <code>true</code> if a newer version of the database has been released; otherwise <code>false</code> -124 * @throws UpdateException thrown if there is an error connecting to the github documentation site or accessing the local -125 * database. -126 */ -127 protected boolean shouldUpdate(final long lastChecked, final long now, final DatabaseProperties properties, -128 String currentVersion) throws UpdateException { -129 //check every 30 days if we know there is an update, otherwise check every 7 days -130 final int checkRange = 30; -131 if (!DateUtil.withinDateRange(lastChecked, now, checkRange)) { -132 LOGGER.debug("Checking web for new version."); -133 final String currentRelease = getCurrentReleaseVersion(); -134 if (currentRelease != null) { -135 final DependencyVersion v = new DependencyVersion(currentRelease); -136 if (v.getVersionParts() != null && v.getVersionParts().size() >= 3) { -137 updateToVersion = v.toString(); -138 if (!currentRelease.equals(updateToVersion)) { -139 properties.save(CURRENT_ENGINE_RELEASE, updateToVersion); -140 } -141 properties.save(ENGINE_VERSION_CHECKED_ON, Long.toString(now)); -142 } -143 } -144 LOGGER.debug("Current Release: {}", updateToVersion); -145 } -146 if (updateToVersion == null) { -147 LOGGER.debug("Unable to obtain current release"); -148 return false; -149 } -150 final DependencyVersion running = new DependencyVersion(currentVersion); -151 final DependencyVersion released = new DependencyVersion(updateToVersion); -152 if (running.compareTo(released) < 0) { -153 LOGGER.debug("Upgrade recommended"); -154 return true; -155 } -156 LOGGER.debug("Upgrade not needed"); -157 return false; -158 } -159 -160 /** -161 * Opens the CVE and CPE data stores. -162 * -163 * @throws DatabaseException thrown if a data store cannot be opened -164 */ -165 protected final void openDatabase() throws DatabaseException { -166 if (cveDB != null) { -167 return; -168 } -169 cveDB = new CveDB(); -170 cveDB.open(); -171 } -172 -173 /** -174 * Closes the CVE and CPE data stores. -175 */ -176 protected void closeDatabase() { -177 if (cveDB != null) { -178 try { -179 cveDB.close(); -180 cveDB = null; -181 } catch (Throwable ignore) { -182 LOGGER.trace("Error closing the cveDB", ignore); -183 } -184 } -185 } -186 -187 /** -188 * Retrieves the current released version number from the github documentation site. -189 * -190 * @return the current released version number -191 */ -192 protected String getCurrentReleaseVersion() { -193 HttpURLConnection conn = null; -194 try { -195 final String str = Settings.getString(Settings.KEYS.ENGINE_VERSION_CHECK_URL, "http://jeremylong.github.io/DependencyCheck/current.txt"); -196 final URL url = new URL(str); -197 conn = URLConnectionFactory.createHttpURLConnection(url); -198 conn.connect(); -199 if (conn.getResponseCode() != 200) { -200 return null; -201 } -202 final String releaseVersion = IOUtils.toString(conn.getInputStream(), "UTF-8"); -203 if (releaseVersion != null) { -204 return releaseVersion.trim(); -205 } -206 } catch (MalformedURLException ex) { -207 LOGGER.debug("unable to retrieve current release version of dependency-check", ex); -208 } catch (URLConnectionFailureException ex) { -209 LOGGER.debug("unable to retrieve current release version of dependency-check", ex); -210 } catch (IOException ex) { -211 LOGGER.debug("unable to retrieve current release version of dependency-check", ex); -212 } finally { -213 if (conn != null) { -214 conn.disconnect(); -215 } -216 } -217 return null; -218 } -219 } +59 public static final String CURRENT_ENGINE_RELEASE = "CurrentEngineRelease"; +60 /** +61 * Reference to the Cve Database. +62 */ +63 private CveDB cveDB = null; +64 +65 /** +66 * The version retrieved from the database properties or web to check +67 * against. +68 */ +69 private String updateToVersion; +70 +71 /** +72 * Getter for updateToVersion - only used for testing. Represents the +73 * version retrieved from the database. +74 * +75 * @return the version to test +76 */ +77 protected String getUpdateToVersion() { +78 return updateToVersion; +79 } +80 +81 /** +82 * Setter for updateToVersion - only used for testing. Represents the +83 * version retrieved from the database. +84 * +85 * @param version the version to test +86 */ +87 protected void setUpdateToVersion(String version) { +88 updateToVersion = version; +89 } +90 +91 /** +92 * Downloads the current released version number and compares it to the +93 * running engine's version number. If the released version number is newer +94 * a warning is printed recommending an upgrade. +95 * +96 * @throws UpdateException thrown if the local database properties could not +97 * be updated +98 */ +99 @Override +100 public void update() throws UpdateException { +101 try { +102 if (Settings.getBoolean(Settings.KEYS.AUTO_UPDATE)) { +103 openDatabase(); +104 LOGGER.debug("Begin Engine Version Check"); +105 final DatabaseProperties properties = cveDB.getDatabaseProperties(); +106 final long lastChecked = Long.parseLong(properties.getProperty(ENGINE_VERSION_CHECKED_ON, "0")); +107 final long now = System.currentTimeMillis(); +108 updateToVersion = properties.getProperty(CURRENT_ENGINE_RELEASE, ""); +109 final String currentVersion = Settings.getString(Settings.KEYS.APPLICATION_VERSION, "0.0.0"); +110 LOGGER.debug("Last checked: {}", lastChecked); +111 LOGGER.debug("Now: {}", now); +112 LOGGER.debug("Current version: {}", currentVersion); +113 final boolean updateNeeded = shouldUpdate(lastChecked, now, properties, currentVersion); +114 if (updateNeeded) { +115 LOGGER.warn("A new version of dependency-check is available. Consider updating to version {}.", +116 updateToVersion); +117 } +118 } +119 } catch (DatabaseException ex) { +120 LOGGER.debug("Database Exception opening databases to retrieve properties", ex); +121 throw new UpdateException("Error occured updating database properties."); +122 } catch (InvalidSettingException ex) { +123 LOGGER.debug("Unable to determine if autoupdate is enabled", ex); +124 } finally { +125 closeDatabase(); +126 } +127 } +128 +129 /** +130 * Determines if a new version of the dependency-check engine has been +131 * released. +132 * +133 * @param lastChecked the epoch time of the last version check +134 * @param now the current epoch time +135 * @param properties the database properties object +136 * @param currentVersion the current version of dependency-check +137 * @return <code>true</code> if a newer version of the database has been +138 * released; otherwise <code>false</code> +139 * @throws UpdateException thrown if there is an error connecting to the +140 * github documentation site or accessing the local database. +141 */ +142 protected boolean shouldUpdate(final long lastChecked, final long now, final DatabaseProperties properties, +143 String currentVersion) throws UpdateException { +144 //check every 30 days if we know there is an update, otherwise check every 7 days +145 final int checkRange = 30; +146 if (!DateUtil.withinDateRange(lastChecked, now, checkRange)) { +147 LOGGER.debug("Checking web for new version."); +148 final String currentRelease = getCurrentReleaseVersion(); +149 if (currentRelease != null) { +150 final DependencyVersion v = new DependencyVersion(currentRelease); +151 if (v.getVersionParts() != null && v.getVersionParts().size() >= 3) { +152 updateToVersion = v.toString(); +153 if (!currentRelease.equals(updateToVersion)) { +154 properties.save(CURRENT_ENGINE_RELEASE, updateToVersion); +155 } +156 properties.save(ENGINE_VERSION_CHECKED_ON, Long.toString(now)); +157 } +158 } +159 LOGGER.debug("Current Release: {}", updateToVersion); +160 } +161 if (updateToVersion == null) { +162 LOGGER.debug("Unable to obtain current release"); +163 return false; +164 } +165 final DependencyVersion running = new DependencyVersion(currentVersion); +166 final DependencyVersion released = new DependencyVersion(updateToVersion); +167 if (running.compareTo(released) < 0) { +168 LOGGER.debug("Upgrade recommended"); +169 return true; +170 } +171 LOGGER.debug("Upgrade not needed"); +172 return false; +173 } +174 +175 /** +176 * Opens the CVE and CPE data stores. +177 * +178 * @throws DatabaseException thrown if a data store cannot be opened +179 */ +180 protected final void openDatabase() throws DatabaseException { +181 if (cveDB != null) { +182 return; +183 } +184 cveDB = new CveDB(); +185 cveDB.open(); +186 } +187 +188 /** +189 * Closes the CVE and CPE data stores. +190 */ +191 protected void closeDatabase() { +192 if (cveDB != null) { +193 try { +194 cveDB.close(); +195 cveDB = null; +196 } catch (Throwable ignore) { +197 LOGGER.trace("Error closing the cveDB", ignore); +198 } +199 } +200 } +201 +202 /** +203 * Retrieves the current released version number from the github +204 * documentation site. +205 * +206 * @return the current released version number +207 */ +208 protected String getCurrentReleaseVersion() { +209 HttpURLConnection conn = null; +210 try { +211 final String str = Settings.getString(Settings.KEYS.ENGINE_VERSION_CHECK_URL, "http://jeremylong.github.io/DependencyCheck/current.txt"); +212 final URL url = new URL(str); +213 conn = URLConnectionFactory.createHttpURLConnection(url); +214 conn.connect(); +215 if (conn.getResponseCode() != 200) { +216 return null; +217 } +218 final String releaseVersion = IOUtils.toString(conn.getInputStream(), "UTF-8"); +219 if (releaseVersion != null) { +220 return releaseVersion.trim(); +221 } +222 } catch (MalformedURLException ex) { +223 LOGGER.debug("Unable to retrieve current release version of dependency-check", ex); +224 } catch (URLConnectionFailureException ex) { +225 LOGGER.debug("Unable to retrieve current release version of dependency-check", ex); +226 } catch (IOException ex) { +227 LOGGER.debug("Unable to retrieve current release version of dependency-check", ex); +228 } finally { +229 if (conn != null) { +230 conn.disconnect(); +231 } +232 } +233 return null; +234 } +235 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/NvdCveUpdater.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/NvdCveUpdater.html index 8d5a2bef0..3ec41ca83 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/NvdCveUpdater.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/NvdCveUpdater.html @@ -58,7 +58,7 @@ 50 public class NvdCveUpdater extends BaseUpdater implements CachedWebDataSource { 51 52 /** -53 * The logger +53 * The logger. 54 */ 55 private static final Logger LOGGER = LoggerFactory.getLogger(NvdCveUpdater.class); 56 /** @@ -67,301 +67,297 @@ 59 public static final int MAX_THREAD_POOL_SIZE = Settings.getInt(Settings.KEYS.MAX_DOWNLOAD_THREAD_POOL_SIZE, 3); 60 61 /** -62 * <p> -63 * Downloads the latest NVD CVE XML file from the web and imports it into -64 * the current CVE Database.</p> -65 * -66 * @throws UpdateException is thrown if there is an error updating the -67 * database -68 */ -69 @Override -70 public void update() throws UpdateException { -71 try { -72 openDataStores(); -73 boolean autoUpdate = true; -74 try { -75 autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE); -76 } catch (InvalidSettingException ex) { -77 LOGGER.debug("Invalid setting for auto-update; using true."); -78 } -79 if (autoUpdate && checkUpdate()) { -80 final UpdateableNvdCve updateable = getUpdatesNeeded(); -81 getProperties().save(DatabaseProperties.LAST_CHECKED, Long.toString(System.currentTimeMillis())); -82 if (updateable.isUpdateNeeded()) { -83 performUpdate(updateable); -84 } -85 } -86 } catch (MalformedURLException ex) { -87 LOGGER.warn( -88 "NVD CVE properties files contain an invalid URL, unable to update the data to use the most current data."); -89 LOGGER.debug("", ex); -90 } catch (DownloadFailedException ex) { -91 LOGGER.warn( -92 "Unable to download the NVD CVE data; the results may not include the most recent CPE/CVEs from the NVD."); -93 if (Settings.getString(Settings.KEYS.PROXY_SERVER) == null) { -94 LOGGER.info( -95 "If you are behind a proxy you may need to configure dependency-check to use the proxy."); -96 } -97 LOGGER.debug("", ex); -98 } finally { -99 closeDataStores(); -100 } -101 } -102 -103 /** -104 * Checks if the NVD CVE XML files were last checked recently. As an -105 * optimization, we can avoid repetitive checks against the NVD. Setting -106 * CVE_CHECK_VALID_FOR_HOURS determines the duration since last check before -107 * checking again. A database property stores the timestamp of the last -108 * check. -109 * -110 * @return true to proceed with the check, or false to skip. -111 * @throws UpdateException thrown when there is an issue checking for -112 * updates. -113 */ -114 private boolean checkUpdate() throws UpdateException { -115 boolean proceed = true; -116 // If the valid setting has not been specified, then we proceed to check... -117 final int validForHours = Settings.getInt(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, 0); -118 if (dataExists() && 0 < validForHours) { -119 // ms Valid = valid (hours) x 60 min/hour x 60 sec/min x 1000 ms/sec -120 final long msValid = validForHours * 60L * 60L * 1000L; -121 final long lastChecked = Long.parseLong(getProperties().getProperty(DatabaseProperties.LAST_CHECKED, "0")); -122 final long now = System.currentTimeMillis(); -123 proceed = (now - lastChecked) > msValid; -124 if (!proceed) { -125 LOGGER.info("Skipping NVD check since last check was within {} hours.", validForHours); -126 LOGGER.debug("Last NVD was at {}, and now {} is within {} ms.", -127 lastChecked, now, msValid); -128 } -129 } -130 return proceed; -131 } -132 -133 /** -134 * Checks the CVE Index to ensure data exists and analysis can continue. -135 * -136 * @return true if the database contains data -137 */ -138 private boolean dataExists() { -139 CveDB cve = null; -140 try { -141 cve = new CveDB(); -142 cve.open(); -143 return cve.dataExists(); -144 } catch (DatabaseException ex) { -145 return false; -146 } finally { -147 if (cve != null) { -148 cve.close(); -149 } -150 } -151 } -152 -153 /** -154 * Downloads the latest NVD CVE XML file from the web and imports it into -155 * the current CVE Database. -156 * -157 * @param updateable a collection of NVD CVE data file references that need -158 * to be downloaded and processed to update the database -159 * @throws UpdateException is thrown if there is an error updating the -160 * database -161 */ -162 public void performUpdate(UpdateableNvdCve updateable) throws UpdateException { -163 int maxUpdates = 0; -164 try { -165 for (NvdCveInfo cve : updateable) { -166 if (cve.getNeedsUpdate()) { -167 maxUpdates += 1; -168 } +62 * Downloads the latest NVD CVE XML file from the web and imports it into +63 * the current CVE Database. +64 * +65 * @throws UpdateException is thrown if there is an error updating the +66 * database +67 */ +68 @Override +69 public void update() throws UpdateException { +70 try { +71 openDataStores(); +72 boolean autoUpdate = true; +73 try { +74 autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE); +75 } catch (InvalidSettingException ex) { +76 LOGGER.debug("Invalid setting for auto-update; using true."); +77 } +78 if (autoUpdate && checkUpdate()) { +79 final UpdateableNvdCve updateable = getUpdatesNeeded(); +80 getProperties().save(DatabaseProperties.LAST_CHECKED, Long.toString(System.currentTimeMillis())); +81 if (updateable.isUpdateNeeded()) { +82 performUpdate(updateable); +83 } +84 } +85 } catch (MalformedURLException ex) { +86 throw new UpdateException("NVD CVE properties files contain an invalid URL, unable to update the data to use the most current data.", ex); +87 } catch (DownloadFailedException ex) { +88 LOGGER.warn( +89 "Unable to download the NVD CVE data; the results may not include the most recent CPE/CVEs from the NVD."); +90 if (Settings.getString(Settings.KEYS.PROXY_SERVER) == null) { +91 LOGGER.info( +92 "If you are behind a proxy you may need to configure dependency-check to use the proxy."); +93 } +94 throw new UpdateException("Unable to download the NVD CVE data.", ex); +95 } finally { +96 closeDataStores(); +97 } +98 } +99 +100 /** +101 * Checks if the NVD CVE XML files were last checked recently. As an +102 * optimization, we can avoid repetitive checks against the NVD. Setting +103 * CVE_CHECK_VALID_FOR_HOURS determines the duration since last check before +104 * checking again. A database property stores the timestamp of the last +105 * check. +106 * +107 * @return true to proceed with the check, or false to skip +108 * @throws UpdateException thrown when there is an issue checking for +109 * updates +110 */ +111 private boolean checkUpdate() throws UpdateException { +112 boolean proceed = true; +113 // If the valid setting has not been specified, then we proceed to check... +114 final int validForHours = Settings.getInt(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, 0); +115 if (dataExists() && 0 < validForHours) { +116 // ms Valid = valid (hours) x 60 min/hour x 60 sec/min x 1000 ms/sec +117 final long msValid = validForHours * 60L * 60L * 1000L; +118 final long lastChecked = Long.parseLong(getProperties().getProperty(DatabaseProperties.LAST_CHECKED, "0")); +119 final long now = System.currentTimeMillis(); +120 proceed = (now - lastChecked) > msValid; +121 if (!proceed) { +122 LOGGER.info("Skipping NVD check since last check was within {} hours.", validForHours); +123 LOGGER.debug("Last NVD was at {}, and now {} is within {} ms.", +124 lastChecked, now, msValid); +125 } +126 } +127 return proceed; +128 } +129 +130 /** +131 * Checks the CVE Index to ensure data exists and analysis can continue. +132 * +133 * @return true if the database contains data +134 */ +135 private boolean dataExists() { +136 CveDB cve = null; +137 try { +138 cve = new CveDB(); +139 cve.open(); +140 return cve.dataExists(); +141 } catch (DatabaseException ex) { +142 return false; +143 } finally { +144 if (cve != null) { +145 cve.close(); +146 } +147 } +148 } +149 +150 /** +151 * Downloads the latest NVD CVE XML file from the web and imports it into +152 * the current CVE Database. +153 * +154 * @param updateable a collection of NVD CVE data file references that need +155 * to be downloaded and processed to update the database +156 * @throws UpdateException is thrown if there is an error updating the +157 * database +158 */ +159 public void performUpdate(UpdateableNvdCve updateable) throws UpdateException { +160 int maxUpdates = 0; +161 try { +162 for (NvdCveInfo cve : updateable) { +163 if (cve.getNeedsUpdate()) { +164 maxUpdates += 1; +165 } +166 } +167 if (maxUpdates <= 0) { +168 return; 169 } -170 if (maxUpdates <= 0) { -171 return; +170 if (maxUpdates > 3) { +171 LOGGER.info("NVD CVE requires several updates; this could take a couple of minutes."); 172 } -173 if (maxUpdates > 3) { -174 LOGGER.info( -175 "NVD CVE requires several updates; this could take a couple of minutes."); -176 } -177 if (maxUpdates > 0) { -178 openDataStores(); -179 } -180 -181 final int poolSize = (MAX_THREAD_POOL_SIZE < maxUpdates) ? MAX_THREAD_POOL_SIZE : maxUpdates; -182 -183 final ExecutorService downloadExecutors = Executors.newFixedThreadPool(poolSize); -184 final ExecutorService processExecutor = Executors.newSingleThreadExecutor(); -185 final Set<Future<Future<ProcessTask>>> downloadFutures = new HashSet<Future<Future<ProcessTask>>>(maxUpdates); -186 for (NvdCveInfo cve : updateable) { -187 if (cve.getNeedsUpdate()) { -188 final DownloadTask call = new DownloadTask(cve, processExecutor, getCveDB(), Settings.getInstance()); -189 downloadFutures.add(downloadExecutors.submit(call)); -190 } -191 } -192 downloadExecutors.shutdown(); -193 -194 //next, move the future future processTasks to just future processTasks -195 final Set<Future<ProcessTask>> processFutures = new HashSet<Future<ProcessTask>>(maxUpdates); -196 for (Future<Future<ProcessTask>> future : downloadFutures) { -197 Future<ProcessTask> task = null; -198 try { -199 task = future.get(); -200 } catch (InterruptedException ex) { -201 downloadExecutors.shutdownNow(); -202 processExecutor.shutdownNow(); -203 -204 LOGGER.debug("Thread was interrupted during download", ex); -205 throw new UpdateException("The download was interrupted", ex); -206 } catch (ExecutionException ex) { -207 downloadExecutors.shutdownNow(); -208 processExecutor.shutdownNow(); -209 -210 LOGGER.debug("Thread was interrupted during download execution", ex); -211 throw new UpdateException("The execution of the download was interrupted", ex); -212 } -213 if (task == null) { -214 downloadExecutors.shutdownNow(); -215 processExecutor.shutdownNow(); -216 LOGGER.debug("Thread was interrupted during download"); -217 throw new UpdateException("The download was interrupted; unable to complete the update"); -218 } else { -219 processFutures.add(task); -220 } -221 } -222 -223 for (Future<ProcessTask> future : processFutures) { -224 try { -225 final ProcessTask task = future.get(); -226 if (task.getException() != null) { -227 throw task.getException(); -228 } -229 } catch (InterruptedException ex) { +173 if (maxUpdates > 0) { +174 openDataStores(); +175 } +176 +177 final int poolSize = (MAX_THREAD_POOL_SIZE < maxUpdates) ? MAX_THREAD_POOL_SIZE : maxUpdates; +178 +179 final ExecutorService downloadExecutors = Executors.newFixedThreadPool(poolSize); +180 final ExecutorService processExecutor = Executors.newSingleThreadExecutor(); +181 final Set<Future<Future<ProcessTask>>> downloadFutures = new HashSet<Future<Future<ProcessTask>>>(maxUpdates); +182 for (NvdCveInfo cve : updateable) { +183 if (cve.getNeedsUpdate()) { +184 final DownloadTask call = new DownloadTask(cve, processExecutor, getCveDB(), Settings.getInstance()); +185 downloadFutures.add(downloadExecutors.submit(call)); +186 } +187 } +188 downloadExecutors.shutdown(); +189 +190 //next, move the future future processTasks to just future processTasks +191 final Set<Future<ProcessTask>> processFutures = new HashSet<Future<ProcessTask>>(maxUpdates); +192 for (Future<Future<ProcessTask>> future : downloadFutures) { +193 Future<ProcessTask> task = null; +194 try { +195 task = future.get(); +196 } catch (InterruptedException ex) { +197 downloadExecutors.shutdownNow(); +198 processExecutor.shutdownNow(); +199 +200 LOGGER.debug("Thread was interrupted during download", ex); +201 throw new UpdateException("The download was interrupted", ex); +202 } catch (ExecutionException ex) { +203 downloadExecutors.shutdownNow(); +204 processExecutor.shutdownNow(); +205 +206 LOGGER.debug("Thread was interrupted during download execution", ex); +207 throw new UpdateException("The execution of the download was interrupted", ex); +208 } +209 if (task == null) { +210 downloadExecutors.shutdownNow(); +211 processExecutor.shutdownNow(); +212 LOGGER.debug("Thread was interrupted during download"); +213 throw new UpdateException("The download was interrupted; unable to complete the update"); +214 } else { +215 processFutures.add(task); +216 } +217 } +218 +219 for (Future<ProcessTask> future : processFutures) { +220 try { +221 final ProcessTask task = future.get(); +222 if (task.getException() != null) { +223 throw task.getException(); +224 } +225 } catch (InterruptedException ex) { +226 processExecutor.shutdownNow(); +227 LOGGER.debug("Thread was interrupted during processing", ex); +228 throw new UpdateException(ex); +229 } catch (ExecutionException ex) { 230 processExecutor.shutdownNow(); -231 LOGGER.debug("Thread was interrupted during processing", ex); +231 LOGGER.debug("Execution Exception during process", ex); 232 throw new UpdateException(ex); -233 } catch (ExecutionException ex) { -234 processExecutor.shutdownNow(); -235 LOGGER.debug("Execution Exception during process", ex); -236 throw new UpdateException(ex); -237 } finally { -238 processExecutor.shutdown(); -239 } -240 } -241 -242 if (maxUpdates >= 1) { //ensure the modified file date gets written (we may not have actually updated it) -243 getProperties().save(updateable.get(MODIFIED)); -244 LOGGER.info("Begin database maintenance."); -245 getCveDB().cleanupDatabase(); -246 LOGGER.info("End database maintenance."); -247 } -248 } finally { -249 closeDataStores(); -250 } -251 } -252 -253 /** -254 * Determines if the index needs to be updated. This is done by fetching the -255 * NVD CVE meta data and checking the last update date. If the data needs to -256 * be refreshed this method will return the NvdCveUrl for the files that -257 * need to be updated. -258 * -259 * @return the collection of files that need to be updated -260 * @throws MalformedURLException is thrown if the URL for the NVD CVE Meta -261 * data is incorrect -262 * @throws DownloadFailedException is thrown if there is an error. -263 * downloading the NVD CVE download data file -264 * @throws UpdateException Is thrown if there is an issue with the last -265 * updated properties file -266 */ -267 protected final UpdateableNvdCve getUpdatesNeeded() throws MalformedURLException, DownloadFailedException, UpdateException { -268 UpdateableNvdCve updates = null; -269 try { -270 updates = retrieveCurrentTimestampsFromWeb(); -271 } catch (InvalidDataException ex) { -272 final String msg = "Unable to retrieve valid timestamp from nvd cve downloads page"; -273 LOGGER.debug(msg, ex); -274 throw new DownloadFailedException(msg, ex); -275 } catch (InvalidSettingException ex) { -276 LOGGER.debug("Invalid setting found when retrieving timestamps", ex); -277 throw new DownloadFailedException("Invalid settings", ex); +233 } finally { +234 processExecutor.shutdown(); +235 } +236 } +237 +238 if (maxUpdates >= 1) { //ensure the modified file date gets written (we may not have actually updated it) +239 getProperties().save(updateable.get(MODIFIED)); +240 LOGGER.info("Begin database maintenance."); +241 getCveDB().cleanupDatabase(); +242 LOGGER.info("End database maintenance."); +243 } +244 } finally { +245 closeDataStores(); +246 } +247 } +248 +249 /** +250 * Determines if the index needs to be updated. This is done by fetching the +251 * NVD CVE meta data and checking the last update date. If the data needs to +252 * be refreshed this method will return the NvdCveUrl for the files that +253 * need to be updated. +254 * +255 * @return the collection of files that need to be updated +256 * @throws MalformedURLException is thrown if the URL for the NVD CVE Meta +257 * data is incorrect +258 * @throws DownloadFailedException is thrown if there is an error. +259 * downloading the NVD CVE download data file +260 * @throws UpdateException Is thrown if there is an issue with the last +261 * updated properties file +262 */ +263 protected final UpdateableNvdCve getUpdatesNeeded() throws MalformedURLException, DownloadFailedException, UpdateException { +264 UpdateableNvdCve updates = null; +265 try { +266 updates = retrieveCurrentTimestampsFromWeb(); +267 } catch (InvalidDataException ex) { +268 final String msg = "Unable to retrieve valid timestamp from nvd cve downloads page"; +269 LOGGER.debug(msg, ex); +270 throw new DownloadFailedException(msg, ex); +271 } catch (InvalidSettingException ex) { +272 LOGGER.debug("Invalid setting found when retrieving timestamps", ex); +273 throw new DownloadFailedException("Invalid settings", ex); +274 } +275 +276 if (updates == null) { +277 throw new DownloadFailedException("Unable to retrieve the timestamps of the currently published NVD CVE data"); 278 } -279 -280 if (updates == null) { -281 throw new DownloadFailedException("Unable to retrieve the timestamps of the currently published NVD CVE data"); -282 } -283 if (!getProperties().isEmpty()) { -284 try { -285 final long lastUpdated = Long.parseLong(getProperties().getProperty(DatabaseProperties.LAST_UPDATED, "0")); -286 final long now = System.currentTimeMillis(); -287 final int days = Settings.getInt(Settings.KEYS.CVE_MODIFIED_VALID_FOR_DAYS, 7); -288 if (lastUpdated == updates.getTimeStamp(MODIFIED)) { -289 updates.clear(); //we don't need to update anything. -290 } else if (DateUtil.withinDateRange(lastUpdated, now, days)) { -291 for (NvdCveInfo entry : updates) { -292 if (MODIFIED.equals(entry.getId())) { -293 entry.setNeedsUpdate(true); -294 } else { -295 entry.setNeedsUpdate(false); -296 } -297 } -298 } else { //we figure out which of the several XML files need to be downloaded. -299 for (NvdCveInfo entry : updates) { -300 if (MODIFIED.equals(entry.getId())) { -301 entry.setNeedsUpdate(true); -302 } else { -303 long currentTimestamp = 0; -304 try { -305 currentTimestamp = Long.parseLong(getProperties().getProperty(DatabaseProperties.LAST_UPDATED_BASE -306 + entry.getId(), "0")); -307 } catch (NumberFormatException ex) { -308 LOGGER.debug("Error parsing '{}' '{}' from nvdcve.lastupdated", -309 DatabaseProperties.LAST_UPDATED_BASE, entry.getId(), ex); -310 } -311 if (currentTimestamp == entry.getTimestamp()) { -312 entry.setNeedsUpdate(false); -313 } -314 } -315 } -316 } -317 } catch (NumberFormatException ex) { -318 LOGGER.warn("An invalid schema version or timestamp exists in the data.properties file."); -319 LOGGER.debug("", ex); -320 } -321 } -322 return updates; -323 } -324 -325 /** -326 * Retrieves the timestamps from the NVD CVE meta data file. -327 * -328 * @return the timestamp from the currently published nvdcve downloads page -329 * @throws MalformedURLException thrown if the URL for the NVD CCE Meta data -330 * is incorrect. -331 * @throws DownloadFailedException thrown if there is an error downloading -332 * the nvd cve meta data file -333 * @throws InvalidDataException thrown if there is an exception parsing the -334 * timestamps -335 * @throws InvalidSettingException thrown if the settings are invalid -336 */ -337 private UpdateableNvdCve retrieveCurrentTimestampsFromWeb() -338 throws MalformedURLException, DownloadFailedException, InvalidDataException, InvalidSettingException { -339 -340 final UpdateableNvdCve updates = new UpdateableNvdCve(); -341 updates.add(MODIFIED, Settings.getString(Settings.KEYS.CVE_MODIFIED_20_URL), -342 Settings.getString(Settings.KEYS.CVE_MODIFIED_12_URL), -343 false); -344 -345 final int start = Settings.getInt(Settings.KEYS.CVE_START_YEAR); -346 final int end = Calendar.getInstance().get(Calendar.YEAR); -347 final String baseUrl20 = Settings.getString(Settings.KEYS.CVE_SCHEMA_2_0); -348 final String baseUrl12 = Settings.getString(Settings.KEYS.CVE_SCHEMA_1_2); -349 for (int i = start; i <= end; i++) { -350 updates.add(Integer.toString(i), String.format(baseUrl20, i), -351 String.format(baseUrl12, i), -352 true); -353 } -354 return updates; -355 } -356 } +279 if (!getProperties().isEmpty()) { +280 try { +281 final long lastUpdated = Long.parseLong(getProperties().getProperty(DatabaseProperties.LAST_UPDATED, "0")); +282 final long now = System.currentTimeMillis(); +283 final int days = Settings.getInt(Settings.KEYS.CVE_MODIFIED_VALID_FOR_DAYS, 7); +284 if (lastUpdated == updates.getTimeStamp(MODIFIED)) { +285 updates.clear(); //we don't need to update anything. +286 } else if (DateUtil.withinDateRange(lastUpdated, now, days)) { +287 for (NvdCveInfo entry : updates) { +288 if (MODIFIED.equals(entry.getId())) { +289 entry.setNeedsUpdate(true); +290 } else { +291 entry.setNeedsUpdate(false); +292 } +293 } +294 } else { //we figure out which of the several XML files need to be downloaded. +295 for (NvdCveInfo entry : updates) { +296 if (MODIFIED.equals(entry.getId())) { +297 entry.setNeedsUpdate(true); +298 } else { +299 long currentTimestamp = 0; +300 try { +301 currentTimestamp = Long.parseLong(getProperties().getProperty(DatabaseProperties.LAST_UPDATED_BASE +302 + entry.getId(), "0")); +303 } catch (NumberFormatException ex) { +304 LOGGER.debug("Error parsing '{}' '{}' from nvdcve.lastupdated", +305 DatabaseProperties.LAST_UPDATED_BASE, entry.getId(), ex); +306 } +307 if (currentTimestamp == entry.getTimestamp()) { +308 entry.setNeedsUpdate(false); +309 } +310 } +311 } +312 } +313 } catch (NumberFormatException ex) { +314 LOGGER.warn("An invalid schema version or timestamp exists in the data.properties file."); +315 LOGGER.debug("", ex); +316 } +317 } +318 return updates; +319 } +320 +321 /** +322 * Retrieves the timestamps from the NVD CVE meta data file. +323 * +324 * @return the timestamp from the currently published nvdcve downloads page +325 * @throws MalformedURLException thrown if the URL for the NVD CCE Meta data +326 * is incorrect. +327 * @throws DownloadFailedException thrown if there is an error downloading +328 * the nvd cve meta data file +329 * @throws InvalidDataException thrown if there is an exception parsing the +330 * timestamps +331 * @throws InvalidSettingException thrown if the settings are invalid +332 */ +333 private UpdateableNvdCve retrieveCurrentTimestampsFromWeb() +334 throws MalformedURLException, DownloadFailedException, InvalidDataException, InvalidSettingException { +335 +336 final UpdateableNvdCve updates = new UpdateableNvdCve(); +337 updates.add(MODIFIED, Settings.getString(Settings.KEYS.CVE_MODIFIED_20_URL), +338 Settings.getString(Settings.KEYS.CVE_MODIFIED_12_URL), +339 false); +340 +341 final int start = Settings.getInt(Settings.KEYS.CVE_START_YEAR); +342 final int end = Calendar.getInstance().get(Calendar.YEAR); +343 final String baseUrl20 = Settings.getString(Settings.KEYS.CVE_SCHEMA_2_0); +344 final String baseUrl12 = Settings.getString(Settings.KEYS.CVE_SCHEMA_1_2); +345 for (int i = start; i <= end; i++) { +346 updates.add(Integer.toString(i), String.format(baseUrl20, i), +347 String.format(baseUrl12, i), +348 true); +349 } +350 return updates; +351 } +352 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/cpe/CPEHandler.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/cpe/CPEHandler.html index 80c05cb39..fcf7d052b 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/cpe/CPEHandler.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/cpe/CPEHandler.html @@ -30,346 +30,357 @@ 22 import java.util.List; 23 import org.owasp.dependencycheck.data.update.NvdCveUpdater; 24 import org.owasp.dependencycheck.data.update.exception.InvalidDataException; -25 import org.slf4j.Logger; -26 import org.slf4j.LoggerFactory; -27 import org.xml.sax.Attributes; -28 import org.xml.sax.SAXException; -29 import org.xml.sax.helpers.DefaultHandler; -30 -31 /** -32 * A SAX Handler that will parse the CPE XML and load it into the databse. -33 * -34 * @author Jeremy Long -35 */ -36 public class CPEHandler extends DefaultHandler { -37 -38 /** -39 * The current CPE schema. -40 */ -41 private static final String CURRENT_SCHEMA_VERSION = "2.3"; -42 /** -43 * The text content of the node being processed. This can be used during the end element event. -44 */ -45 private StringBuilder nodeText = null; -46 /** -47 * A reference to the current element. -48 */ -49 private final Element current = new Element(); -50 /** -51 * The logger. -52 */ -53 private static final Logger LOGGER = LoggerFactory.getLogger(NvdCveUpdater.class); -54 /** -55 * The list of CPE values. -56 */ -57 private final List<Cpe> data = new ArrayList<Cpe>(); -58 -59 /** -60 * Returns the list of CPE values. -61 * -62 * @return the list of CPE values -63 */ -64 public List<Cpe> getData() { -65 return data; -66 } -67 -68 /** -69 * Handles the start element event. -70 * -71 * @param uri the elements uri -72 * @param localName the local name -73 * @param qName the qualified name -74 * @param attributes the attributes -75 * @throws SAXException thrown if there is an exception processing the element -76 */ -77 @Override -78 public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { -79 nodeText = null; -80 current.setNode(qName); -81 if (current.isCpeItemNode()) { -82 final String temp = attributes.getValue("deprecated"); -83 final String value = attributes.getValue("name"); -84 final boolean delete = "true".equalsIgnoreCase(temp); -85 if (!delete && value.startsWith("cpe:/a:") && value.length() > 7) { -86 try { -87 final Cpe cpe = new Cpe(value); -88 data.add(cpe); -89 } catch (UnsupportedEncodingException ex) { -90 LOGGER.debug("Unable to parse the CPE", ex); -91 } catch (InvalidDataException ex) { -92 LOGGER.debug("CPE is not the correct format", ex); -93 } -94 } -95 } else if (current.isSchemaVersionNode()) { -96 nodeText = new StringBuilder(3); -97 } -98 // } else if (current.isTitleNode()) { -99 // //do nothing -100 // } else if (current.isMetaNode()) { -101 // //do nothing -102 // } else if (current.isTimestampNode()) { -103 // //do nothing -104 // } else if (current.isCpeListNode()) { -105 // //do nothing -106 // } else if (current.isNotesNode()) { -107 // //do nothing -108 // } else if (current.isNoteNode()) { -109 // //do nothing -110 // } else if (current.isCheckNode()) { -111 // //do nothing -112 // } else if (current.isGeneratorNode()) { -113 // //do nothing -114 // } else if (current.isProductNameNode()) { -115 // //do nothing -116 // } else if (current.isProductVersionNode()) { -117 // //do nothing -118 } -119 -120 /** -121 * Reads the characters in the current node. -122 * -123 * @param ch the char array -124 * @param start the start position of the data read -125 * @param length the length of the data read -126 * @throws SAXException thrown if there is an exception processing the characters -127 */ -128 @Override -129 public void characters(char[] ch, int start, int length) throws SAXException { -130 if (nodeText != null) { -131 nodeText.append(ch, start, length); -132 } -133 } -134 -135 /** -136 * Handles the end element event. Stores the CPE data in the Cve Database if the cpe item node is ending. -137 * -138 * @param uri the element's uri -139 * @param localName the local name -140 * @param qName the qualified name -141 * @throws SAXException thrown if there is an exception processing the element -142 */ -143 @Override -144 public void endElement(String uri, String localName, String qName) throws SAXException { -145 current.setNode(qName); -146 if (current.isSchemaVersionNode() && !CURRENT_SCHEMA_VERSION.equals(nodeText.toString())) { -147 throw new SAXException("ERROR: Unexpecgted CPE Schema Version, expected: " -148 + CURRENT_SCHEMA_VERSION + ", file is: " + nodeText); -149 -150 } -151 // } else if (current.isCpeItemNode()) { -152 // //do nothing -153 // } else if (current.isTitleNode()) { -154 // //do nothing -155 // } else if (current.isCpeListNode()) { -156 // //do nothing -157 // } else if (current.isMetaNode()) { -158 // //do nothing -159 // } else if (current.isNotesNode()) { -160 // //do nothing -161 // } else if (current.isNoteNode()) { +25 import org.owasp.dependencycheck.utils.Settings; +26 import org.slf4j.Logger; +27 import org.slf4j.LoggerFactory; +28 import org.xml.sax.Attributes; +29 import org.xml.sax.SAXException; +30 import org.xml.sax.helpers.DefaultHandler; +31 +32 /** +33 * A SAX Handler that will parse the CPE XML and load it into the databse. +34 * +35 * @author Jeremy Long +36 */ +37 public class CPEHandler extends DefaultHandler { +38 +39 /** +40 * The current CPE schema. +41 */ +42 private static final String CURRENT_SCHEMA_VERSION = "2.3"; +43 /** +44 * The Starts with expression to filter CVE entries by CPE. +45 */ +46 private static final String CPE_STARTS_WITH = Settings.getString(Settings.KEYS.CVE_CPE_STARTS_WITH_FILTER, "cpe:/a:"); +47 /** +48 * The text content of the node being processed. This can be used during the +49 * end element event. +50 */ +51 private StringBuilder nodeText = null; +52 /** +53 * A reference to the current element. +54 */ +55 private final Element current = new Element(); +56 /** +57 * The logger. +58 */ +59 private static final Logger LOGGER = LoggerFactory.getLogger(NvdCveUpdater.class); +60 /** +61 * The list of CPE values. +62 */ +63 private final List<Cpe> data = new ArrayList<Cpe>(); +64 +65 /** +66 * Returns the list of CPE values. +67 * +68 * @return the list of CPE values +69 */ +70 public List<Cpe> getData() { +71 return data; +72 } +73 +74 /** +75 * Handles the start element event. +76 * +77 * @param uri the elements uri +78 * @param localName the local name +79 * @param qName the qualified name +80 * @param attributes the attributes +81 * @throws SAXException thrown if there is an exception processing the +82 * element +83 */ +84 @Override +85 public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { +86 nodeText = null; +87 current.setNode(qName); +88 if (current.isCpeItemNode()) { +89 final String temp = attributes.getValue("deprecated"); +90 final String value = attributes.getValue("name"); +91 final boolean delete = "true".equalsIgnoreCase(temp); +92 if (!delete && value.startsWith(CPE_STARTS_WITH) && value.length() > 7) { +93 try { +94 final Cpe cpe = new Cpe(value); +95 data.add(cpe); +96 } catch (UnsupportedEncodingException ex) { +97 LOGGER.debug("Unable to parse the CPE", ex); +98 } catch (InvalidDataException ex) { +99 LOGGER.debug("CPE is not the correct format", ex); +100 } +101 } +102 } else if (current.isSchemaVersionNode()) { +103 nodeText = new StringBuilder(3); +104 } +105 // } else if (current.isTitleNode()) { +106 // //do nothing +107 // } else if (current.isMetaNode()) { +108 // //do nothing +109 // } else if (current.isTimestampNode()) { +110 // //do nothing +111 // } else if (current.isCpeListNode()) { +112 // //do nothing +113 // } else if (current.isNotesNode()) { +114 // //do nothing +115 // } else if (current.isNoteNode()) { +116 // //do nothing +117 // } else if (current.isCheckNode()) { +118 // //do nothing +119 // } else if (current.isGeneratorNode()) { +120 // //do nothing +121 // } else if (current.isProductNameNode()) { +122 // //do nothing +123 // } else if (current.isProductVersionNode()) { +124 // //do nothing +125 } +126 +127 /** +128 * Reads the characters in the current node. +129 * +130 * @param ch the char array +131 * @param start the start position of the data read +132 * @param length the length of the data read +133 * @throws SAXException thrown if there is an exception processing the +134 * characters +135 */ +136 @Override +137 public void characters(char[] ch, int start, int length) throws SAXException { +138 if (nodeText != null) { +139 nodeText.append(ch, start, length); +140 } +141 } +142 +143 /** +144 * Handles the end element event. Stores the CPE data in the Cve Database if +145 * the cpe item node is ending. +146 * +147 * @param uri the element's uri +148 * @param localName the local name +149 * @param qName the qualified name +150 * @throws SAXException thrown if there is an exception processing the +151 * element +152 */ +153 @Override +154 public void endElement(String uri, String localName, String qName) throws SAXException { +155 current.setNode(qName); +156 if (current.isSchemaVersionNode() && !CURRENT_SCHEMA_VERSION.equals(nodeText.toString())) { +157 throw new SAXException("ERROR: Unexpecgted CPE Schema Version, expected: " +158 + CURRENT_SCHEMA_VERSION + ", file is: " + nodeText); +159 +160 } +161 // } else if (current.isCpeItemNode()) { 162 // //do nothing -163 // } else if (current.isCheckNode()) { +163 // } else if (current.isTitleNode()) { 164 // //do nothing -165 // } else if (current.isGeneratorNode()) { +165 // } else if (current.isCpeListNode()) { 166 // //do nothing -167 // } else if (current.isProductNameNode()) { +167 // } else if (current.isMetaNode()) { 168 // //do nothing -169 // } else if (current.isProductVersionNode()) { +169 // } else if (current.isNotesNode()) { 170 // //do nothing -171 // else if (current.isTimestampNode()) { +171 // } else if (current.isNoteNode()) { 172 // //do nothing -173 // } else { -174 // throw new SAXException("ERROR STATE: Unexpected qName '" + qName + "'"); -175 // } -176 } -177 -178 // <editor-fold defaultstate="collapsed" desc="The Element Class that maintains state information about the current node"> -179 /** -180 * A simple class to maintain information about the current element while parsing the CPE XML. -181 */ -182 protected static final class Element { -183 -184 /** -185 * A node type in the CPE Schema 2.2 -186 */ -187 public static final String CPE_LIST = "cpe-list"; -188 /** -189 * A node type in the CPE Schema 2.2 -190 */ -191 public static final String CPE_ITEM = "cpe-item"; -192 /** -193 * A node type in the CPE Schema 2.2 -194 */ -195 public static final String TITLE = "title"; -196 /** -197 * A node type in the CPE Schema 2.2 -198 */ -199 public static final String NOTES = "notes"; -200 /** -201 * A node type in the CPE Schema 2.2 -202 */ -203 public static final String NOTE = "note"; -204 /** -205 * A node type in the CPE Schema 2.2 -206 */ -207 public static final String CHECK = "check"; -208 /** -209 * A node type in the CPE Schema 2.2 -210 */ -211 public static final String META = "meta:item-metadata"; -212 /** -213 * A node type in the CPE Schema 2.2 -214 */ -215 public static final String GENERATOR = "generator"; -216 /** -217 * A node type in the CPE Schema 2.2 -218 */ -219 public static final String PRODUCT_NAME = "product_name"; -220 /** -221 * A node type in the CPE Schema 2.2 -222 */ -223 public static final String PRODUCT_VERSION = "product_version"; -224 /** -225 * A node type in the CPE Schema 2.2 -226 */ -227 public static final String SCHEMA_VERSION = "schema_version"; -228 /** -229 * A node type in the CPE Schema 2.2 -230 */ -231 public static final String TIMESTAMP = "timestamp"; -232 /** -233 * A reference to the current node. -234 */ -235 private String node = null; -236 -237 /** -238 * Gets the value of node -239 * -240 * @return the value of node +173 // } else if (current.isCheckNode()) { +174 // //do nothing +175 // } else if (current.isGeneratorNode()) { +176 // //do nothing +177 // } else if (current.isProductNameNode()) { +178 // //do nothing +179 // } else if (current.isProductVersionNode()) { +180 // //do nothing +181 // else if (current.isTimestampNode()) { +182 // //do nothing +183 // } else { +184 // throw new SAXException("ERROR STATE: Unexpected qName '" + qName + "'"); +185 // } +186 } +187 +188 // <editor-fold defaultstate="collapsed" desc="The Element Class that maintains state information about the current node"> +189 /** +190 * A simple class to maintain information about the current element while +191 * parsing the CPE XML. +192 */ +193 protected static final class Element { +194 +195 /** +196 * A node type in the CPE Schema 2.2 +197 */ +198 public static final String CPE_LIST = "cpe-list"; +199 /** +200 * A node type in the CPE Schema 2.2 +201 */ +202 public static final String CPE_ITEM = "cpe-item"; +203 /** +204 * A node type in the CPE Schema 2.2 +205 */ +206 public static final String TITLE = "title"; +207 /** +208 * A node type in the CPE Schema 2.2 +209 */ +210 public static final String NOTES = "notes"; +211 /** +212 * A node type in the CPE Schema 2.2 +213 */ +214 public static final String NOTE = "note"; +215 /** +216 * A node type in the CPE Schema 2.2 +217 */ +218 public static final String CHECK = "check"; +219 /** +220 * A node type in the CPE Schema 2.2 +221 */ +222 public static final String META = "meta:item-metadata"; +223 /** +224 * A node type in the CPE Schema 2.2 +225 */ +226 public static final String GENERATOR = "generator"; +227 /** +228 * A node type in the CPE Schema 2.2 +229 */ +230 public static final String PRODUCT_NAME = "product_name"; +231 /** +232 * A node type in the CPE Schema 2.2 +233 */ +234 public static final String PRODUCT_VERSION = "product_version"; +235 /** +236 * A node type in the CPE Schema 2.2 +237 */ +238 public static final String SCHEMA_VERSION = "schema_version"; +239 /** +240 * A node type in the CPE Schema 2.2 241 */ -242 public String getNode() { -243 return this.node; -244 } -245 -246 /** -247 * Sets the value of node -248 * -249 * @param node new value of node -250 */ -251 public void setNode(String node) { -252 this.node = node; -253 } -254 -255 /** -256 * Checks if the handler is at the CPE_LIST node -257 * -258 * @return true or false -259 */ -260 public boolean isCpeListNode() { -261 return CPE_LIST.equals(node); -262 } -263 -264 /** -265 * Checks if the handler is at the CPE_ITEM node -266 * -267 * @return true or false -268 */ -269 public boolean isCpeItemNode() { -270 return CPE_ITEM.equals(node); -271 } -272 -273 /** -274 * Checks if the handler is at the TITLE node -275 * -276 * @return true or false -277 */ -278 public boolean isTitleNode() { -279 return TITLE.equals(node); -280 } -281 -282 /** -283 * Checks if the handler is at the NOTES node -284 * -285 * @return true or false -286 */ -287 public boolean isNotesNode() { -288 return NOTES.equals(node); -289 } -290 -291 /** -292 * Checks if the handler is at the NOTE node -293 * -294 * @return true or false -295 */ -296 public boolean isNoteNode() { -297 return NOTE.equals(node); -298 } -299 -300 /** -301 * Checks if the handler is at the CHECK node -302 * -303 * @return true or false -304 */ -305 public boolean isCheckNode() { -306 return CHECK.equals(node); -307 } -308 -309 /** -310 * Checks if the handler is at the META node -311 * -312 * @return true or false -313 */ -314 public boolean isMetaNode() { -315 return META.equals(node); -316 } -317 -318 /** -319 * Checks if the handler is at the GENERATOR node -320 * -321 * @return true or false -322 */ -323 public boolean isGeneratorNode() { -324 return GENERATOR.equals(node); -325 } -326 -327 /** -328 * Checks if the handler is at the PRODUCT_NAME node -329 * -330 * @return true or false -331 */ -332 public boolean isProductNameNode() { -333 return PRODUCT_NAME.equals(node); -334 } -335 -336 /** -337 * Checks if the handler is at the PRODUCT_VERSION node -338 * -339 * @return true or false -340 */ -341 public boolean isProductVersionNode() { -342 return PRODUCT_VERSION.equals(node); -343 } -344 -345 /** -346 * Checks if the handler is at the SCHEMA_VERSION node -347 * -348 * @return true or false -349 */ -350 public boolean isSchemaVersionNode() { -351 return SCHEMA_VERSION.equals(node); -352 } -353 -354 /** -355 * Checks if the handler is at the TIMESTAMP node -356 * -357 * @return true or false -358 */ -359 public boolean isTimestampNode() { -360 return TIMESTAMP.equals(node); -361 } -362 } -363 // </editor-fold> -364 } +242 public static final String TIMESTAMP = "timestamp"; +243 /** +244 * A reference to the current node. +245 */ +246 private String node = null; +247 +248 /** +249 * Gets the value of node +250 * +251 * @return the value of node +252 */ +253 public String getNode() { +254 return this.node; +255 } +256 +257 /** +258 * Sets the value of node +259 * +260 * @param node new value of node +261 */ +262 public void setNode(String node) { +263 this.node = node; +264 } +265 +266 /** +267 * Checks if the handler is at the CPE_LIST node +268 * +269 * @return true or false +270 */ +271 public boolean isCpeListNode() { +272 return CPE_LIST.equals(node); +273 } +274 +275 /** +276 * Checks if the handler is at the CPE_ITEM node +277 * +278 * @return true or false +279 */ +280 public boolean isCpeItemNode() { +281 return CPE_ITEM.equals(node); +282 } +283 +284 /** +285 * Checks if the handler is at the TITLE node +286 * +287 * @return true or false +288 */ +289 public boolean isTitleNode() { +290 return TITLE.equals(node); +291 } +292 +293 /** +294 * Checks if the handler is at the NOTES node +295 * +296 * @return true or false +297 */ +298 public boolean isNotesNode() { +299 return NOTES.equals(node); +300 } +301 +302 /** +303 * Checks if the handler is at the NOTE node +304 * +305 * @return true or false +306 */ +307 public boolean isNoteNode() { +308 return NOTE.equals(node); +309 } +310 +311 /** +312 * Checks if the handler is at the CHECK node +313 * +314 * @return true or false +315 */ +316 public boolean isCheckNode() { +317 return CHECK.equals(node); +318 } +319 +320 /** +321 * Checks if the handler is at the META node +322 * +323 * @return true or false +324 */ +325 public boolean isMetaNode() { +326 return META.equals(node); +327 } +328 +329 /** +330 * Checks if the handler is at the GENERATOR node +331 * +332 * @return true or false +333 */ +334 public boolean isGeneratorNode() { +335 return GENERATOR.equals(node); +336 } +337 +338 /** +339 * Checks if the handler is at the PRODUCT_NAME node +340 * +341 * @return true or false +342 */ +343 public boolean isProductNameNode() { +344 return PRODUCT_NAME.equals(node); +345 } +346 +347 /** +348 * Checks if the handler is at the PRODUCT_VERSION node +349 * +350 * @return true or false +351 */ +352 public boolean isProductVersionNode() { +353 return PRODUCT_VERSION.equals(node); +354 } +355 +356 /** +357 * Checks if the handler is at the SCHEMA_VERSION node +358 * +359 * @return true or false +360 */ +361 public boolean isSchemaVersionNode() { +362 return SCHEMA_VERSION.equals(node); +363 } +364 +365 /** +366 * Checks if the handler is at the TIMESTAMP node +367 * +368 * @return true or false +369 */ +370 public boolean isTimestampNode() { +371 return TIMESTAMP.equals(node); +372 } +373 } +374 // </editor-fold> +375 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/cpe/package-frame.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/cpe/package-frame.html index 1f34a5f94..11e04fcaa 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/cpe/package-frame.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/cpe/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.update.cpe + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.update.cpe diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/cpe/package-summary.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/cpe/package-summary.html index 44c6d63ac..26db8b0e6 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/cpe/package-summary.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/cpe/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.update.cpe + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.update.cpe diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/exception/UpdateException.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/exception/UpdateException.html index 4b1964f16..613077854 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/exception/UpdateException.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/exception/UpdateException.html @@ -25,55 +25,53 @@ 17 */ 18 package org.owasp.dependencycheck.data.update.exception; 19 -20 import java.io.IOException; -21 -22 /** -23 * An exception used when an error occurs reading a setting. -24 * -25 * @author Jeremy Long -26 */ -27 public class UpdateException extends IOException { -28 -29 /** -30 * The serial version uid. -31 */ -32 private static final long serialVersionUID = 1L; -33 -34 /** -35 * Creates a new UpdateException. -36 */ -37 public UpdateException() { -38 super(); -39 } -40 -41 /** -42 * Creates a new UpdateException. -43 * -44 * @param msg a message for the exception. -45 */ -46 public UpdateException(String msg) { -47 super(msg); -48 } -49 -50 /** -51 * Creates a new UpdateException. -52 * -53 * @param ex the cause of the update exception. -54 */ -55 public UpdateException(Throwable ex) { -56 super(ex); -57 } -58 -59 /** -60 * Creates a new UpdateException. -61 * -62 * @param msg a message for the exception. -63 * @param ex the cause of the update exception. -64 */ -65 public UpdateException(String msg, Throwable ex) { -66 super(msg, ex); -67 } -68 } +20 /** +21 * An exception used when an error occurs reading a setting. +22 * +23 * @author Jeremy Long +24 */ +25 public class UpdateException extends Exception { +26 +27 /** +28 * The serial version uid. +29 */ +30 private static final long serialVersionUID = 1L; +31 +32 /** +33 * Creates a new UpdateException. +34 */ +35 public UpdateException() { +36 super(); +37 } +38 +39 /** +40 * Creates a new UpdateException. +41 * +42 * @param msg a message for the exception. +43 */ +44 public UpdateException(String msg) { +45 super(msg); +46 } +47 +48 /** +49 * Creates a new UpdateException. +50 * +51 * @param ex the cause of the update exception. +52 */ +53 public UpdateException(Throwable ex) { +54 super(ex); +55 } +56 +57 /** +58 * Creates a new UpdateException. +59 * +60 * @param msg a message for the exception. +61 * @param ex the cause of the update exception. +62 */ +63 public UpdateException(String msg, Throwable ex) { +64 super(msg, ex); +65 } +66 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/exception/package-frame.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/exception/package-frame.html index dde687c2a..57b992737 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/exception/package-frame.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/exception/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.update.exception + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.update.exception diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/exception/package-summary.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/exception/package-summary.html index c12f2cda7..77ce80767 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/exception/package-summary.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/exception/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.update.exception + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.update.exception diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/UpdateableNvdCve.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/UpdateableNvdCve.html index b709e5b89..f49ff0e69 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/UpdateableNvdCve.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/UpdateableNvdCve.html @@ -33,163 +33,170 @@ 25 import java.util.TreeMap; 26 import org.owasp.dependencycheck.utils.DownloadFailedException; 27 import org.owasp.dependencycheck.utils.Downloader; -28 -29 /** -30 * Contains a collection of updateable NvdCveInfo objects. This is used to determine which files need to be downloaded and -31 * processed. -32 * -33 * @author Jeremy Long -34 */ -35 public class UpdateableNvdCve implements Iterable<NvdCveInfo>, Iterator<NvdCveInfo> { -36 -37 /** -38 * A collection of sources of data. -39 */ -40 private final Map<String, NvdCveInfo> collection = new TreeMap<String, NvdCveInfo>(); -41 -42 /** -43 * Returns the collection of NvdCveInfo objects. This method is mainly used for testing. -44 * -45 * @return the collection of NvdCveInfo objects -46 */ -47 protected Map<String, NvdCveInfo> getCollection() { -48 return collection; -49 } -50 -51 /** -52 * Gets whether or not an update is needed. -53 * -54 * @return true or false depending on whether an update is needed -55 */ -56 public boolean isUpdateNeeded() { -57 for (NvdCveInfo item : this) { -58 if (item.getNeedsUpdate()) { -59 return true; -60 } -61 } -62 return false; -63 } -64 -65 /** -66 * Adds a new entry of updateable information to the contained collection. -67 * -68 * @param id the key for the item to be added -69 * @param url the URL to download the item -70 * @param oldUrl the URL for the old version of the item (the NVD CVE old schema still contains useful data we need). -71 * @throws MalformedURLException thrown if the URL provided is invalid -72 * @throws DownloadFailedException thrown if the download fails. -73 */ -74 public void add(String id, String url, String oldUrl) throws MalformedURLException, DownloadFailedException { -75 add(id, url, oldUrl, false); -76 } -77 -78 /** -79 * Adds a new entry of updateable information to the contained collection. -80 * -81 * @param id the key for the item to be added -82 * @param url the URL to download the item -83 * @param oldUrl the URL for the old version of the item (the NVD CVE old schema still contains useful data we need). -84 * @param needsUpdate whether or not the data needs to be updated -85 * @throws MalformedURLException thrown if the URL provided is invalid -86 * @throws DownloadFailedException thrown if the download fails. -87 */ -88 public void add(String id, String url, String oldUrl, boolean needsUpdate) throws MalformedURLException, DownloadFailedException { -89 final NvdCveInfo item = new NvdCveInfo(); -90 item.setNeedsUpdate(needsUpdate); //the others default to true, to make life easier later this should default to false. -91 item.setId(id); -92 item.setUrl(url); -93 item.setOldSchemaVersionUrl(oldUrl); -94 item.setTimestamp(Downloader.getLastModified(new URL(url))); -95 collection.put(id, item); -96 } -97 -98 /** -99 * Clears the contained collection of NvdCveInfo entries. -100 */ -101 public void clear() { -102 collection.clear(); +28 import org.slf4j.Logger; +29 import org.slf4j.LoggerFactory; +30 +31 /** +32 * Contains a collection of updateable NvdCveInfo objects. This is used to determine which files need to be downloaded and +33 * processed. +34 * +35 * @author Jeremy Long +36 */ +37 public class UpdateableNvdCve implements Iterable<NvdCveInfo>, Iterator<NvdCveInfo> { +38 +39 /** +40 * A reference to the logger. +41 */ +42 private static final Logger LOGGER = LoggerFactory.getLogger(UpdateableNvdCve.class); +43 /** +44 * A collection of sources of data. +45 */ +46 private final Map<String, NvdCveInfo> collection = new TreeMap<String, NvdCveInfo>(); +47 +48 /** +49 * Returns the collection of NvdCveInfo objects. This method is mainly used for testing. +50 * +51 * @return the collection of NvdCveInfo objects +52 */ +53 protected Map<String, NvdCveInfo> getCollection() { +54 return collection; +55 } +56 +57 /** +58 * Gets whether or not an update is needed. +59 * +60 * @return true or false depending on whether an update is needed +61 */ +62 public boolean isUpdateNeeded() { +63 for (NvdCveInfo item : this) { +64 if (item.getNeedsUpdate()) { +65 return true; +66 } +67 } +68 return false; +69 } +70 +71 /** +72 * Adds a new entry of updateable information to the contained collection. +73 * +74 * @param id the key for the item to be added +75 * @param url the URL to download the item +76 * @param oldUrl the URL for the old version of the item (the NVD CVE old schema still contains useful data we need). +77 * @throws MalformedURLException thrown if the URL provided is invalid +78 * @throws DownloadFailedException thrown if the download fails. +79 */ +80 public void add(String id, String url, String oldUrl) throws MalformedURLException, DownloadFailedException { +81 add(id, url, oldUrl, false); +82 } +83 +84 /** +85 * Adds a new entry of updateable information to the contained collection. +86 * +87 * @param id the key for the item to be added +88 * @param url the URL to download the item +89 * @param oldUrl the URL for the old version of the item (the NVD CVE old schema still contains useful data we need). +90 * @param needsUpdate whether or not the data needs to be updated +91 * @throws MalformedURLException thrown if the URL provided is invalid +92 * @throws DownloadFailedException thrown if the download fails. +93 */ +94 public void add(String id, String url, String oldUrl, boolean needsUpdate) throws MalformedURLException, DownloadFailedException { +95 final NvdCveInfo item = new NvdCveInfo(); +96 item.setNeedsUpdate(needsUpdate); //the others default to true, to make life easier later this should default to false. +97 item.setId(id); +98 item.setUrl(url); +99 item.setOldSchemaVersionUrl(oldUrl); +100 LOGGER.debug("Checking for updates from: {}", url); +101 item.setTimestamp(Downloader.getLastModified(new URL(url))); +102 collection.put(id, item); 103 } 104 105 /** -106 * Returns the timestamp for the given entry. -107 * -108 * @param key the key to lookup in the collection of NvdCveInfo items -109 * @return the timestamp for the given entry -110 */ -111 public long getTimeStamp(String key) { -112 return collection.get(key).getTimestamp(); -113 } -114 /** -115 * An internal iterator used to implement iterable. -116 */ -117 private Iterator<Entry<String, NvdCveInfo>> iterableContent = null; -118 -119 /** -120 * <p> -121 * Returns an iterator for the NvdCveInfo contained.</p> -122 * <p> -123 * <b>This method is not thread safe.</b></p> -124 * -125 * @return an NvdCveInfo Iterator -126 */ -127 @Override -128 public Iterator<NvdCveInfo> iterator() { -129 iterableContent = collection.entrySet().iterator(); -130 return this; -131 } -132 -133 /** -134 * <p> -135 * Returns whether or not there is another item in the collection.</p> -136 * <p> -137 * <b>This method is not thread safe.</b></p> -138 * -139 * @return true or false depending on whether or not another item exists in the collection -140 */ -141 @Override -142 public boolean hasNext() { -143 return iterableContent.hasNext(); -144 } -145 -146 /** -147 * <p> -148 * Returns the next item in the collection.</p> -149 * <p> -150 * <b>This method is not thread safe.</b></p> -151 * -152 * @return the next NvdCveInfo item in the collection -153 */ -154 @Override -155 public NvdCveInfo next() { -156 return iterableContent.next().getValue(); -157 } -158 -159 /** -160 * <p> -161 * Removes the current NvdCveInfo object from the collection.</p> -162 * <p> -163 * <b>This method is not thread safe.</b></p> -164 */ -165 @Override -166 public void remove() { -167 iterableContent.remove(); -168 } -169 -170 /** -171 * Returns the specified item from the collection. -172 * -173 * @param key the key to lookup the return value -174 * @return the NvdCveInfo object stored using the specified key -175 */ -176 public NvdCveInfo get(String key) { -177 return collection.get(key); -178 } -179 -180 @Override -181 public String toString() { -182 return "Updateable{" + "size=" + collection.size() + '}'; -183 } -184 } +106 * Clears the contained collection of NvdCveInfo entries. +107 */ +108 public void clear() { +109 collection.clear(); +110 } +111 +112 /** +113 * Returns the timestamp for the given entry. +114 * +115 * @param key the key to lookup in the collection of NvdCveInfo items +116 * @return the timestamp for the given entry +117 */ +118 public long getTimeStamp(String key) { +119 return collection.get(key).getTimestamp(); +120 } +121 /** +122 * An internal iterator used to implement iterable. +123 */ +124 private Iterator<Entry<String, NvdCveInfo>> iterableContent = null; +125 +126 /** +127 * <p> +128 * Returns an iterator for the NvdCveInfo contained.</p> +129 * <p> +130 * <b>This method is not thread safe.</b></p> +131 * +132 * @return an NvdCveInfo Iterator +133 */ +134 @Override +135 public Iterator<NvdCveInfo> iterator() { +136 iterableContent = collection.entrySet().iterator(); +137 return this; +138 } +139 +140 /** +141 * <p> +142 * Returns whether or not there is another item in the collection.</p> +143 * <p> +144 * <b>This method is not thread safe.</b></p> +145 * +146 * @return true or false depending on whether or not another item exists in the collection +147 */ +148 @Override +149 public boolean hasNext() { +150 return iterableContent.hasNext(); +151 } +152 +153 /** +154 * <p> +155 * Returns the next item in the collection.</p> +156 * <p> +157 * <b>This method is not thread safe.</b></p> +158 * +159 * @return the next NvdCveInfo item in the collection +160 */ +161 @Override +162 public NvdCveInfo next() { +163 return iterableContent.next().getValue(); +164 } +165 +166 /** +167 * <p> +168 * Removes the current NvdCveInfo object from the collection.</p> +169 * <p> +170 * <b>This method is not thread safe.</b></p> +171 */ +172 @Override +173 public void remove() { +174 iterableContent.remove(); +175 } +176 +177 /** +178 * Returns the specified item from the collection. +179 * +180 * @param key the key to lookup the return value +181 * @return the NvdCveInfo object stored using the specified key +182 */ +183 public NvdCveInfo get(String key) { +184 return collection.get(key); +185 } +186 +187 @Override +188 public String toString() { +189 return "Updateable{" + "size=" + collection.size() + '}'; +190 } +191 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/package-frame.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/package-frame.html index de11f6060..47e4839a7 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/package-frame.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.update.nvd + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.update.nvd diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/package-summary.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/package-summary.html index 390bfcc25..e06fc753c 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/package-summary.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.update.nvd + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.update.nvd diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/package-frame.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/package-frame.html index 5c62524c9..7d8e31f62 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/package-frame.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.update + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.update diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/package-summary.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/package-summary.html index 890dff6ea..19b61ad8b 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/package-summary.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.data.update + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.data.update diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/dependency/Vulnerability.html b/dependency-check-core/xref/org/owasp/dependencycheck/dependency/Vulnerability.html index f6382c0f0..fe0cd852f 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/dependency/Vulnerability.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/dependency/Vulnerability.html @@ -29,448 +29,447 @@ 21 import java.util.Set; 22 import java.util.SortedSet; 23 import java.util.TreeSet; -24 import java.util.Iterator; -25 -26 /** -27 * Contains the information about a vulnerability. -28 * -29 * @author Jeremy Long -30 */ -31 public class Vulnerability implements Serializable, Comparable<Vulnerability> { -32 -33 /** -34 * The serial version uid. -35 */ -36 private static final long serialVersionUID = 307319490326651052L; -37 -38 /** -39 * The name of the vulnerability. -40 */ -41 private String name; -42 -43 /** -44 * Get the value of name. -45 * -46 * @return the value of name -47 */ -48 public String getName() { -49 return name; -50 } -51 -52 /** -53 * Set the value of name. -54 * -55 * @param name new value of name -56 */ -57 public void setName(String name) { -58 this.name = name; -59 } -60 /** -61 * the description of the vulnerability. -62 */ -63 private String description; -64 -65 /** -66 * Get the value of description. -67 * -68 * @return the value of description -69 */ -70 public String getDescription() { -71 return description; -72 } -73 -74 /** -75 * Set the value of description. -76 * -77 * @param description new value of description -78 */ -79 public void setDescription(String description) { -80 this.description = description; -81 } -82 /** -83 * References for this vulnerability. -84 */ -85 private SortedSet<Reference> references = new TreeSet<Reference>(); -86 -87 /** -88 * Get the value of references. -89 * -90 * @return the value of references -91 */ -92 public Set<Reference> getReferences() { -93 return references; -94 } -95 -96 /** -97 * Set the value of references. -98 * -99 * @param references new value of references -100 */ -101 public void setReferences(SortedSet<Reference> references) { -102 this.references = references; -103 } -104 -105 /** -106 * Adds a reference to the references collection. -107 * -108 * @param ref a reference for the vulnerability -109 */ -110 public void addReference(Reference ref) { -111 this.references.add(ref); -112 } -113 -114 /** -115 * Adds a reference. -116 * -117 * @param referenceSource the source of the reference -118 * @param referenceName the referenceName of the reference -119 * @param referenceUrl the url of the reference -120 */ -121 public void addReference(String referenceSource, String referenceName, String referenceUrl) { -122 final Reference ref = new Reference(); -123 ref.setSource(referenceSource); -124 ref.setName(referenceName); -125 ref.setUrl(referenceUrl); -126 this.references.add(ref); -127 } -128 /** -129 * A set of vulnerable software. -130 */ -131 private SortedSet<VulnerableSoftware> vulnerableSoftware = new TreeSet<VulnerableSoftware>(); -132 -133 /** -134 * Get the value of vulnerableSoftware. -135 * -136 * @return the value of vulnerableSoftware -137 */ -138 public Set<VulnerableSoftware> getVulnerableSoftware() { -139 return vulnerableSoftware; -140 } -141 -142 /** -143 * Set the value of vulnerableSoftware. -144 * -145 * @param vulnerableSoftware new value of vulnerableSoftware -146 */ -147 public void setVulnerableSoftware(SortedSet<VulnerableSoftware> vulnerableSoftware) { -148 this.vulnerableSoftware = vulnerableSoftware; -149 } -150 -151 /** -152 * Adds an entry for vulnerable software. -153 * -154 * @param cpe string representation of a CPE entry -155 * @return if the add succeeded -156 */ -157 public boolean addVulnerableSoftware(String cpe) { -158 return addVulnerableSoftware(cpe, null); -159 } -160 -161 /** -162 * Adds an entry for vulnerable software. -163 * -164 * @param cpe string representation of a cpe -165 * @param previousVersion the previous version (previousVersion - cpe would be considered vulnerable) -166 * @return if the add succeeded -167 */ -168 public boolean addVulnerableSoftware(String cpe, String previousVersion) { -169 final VulnerableSoftware vs = new VulnerableSoftware(); -170 vs.setCpe(cpe); -171 if (previousVersion != null) { -172 vs.setPreviousVersion(previousVersion); -173 } -174 return updateVulnerableSoftware(vs); -175 } -176 -177 /** -178 * Adds or updates a vulnerable software entry. -179 * -180 * @param vulnSoftware the vulnerable software -181 * @return if the update succeeded -182 */ -183 public boolean updateVulnerableSoftware(VulnerableSoftware vulnSoftware) { -184 if (vulnerableSoftware.contains(vulnSoftware)) { -185 vulnerableSoftware.remove(vulnSoftware); -186 } -187 return vulnerableSoftware.add(vulnSoftware); -188 } -189 /** -190 * The CWE for the vulnerability. -191 */ -192 private String cwe; -193 -194 /** -195 * Get the value of cwe. -196 * -197 * @return the value of cwe -198 */ -199 public String getCwe() { -200 return cwe; -201 } -202 -203 /** -204 * Set the value of cwe. -205 * -206 * @param cwe new value of cwe -207 */ -208 public void setCwe(String cwe) { -209 this.cwe = cwe; -210 } -211 /** -212 * CVSS Score. -213 */ -214 private float cvssScore; -215 -216 /** -217 * Get the value of cvssScore. -218 * -219 * @return the value of cvssScore -220 */ -221 public float getCvssScore() { -222 return cvssScore; -223 } -224 -225 /** -226 * Set the value of cvssScore. -227 * -228 * @param cvssScore new value of cvssScore -229 */ -230 public void setCvssScore(float cvssScore) { -231 this.cvssScore = cvssScore; -232 } -233 /** -234 * CVSS Access Vector. -235 */ -236 private String cvssAccessVector; -237 -238 /** -239 * Get the value of cvssAccessVector. -240 * -241 * @return the value of cvssAccessVector -242 */ -243 public String getCvssAccessVector() { -244 return cvssAccessVector; -245 } -246 -247 /** -248 * Set the value of cvssAccessVector. -249 * -250 * @param cvssAccessVector new value of cvssAccessVector -251 */ -252 public void setCvssAccessVector(String cvssAccessVector) { -253 this.cvssAccessVector = cvssAccessVector; -254 } -255 /** -256 * CVSS Access Complexity. -257 */ -258 private String cvssAccessComplexity; -259 -260 /** -261 * Get the value of cvssAccessComplexity. -262 * -263 * @return the value of cvssAccessComplexity -264 */ -265 public String getCvssAccessComplexity() { -266 return cvssAccessComplexity; -267 } -268 -269 /** -270 * Set the value of cvssAccessComplexity. -271 * -272 * @param cvssAccessComplexity new value of cvssAccessComplexity -273 */ -274 public void setCvssAccessComplexity(String cvssAccessComplexity) { -275 this.cvssAccessComplexity = cvssAccessComplexity; -276 } -277 /** -278 * CVSS Authentication. -279 */ -280 private String cvssAuthentication; -281 -282 /** -283 * Get the value of cvssAuthentication. -284 * -285 * @return the value of cvssAuthentication -286 */ -287 public String getCvssAuthentication() { -288 return cvssAuthentication; -289 } -290 -291 /** -292 * Set the value of cvssAuthentication. -293 * -294 * @param cvssAuthentication new value of cvssAuthentication -295 */ -296 public void setCvssAuthentication(String cvssAuthentication) { -297 this.cvssAuthentication = cvssAuthentication; -298 } -299 /** -300 * CVSS Confidentiality Impact. -301 */ -302 private String cvssConfidentialityImpact; -303 -304 /** -305 * Get the value of cvssConfidentialityImpact. -306 * -307 * @return the value of cvssConfidentialityImpact -308 */ -309 public String getCvssConfidentialityImpact() { -310 return cvssConfidentialityImpact; -311 } -312 -313 /** -314 * Set the value of cvssConfidentialityImpact. -315 * -316 * @param cvssConfidentialityImpact new value of cvssConfidentialityImpact -317 */ -318 public void setCvssConfidentialityImpact(String cvssConfidentialityImpact) { -319 this.cvssConfidentialityImpact = cvssConfidentialityImpact; -320 } -321 /** -322 * CVSS Integrity Impact. -323 */ -324 private String cvssIntegrityImpact; -325 -326 /** -327 * Get the value of cvssIntegrityImpact. -328 * -329 * @return the value of cvssIntegrityImpact -330 */ -331 public String getCvssIntegrityImpact() { -332 return cvssIntegrityImpact; -333 } -334 -335 /** -336 * Set the value of cvssIntegrityImpact. -337 * -338 * @param cvssIntegrityImpact new value of cvssIntegrityImpact -339 */ -340 public void setCvssIntegrityImpact(String cvssIntegrityImpact) { -341 this.cvssIntegrityImpact = cvssIntegrityImpact; -342 } -343 /** -344 * CVSS Availability Impact. -345 */ -346 private String cvssAvailabilityImpact; -347 -348 /** -349 * Get the value of cvssAvailabilityImpact. -350 * -351 * @return the value of cvssAvailabilityImpact -352 */ -353 public String getCvssAvailabilityImpact() { -354 return cvssAvailabilityImpact; -355 } -356 -357 /** -358 * Set the value of cvssAvailabilityImpact. -359 * -360 * @param cvssAvailabilityImpact new value of cvssAvailabilityImpact -361 */ -362 public void setCvssAvailabilityImpact(String cvssAvailabilityImpact) { -363 this.cvssAvailabilityImpact = cvssAvailabilityImpact; -364 } -365 -366 @Override -367 public boolean equals(Object obj) { -368 if (obj == null) { -369 return false; -370 } -371 if (getClass() != obj.getClass()) { -372 return false; -373 } -374 final Vulnerability other = (Vulnerability) obj; -375 if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) { -376 return false; -377 } -378 return true; -379 } -380 -381 @Override -382 public int hashCode() { -383 int hash = 5; -384 hash = 41 * hash + (this.name != null ? this.name.hashCode() : 0); -385 return hash; -386 } -387 -388 @Override -389 public String toString() { -390 final StringBuilder sb = new StringBuilder("Vulnerability "); -391 sb.append(this.name); -392 sb.append("\nReferences:\n"); -393 for (Iterator i = this.references.iterator(); i.hasNext();) { -394 sb.append("=> "); -395 sb.append(i.next()); -396 sb.append("\n"); -397 } -398 sb.append("\nSoftware:\n"); -399 for (Iterator i = this.vulnerableSoftware.iterator(); i.hasNext();) { -400 sb.append("=> "); -401 sb.append(i.next()); -402 sb.append("\n"); -403 } -404 return sb.toString(); -405 } -406 /** -407 * Compares two vulnerabilities. -408 * -409 * @param v a vulnerability to be compared -410 * @return a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than -411 * the specified vulnerability -412 */ -413 @Override -414 public int compareTo(Vulnerability v) { -415 return v.getName().compareTo(this.getName()); -416 } -417 -418 /** -419 * The CPE id that caused this vulnerability to be flagged. -420 */ -421 private String matchedCPE; -422 /** -423 * Whether or not all previous versions were affected. -424 */ -425 private String matchedAllPreviousCPE; -426 -427 /** -428 * Sets the CPE that caused this vulnerability to be flagged. -429 * -430 * @param cpeId a CPE identifier -431 * @param previous a flag indicating whether or not all previous versions were affected (any non-null value is -432 * considered true) -433 */ -434 public void setMatchedCPE(String cpeId, String previous) { -435 matchedCPE = cpeId; -436 matchedAllPreviousCPE = previous; -437 } -438 -439 /** -440 * Get the value of matchedCPE. -441 * -442 * @return the value of matchedCPE -443 */ -444 public String getMatchedCPE() { -445 return matchedCPE; -446 } -447 -448 /** -449 * Get the value of matchedAllPreviousCPE. -450 * -451 * @return the value of matchedAllPreviousCPE -452 */ -453 public String getMatchedAllPreviousCPE() { -454 return matchedAllPreviousCPE; -455 } -456 -457 /** -458 * Determines whether or not matchedAllPreviousCPE has been set. -459 * -460 * @return true if matchedAllPreviousCPE is not null; otherwise false -461 */ -462 public boolean hasMatchedAllPreviousCPE() { -463 return matchedAllPreviousCPE != null; -464 } -465 } +24 +25 /** +26 * Contains the information about a vulnerability. +27 * +28 * @author Jeremy Long +29 */ +30 public class Vulnerability implements Serializable, Comparable<Vulnerability> { +31 +32 /** +33 * The serial version uid. +34 */ +35 private static final long serialVersionUID = 307319490326651052L; +36 +37 /** +38 * The name of the vulnerability. +39 */ +40 private String name; +41 +42 /** +43 * Get the value of name. +44 * +45 * @return the value of name +46 */ +47 public String getName() { +48 return name; +49 } +50 +51 /** +52 * Set the value of name. +53 * +54 * @param name new value of name +55 */ +56 public void setName(String name) { +57 this.name = name; +58 } +59 /** +60 * the description of the vulnerability. +61 */ +62 private String description; +63 +64 /** +65 * Get the value of description. +66 * +67 * @return the value of description +68 */ +69 public String getDescription() { +70 return description; +71 } +72 +73 /** +74 * Set the value of description. +75 * +76 * @param description new value of description +77 */ +78 public void setDescription(String description) { +79 this.description = description; +80 } +81 /** +82 * References for this vulnerability. +83 */ +84 private SortedSet<Reference> references = new TreeSet<Reference>(); +85 +86 /** +87 * Get the value of references. +88 * +89 * @return the value of references +90 */ +91 public Set<Reference> getReferences() { +92 return references; +93 } +94 +95 /** +96 * Set the value of references. +97 * +98 * @param references new value of references +99 */ +100 public void setReferences(SortedSet<Reference> references) { +101 this.references = references; +102 } +103 +104 /** +105 * Adds a reference to the references collection. +106 * +107 * @param ref a reference for the vulnerability +108 */ +109 public void addReference(Reference ref) { +110 this.references.add(ref); +111 } +112 +113 /** +114 * Adds a reference. +115 * +116 * @param referenceSource the source of the reference +117 * @param referenceName the referenceName of the reference +118 * @param referenceUrl the url of the reference +119 */ +120 public void addReference(String referenceSource, String referenceName, String referenceUrl) { +121 final Reference ref = new Reference(); +122 ref.setSource(referenceSource); +123 ref.setName(referenceName); +124 ref.setUrl(referenceUrl); +125 this.references.add(ref); +126 } +127 /** +128 * A set of vulnerable software. +129 */ +130 private SortedSet<VulnerableSoftware> vulnerableSoftware = new TreeSet<VulnerableSoftware>(); +131 +132 /** +133 * Get the value of vulnerableSoftware. +134 * +135 * @return the value of vulnerableSoftware +136 */ +137 public Set<VulnerableSoftware> getVulnerableSoftware() { +138 return vulnerableSoftware; +139 } +140 +141 /** +142 * Set the value of vulnerableSoftware. +143 * +144 * @param vulnerableSoftware new value of vulnerableSoftware +145 */ +146 public void setVulnerableSoftware(SortedSet<VulnerableSoftware> vulnerableSoftware) { +147 this.vulnerableSoftware = vulnerableSoftware; +148 } +149 +150 /** +151 * Adds an entry for vulnerable software. +152 * +153 * @param cpe string representation of a CPE entry +154 * @return if the add succeeded +155 */ +156 public boolean addVulnerableSoftware(String cpe) { +157 return addVulnerableSoftware(cpe, null); +158 } +159 +160 /** +161 * Adds an entry for vulnerable software. +162 * +163 * @param cpe string representation of a cpe +164 * @param previousVersion the previous version (previousVersion - cpe would be considered vulnerable) +165 * @return if the add succeeded +166 */ +167 public boolean addVulnerableSoftware(String cpe, String previousVersion) { +168 final VulnerableSoftware vs = new VulnerableSoftware(); +169 vs.setCpe(cpe); +170 if (previousVersion != null) { +171 vs.setPreviousVersion(previousVersion); +172 } +173 return updateVulnerableSoftware(vs); +174 } +175 +176 /** +177 * Adds or updates a vulnerable software entry. +178 * +179 * @param vulnSoftware the vulnerable software +180 * @return if the update succeeded +181 */ +182 public boolean updateVulnerableSoftware(VulnerableSoftware vulnSoftware) { +183 if (vulnerableSoftware.contains(vulnSoftware)) { +184 vulnerableSoftware.remove(vulnSoftware); +185 } +186 return vulnerableSoftware.add(vulnSoftware); +187 } +188 /** +189 * The CWE for the vulnerability. +190 */ +191 private String cwe; +192 +193 /** +194 * Get the value of cwe. +195 * +196 * @return the value of cwe +197 */ +198 public String getCwe() { +199 return cwe; +200 } +201 +202 /** +203 * Set the value of cwe. +204 * +205 * @param cwe new value of cwe +206 */ +207 public void setCwe(String cwe) { +208 this.cwe = cwe; +209 } +210 /** +211 * CVSS Score. +212 */ +213 private float cvssScore; +214 +215 /** +216 * Get the value of cvssScore. +217 * +218 * @return the value of cvssScore +219 */ +220 public float getCvssScore() { +221 return cvssScore; +222 } +223 +224 /** +225 * Set the value of cvssScore. +226 * +227 * @param cvssScore new value of cvssScore +228 */ +229 public void setCvssScore(float cvssScore) { +230 this.cvssScore = cvssScore; +231 } +232 /** +233 * CVSS Access Vector. +234 */ +235 private String cvssAccessVector; +236 +237 /** +238 * Get the value of cvssAccessVector. +239 * +240 * @return the value of cvssAccessVector +241 */ +242 public String getCvssAccessVector() { +243 return cvssAccessVector; +244 } +245 +246 /** +247 * Set the value of cvssAccessVector. +248 * +249 * @param cvssAccessVector new value of cvssAccessVector +250 */ +251 public void setCvssAccessVector(String cvssAccessVector) { +252 this.cvssAccessVector = cvssAccessVector; +253 } +254 /** +255 * CVSS Access Complexity. +256 */ +257 private String cvssAccessComplexity; +258 +259 /** +260 * Get the value of cvssAccessComplexity. +261 * +262 * @return the value of cvssAccessComplexity +263 */ +264 public String getCvssAccessComplexity() { +265 return cvssAccessComplexity; +266 } +267 +268 /** +269 * Set the value of cvssAccessComplexity. +270 * +271 * @param cvssAccessComplexity new value of cvssAccessComplexity +272 */ +273 public void setCvssAccessComplexity(String cvssAccessComplexity) { +274 this.cvssAccessComplexity = cvssAccessComplexity; +275 } +276 /** +277 * CVSS Authentication. +278 */ +279 private String cvssAuthentication; +280 +281 /** +282 * Get the value of cvssAuthentication. +283 * +284 * @return the value of cvssAuthentication +285 */ +286 public String getCvssAuthentication() { +287 return cvssAuthentication; +288 } +289 +290 /** +291 * Set the value of cvssAuthentication. +292 * +293 * @param cvssAuthentication new value of cvssAuthentication +294 */ +295 public void setCvssAuthentication(String cvssAuthentication) { +296 this.cvssAuthentication = cvssAuthentication; +297 } +298 /** +299 * CVSS Confidentiality Impact. +300 */ +301 private String cvssConfidentialityImpact; +302 +303 /** +304 * Get the value of cvssConfidentialityImpact. +305 * +306 * @return the value of cvssConfidentialityImpact +307 */ +308 public String getCvssConfidentialityImpact() { +309 return cvssConfidentialityImpact; +310 } +311 +312 /** +313 * Set the value of cvssConfidentialityImpact. +314 * +315 * @param cvssConfidentialityImpact new value of cvssConfidentialityImpact +316 */ +317 public void setCvssConfidentialityImpact(String cvssConfidentialityImpact) { +318 this.cvssConfidentialityImpact = cvssConfidentialityImpact; +319 } +320 /** +321 * CVSS Integrity Impact. +322 */ +323 private String cvssIntegrityImpact; +324 +325 /** +326 * Get the value of cvssIntegrityImpact. +327 * +328 * @return the value of cvssIntegrityImpact +329 */ +330 public String getCvssIntegrityImpact() { +331 return cvssIntegrityImpact; +332 } +333 +334 /** +335 * Set the value of cvssIntegrityImpact. +336 * +337 * @param cvssIntegrityImpact new value of cvssIntegrityImpact +338 */ +339 public void setCvssIntegrityImpact(String cvssIntegrityImpact) { +340 this.cvssIntegrityImpact = cvssIntegrityImpact; +341 } +342 /** +343 * CVSS Availability Impact. +344 */ +345 private String cvssAvailabilityImpact; +346 +347 /** +348 * Get the value of cvssAvailabilityImpact. +349 * +350 * @return the value of cvssAvailabilityImpact +351 */ +352 public String getCvssAvailabilityImpact() { +353 return cvssAvailabilityImpact; +354 } +355 +356 /** +357 * Set the value of cvssAvailabilityImpact. +358 * +359 * @param cvssAvailabilityImpact new value of cvssAvailabilityImpact +360 */ +361 public void setCvssAvailabilityImpact(String cvssAvailabilityImpact) { +362 this.cvssAvailabilityImpact = cvssAvailabilityImpact; +363 } +364 +365 @Override +366 public boolean equals(Object obj) { +367 if (obj == null) { +368 return false; +369 } +370 if (getClass() != obj.getClass()) { +371 return false; +372 } +373 final Vulnerability other = (Vulnerability) obj; +374 if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) { +375 return false; +376 } +377 return true; +378 } +379 +380 @Override +381 public int hashCode() { +382 int hash = 5; +383 hash = 41 * hash + (this.name != null ? this.name.hashCode() : 0); +384 return hash; +385 } +386 +387 @Override +388 public String toString() { +389 final StringBuilder sb = new StringBuilder("Vulnerability "); +390 sb.append(this.name); +391 sb.append("\nReferences:\n"); +392 for (Reference reference : this.references) { +393 sb.append("=> "); +394 sb.append(reference); +395 sb.append("\n"); +396 } +397 sb.append("\nSoftware:\n"); +398 for (VulnerableSoftware software : this.vulnerableSoftware) { +399 sb.append("=> "); +400 sb.append(software); +401 sb.append("\n"); +402 } +403 return sb.toString(); +404 } +405 /** +406 * Compares two vulnerabilities. +407 * +408 * @param v a vulnerability to be compared +409 * @return a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than +410 * the specified vulnerability +411 */ +412 @Override +413 public int compareTo(Vulnerability v) { +414 return v.getName().compareTo(this.getName()); +415 } +416 +417 /** +418 * The CPE id that caused this vulnerability to be flagged. +419 */ +420 private String matchedCPE; +421 /** +422 * Whether or not all previous versions were affected. +423 */ +424 private String matchedAllPreviousCPE; +425 +426 /** +427 * Sets the CPE that caused this vulnerability to be flagged. +428 * +429 * @param cpeId a CPE identifier +430 * @param previous a flag indicating whether or not all previous versions were affected (any non-null value is +431 * considered true) +432 */ +433 public void setMatchedCPE(String cpeId, String previous) { +434 matchedCPE = cpeId; +435 matchedAllPreviousCPE = previous; +436 } +437 +438 /** +439 * Get the value of matchedCPE. +440 * +441 * @return the value of matchedCPE +442 */ +443 public String getMatchedCPE() { +444 return matchedCPE; +445 } +446 +447 /** +448 * Get the value of matchedAllPreviousCPE. +449 * +450 * @return the value of matchedAllPreviousCPE +451 */ +452 public String getMatchedAllPreviousCPE() { +453 return matchedAllPreviousCPE; +454 } +455 +456 /** +457 * Determines whether or not matchedAllPreviousCPE has been set. +458 * +459 * @return true if matchedAllPreviousCPE is not null; otherwise false +460 */ +461 public boolean hasMatchedAllPreviousCPE() { +462 return matchedAllPreviousCPE != null; +463 } +464 }
      diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/dependency/package-frame.html b/dependency-check-core/xref/org/owasp/dependencycheck/dependency/package-frame.html index 1490db258..c959cd748 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/dependency/package-frame.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/dependency/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.dependency + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.dependency diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/dependency/package-summary.html b/dependency-check-core/xref/org/owasp/dependencycheck/dependency/package-summary.html index 3bce3140f..f32ec399a 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/dependency/package-summary.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/dependency/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.dependency + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.dependency diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/exception/ExceptionCollection.html b/dependency-check-core/xref/org/owasp/dependencycheck/exception/ExceptionCollection.html new file mode 100644 index 000000000..cdb8e053d --- /dev/null +++ b/dependency-check-core/xref/org/owasp/dependencycheck/exception/ExceptionCollection.html @@ -0,0 +1,227 @@ + + + +ExceptionCollection xref + + + +
      +1   /*
      +2    * This file is part of dependency-check-core.
      +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) 2016 Jeremy Long. All Rights Reserved.
      +17   */
      +18  package org.owasp.dependencycheck.exception;
      +19  
      +20  import java.io.PrintStream;
      +21  import java.io.PrintWriter;
      +22  import java.util.ArrayList;
      +23  import java.util.List;
      +24  
      +25  /**
      +26   * A collection of several exceptions.
      +27   *
      +28   * @author Jeremy Lomg
      +29   */
      +30  public class ExceptionCollection extends Exception {
      +31  
      +32      /**
      +33       * Instantiates a new exception collection.
      +34       *
      +35       * @param exceptions a list of exceptions
      +36       */
      +37      public ExceptionCollection(List<Throwable> exceptions) {
      +38          super();
      +39          this.exceptions = exceptions;
      +40      }
      +41  
      +42      /**
      +43       * Instantiates a new exception collection.
      +44       *
      +45       * @param msg the exception message
      +46       * @param exceptions a list of exceptions
      +47       */
      +48      public ExceptionCollection(String msg, List<Throwable> exceptions) {
      +49          super(msg);
      +50          this.exceptions = exceptions;
      +51      }
      +52  
      +53      /**
      +54       * Instantiates a new exception collection.
      +55       *
      +56       * @param exceptions a list of exceptions
      +57       * @param fatal indicates if the exception that occurred is fatal - meaning
      +58       * that no analysis was performed.
      +59       */
      +60      public ExceptionCollection(List<Throwable> exceptions, boolean fatal) {
      +61          super();
      +62          this.exceptions = exceptions;
      +63          this.fatal = fatal;
      +64      }
      +65  
      +66      /**
      +67       * Instantiates a new exception collection.
      +68       *
      +69       * @param msg the exception message
      +70       * @param exceptions a list of exceptions
      +71       * @param fatal indicates if the exception that occurred is fatal - meaning
      +72       * that no analysis was performed.
      +73       */
      +74      public ExceptionCollection(String msg, List<Throwable> exceptions, boolean fatal) {
      +75          super(msg);
      +76          this.exceptions = exceptions;
      +77          this.fatal = fatal;
      +78      }
      +79  
      +80      /**
      +81       * Instantiates a new exception collection.
      +82       *
      +83       * @param exceptions a list of exceptions
      +84       * @param fatal indicates if the exception that occurred is fatal - meaning
      +85       * that no analysis was performed.
      +86       */
      +87      public ExceptionCollection(Throwable exceptions, boolean fatal) {
      +88          super();
      +89          this.exceptions = new ArrayList<Throwable>();
      +90          this.exceptions.add(exceptions);
      +91          this.fatal = fatal;
      +92      }
      +93          /**
      +94       * Instantiates a new exception collection.
      +95       *
      +96       * @param msg the exception message
      +97       * @param exception a list of exceptions
      +98       */
      +99      public ExceptionCollection(String msg, Throwable exception) {
      +100         super(msg);
      +101         this.exceptions = new ArrayList<Throwable>();
      +102         this.exceptions.add(exception);
      +103         this.fatal = false;
      +104     }
      +105 
      +106     /**
      +107      * Instantiates a new exception collection.
      +108      */
      +109     public ExceptionCollection() {
      +110         super();
      +111         this.exceptions = new ArrayList<Throwable>();
      +112     }
      +113     /**
      +114      * The serial version uid.
      +115      */
      +116     private static final long serialVersionUID = 1L;
      +117 
      +118     /**
      +119      * A collection of exceptions.
      +120      */
      +121     private List<Throwable> exceptions;
      +122 
      +123     /**
      +124      * Get the value of exceptions.
      +125      *
      +126      * @return the value of exceptions
      +127      */
      +128     public List<Throwable> getExceptions() {
      +129         return exceptions;
      +130     }
      +131 
      +132     /**
      +133      * Adds an exception to the collection.
      +134      *
      +135      * @param ex the exception to add
      +136      */
      +137     public void addException(Throwable ex) {
      +138         this.exceptions.add(ex);
      +139     }
      +140 
      +141     /**
      +142      * Adds an exception to the collection.
      +143      *
      +144      * @param ex the exception to add
      +145      * @param fatal flag indicating if this is a fatal error
      +146      */
      +147     public void addException(Throwable ex, boolean fatal) {
      +148         addException(ex);
      +149         this.fatal = fatal;
      +150     }
      +151 
      +152     /**
      +153      * Flag indicating if a fatal exception occurred that would prevent the
      +154      * attempt at completing the analysis even if exceptions occurred.
      +155      */
      +156     private boolean fatal = false;
      +157 
      +158     /**
      +159      * Get the value of fatal.
      +160      *
      +161      * @return the value of fatal
      +162      */
      +163     public boolean isFatal() {
      +164         return fatal;
      +165     }
      +166 
      +167     /**
      +168      * Set the value of fatal.
      +169      *
      +170      * @param fatal new value of fatal
      +171      */
      +172     public void setFatal(boolean fatal) {
      +173         this.fatal = fatal;
      +174     }
      +175 
      +176     /**
      +177      * Prints the stack trace.
      +178      *
      +179      * @param s the writer to print to
      +180      */
      +181     @Override
      +182     public void printStackTrace(PrintWriter s) {
      +183         s.println("Multiple Exceptions Occured");
      +184         super.printStackTrace(s);
      +185         for (Throwable t : this.exceptions) {
      +186             s.println("Next Exception:");
      +187             t.printStackTrace(s);
      +188         }
      +189     }
      +190 
      +191     /**
      +192      * Prints the stack trace.
      +193      *
      +194      * @param s the stream to write the stack trace to
      +195      */
      +196     @Override
      +197     public void printStackTrace(PrintStream s) {
      +198         s.println("Multiple Exceptions Occured");
      +199         super.printStackTrace(s);
      +200         for (Throwable t : this.exceptions) {
      +201             s.println("Next Exception:");
      +202             t.printStackTrace(s);
      +203         }
      +204     }
      +205 
      +206     /**
      +207      * Prints the stack trace to standard error.
      +208      */
      +209     @Override
      +210     public void printStackTrace() {
      +211         this.printStackTrace(System.err);
      +212     }
      +213 
      +214 }
      +
      +
      + + + diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/exception/InitializationException.html b/dependency-check-core/xref/org/owasp/dependencycheck/exception/InitializationException.html new file mode 100644 index 000000000..e607c467b --- /dev/null +++ b/dependency-check-core/xref/org/owasp/dependencycheck/exception/InitializationException.html @@ -0,0 +1,79 @@ + + + +InitializationException xref + + + +
      +1   /*
      +2    * This file is part of dependency-check-core.
      +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) 2016 Jeremy Long. All Rights Reserved.
      +17   */
      +18  package org.owasp.dependencycheck.exception;
      +19  
      +20  /**
      +21   * An exception used when initializing analyzers.
      +22   *
      +23   * @author Jeremy Long
      +24   */
      +25  public class InitializationException extends Exception {
      +26  
      +27      /**
      +28       * The serial version uid.
      +29       */
      +30      private static final long serialVersionUID = 1L;
      +31  
      +32      /**
      +33       * Creates a new InitializationException.
      +34       */
      +35      public InitializationException() {
      +36          super();
      +37      }
      +38  
      +39      /**
      +40       * Creates a new InitializationException.
      +41       *
      +42       * @param msg a message for the exception.
      +43       */
      +44      public InitializationException(String msg) {
      +45          super(msg);
      +46      }
      +47  
      +48      /**
      +49       * Creates a new InitializationException.
      +50       *
      +51       * @param ex the cause of the exception.
      +52       */
      +53      public InitializationException(Throwable ex) {
      +54          super(ex);
      +55      }
      +56  
      +57      /**
      +58       * Creates a new InitializationException.
      +59       *
      +60       * @param msg a message for the exception.
      +61       * @param ex the cause of the exception.
      +62       */
      +63      public InitializationException(String msg, Throwable ex) {
      +64          super(msg, ex);
      +65      }
      +66  }
      +
      +
      + + + diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/exception/ReportException.html b/dependency-check-core/xref/org/owasp/dependencycheck/exception/ReportException.html new file mode 100644 index 000000000..54f50ed44 --- /dev/null +++ b/dependency-check-core/xref/org/owasp/dependencycheck/exception/ReportException.html @@ -0,0 +1,79 @@ + + + +ReportException xref + + + +
      +1   /*
      +2    * This file is part of dependency-check-core.
      +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) 2016 Jeremy Long. All Rights Reserved.
      +17   */
      +18  package org.owasp.dependencycheck.exception;
      +19  
      +20  /**
      +21   * An exception used when generating reports.
      +22   *
      +23   * @author Jeremy Long
      +24   */
      +25  public class ReportException extends Exception {
      +26  
      +27      /**
      +28       * The serial version uid.
      +29       */
      +30      private static final long serialVersionUID = 1L;
      +31  
      +32      /**
      +33       * Creates a new ReportException.
      +34       */
      +35      public ReportException() {
      +36          super();
      +37      }
      +38  
      +39      /**
      +40       * Creates a new ReportException.
      +41       *
      +42       * @param msg a message for the exception.
      +43       */
      +44      public ReportException(String msg) {
      +45          super(msg);
      +46      }
      +47  
      +48      /**
      +49       * Creates a new ReportException.
      +50       *
      +51       * @param ex the cause of the exception.
      +52       */
      +53      public ReportException(Throwable ex) {
      +54          super(ex);
      +55      }
      +56  
      +57      /**
      +58       * Creates a new ReportException.
      +59       *
      +60       * @param msg a message for the exception.
      +61       * @param ex the cause of the exception.
      +62       */
      +63      public ReportException(String msg, Throwable ex) {
      +64          super(msg, ex);
      +65      }
      +66  }
      +
      +
      + + + diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/exception/package-frame.html b/dependency-check-core/xref/org/owasp/dependencycheck/exception/package-frame.html index 3f6e4600c..761d461c2 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/exception/package-frame.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/exception/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference Package org.owasp.dependencycheck.exception + Dependency-Check Core 1.4.2 Reference Package org.owasp.dependencycheck.exception @@ -16,7 +16,16 @@ diff --git a/dependency-check-core/xref/overview-summary.html b/dependency-check-core/xref/overview-summary.html index 13d19e050..f8b6c49f5 100644 --- a/dependency-check-core/xref/overview-summary.html +++ b/dependency-check-core/xref/overview-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Core 1.4.0 Reference + Dependency-Check Core 1.4.2 Reference @@ -24,7 +24,7 @@ -

      Dependency-Check Core 1.4.0 Reference

      +

      Dependency-Check Core 1.4.2 Reference

      @@ -127,21 +127,26 @@ - - - + + + + + +
      org.owasp.dependencycheck.reporting
      - org.owasp.dependencycheck.suppression -
      org.owasp.dependencycheck.utils
      + org.owasp.dependencycheck.xml.hints +
      org.owasp.dependencycheck.xml.pom
      + org.owasp.dependencycheck.xml.suppression +
      diff --git a/dependency-check-gradle/configuration-purge.html b/dependency-check-gradle/configuration-purge.html index 17daea11b..be17941da 100644 --- a/dependency-check-gradle/configuration-purge.html +++ b/dependency-check-gradle/configuration-purge.html @@ -1,13 +1,13 @@ - + dependency-check – Tasks @@ -41,7 +41,7 @@
    250. Tasks
    251. -
    252. | Last Published: 2016-06-16
    253. +
    254. | Last Published: 2016-07-31
    255. - Version: 1.4.0 + Version: 1.4.2
    256. diff --git a/dependency-check-gradle/configuration-update.html b/dependency-check-gradle/configuration-update.html index 3b635961f..1aefa7664 100644 --- a/dependency-check-gradle/configuration-update.html +++ b/dependency-check-gradle/configuration-update.html @@ -1,13 +1,13 @@ - + dependency-check – Tasks @@ -41,7 +41,7 @@
      diff --git a/dependency-check-gradle/index.html b/dependency-check-gradle/index.html index 0c4021624..de4d955a6 100644 --- a/dependency-check-gradle/index.html +++ b/dependency-check-gradle/index.html @@ -1,13 +1,13 @@ - + dependency-check – Usage @@ -41,7 +41,7 @@

      org.apache.lucene:lucene-core

      @@ -1088,7 +1088,7 @@ -
      jar
      Newer versions4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      6.0.0
      6.0.1 Latest Major
      +4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      5.5.2
      6.0.0
      6.0.1
      6.1.0 Latest Major

      org.apache.lucene:lucene-queryparser

      @@ -1115,7 +1115,7 @@ -
      jar
      Newer versions4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      6.0.0
      6.0.1 Latest Major
      +4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      5.5.2
      6.0.0
      6.0.1
      6.1.0 Latest Major

      org.apache.lucene:lucene-test-framework

      @@ -1142,7 +1142,7 @@ -
      jar
      Newer versions4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      6.0.0
      6.0.1 Latest Major
      +4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      5.5.2
      6.0.0
      6.0.1
      6.1.0 Latest Major

      org.apache.maven:maven-core

      @@ -1373,7 +1373,7 @@ - + @@ -1385,13 +1385,13 @@ -
      jmockit
      Current Version1.22
      1.24
      Scope test
      jar
      Newer versions1.23 Next Minor
      1.24 Latest Minor
      +1.25 Next Minor

      org.jsoup:jsoup

      - + @@ -1400,7 +1400,7 @@ - + @@ -1409,10 +1409,7 @@ - - - -
      Status There is at least one newer incremental version available. Incremental updates are typically passive.
       No newer versions available.
      Group Id org.jsoup
      jsoup
      Current Version1.9.1
      1.9.2
      Scope
      Typejar
      Newer versions1.9.2 Next Incremental
      +jar

      org.owasp:dependency-check-core

      @@ -1427,7 +1424,7 @@ - + @@ -1451,7 +1448,7 @@ - + diff --git a/dependency-check-maven/findbugs.html b/dependency-check-maven/findbugs.html index 7c0b90a98..90bf5ee82 100644 --- a/dependency-check-maven/findbugs.html +++ b/dependency-check-maven/findbugs.html @@ -1,13 +1,13 @@ - + dependency-check-maven – FindBugs Bug Detector Report @@ -52,7 +52,7 @@ @@ -253,7 +253,7 @@ - +
      dependency-check-core
      Current Version1.4.0
      1.4.2
      Scope compile
      dependency-check-utils
      Current Version1.4.0
      1.4.2
      Scope compile
      Missing Classes
      1010 0 0
      @@ -261,25 +261,7 @@ - - - -
      ClassBugs
      org.owasp.dependencycheck.maven.Engine1
      -
      -

      org.owasp.dependencycheck.maven.Engine

      - - - - - - - - - - - - -
      BugCategoryDetailsLinePriority
      The class name org.owasp.dependencycheck.maven.Engine shadows the simple name of the superclass org.owasp.dependencycheck.EngineBAD_PRACTICENM_SAME_SIMPLE_NAME_AS_SUPERCLASS41-226High
      +Bugs diff --git a/dependency-check-maven/help-mojo.html b/dependency-check-maven/help-mojo.html index 46fe99e45..eb4eed6bc 100644 --- a/dependency-check-maven/help-mojo.html +++ b/dependency-check-maven/help-mojo.html @@ -1,13 +1,13 @@ - + dependency-check-maven – dependency-check:help @@ -52,7 +52,7 @@ @@ -153,7 +153,7 @@

      Full name:

      -

      org.owasp:dependency-check-maven:1.4.0:help

      +

      org.owasp:dependency-check-maven:1.4.2:help

      Description:

      diff --git a/dependency-check-maven/index.html b/dependency-check-maven/index.html index cba904a4f..3da02ab8a 100644 --- a/dependency-check-maven/index.html +++ b/dependency-check-maven/index.html @@ -1,13 +1,13 @@ - + dependency-check-maven – Usage @@ -52,7 +52,7 @@ @@ -163,7 +163,7 @@ <plugin> <groupId>org.owasp</groupId> <artifactId>dependency-check-maven</artifactId> - <version>1.4.0</version> + <version>1.4.2</version> <executions> <execution> <goals> @@ -191,18 +191,16 @@ <plugins> ... <plugin> - <plugin> - <groupId>org.owasp</groupId> - <artifactId>dependency-check-maven</artifactId> - <version>1.4.0</version> - <reportSets> - <reportSet> - <reports> - <report>aggregate</report> - </reports> - </reportSet> - </reportSets> - </plugin> + <groupId>org.owasp</groupId> + <artifactId>dependency-check-maven</artifactId> + <version>1.4.2</version> + <reportSets> + <reportSet> + <reports> + <report>aggregate</report> + </reports> + </reportSet> + </reportSets> </plugin> ... </plugins> @@ -225,7 +223,7 @@ <plugin> <groupId>org.owasp</groupId> <artifactId>dependency-check-maven</artifactId> - <version>1.4.0</version> + <version>1.4.2</version> <configuration> <failBuildOnCVSS>8</failBuildOnCVSS> </configuration> @@ -258,7 +256,7 @@ <plugin> <groupId>org.owasp</groupId> <artifactId>dependency-check-maven</artifactId> - <version>1.4.0</version> + <version>1.4.2</version> <configuration> <skipProvidedScope>true</skipProvidedScope> <skipRuntimeScope>true</skipRuntimeScope> @@ -292,7 +290,7 @@ <plugin> <groupId>org.owasp</groupId> <artifactId>dependency-check-maven</artifactId> - <version>1.4.0</version> + <version>1.4.2</version> <configuration> <cveUrl12Modified>http://internal-mirror.mycorp.com/downloads/nist/nvdcve-Modified.xml.gz</cveUrl12Modified> <cveUrl20Modified>http://internal-mirror.mycorp.com/downloads/nist/nvdcve-2.0-Modified.xml.gz</cveUrl20Modified> @@ -328,7 +326,7 @@ <plugin> <groupId>org.owasp</groupId> <artifactId>dependency-check-maven</artifactId> - <version>1.4.0</version> + <version>1.4.2</version> <executions> <execution> <goals> diff --git a/dependency-check-maven/integration.html b/dependency-check-maven/integration.html index 2e6dc57bf..df329bac3 100644 --- a/dependency-check-maven/integration.html +++ b/dependency-check-maven/integration.html @@ -1,13 +1,13 @@ - + dependency-check-maven – CI Management @@ -52,7 +52,7 @@ diff --git a/dependency-check-maven/issue-tracking.html b/dependency-check-maven/issue-tracking.html index 3418be32f..b440e4d15 100644 --- a/dependency-check-maven/issue-tracking.html +++ b/dependency-check-maven/issue-tracking.html @@ -1,13 +1,13 @@ - + dependency-check-maven – Issue Management @@ -52,7 +52,7 @@ diff --git a/dependency-check-maven/license.html b/dependency-check-maven/license.html index 1edb451b5..ead3757c5 100644 --- a/dependency-check-maven/license.html +++ b/dependency-check-maven/license.html @@ -1,13 +1,13 @@ - + dependency-check-maven – Project Licenses @@ -52,7 +52,7 @@ diff --git a/dependency-check-maven/mail-lists.html b/dependency-check-maven/mail-lists.html index 76806f7c3..b8e26dee9 100644 --- a/dependency-check-maven/mail-lists.html +++ b/dependency-check-maven/mail-lists.html @@ -1,13 +1,13 @@ - + dependency-check-maven – Project Mailing Lists @@ -52,7 +52,7 @@ diff --git a/dependency-check-maven/plugin-info.html b/dependency-check-maven/plugin-info.html index a2f15e6ef..906023619 100644 --- a/dependency-check-maven/plugin-info.html +++ b/dependency-check-maven/plugin-info.html @@ -1,13 +1,13 @@ - + dependency-check-maven – Plugin Documentation @@ -52,7 +52,7 @@ @@ -299,7 +299,7 @@ have any known published vulnerabilities. <plugin> <groupId>org.owasp</groupId> <artifactId>dependency-check-maven</artifactId> - <version>1.4.0</version> + <version>1.4.2</version> </plugin> ... </plugins> @@ -309,7 +309,7 @@ have any known published vulnerabilities. <plugin> <groupId>org.owasp</groupId> <artifactId>dependency-check-maven</artifactId> - <version>1.4.0</version> + <version>1.4.2</version> </plugin> ... </plugins> @@ -321,7 +321,7 @@ have any known published vulnerabilities. <plugin> <groupId>org.owasp</groupId> <artifactId>dependency-check-maven</artifactId> - <version>1.4.0</version> + <version>1.4.2</version> </plugin> ... </plugins> diff --git a/dependency-check-maven/plugin-updates-report.html b/dependency-check-maven/plugin-updates-report.html index 7cbff46e9..39340baf3 100644 --- a/dependency-check-maven/plugin-updates-report.html +++ b/dependency-check-maven/plugin-updates-report.html @@ -1,13 +1,13 @@ - + dependency-check-maven – Plugin Updates Report @@ -52,7 +52,7 @@ @@ -244,7 +244,7 @@ # of plugins using the latest version available -19 +20 # of plugins where the next version available is smaller than an incremental version update @@ -260,7 +260,7 @@ # of plugins where the next version available is a major version update -1 +0 # of plugins where a dependencies section containes a dependency with an updated version @@ -382,7 +382,7 @@ org.apache.maven.plugins maven-jar-plugin -3.0.0 +3.0.2 @@ -392,7 +392,7 @@ org.apache.maven.plugins maven-javadoc-plugin -2.10.3 +2.10.4 @@ -429,14 +429,14 @@ - + org.apache.maven.plugins maven-source-plugin -2.4 +3.0.1 + -3.0.0 @@ -678,7 +678,7 @@ maven-jar-plugin Current Version -3.0.0 +3.0.2

      Plugin org.apache.maven.plugins:maven-javadoc-plugin

      @@ -693,7 +693,7 @@ -
      maven-javadoc-plugin
      Current Version2.10.3
      +2.10.4

      Plugin org.apache.maven.plugins:maven-plugin-plugin

      @@ -759,7 +759,7 @@
      - + @@ -768,10 +768,7 @@ - - - -
      Status There is at least one newer major version available. Major updates are rarely passive.
       No newer versions available.
      Group Id org.apache.maven.plugins
      maven-source-plugin
      Current Version2.4
      Newer versions3.0.0 Next Major
      +3.0.1

      Plugin org.apache.maven.plugins:maven-surefire-plugin

      diff --git a/dependency-check-maven/pmd.html b/dependency-check-maven/pmd.html index 0cf9011ef..33f103af2 100644 --- a/dependency-check-maven/pmd.html +++ b/dependency-check-maven/pmd.html @@ -1,13 +1,13 @@ - + dependency-check-maven – PMD Results @@ -52,7 +52,7 @@ @@ -250,7 +250,7 @@ -
      Line
      Useless parentheses.761
      +774 diff --git a/dependency-check-maven/project-info.html b/dependency-check-maven/project-info.html index e8e36b725..28c1de9f6 100644 --- a/dependency-check-maven/project-info.html +++ b/dependency-check-maven/project-info.html @@ -1,13 +1,13 @@ - + dependency-check-maven – Project Information @@ -52,7 +52,7 @@ diff --git a/dependency-check-maven/project-reports.html b/dependency-check-maven/project-reports.html index 27bc1006c..35432b2ee 100644 --- a/dependency-check-maven/project-reports.html +++ b/dependency-check-maven/project-reports.html @@ -1,13 +1,13 @@ - + dependency-check-maven – Generated Reports @@ -52,7 +52,7 @@ diff --git a/dependency-check-maven/project-summary.html b/dependency-check-maven/project-summary.html index dd0897cf5..7595cf962 100644 --- a/dependency-check-maven/project-summary.html +++ b/dependency-check-maven/project-summary.html @@ -1,13 +1,13 @@ - + dependency-check-maven – Project Summary @@ -52,7 +52,7 @@ @@ -238,7 +238,7 @@ dependency-check-maven Version -1.4.0 +1.4.2 Type maven-plugin diff --git a/dependency-check-maven/purge-mojo.html b/dependency-check-maven/purge-mojo.html index 7b5540450..bc7272f9b 100644 --- a/dependency-check-maven/purge-mojo.html +++ b/dependency-check-maven/purge-mojo.html @@ -1,13 +1,13 @@ - + dependency-check-maven – dependency-check:purge @@ -52,7 +52,7 @@ @@ -155,7 +155,7 @@

      Full name:

      -

      org.owasp:dependency-check-maven:1.4.0:purge

      +

      org.owasp:dependency-check-maven:1.4.2:purge

      Description:

      @@ -214,6 +214,17 @@ the CVSS scores are 0-10, by default the build will never fail.
      Default +failOnError + +boolean + +- + +Sets whether or not the external report format should be used.
      Default value is: true.
      User property is: failOnError. + + + + format String @@ -225,7 +236,7 @@ configuration option has no affect if using this within the Site plug-in unless the externalReport is set to true. Default is HTML.
      Default value is: HTML.
      User property is: format. - + outputDirectory @@ -236,7 +247,7 @@ plug-in unless the externalReport is set to true. Default is HTML.
      Defau The output directory. This generally maps to "target".
      Default value is: ${project.build.directory}.
      - + reportOutputDirectory @@ -1062,6 +1073,20 @@ the CVSS scores are 0-10, by default the build will never fail.
    257. Default: 11

    258. +

      failOnError:

      + +
      Sets whether or not the external report format should be used.
      + +
        + +
      • Type: boolean
      • + +
      • Required: Yes
      • + +
      • User Property: failOnError
      • + +
      • Default: true
      • +

      format:

      The report format to be generated (HTML, XML, VULN, ALL). This diff --git a/dependency-check-maven/source-repository.html b/dependency-check-maven/source-repository.html index 0a1a4c892..70e300903 100644 --- a/dependency-check-maven/source-repository.html +++ b/dependency-check-maven/source-repository.html @@ -1,13 +1,13 @@ - + dependency-check-maven – Source Code Management @@ -52,7 +52,7 @@ diff --git a/dependency-check-maven/surefire-report.html b/dependency-check-maven/surefire-report.html index 7ca3cfd7f..6c9123c61 100644 --- a/dependency-check-maven/surefire-report.html +++ b/dependency-check-maven/surefire-report.html @@ -1,13 +1,13 @@ - + dependency-check-maven – Surefire Report @@ -52,7 +52,7 @@ @@ -273,7 +273,7 @@ function toggleDisplay(elementId) { 0 0 100% -0.756
      +0.636

      Note: failures are anticipated and checked for with assertions while errors are unanticipated.


      Package List

      @@ -294,7 +294,7 @@ function toggleDisplay(elementId) { 0 0 100% -0.756
      +0.636

      Note: package statistics are not computed recursively, they only sum up all of its testsuites numbers.

      org.owasp.dependencycheck.maven

      @@ -316,7 +316,7 @@ function toggleDisplay(elementId) { 0 0 100% -0.756

      +0.636

      Test Cases

      [Summary] [Package List] [Test Cases]

      diff --git a/dependency-check-maven/taglist.html b/dependency-check-maven/taglist.html index 03290eb36..66fae20d6 100644 --- a/dependency-check-maven/taglist.html +++ b/dependency-check-maven/taglist.html @@ -1,13 +1,13 @@ - + dependency-check-maven – Tag List report @@ -52,7 +52,7 @@ @@ -259,7 +259,7 @@ Line fix logging -1112 +1118 org.owasp.dependencycheck.maven.BaseDependencyCheckMojoTest Line diff --git a/dependency-check-maven/team-list.html b/dependency-check-maven/team-list.html index 972087c02..940d77421 100644 --- a/dependency-check-maven/team-list.html +++ b/dependency-check-maven/team-list.html @@ -1,13 +1,13 @@ - + dependency-check-maven – Project Team @@ -52,7 +52,7 @@ diff --git a/dependency-check-maven/update-only-mojo.html b/dependency-check-maven/update-only-mojo.html index 2fe281ffd..fdd494c45 100644 --- a/dependency-check-maven/update-only-mojo.html +++ b/dependency-check-maven/update-only-mojo.html @@ -1,13 +1,13 @@ - + dependency-check-maven – dependency-check:update-only @@ -52,7 +52,7 @@ @@ -155,7 +155,7 @@

      Full name:

      -

      org.owasp:dependency-check-maven:1.4.0:update-only

      +

      org.owasp:dependency-check-maven:1.4.2:update-only

      Description:

      @@ -215,6 +215,17 @@ the CVSS scores are 0-10, by default the build will never fail.
      Default +failOnError + +boolean + +- + +Sets whether or not the external report format should be used.
      Default value is: true.
      User property is: failOnError. + + + + format String @@ -226,7 +237,7 @@ configuration option has no affect if using this within the Site plug-in unless the externalReport is set to true. Default is HTML.
      Default value is: HTML.
      User property is: format. - + outputDirectory @@ -237,7 +248,7 @@ plug-in unless the externalReport is set to true. Default is HTML.
      Defau The output directory. This generally maps to "target".
      Default value is: ${project.build.directory}.
      - + reportOutputDirectory @@ -1063,6 +1074,20 @@ the CVSS scores are 0-10, by default the build will never fail.
    259. Default: 11

    260. +

      failOnError:

      + +
      Sets whether or not the external report format should be used.
      + +
        + +
      • Type: boolean
      • + +
      • Required: Yes
      • + +
      • User Property: failOnError
      • + +
      • Default: true
      • +

      format:

      The report format to be generated (HTML, XML, VULN, ALL). This diff --git a/dependency-check-maven/xref-test/index.html b/dependency-check-maven/xref-test/index.html index 46ddeb355..c8670889a 100644 --- a/dependency-check-maven/xref-test/index.html +++ b/dependency-check-maven/xref-test/index.html @@ -4,7 +4,7 @@ - Dependency-Check Maven Plugin 1.4.0 Reference + Dependency-Check Maven Plugin 1.4.2 Reference diff --git a/dependency-check-maven/xref-test/org/owasp/dependencycheck/maven/BaseDependencyCheckMojoTest.html b/dependency-check-maven/xref-test/org/owasp/dependencycheck/maven/BaseDependencyCheckMojoTest.html index 566d99de2..030c6a7d6 100644 --- a/dependency-check-maven/xref-test/org/owasp/dependencycheck/maven/BaseDependencyCheckMojoTest.html +++ b/dependency-check-maven/xref-test/org/owasp/dependencycheck/maven/BaseDependencyCheckMojoTest.html @@ -98,7 +98,7 @@ 90 91 boolean autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE); 92 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); -93 Engine engine = new Engine(null, null); +93 MavenEngine engine = new MavenEngine(null, null); 94 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate); 95 96 assertTrue(engine.getDependencies().isEmpty()); diff --git a/dependency-check-maven/xref-test/org/owasp/dependencycheck/maven/package-frame.html b/dependency-check-maven/xref-test/org/owasp/dependencycheck/maven/package-frame.html index 413f12df2..73d2702f4 100644 --- a/dependency-check-maven/xref-test/org/owasp/dependencycheck/maven/package-frame.html +++ b/dependency-check-maven/xref-test/org/owasp/dependencycheck/maven/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Maven Plugin 1.4.0 Reference Package org.owasp.dependencycheck.maven + Dependency-Check Maven Plugin 1.4.2 Reference Package org.owasp.dependencycheck.maven diff --git a/dependency-check-maven/xref-test/org/owasp/dependencycheck/maven/package-summary.html b/dependency-check-maven/xref-test/org/owasp/dependencycheck/maven/package-summary.html index c86605253..9cd96733e 100644 --- a/dependency-check-maven/xref-test/org/owasp/dependencycheck/maven/package-summary.html +++ b/dependency-check-maven/xref-test/org/owasp/dependencycheck/maven/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Maven Plugin 1.4.0 Reference Package org.owasp.dependencycheck.maven + Dependency-Check Maven Plugin 1.4.2 Reference Package org.owasp.dependencycheck.maven diff --git a/dependency-check-maven/xref-test/overview-frame.html b/dependency-check-maven/xref-test/overview-frame.html index 6b6173eb4..5c34377a7 100644 --- a/dependency-check-maven/xref-test/overview-frame.html +++ b/dependency-check-maven/xref-test/overview-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Maven Plugin 1.4.0 Reference + Dependency-Check Maven Plugin 1.4.2 Reference diff --git a/dependency-check-maven/xref-test/overview-summary.html b/dependency-check-maven/xref-test/overview-summary.html index 5a9b7a970..111abb945 100644 --- a/dependency-check-maven/xref-test/overview-summary.html +++ b/dependency-check-maven/xref-test/overview-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Maven Plugin 1.4.0 Reference + Dependency-Check Maven Plugin 1.4.2 Reference @@ -24,7 +24,7 @@
      -

      Dependency-Check Maven Plugin 1.4.0 Reference

      +

      Dependency-Check Maven Plugin 1.4.2 Reference

      diff --git a/dependency-check-maven/xref/allclasses-frame.html b/dependency-check-maven/xref/allclasses-frame.html index 7d490bb9b..e06fbf0ef 100644 --- a/dependency-check-maven/xref/allclasses-frame.html +++ b/dependency-check-maven/xref/allclasses-frame.html @@ -21,10 +21,10 @@ CheckMojo
    261. - Engine + HelpMojo
    262. - HelpMojo + MavenEngine
    263. MavenLoggerAdapter diff --git a/dependency-check-maven/xref/index.html b/dependency-check-maven/xref/index.html index 46ddeb355..c8670889a 100644 --- a/dependency-check-maven/xref/index.html +++ b/dependency-check-maven/xref/index.html @@ -4,7 +4,7 @@ - Dependency-Check Maven Plugin 1.4.0 Reference + Dependency-Check Maven Plugin 1.4.2 Reference diff --git a/dependency-check-maven/xref/org/owasp/dependencycheck/maven/AggregateMojo.html b/dependency-check-maven/xref/org/owasp/dependencycheck/maven/AggregateMojo.html index c4241a087..16feec78c 100644 --- a/dependency-check-maven/xref/org/owasp/dependencycheck/maven/AggregateMojo.html +++ b/dependency-check-maven/xref/org/owasp/dependencycheck/maven/AggregateMojo.html @@ -44,289 +44,349 @@ 36 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; 37 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; 38 import org.owasp.dependencycheck.dependency.Dependency; -39 import org.owasp.dependencycheck.utils.Settings; -40 -41 /** -42 * Maven Plugin that checks project dependencies and the dependencies of all child modules to see if they have any known published -43 * vulnerabilities. -44 * -45 * @author Jeremy Long -46 */ -47 @Mojo( -48 name = "aggregate", -49 defaultPhase = LifecyclePhase.VERIFY, -50 /*aggregator = true,*/ -51 threadSafe = false, -52 requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME, -53 requiresOnline = true -54 ) -55 public class AggregateMojo extends BaseDependencyCheckMojo { -56 -57 /** -58 * Executes the aggregate dependency-check goal. This runs dependency-check and generates the subsequent reports. -59 * -60 * @throws MojoExecutionException thrown if there is ane exception running the mojo -61 * @throws MojoFailureException thrown if dependency-check is configured to fail the build -62 */ -63 @Override -64 public void runCheck() throws MojoExecutionException, MojoFailureException { -65 final Engine engine = generateDataFile(); -66 -67 //if (getProject() == getReactorProjects().get(getReactorProjects().size() - 1)) { -68 if (getProject() == getLastProject()) { -69 -70 //ensure that the .ser file was created for each. -71 for (MavenProject current : getReactorProjects()) { -72 final File dataFile = getDataFile(current); -73 if (dataFile == null && !skipProject(current)) { //dc was never run on this project. write the ser to the target. -74 getLog().error(String.format("Module '%s' did not execute dependency-check; an attempt will be made to perform " -75 + "the check but dependencies may be missed resulting in false negatives.", current.getName())); -76 generateDataFile(engine, current); -77 } -78 } +39 import org.owasp.dependencycheck.exception.ExceptionCollection; +40 import org.owasp.dependencycheck.exception.ReportException; +41 import org.owasp.dependencycheck.utils.Settings; +42 +43 /** +44 * Maven Plugin that checks project dependencies and the dependencies of all +45 * child modules to see if they have any known published vulnerabilities. +46 * +47 * @author Jeremy Long +48 */ +49 @Mojo( +50 name = "aggregate", +51 defaultPhase = LifecyclePhase.VERIFY, +52 /*aggregator = true,*/ +53 threadSafe = false, +54 requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME, +55 requiresOnline = true +56 ) +57 public class AggregateMojo extends BaseDependencyCheckMojo { +58 +59 /** +60 * The key to store aggregate exception in the root Maven execution context. +61 */ +62 private static final String AGGREGATE_EXCEPTIONS = "AggregateExceptions"; +63 +64 /** +65 * Executes the aggregate dependency-check goal. This runs dependency-check +66 * and generates the subsequent reports. +67 * +68 * @throws MojoExecutionException thrown if there is ane exception running +69 * the mojo +70 * @throws MojoFailureException thrown if dependency-check is configured to +71 * fail the build +72 */ +73 @Override +74 public void runCheck() throws MojoExecutionException, MojoFailureException { +75 final MavenEngine engine = generateDataFile(); +76 if (engine == null) { +77 return; +78 } 79 -80 for (MavenProject current : getReactorProjects()) { -81 List<Dependency> dependencies = readDataFile(current); -82 if (dependencies == null) { -83 dependencies = new ArrayList<Dependency>(); -84 } -85 final Set<MavenProject> childProjects = getDescendants(current); -86 for (MavenProject reportOn : childProjects) { -87 final List<Dependency> childDeps = readDataFile(reportOn); -88 if (childDeps != null && !childDeps.isEmpty()) { -89 if (getLog().isDebugEnabled()) { -90 getLog().debug(String.format("Adding %d dependencies from %s", childDeps.size(), reportOn.getName())); -91 } -92 dependencies.addAll(childDeps); -93 } else { -94 if (getLog().isDebugEnabled()) { -95 getLog().debug(String.format("No dependencies read for %s", reportOn.getName())); -96 } -97 } -98 } -99 engine.getDependencies().clear(); -100 engine.getDependencies().addAll(dependencies); -101 final DependencyBundlingAnalyzer bundler = new DependencyBundlingAnalyzer(); -102 try { -103 if (getLog().isDebugEnabled()) { -104 getLog().debug(String.format("Dependency count pre-bundler: %s", engine.getDependencies().size())); +80 if (getProject() == getLastProject()) { +81 //ensure that the .ser file was created for each. +82 for (MavenProject current : getReactorProjects()) { +83 final File dataFile = getDataFile(current); +84 if (dataFile == null && !skipProject(current)) { //dc was never run on this project. write the ser to the target. +85 getLog().error(String.format("Module '%s' did not execute dependency-check; an attempt will be made to perform " +86 + "the check but dependencies may be missed resulting in false negatives.", current.getName())); +87 generateDataFile(engine, current); +88 } +89 } +90 for (MavenProject current : getReactorProjects()) { +91 List<Dependency> dependencies = readDataFile(current); +92 if (dependencies == null) { +93 dependencies = new ArrayList<Dependency>(); +94 } +95 final Set<MavenProject> childProjects = getDescendants(current); +96 for (MavenProject reportOn : childProjects) { +97 final List<Dependency> childDeps = readDataFile(reportOn); +98 if (childDeps != null && !childDeps.isEmpty()) { +99 if (getLog().isDebugEnabled()) { +100 getLog().debug(String.format("Adding %d dependencies from %s", childDeps.size(), reportOn.getName())); +101 } +102 dependencies.addAll(childDeps); +103 } else if (getLog().isDebugEnabled()) { +104 getLog().debug(String.format("No dependencies read for %s", reportOn.getName())); 105 } -106 bundler.analyze(null, engine); -107 if (getLog().isDebugEnabled()) { -108 getLog().debug(String.format("Dependency count post-bundler: %s", engine.getDependencies().size())); -109 } -110 } catch (AnalysisException ex) { -111 getLog().warn("An error occurred grouping the dependencies; duplicate entries may exist in the report", ex); -112 getLog().debug("Bundling Exception", ex); -113 } -114 -115 File outputDir = getCorrectOutputDirectory(current); -116 if (outputDir == null) { -117 //in some regards we shouldn't be writting this, but we are anyway. -118 //we shouldn't write this because nothing is configured to generate this report. -119 outputDir = new File(current.getBuild().getDirectory()); -120 } -121 writeReports(engine, current, outputDir); -122 } -123 } -124 engine.cleanup(); -125 Settings.cleanup(); -126 } -127 -128 /** -129 * Gets the last project in the reactor - taking into account skipped projects. -130 * -131 * @return the last project in the reactor -132 */ -133 private MavenProject getLastProject() { -134 for (int x = getReactorProjects().size() - 1; x >= 0; x--) { -135 final MavenProject p = getReactorProjects().get(x); -136 if (!skipProject(p)) { -137 return p; -138 } -139 -140 } -141 return null; -142 } -143 -144 /** -145 * Tests if the project is being skipped in the Maven site report. -146 * -147 * @param project a project in the reactor -148 * @return true if the project is skipped; otherwise false -149 */ -150 private boolean skipProject(MavenProject project) { -151 final String skip = (String) project.getProperties().get("maven.site.skip"); -152 return "true".equalsIgnoreCase(skip) && isGeneratingSite(); -153 } -154 -155 /** -156 * Returns a set containing all the descendant projects of the given project. -157 * -158 * @param project the project for which all descendants will be returned -159 * @return the set of descendant projects -160 */ -161 protected Set<MavenProject> getDescendants(MavenProject project) { -162 if (project == null) { -163 return Collections.emptySet(); -164 } -165 final Set<MavenProject> descendants = new HashSet<MavenProject>(); -166 int size = 0; -167 if (getLog().isDebugEnabled()) { -168 getLog().debug(String.format("Collecting descendants of %s", project.getName())); -169 } -170 for (String m : project.getModules()) { -171 for (MavenProject mod : getReactorProjects()) { -172 try { -173 File mpp = new File(project.getBasedir(), m); -174 mpp = mpp.getCanonicalFile(); -175 if (mpp.compareTo(mod.getBasedir()) == 0 && descendants.add(mod) -176 && getLog().isDebugEnabled()) { -177 getLog().debug(String.format("Decendent module %s added", mod.getName())); -178 -179 } -180 } catch (IOException ex) { -181 if (getLog().isDebugEnabled()) { -182 getLog().debug("Unable to determine module path", ex); -183 } -184 } -185 } -186 } -187 do { -188 size = descendants.size(); -189 for (MavenProject p : getReactorProjects()) { -190 if (project.equals(p.getParent()) || descendants.contains(p.getParent())) { -191 if (descendants.add(p) && getLog().isDebugEnabled()) { -192 getLog().debug(String.format("Decendent %s added", p.getName())); -193 -194 } -195 for (MavenProject modTest : getReactorProjects()) { -196 if (p.getModules() != null && p.getModules().contains(modTest.getName()) -197 && descendants.add(modTest) -198 && getLog().isDebugEnabled()) { -199 getLog().debug(String.format("Decendent %s added", modTest.getName())); -200 } -201 } -202 } -203 final Set<MavenProject> addedDescendants = new HashSet<MavenProject>(); -204 for (MavenProject dec : descendants) { -205 for (String mod : dec.getModules()) { -206 try { -207 File mpp = new File(dec.getBasedir(), mod); -208 mpp = mpp.getCanonicalFile(); -209 if (mpp.compareTo(p.getBasedir()) == 0) { -210 addedDescendants.add(p); -211 } -212 } catch (IOException ex) { -213 if (getLog().isDebugEnabled()) { -214 getLog().debug("Unable to determine module path", ex); -215 } -216 } +106 } +107 engine.getDependencies().clear(); +108 engine.getDependencies().addAll(dependencies); +109 final DependencyBundlingAnalyzer bundler = new DependencyBundlingAnalyzer(); +110 try { +111 if (getLog().isDebugEnabled()) { +112 getLog().debug(String.format("Dependency count pre-bundler: %s", engine.getDependencies().size())); +113 } +114 bundler.analyze(null, engine); +115 if (getLog().isDebugEnabled()) { +116 getLog().debug(String.format("Dependency count post-bundler: %s", engine.getDependencies().size())); +117 } +118 } catch (AnalysisException ex) { +119 getLog().warn("An error occurred grouping the dependencies; duplicate entries may exist in the report", ex); +120 getLog().debug("Bundling Exception", ex); +121 } +122 +123 File outputDir = getCorrectOutputDirectory(current); +124 if (outputDir == null) { +125 //in some regards we shouldn't be writting this, but we are anyway. +126 //we shouldn't write this because nothing is configured to generate this report. +127 outputDir = new File(current.getBuild().getDirectory()); +128 } +129 try { +130 writeReports(engine, current, outputDir); +131 } catch (ReportException ex) { +132 ExceptionCollection exCol = (ExceptionCollection) engine.getExecutionRoot().getContextValue(AGGREGATE_EXCEPTIONS); +133 if (exCol == null) { +134 exCol = new ExceptionCollection("Error writing aggregate report", ex); +135 } else { +136 exCol.addException(ex); +137 } +138 if (this.isFailOnError()) { +139 throw new MojoExecutionException("One or more exceptions occured during dependency-check analysis", exCol); +140 } else { +141 getLog().debug("One or more exceptions occured during dependency-check analysis", exCol); +142 } +143 } +144 } +145 } +146 engine.cleanup(); +147 Settings.cleanup(); +148 } +149 +150 /** +151 * Gets the last project in the reactor - taking into account skipped +152 * projects. +153 * +154 * @return the last project in the reactor +155 */ +156 private MavenProject getLastProject() { +157 for (int x = getReactorProjects().size() - 1; x >= 0; x--) { +158 final MavenProject p = getReactorProjects().get(x); +159 if (!skipProject(p)) { +160 return p; +161 } +162 } +163 return null; +164 } +165 +166 /** +167 * Tests if the project is being skipped in the Maven site report. +168 * +169 * @param project a project in the reactor +170 * @return true if the project is skipped; otherwise false +171 */ +172 private boolean skipProject(MavenProject project) { +173 final String skip = (String) project.getProperties().get("maven.site.skip"); +174 return "true".equalsIgnoreCase(skip) && isGeneratingSite(); +175 } +176 +177 /** +178 * Returns a set containing all the descendant projects of the given +179 * project. +180 * +181 * @param project the project for which all descendants will be returned +182 * @return the set of descendant projects +183 */ +184 protected Set<MavenProject> getDescendants(MavenProject project) { +185 if (project == null) { +186 return Collections.emptySet(); +187 } +188 final Set<MavenProject> descendants = new HashSet<MavenProject>(); +189 int size = 0; +190 if (getLog().isDebugEnabled()) { +191 getLog().debug(String.format("Collecting descendants of %s", project.getName())); +192 } +193 for (String m : project.getModules()) { +194 for (MavenProject mod : getReactorProjects()) { +195 try { +196 File mpp = new File(project.getBasedir(), m); +197 mpp = mpp.getCanonicalFile(); +198 if (mpp.compareTo(mod.getBasedir()) == 0 && descendants.add(mod) +199 && getLog().isDebugEnabled()) { +200 getLog().debug(String.format("Decendent module %s added", mod.getName())); +201 +202 } +203 } catch (IOException ex) { +204 if (getLog().isDebugEnabled()) { +205 getLog().debug("Unable to determine module path", ex); +206 } +207 } +208 } +209 } +210 do { +211 size = descendants.size(); +212 for (MavenProject p : getReactorProjects()) { +213 if (project.equals(p.getParent()) || descendants.contains(p.getParent())) { +214 if (descendants.add(p) && getLog().isDebugEnabled()) { +215 getLog().debug(String.format("Decendent %s added", p.getName())); +216 217 } -218 } -219 for (MavenProject addedDescendant : addedDescendants) { -220 if (descendants.add(addedDescendant) && getLog().isDebugEnabled()) { -221 getLog().debug(String.format("Decendent module %s added", addedDescendant.getName())); -222 } -223 } -224 } -225 } while (size != 0 && size != descendants.size()); -226 if (getLog().isDebugEnabled()) { -227 getLog().debug(String.format("%s has %d children", project, descendants.size())); -228 } -229 return descendants; -230 } -231 -232 /** -233 * Test if the project has pom packaging -234 * -235 * @param mavenProject Project to test -236 * @return <code>true</code> if it has a pom packaging; otherwise <code>false</code> -237 */ -238 protected boolean isMultiModule(MavenProject mavenProject) { -239 return "pom".equals(mavenProject.getPackaging()); -240 } -241 -242 /** -243 * Initilizes the engine, runs a scan, and writes the serialized dependencies to disk. -244 * -245 * @return the Engine used to execute dependency-check -246 * @throws MojoExecutionException thrown if there is an exception running the mojo -247 * @throws MojoFailureException thrown if dependency-check is configured to fail the build if severe CVEs are identified. -248 */ -249 protected Engine generateDataFile() throws MojoExecutionException, MojoFailureException { -250 final Engine engine; -251 try { -252 engine = initializeEngine(); -253 } catch (DatabaseException ex) { -254 if (getLog().isDebugEnabled()) { -255 getLog().debug("Database connection error", ex); -256 } -257 throw new MojoExecutionException("An exception occured connecting to the local database. Please see the log file for more details.", ex); -258 } -259 return generateDataFile(engine, getProject()); -260 } -261 -262 /** -263 * Runs dependency-check's Engine and writes the serialized dependencies to disk. -264 * -265 * @param engine the Engine to use when scanning. -266 * @param project the project to scan and generate the data file for -267 * @return the Engine used to execute dependency-check -268 * @throws MojoExecutionException thrown if there is an exception running the mojo -269 * @throws MojoFailureException thrown if dependency-check is configured to fail the build if severe CVEs are identified. -270 */ -271 protected Engine generateDataFile(Engine engine, MavenProject project) throws MojoExecutionException, MojoFailureException { -272 if (getLog().isDebugEnabled()) { -273 getLog().debug(String.format("Begin Scanning: %s", project.getName())); -274 } -275 engine.getDependencies().clear(); -276 engine.resetFileTypeAnalyzers(); -277 scanArtifacts(project, engine); -278 engine.analyzeDependencies(); -279 final File target = new File(project.getBuild().getDirectory()); -280 writeDataFile(project, target, engine.getDependencies()); -281 showSummary(project, engine.getDependencies()); -282 checkForFailure(engine.getDependencies()); -283 return engine; -284 } -285 -286 @Override -287 public boolean canGenerateReport() { -288 return true; //aggregate always returns true for now - we can look at a more complicated/acurate solution later -289 } -290 -291 /** -292 * The name of the report in the site. -293 */ -294 @SuppressWarnings("CanBeFinal") -295 @Parameter(property = "name", defaultValue = "dependency-check:aggregate", required = true) -296 private String name = "dependency-check:aggregate"; -297 -298 /** -299 * Returns the report name. -300 * -301 * @param locale the location -302 * @return the report name -303 */ -304 @Override -305 public String getName(Locale locale) { -306 return name; -307 } -308 -309 /** -310 * Gets the description of the Dependency-Check report to be displayed in the Maven Generated Reports page. -311 * -312 * @param locale The Locale to get the description for -313 * @return the description -314 */ -315 @Override -316 public String getDescription(Locale locale) { -317 return "Generates an aggregate report of all child Maven projects providing details on any " -318 + "published vulnerabilities within project dependencies. This report is a best " -319 + "effort and may contain false positives and false negatives."; -320 } -321 } +218 for (MavenProject modTest : getReactorProjects()) { +219 if (p.getModules() != null && p.getModules().contains(modTest.getName()) +220 && descendants.add(modTest) +221 && getLog().isDebugEnabled()) { +222 getLog().debug(String.format("Decendent %s added", modTest.getName())); +223 } +224 } +225 } +226 final Set<MavenProject> addedDescendants = new HashSet<MavenProject>(); +227 for (MavenProject dec : descendants) { +228 for (String mod : dec.getModules()) { +229 try { +230 File mpp = new File(dec.getBasedir(), mod); +231 mpp = mpp.getCanonicalFile(); +232 if (mpp.compareTo(p.getBasedir()) == 0) { +233 addedDescendants.add(p); +234 } +235 } catch (IOException ex) { +236 if (getLog().isDebugEnabled()) { +237 getLog().debug("Unable to determine module path", ex); +238 } +239 } +240 } +241 } +242 for (MavenProject addedDescendant : addedDescendants) { +243 if (descendants.add(addedDescendant) && getLog().isDebugEnabled()) { +244 getLog().debug(String.format("Decendent module %s added", addedDescendant.getName())); +245 } +246 } +247 } +248 } while (size != 0 && size != descendants.size()); +249 if (getLog().isDebugEnabled()) { +250 getLog().debug(String.format("%s has %d children", project, descendants.size())); +251 } +252 return descendants; +253 } +254 +255 /** +256 * Test if the project has pom packaging +257 * +258 * @param mavenProject Project to test +259 * @return <code>true</code> if it has a pom packaging; otherwise +260 * <code>false</code> +261 */ +262 protected boolean isMultiModule(MavenProject mavenProject) { +263 return "pom".equals(mavenProject.getPackaging()); +264 } +265 +266 /** +267 * Initializes the engine, runs a scan, and writes the serialized +268 * dependencies to disk. +269 * +270 * @return the MavenEngine used to execute dependency-check +271 * @throws MojoExecutionException thrown if there is an exception running +272 * the mojo +273 * @throws MojoFailureException thrown if dependency-check is configured to +274 * fail the build if severe CVEs are identified. +275 */ +276 protected MavenEngine generateDataFile() throws MojoExecutionException, MojoFailureException { +277 MavenEngine engine = null; +278 try { +279 engine = initializeEngine(); +280 } catch (DatabaseException ex) { +281 if (getLog().isDebugEnabled()) { +282 getLog().debug("Database connection error", ex); +283 } +284 final String msg = "An exception occured connecting to the local database. Please see the log file for more details."; +285 if (this.isFailOnError()) { +286 throw new MojoExecutionException(msg, ex); +287 } +288 getLog().error(msg, ex); +289 return null; +290 } +291 return generateDataFile(engine, getProject()); +292 } +293 +294 /** +295 * Runs dependency-check's MavenEngine and writes the serialized +296 * dependencies to disk. +297 * +298 * @param engine the MavenEngine to use when scanning. +299 * @param project the project to scan and generate the data file for +300 * @return the MavenEngine used to execute dependency-check +301 * @throws MojoExecutionException thrown if there is an exception running +302 * the mojo +303 * @throws MojoFailureException thrown if dependency-check is configured to +304 * fail the build if severe CVEs are identified. +305 */ +306 protected MavenEngine generateDataFile(MavenEngine engine, MavenProject project) throws MojoExecutionException, MojoFailureException { +307 if (getLog().isDebugEnabled()) { +308 getLog().debug(String.format("Begin Scanning: %s", project.getName())); +309 } +310 engine.getDependencies().clear(); +311 engine.resetFileTypeAnalyzers(); +312 scanArtifacts(project, engine); +313 try { +314 engine.analyzeDependencies(); +315 } catch (ExceptionCollection ex) { +316 ExceptionCollection col = (ExceptionCollection) engine.getExecutionRoot().getContextValue(AGGREGATE_EXCEPTIONS); +317 if (col == null) { +318 col = ex; +319 } else if (ex.isFatal()) { +320 col.setFatal(true); +321 col.getExceptions().addAll(ex.getExceptions()); +322 } +323 if (col.isFatal()) { +324 final String msg = String.format("Fatal exception(s) analyzing %s", project.getName()); +325 if (this.isFailOnError()) { +326 throw new MojoExecutionException(msg, ex); +327 } +328 getLog().error(msg, col); +329 return null; +330 } else { +331 final String msg = String.format("Exception(s) analyzing %s", project.getName()); +332 if (getLog().isDebugEnabled()) { +333 getLog().debug(msg, ex); +334 } +335 engine.getExecutionRoot().setContextValue(AGGREGATE_EXCEPTIONS, col); +336 } +337 } +338 final File target = new File(project.getBuild().getDirectory()); +339 writeDataFile(project, target, engine.getDependencies()); +340 showSummary(project, engine.getDependencies()); +341 checkForFailure(engine.getDependencies()); +342 return engine; +343 } +344 +345 @Override +346 public boolean canGenerateReport() { +347 return true; //aggregate always returns true for now - we can look at a more complicated/acurate solution later +348 } +349 +350 /** +351 * The name of the report in the site. +352 */ +353 @SuppressWarnings("CanBeFinal") +354 @Parameter(property = "name", defaultValue = "dependency-check:aggregate", required = true) +355 private String name = "dependency-check:aggregate"; +356 +357 /** +358 * Returns the report name. +359 * +360 * @param locale the location +361 * @return the report name +362 */ +363 @Override +364 public String getName(Locale locale) { +365 return name; +366 } +367 +368 /** +369 * Gets the description of the Dependency-Check report to be displayed in +370 * the Maven Generated Reports page. +371 * +372 * @param locale The Locale to get the description for +373 * @return the description +374 */ +375 @Override +376 public String getDescription(Locale locale) { +377 return "Generates an aggregate report of all child Maven projects providing details on any " +378 + "published vulnerabilities within project dependencies. This report is a best " +379 + "effort and may contain false positives and false negatives."; +380 } +381 }
      diff --git a/dependency-check-maven/xref/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.html b/dependency-check-maven/xref/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.html index 8b19a40c7..72887c849 100644 --- a/dependency-check-maven/xref/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.html +++ b/dependency-check-maven/xref/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.html @@ -55,1087 +55,1093 @@ 47 import org.owasp.dependencycheck.dependency.Dependency; 48 import org.owasp.dependencycheck.dependency.Identifier; 49 import org.owasp.dependencycheck.dependency.Vulnerability; -50 import org.owasp.dependencycheck.reporting.ReportGenerator; -51 import org.owasp.dependencycheck.utils.ExpectedOjectInputStream; -52 import org.owasp.dependencycheck.utils.Settings; -53 import org.sonatype.plexus.components.sec.dispatcher.DefaultSecDispatcher; -54 import org.sonatype.plexus.components.sec.dispatcher.SecDispatcher; -55 import org.sonatype.plexus.components.sec.dispatcher.SecDispatcherException; -56 -57 /** -58 * -59 * @author Jeremy Long -60 */ -61 public abstract class BaseDependencyCheckMojo extends AbstractMojo implements MavenReport { -62 -63 //<editor-fold defaultstate="collapsed" desc="Private fields"> -64 /** -65 * The properties file location. -66 */ -67 private static final String PROPERTIES_FILE = "mojo.properties"; -68 /** -69 * System specific new line character. -70 */ -71 private static final String NEW_LINE = System.getProperty("line.separator", "\n").intern(); -72 /** -73 * Sets whether or not the external report format should be used. -74 */ -75 @Parameter(property = "metaFileName", defaultValue = "dependency-check.ser", required = true) -76 private String dataFileName; -77 -78 //</editor-fold> -79 // <editor-fold defaultstate="collapsed" desc="Maven bound parameters and components"> +50 import org.owasp.dependencycheck.exception.ReportException; +51 import org.owasp.dependencycheck.reporting.ReportGenerator; +52 import org.owasp.dependencycheck.utils.ExpectedOjectInputStream; +53 import org.owasp.dependencycheck.utils.Settings; +54 import org.sonatype.plexus.components.sec.dispatcher.DefaultSecDispatcher; +55 import org.sonatype.plexus.components.sec.dispatcher.SecDispatcher; +56 import org.sonatype.plexus.components.sec.dispatcher.SecDispatcherException; +57 +58 /** +59 * +60 * @author Jeremy Long +61 */ +62 public abstract class BaseDependencyCheckMojo extends AbstractMojo implements MavenReport { +63 +64 //<editor-fold defaultstate="collapsed" desc="Private fields"> +65 /** +66 * The properties file location. +67 */ +68 private static final String PROPERTIES_FILE = "mojo.properties"; +69 /** +70 * System specific new line character. +71 */ +72 private static final String NEW_LINE = System.getProperty("line.separator", "\n").intern(); +73 //</editor-fold> +74 // <editor-fold defaultstate="collapsed" desc="Maven bound parameters and components"> +75 /** +76 * Sets whether or not the external report format should be used. +77 */ +78 @Parameter(property = "metaFileName", defaultValue = "dependency-check.ser", required = true) +79 private String dataFileName; 80 /** -81 * The Maven Project Object. +81 * Sets whether or not the external report format should be used. 82 */ -83 @Parameter(property = "project", required = true, readonly = true) -84 private MavenProject project; -85 /** -86 * List of Maven project of the current build -87 */ -88 @Parameter(readonly = true, required = true, property = "reactorProjects") -89 private List<MavenProject> reactorProjects; -90 -91 /** -92 * The output directory. This generally maps to "target". -93 */ -94 @Parameter(defaultValue = "${project.build.directory}", required = true) -95 private File outputDirectory; -96 /** -97 * Specifies the destination directory for the generated Dependency-Check -98 * report. This generally maps to "target/site". -99 */ -100 @Parameter(property = "project.reporting.outputDirectory", required = true) -101 private File reportOutputDirectory; -102 /** -103 * Specifies if the build should be failed if a CVSS score above a specified -104 * level is identified. The default is 11 which means since the CVSS scores -105 * are 0-10, by default the build will never fail. -106 */ -107 @SuppressWarnings("CanBeFinal") -108 @Parameter(property = "failBuildOnCVSS", defaultValue = "11", required = true) -109 private float failBuildOnCVSS = 11; -110 /** -111 * Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not -112 * recommended that this be turned to false. Default is true. -113 */ -114 @SuppressWarnings("CanBeFinal") -115 @Parameter(property = "autoUpdate") -116 private Boolean autoUpdate; +83 @Parameter(property = "failOnError", defaultValue = "true", required = true) +84 private boolean failOnError; +85 +86 /** +87 * Returns if the mojo should fail the build if an exception occurs. +88 * +89 * @return whether or not the mojo should fail the build +90 */ +91 protected boolean isFailOnError() { +92 return failOnError; +93 } +94 +95 /** +96 * The Maven Project Object. +97 */ +98 @Parameter(property = "project", required = true, readonly = true) +99 private MavenProject project; +100 /** +101 * List of Maven project of the current build +102 */ +103 @Parameter(readonly = true, required = true, property = "reactorProjects") +104 private List<MavenProject> reactorProjects; +105 +106 /** +107 * The output directory. This generally maps to "target". +108 */ +109 @Parameter(defaultValue = "${project.build.directory}", required = true) +110 private File outputDirectory; +111 /** +112 * Specifies the destination directory for the generated Dependency-Check +113 * report. This generally maps to "target/site". +114 */ +115 @Parameter(property = "project.reporting.outputDirectory", required = true) +116 private File reportOutputDirectory; 117 /** -118 * Sets whether Experimental analyzers are enabled. Default is false. -119 */ -120 @SuppressWarnings("CanBeFinal") -121 @Parameter(property = "enableExperimental") -122 private Boolean enableExperimental; -123 /** -124 * Generate aggregate reports in multi-module projects. -125 * -126 * @deprecated use the aggregate goal instead -127 */ -128 @Parameter(property = "aggregate") -129 @Deprecated -130 private Boolean aggregate; +118 * Specifies if the build should be failed if a CVSS score above a specified +119 * level is identified. The default is 11 which means since the CVSS scores +120 * are 0-10, by default the build will never fail. +121 */ +122 @SuppressWarnings("CanBeFinal") +123 @Parameter(property = "failBuildOnCVSS", defaultValue = "11", required = true) +124 private float failBuildOnCVSS = 11; +125 /** +126 * Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not +127 * recommended that this be turned to false. Default is true. +128 */ +129 @Parameter(property = "autoUpdate") +130 private Boolean autoUpdate; 131 /** -132 * The report format to be generated (HTML, XML, VULN, ALL). This -133 * configuration option has no affect if using this within the Site plug-in -134 * unless the externalReport is set to true. Default is HTML. -135 */ -136 @SuppressWarnings("CanBeFinal") -137 @Parameter(property = "format", defaultValue = "HTML", required = true) -138 private String format = "HTML"; -139 /** -140 * The Maven settings. -141 */ -142 @Parameter(property = "mavenSettings", defaultValue = "${settings}", required = false) -143 private org.apache.maven.settings.Settings mavenSettings; -144 -145 /** -146 * The maven settings proxy id. -147 */ -148 @SuppressWarnings("CanBeFinal") -149 @Parameter(property = "mavenSettingsProxyId", required = false) -150 private String mavenSettingsProxyId; -151 +132 * Sets whether Experimental analyzers are enabled. Default is false. +133 */ +134 @Parameter(property = "enableExperimental") +135 private Boolean enableExperimental; +136 /** +137 * Generate aggregate reports in multi-module projects. +138 * +139 * @deprecated use the aggregate goal instead +140 */ +141 @Parameter(property = "aggregate") +142 @Deprecated +143 private Boolean aggregate; +144 /** +145 * The report format to be generated (HTML, XML, VULN, ALL). This +146 * configuration option has no affect if using this within the Site plug-in +147 * unless the externalReport is set to true. Default is HTML. +148 */ +149 @SuppressWarnings("CanBeFinal") +150 @Parameter(property = "format", defaultValue = "HTML", required = true) +151 private String format = "HTML"; 152 /** -153 * The Connection Timeout. +153 * The Maven settings. 154 */ -155 @Parameter(property = "connectionTimeout", defaultValue = "", required = false) -156 private String connectionTimeout; -157 /** -158 * The path to the suppression file. -159 */ -160 @Parameter(property = "suppressionFile", defaultValue = "", required = false) -161 private String suppressionFile; -162 /** -163 * Flag indicating whether or not to show a summary in the output. -164 */ -165 @Parameter(property = "showSummary", defaultValue = "true", required = false) -166 private boolean showSummary = true; -167 -168 /** -169 * Whether or not the Jar Analyzer is enabled. -170 */ -171 @Parameter(property = "jarAnalyzerEnabled", required = false) -172 private Boolean jarAnalyzerEnabled; -173 +155 @Parameter(property = "mavenSettings", defaultValue = "${settings}", required = false) +156 private org.apache.maven.settings.Settings mavenSettings; +157 +158 /** +159 * The maven settings proxy id. +160 */ +161 @Parameter(property = "mavenSettingsProxyId", required = false) +162 private String mavenSettingsProxyId; +163 +164 /** +165 * The Connection Timeout. +166 */ +167 @Parameter(property = "connectionTimeout", defaultValue = "", required = false) +168 private String connectionTimeout; +169 /** +170 * The path to the suppression file. +171 */ +172 @Parameter(property = "suppressionFile", defaultValue = "", required = false) +173 private String suppressionFile; 174 /** -175 * Whether or not the Archive Analyzer is enabled. +175 * Flag indicating whether or not to show a summary in the output. 176 */ -177 @Parameter(property = "archiveAnalyzerEnabled", required = false) -178 private Boolean archiveAnalyzerEnabled; -179 -180 /** -181 * Sets whether the Python Distribution Analyzer will be used. -182 */ -183 @Parameter(property = "pyDistributionAnalyzerEnabled", required = false) -184 private Boolean pyDistributionAnalyzerEnabled; -185 /** -186 * Sets whether the Python Package Analyzer will be used. -187 */ -188 @Parameter(property = "pyPackageAnalyzerEnabled", required = false) -189 private Boolean pyPackageAnalyzerEnabled; -190 /** -191 * Sets whether the Ruby Gemspec Analyzer will be used. -192 */ -193 @Parameter(property = "rubygemsAnalyzerEnabled", required = false) -194 private Boolean rubygemsAnalyzerEnabled; -195 /** -196 * Sets whether or not the openssl Analyzer should be used. -197 */ -198 @Parameter(property = "opensslAnalyzerEnabled", required = false) -199 private Boolean opensslAnalyzerEnabled; -200 /** -201 * Sets whether or not the CMake Analyzer should be used. -202 */ -203 @Parameter(property = "cmakeAnalyzerEnabled", required = false) -204 private Boolean cmakeAnalyzerEnabled; -205 /** -206 * Sets whether or not the autoconf Analyzer should be used. -207 */ -208 @Parameter(property = "autoconfAnalyzerEnabled", required = false) -209 private Boolean autoconfAnalyzerEnabled; -210 /** -211 * Sets whether or not the PHP Composer Lock File Analyzer should be used. -212 */ -213 @Parameter(property = "composerAnalyzerEnabled", required = false) -214 private Boolean composerAnalyzerEnabled; -215 /** -216 * Sets whether or not the Node.js Analyzer should be used. -217 */ -218 @Parameter(property = "nodeAnalyzerEnabled", required = false) -219 private Boolean nodeAnalyzerEnabled; -220 -221 /** -222 * Whether or not the .NET Assembly Analyzer is enabled. -223 */ -224 @Parameter(property = "assemblyAnalyzerEnabled", required = false) -225 private Boolean assemblyAnalyzerEnabled; -226 -227 /** -228 * Whether or not the .NET Nuspec Analyzer is enabled. -229 */ -230 @Parameter(property = "nuspecAnalyzerEnabled", required = false) -231 private Boolean nuspecAnalyzerEnabled; -232 -233 /** -234 * Whether or not the Central Analyzer is enabled. -235 */ -236 @Parameter(property = "centralAnalyzerEnabled", required = false) -237 private Boolean centralAnalyzerEnabled; -238 -239 /** -240 * Whether or not the Nexus Analyzer is enabled. -241 */ -242 @Parameter(property = "nexusAnalyzerEnabled", required = false) -243 private Boolean nexusAnalyzerEnabled; -244 -245 /** -246 * The URL of a Nexus server's REST API end point -247 * (http://domain/nexus/service/local). +177 @SuppressWarnings("CanBeFinal") +178 @Parameter(property = "showSummary", defaultValue = "true", required = false) +179 private boolean showSummary = true; +180 +181 /** +182 * Whether or not the Jar Analyzer is enabled. +183 */ +184 @Parameter(property = "jarAnalyzerEnabled", required = false) +185 private Boolean jarAnalyzerEnabled; +186 +187 /** +188 * Whether or not the Archive Analyzer is enabled. +189 */ +190 @Parameter(property = "archiveAnalyzerEnabled", required = false) +191 private Boolean archiveAnalyzerEnabled; +192 +193 /** +194 * Sets whether the Python Distribution Analyzer will be used. +195 */ +196 @Parameter(property = "pyDistributionAnalyzerEnabled", required = false) +197 private Boolean pyDistributionAnalyzerEnabled; +198 /** +199 * Sets whether the Python Package Analyzer will be used. +200 */ +201 @Parameter(property = "pyPackageAnalyzerEnabled", required = false) +202 private Boolean pyPackageAnalyzerEnabled; +203 /** +204 * Sets whether the Ruby Gemspec Analyzer will be used. +205 */ +206 @Parameter(property = "rubygemsAnalyzerEnabled", required = false) +207 private Boolean rubygemsAnalyzerEnabled; +208 /** +209 * Sets whether or not the openssl Analyzer should be used. +210 */ +211 @Parameter(property = "opensslAnalyzerEnabled", required = false) +212 private Boolean opensslAnalyzerEnabled; +213 /** +214 * Sets whether or not the CMake Analyzer should be used. +215 */ +216 @Parameter(property = "cmakeAnalyzerEnabled", required = false) +217 private Boolean cmakeAnalyzerEnabled; +218 /** +219 * Sets whether or not the autoconf Analyzer should be used. +220 */ +221 @Parameter(property = "autoconfAnalyzerEnabled", required = false) +222 private Boolean autoconfAnalyzerEnabled; +223 /** +224 * Sets whether or not the PHP Composer Lock File Analyzer should be used. +225 */ +226 @Parameter(property = "composerAnalyzerEnabled", required = false) +227 private Boolean composerAnalyzerEnabled; +228 /** +229 * Sets whether or not the Node.js Analyzer should be used. +230 */ +231 @Parameter(property = "nodeAnalyzerEnabled", required = false) +232 private Boolean nodeAnalyzerEnabled; +233 +234 /** +235 * Whether or not the .NET Assembly Analyzer is enabled. +236 */ +237 @Parameter(property = "assemblyAnalyzerEnabled", required = false) +238 private Boolean assemblyAnalyzerEnabled; +239 +240 /** +241 * Whether or not the .NET Nuspec Analyzer is enabled. +242 */ +243 @Parameter(property = "nuspecAnalyzerEnabled", required = false) +244 private Boolean nuspecAnalyzerEnabled; +245 +246 /** +247 * Whether or not the Central Analyzer is enabled. 248 */ -249 @Parameter(property = "nexusUrl", required = false) -250 private String nexusUrl; -251 /** -252 * Whether or not the configured proxy is used to connect to Nexus. -253 */ -254 @Parameter(property = "nexusUsesProxy", required = false) -255 private Boolean nexusUsesProxy; -256 /** -257 * The database connection string. -258 */ -259 @Parameter(property = "connectionString", defaultValue = "", required = false) -260 private String connectionString; -261 -262 /** -263 * Returns the connection string. -264 * -265 * @return the connection string +249 @Parameter(property = "centralAnalyzerEnabled", required = false) +250 private Boolean centralAnalyzerEnabled; +251 +252 /** +253 * Whether or not the Nexus Analyzer is enabled. +254 */ +255 @Parameter(property = "nexusAnalyzerEnabled", required = false) +256 private Boolean nexusAnalyzerEnabled; +257 +258 /** +259 * The URL of a Nexus server's REST API end point +260 * (http://domain/nexus/service/local). +261 */ +262 @Parameter(property = "nexusUrl", required = false) +263 private String nexusUrl; +264 /** +265 * Whether or not the configured proxy is used to connect to Nexus. 266 */ -267 protected String getConnectionString() { -268 return connectionString; -269 } -270 /** -271 * The database driver name. An example would be org.h2.Driver. -272 */ -273 @Parameter(property = "databaseDriverName", defaultValue = "", required = false) -274 private String databaseDriverName; +267 @Parameter(property = "nexusUsesProxy", required = false) +268 private Boolean nexusUsesProxy; +269 /** +270 * The database connection string. +271 */ +272 @Parameter(property = "connectionString", defaultValue = "", required = false) +273 private String connectionString; +274 275 /** -276 * The path to the database driver if it is not on the class path. -277 */ -278 @Parameter(property = "databaseDriverPath", defaultValue = "", required = false) -279 private String databaseDriverPath; -280 /** -281 * The server id in the settings.xml; used to retrieve encrypted passwords -282 * from the settings.xml. -283 */ -284 @Parameter(property = "serverId", defaultValue = "", required = false) -285 private String serverId; -286 /** -287 * A reference to the settings.xml settings. -288 */ -289 @Parameter(defaultValue = "${settings}", readonly = true, required = true) -290 private org.apache.maven.settings.Settings settingsXml; -291 /** -292 * The security dispatcher that can decrypt passwords in the settings.xml. -293 */ -294 @Component(role = SecDispatcher.class, hint = "default") -295 private SecDispatcher securityDispatcher; -296 /** -297 * The database user name. -298 */ -299 @Parameter(property = "databaseUser", defaultValue = "", required = false) -300 private String databaseUser; -301 /** -302 * The password to use when connecting to the database. -303 */ -304 @Parameter(property = "databasePassword", defaultValue = "", required = false) -305 private String databasePassword; -306 /** -307 * A comma-separated list of file extensions to add to analysis next to jar, -308 * zip, .... -309 */ -310 @Parameter(property = "zipExtensions", required = false) -311 private String zipExtensions; -312 /** -313 * Skip Dependency Check altogether. -314 */ -315 @SuppressWarnings("CanBeFinal") -316 @Parameter(property = "dependency-check.skip", defaultValue = "false", required = false) -317 private boolean skip = false; -318 /** -319 * Skip Analysis for Test Scope Dependencies. -320 */ -321 @SuppressWarnings("CanBeFinal") -322 @Parameter(property = "skipTestScope", defaultValue = "true", required = false) -323 private boolean skipTestScope = true; -324 /** -325 * Skip Analysis for Runtime Scope Dependencies. -326 */ -327 @SuppressWarnings("CanBeFinal") -328 @Parameter(property = "skipRuntimeScope", defaultValue = "false", required = false) -329 private boolean skipRuntimeScope = false; -330 /** -331 * Skip Analysis for Provided Scope Dependencies. -332 */ -333 @SuppressWarnings("CanBeFinal") -334 @Parameter(property = "skipProvidedScope", defaultValue = "false", required = false) -335 private boolean skipProvidedScope = false; -336 /** -337 * The data directory, hold DC SQL DB. -338 */ -339 @Parameter(property = "dataDirectory", defaultValue = "", required = false) -340 private String dataDirectory; -341 /** -342 * Data Mirror URL for CVE 1.2. -343 */ -344 @Parameter(property = "cveUrl12Modified", defaultValue = "", required = false) -345 private String cveUrl12Modified; -346 /** -347 * Data Mirror URL for CVE 2.0. -348 */ -349 @Parameter(property = "cveUrl20Modified", defaultValue = "", required = false) -350 private String cveUrl20Modified; -351 /** -352 * Base Data Mirror URL for CVE 1.2. -353 */ -354 @Parameter(property = "cveUrl12Base", defaultValue = "", required = false) -355 private String cveUrl12Base; -356 /** -357 * Data Mirror URL for CVE 2.0. -358 */ -359 @Parameter(property = "cveUrl20Base", defaultValue = "", required = false) -360 private String cveUrl20Base; -361 /** -362 * Optionally skip excessive CVE update checks for a designated duration in -363 * hours. -364 */ -365 @Parameter(property = "cveValidForHours", defaultValue = "", required = false) -366 private Integer cveValidForHours; -367 -368 /** -369 * The path to mono for .NET Assembly analysis on non-windows systems. -370 */ -371 @Parameter(property = "pathToMono", defaultValue = "", required = false) -372 private String pathToMono; -373 +276 * Returns the connection string. +277 * +278 * @return the connection string +279 */ +280 protected String getConnectionString() { +281 return connectionString; +282 } +283 /** +284 * The database driver name. An example would be org.h2.Driver. +285 */ +286 @Parameter(property = "databaseDriverName", defaultValue = "", required = false) +287 private String databaseDriverName; +288 /** +289 * The path to the database driver if it is not on the class path. +290 */ +291 @Parameter(property = "databaseDriverPath", defaultValue = "", required = false) +292 private String databaseDriverPath; +293 /** +294 * The server id in the settings.xml; used to retrieve encrypted passwords +295 * from the settings.xml. +296 */ +297 @Parameter(property = "serverId", defaultValue = "", required = false) +298 private String serverId; +299 /** +300 * A reference to the settings.xml settings. +301 */ +302 @Parameter(defaultValue = "${settings}", readonly = true, required = true) +303 private org.apache.maven.settings.Settings settingsXml; +304 /** +305 * The security dispatcher that can decrypt passwords in the settings.xml. +306 */ +307 @Component(role = SecDispatcher.class, hint = "default") +308 private SecDispatcher securityDispatcher; +309 /** +310 * The database user name. +311 */ +312 @Parameter(property = "databaseUser", defaultValue = "", required = false) +313 private String databaseUser; +314 /** +315 * The password to use when connecting to the database. +316 */ +317 @Parameter(property = "databasePassword", defaultValue = "", required = false) +318 private String databasePassword; +319 /** +320 * A comma-separated list of file extensions to add to analysis next to jar, +321 * zip, .... +322 */ +323 @Parameter(property = "zipExtensions", required = false) +324 private String zipExtensions; +325 /** +326 * Skip Dependency Check altogether. +327 */ +328 @SuppressWarnings("CanBeFinal") +329 @Parameter(property = "dependency-check.skip", defaultValue = "false", required = false) +330 private boolean skip = false; +331 /** +332 * Skip Analysis for Test Scope Dependencies. +333 */ +334 @SuppressWarnings("CanBeFinal") +335 @Parameter(property = "skipTestScope", defaultValue = "true", required = false) +336 private boolean skipTestScope = true; +337 /** +338 * Skip Analysis for Runtime Scope Dependencies. +339 */ +340 @SuppressWarnings("CanBeFinal") +341 @Parameter(property = "skipRuntimeScope", defaultValue = "false", required = false) +342 private boolean skipRuntimeScope = false; +343 /** +344 * Skip Analysis for Provided Scope Dependencies. +345 */ +346 @SuppressWarnings("CanBeFinal") +347 @Parameter(property = "skipProvidedScope", defaultValue = "false", required = false) +348 private boolean skipProvidedScope = false; +349 /** +350 * The data directory, hold DC SQL DB. +351 */ +352 @Parameter(property = "dataDirectory", defaultValue = "", required = false) +353 private String dataDirectory; +354 /** +355 * Data Mirror URL for CVE 1.2. +356 */ +357 @Parameter(property = "cveUrl12Modified", defaultValue = "", required = false) +358 private String cveUrl12Modified; +359 /** +360 * Data Mirror URL for CVE 2.0. +361 */ +362 @Parameter(property = "cveUrl20Modified", defaultValue = "", required = false) +363 private String cveUrl20Modified; +364 /** +365 * Base Data Mirror URL for CVE 1.2. +366 */ +367 @Parameter(property = "cveUrl12Base", defaultValue = "", required = false) +368 private String cveUrl12Base; +369 /** +370 * Data Mirror URL for CVE 2.0. +371 */ +372 @Parameter(property = "cveUrl20Base", defaultValue = "", required = false) +373 private String cveUrl20Base; 374 /** -375 * The Proxy URL. -376 * -377 * @deprecated Please use mavenSettings instead -378 */ -379 @SuppressWarnings("CanBeFinal") -380 @Parameter(property = "proxyUrl", defaultValue = "", required = false) -381 @Deprecated -382 private String proxyUrl = null; -383 /** -384 * Sets whether or not the external report format should be used. -385 * -386 * @deprecated the internal report is no longer supported -387 */ -388 @SuppressWarnings("CanBeFinal") -389 @Parameter(property = "externalReport") -390 @Deprecated -391 private String externalReport = null; -392 // </editor-fold> -393 //<editor-fold defaultstate="collapsed" desc="Base Maven implementation"> -394 -395 /** -396 * Executes dependency-check. -397 * -398 * @throws MojoExecutionException thrown if there is an exception executing -399 * the mojo -400 * @throws MojoFailureException thrown if dependency-check failed the build -401 */ -402 @Override -403 public void execute() throws MojoExecutionException, MojoFailureException { -404 generatingSite = false; -405 if (skip) { -406 getLog().info("Skipping " + getName(Locale.US)); -407 } else { -408 validateAggregate(); -409 project.setContextValue(getOutputDirectoryContextKey(), this.outputDirectory); -410 runCheck(); -411 } -412 } -413 -414 /** -415 * Checks if the aggregate configuration parameter has been set to true. If -416 * it has a MojoExecutionException is thrown because the aggregate -417 * configuration parameter is no longer supported. -418 * -419 * @throws MojoExecutionException thrown if aggregate is set to true -420 */ -421 private void validateAggregate() throws MojoExecutionException { -422 if (aggregate != null && aggregate) { -423 final String msg = "Aggregate configuration detected - as of dependency-check 1.2.8 this no longer supported. " -424 + "Please use the aggregate goal instead."; -425 throw new MojoExecutionException(msg); -426 } -427 } -428 -429 /** -430 * Generates the Dependency-Check Site Report. +375 * Optionally skip excessive CVE update checks for a designated duration in +376 * hours. +377 */ +378 @Parameter(property = "cveValidForHours", defaultValue = "", required = false) +379 private Integer cveValidForHours; +380 +381 /** +382 * The path to mono for .NET Assembly analysis on non-windows systems. +383 */ +384 @Parameter(property = "pathToMono", defaultValue = "", required = false) +385 private String pathToMono; +386 +387 /** +388 * The Proxy URL. +389 * +390 * @deprecated Please use mavenSettings instead +391 */ +392 @SuppressWarnings("CanBeFinal") +393 @Parameter(property = "proxyUrl", defaultValue = "", required = false) +394 @Deprecated +395 private String proxyUrl = null; +396 /** +397 * Sets whether or not the external report format should be used. +398 * +399 * @deprecated the internal report is no longer supported +400 */ +401 @SuppressWarnings("CanBeFinal") +402 @Parameter(property = "externalReport") +403 @Deprecated +404 private String externalReport = null; +405 // </editor-fold> +406 //<editor-fold defaultstate="collapsed" desc="Base Maven implementation"> +407 +408 /** +409 * Executes dependency-check. +410 * +411 * @throws MojoExecutionException thrown if there is an exception executing +412 * the mojo +413 * @throws MojoFailureException thrown if dependency-check failed the build +414 */ +415 @Override +416 public void execute() throws MojoExecutionException, MojoFailureException { +417 generatingSite = false; +418 if (skip) { +419 getLog().info("Skipping " + getName(Locale.US)); +420 } else { +421 validateAggregate(); +422 project.setContextValue(getOutputDirectoryContextKey(), this.outputDirectory); +423 runCheck(); +424 } +425 } +426 +427 /** +428 * Checks if the aggregate configuration parameter has been set to true. If +429 * it has a MojoExecutionException is thrown because the aggregate +430 * configuration parameter is no longer supported. 431 * -432 * @param sink the sink to write the report to -433 * @param locale the locale to use when generating the report -434 * @throws MavenReportException if a maven report exception occurs -435 * @deprecated use -436 * {@link #generate(org.apache.maven.doxia.sink.Sink, java.util.Locale)} -437 * instead. -438 */ -439 @Override -440 @Deprecated -441 public final void generate(@SuppressWarnings("deprecation") org.codehaus.doxia.sink.Sink sink, Locale locale) throws MavenReportException { -442 generate((Sink) sink, locale); -443 } -444 -445 /** -446 * A flag indicating whether or not the maven site is being generated. -447 */ -448 private boolean generatingSite = false; -449 -450 /** -451 * Returns true if the Maven site is being generated. -452 * -453 * @return true if the Maven site is being generated -454 */ -455 protected boolean isGeneratingSite() { -456 return generatingSite; -457 } -458 -459 /** -460 * Generates the Dependency-Check Site Report. -461 * -462 * @param sink the sink to write the report to -463 * @param locale the locale to use when generating the report -464 * @throws MavenReportException if a maven report exception occurs -465 */ -466 public void generate(Sink sink, Locale locale) throws MavenReportException { -467 generatingSite = true; -468 try { -469 validateAggregate(); -470 } catch (MojoExecutionException ex) { -471 throw new MavenReportException(ex.getMessage()); -472 } -473 project.setContextValue(getOutputDirectoryContextKey(), getReportOutputDirectory()); -474 try { -475 runCheck(); -476 } catch (MojoExecutionException ex) { -477 throw new MavenReportException(ex.getMessage(), ex); -478 } catch (MojoFailureException ex) { -479 getLog().warn("Vulnerabilities were identifies that exceed the CVSS threshold for failing the build"); -480 } -481 } -482 -483 /** -484 * Returns the correct output directory depending on if a site is being -485 * executed or not. -486 * -487 * @return the directory to write the report(s) -488 * @throws MojoExecutionException thrown if there is an error loading the -489 * file path -490 */ -491 protected File getCorrectOutputDirectory() throws MojoExecutionException { -492 return getCorrectOutputDirectory(this.project); -493 } -494 -495 /** -496 * Returns the correct output directory depending on if a site is being -497 * executed or not. -498 * -499 * @param current the Maven project to get the output directory from +432 * @throws MojoExecutionException thrown if aggregate is set to true +433 */ +434 private void validateAggregate() throws MojoExecutionException { +435 if (aggregate != null && aggregate) { +436 final String msg = "Aggregate configuration detected - as of dependency-check 1.2.8 this no longer supported. " +437 + "Please use the aggregate goal instead."; +438 throw new MojoExecutionException(msg); +439 } +440 } +441 +442 /** +443 * Generates the Dependency-Check Site Report. +444 * +445 * @param sink the sink to write the report to +446 * @param locale the locale to use when generating the report +447 * @throws MavenReportException if a maven report exception occurs +448 * @deprecated use +449 * {@link #generate(org.apache.maven.doxia.sink.Sink, java.util.Locale)} +450 * instead. +451 */ +452 @Override +453 @Deprecated +454 public final void generate(@SuppressWarnings("deprecation") org.codehaus.doxia.sink.Sink sink, Locale locale) throws MavenReportException { +455 generate((Sink) sink, locale); +456 } +457 +458 /** +459 * A flag indicating whether or not the maven site is being generated. +460 */ +461 private boolean generatingSite = false; +462 +463 /** +464 * Returns true if the Maven site is being generated. +465 * +466 * @return true if the Maven site is being generated +467 */ +468 protected boolean isGeneratingSite() { +469 return generatingSite; +470 } +471 +472 /** +473 * Generates the Dependency-Check Site Report. +474 * +475 * @param sink the sink to write the report to +476 * @param locale the locale to use when generating the report +477 * @throws MavenReportException if a maven report exception occurs +478 */ +479 public void generate(Sink sink, Locale locale) throws MavenReportException { +480 generatingSite = true; +481 try { +482 validateAggregate(); +483 } catch (MojoExecutionException ex) { +484 throw new MavenReportException(ex.getMessage()); +485 } +486 project.setContextValue(getOutputDirectoryContextKey(), getReportOutputDirectory()); +487 try { +488 runCheck(); +489 } catch (MojoExecutionException ex) { +490 throw new MavenReportException(ex.getMessage(), ex); +491 } catch (MojoFailureException ex) { +492 getLog().warn("Vulnerabilities were identifies that exceed the CVSS threshold for failing the build"); +493 } +494 } +495 +496 /** +497 * Returns the correct output directory depending on if a site is being +498 * executed or not. +499 * 500 * @return the directory to write the report(s) -501 */ -502 protected File getCorrectOutputDirectory(MavenProject current) { -503 final Object obj = current.getContextValue(getOutputDirectoryContextKey()); -504 if (obj != null && obj instanceof File) { -505 return (File) obj; -506 } -507 File target = new File(current.getBuild().getDirectory()); -508 if (target.getParentFile() != null && "target".equals(target.getParentFile().getName())) { -509 target = target.getParentFile(); -510 } -511 return target; -512 } -513 -514 /** -515 * Returns the correct output directory depending on if a site is being -516 * executed or not. -517 * -518 * @param current the Maven project to get the output directory from -519 * @return the directory to write the report(s) -520 */ -521 protected File getDataFile(MavenProject current) { -522 if (getLog().isDebugEnabled()) { -523 getLog().debug(String.format("Getting data filefor %s using key '%s'", current.getName(), getDataFileContextKey())); -524 } -525 final Object obj = current.getContextValue(getDataFileContextKey()); -526 if (obj != null) { -527 if (obj instanceof String) { -528 final File f = new File((String) obj); -529 return f; -530 } -531 } else if (getLog().isDebugEnabled()) { -532 getLog().debug("Context value not found"); -533 } -534 return null; -535 } -536 -537 /** -538 * Scans the project's artifacts and adds them to the engine's dependency -539 * list. -540 * -541 * @param project the project to scan the dependencies of -542 * @param engine the engine to use to scan the dependencies -543 */ -544 protected void scanArtifacts(MavenProject project, Engine engine) { -545 for (Artifact a : project.getArtifacts()) { -546 if (excludeFromScan(a)) { -547 continue; -548 } -549 final List<Dependency> deps = engine.scan(a.getFile().getAbsoluteFile()); -550 if (deps != null) { -551 if (deps.size() == 1) { -552 final Dependency d = deps.get(0); -553 if (d != null) { -554 final MavenArtifact ma = new MavenArtifact(a.getGroupId(), a.getArtifactId(), a.getVersion()); -555 d.addAsEvidence("pom", ma, Confidence.HIGHEST); -556 d.addProjectReference(project.getName()); -557 if (getLog().isDebugEnabled()) { -558 getLog().debug(String.format("Adding project reference %s on dependency %s", project.getName(), -559 d.getDisplayFileName())); -560 } -561 } -562 } else if (getLog().isDebugEnabled()) { -563 final String msg = String.format("More then 1 dependency was identified in first pass scan of '%s:%s:%s'", -564 a.getGroupId(), a.getArtifactId(), a.getVersion()); -565 getLog().debug(msg); -566 } -567 } -568 } -569 } -570 -571 /** -572 * Executes the dependency-check scan and generates the necassary report. -573 * -574 * @throws MojoExecutionException thrown if there is an exception running -575 * the scan -576 * @throws MojoFailureException thrown if dependency-check is configured to -577 * fail the build -578 */ -579 public abstract void runCheck() throws MojoExecutionException, MojoFailureException; -580 -581 /** -582 * Sets the Reporting output directory. -583 * -584 * @param directory the output directory -585 */ -586 @Override -587 public void setReportOutputDirectory(File directory) { -588 reportOutputDirectory = directory; -589 } -590 -591 /** -592 * Returns the report output directory. -593 * -594 * @return the report output directory -595 */ -596 @Override -597 public File getReportOutputDirectory() { -598 return reportOutputDirectory; -599 } -600 -601 /** -602 * Returns the output directory. -603 * -604 * @return the output directory -605 */ -606 public File getOutputDirectory() { -607 return outputDirectory; -608 } -609 -610 /** -611 * Returns whether this is an external report. This method always returns -612 * true. -613 * -614 * @return <code>true</code> -615 */ -616 @Override -617 public final boolean isExternalReport() { -618 return true; -619 } -620 -621 /** -622 * Returns the output name. -623 * -624 * @return the output name -625 */ -626 @Override -627 public String getOutputName() { -628 if ("HTML".equalsIgnoreCase(this.format) || "ALL".equalsIgnoreCase(this.format)) { -629 return "dependency-check-report"; -630 } else if ("XML".equalsIgnoreCase(this.format)) { -631 return "dependency-check-report.xml#"; -632 } else if ("VULN".equalsIgnoreCase(this.format)) { -633 return "dependency-check-vulnerability"; -634 } else { -635 getLog().warn("Unknown report format used during site generation."); -636 return "dependency-check-report"; -637 } -638 } -639 -640 /** -641 * Returns the category name. -642 * -643 * @return the category name -644 */ -645 @Override -646 public String getCategoryName() { -647 return MavenReport.CATEGORY_PROJECT_REPORTS; -648 } -649 //</editor-fold> -650 -651 /** -652 * Initializes a new <code>Engine</code> that can be used for scanning. -653 * -654 * @return a newly instantiated <code>Engine</code> -655 * @throws DatabaseException thrown if there is a database exception -656 */ -657 protected Engine initializeEngine() throws DatabaseException { -658 populateSettings(); -659 return new Engine(this.project, -660 this.reactorProjects); +501 * @throws MojoExecutionException thrown if there is an error loading the +502 * file path +503 */ +504 protected File getCorrectOutputDirectory() throws MojoExecutionException { +505 return getCorrectOutputDirectory(this.project); +506 } +507 +508 /** +509 * Returns the correct output directory depending on if a site is being +510 * executed or not. +511 * +512 * @param current the Maven project to get the output directory from +513 * @return the directory to write the report(s) +514 */ +515 protected File getCorrectOutputDirectory(MavenProject current) { +516 final Object obj = current.getContextValue(getOutputDirectoryContextKey()); +517 if (obj != null && obj instanceof File) { +518 return (File) obj; +519 } +520 File target = new File(current.getBuild().getDirectory()); +521 if (target.getParentFile() != null && "target".equals(target.getParentFile().getName())) { +522 target = target.getParentFile(); +523 } +524 return target; +525 } +526 +527 /** +528 * Returns the correct output directory depending on if a site is being +529 * executed or not. +530 * +531 * @param current the Maven project to get the output directory from +532 * @return the directory to write the report(s) +533 */ +534 protected File getDataFile(MavenProject current) { +535 if (getLog().isDebugEnabled()) { +536 getLog().debug(String.format("Getting data filefor %s using key '%s'", current.getName(), getDataFileContextKey())); +537 } +538 final Object obj = current.getContextValue(getDataFileContextKey()); +539 if (obj != null) { +540 if (obj instanceof String) { +541 final File f = new File((String) obj); +542 return f; +543 } +544 } else if (getLog().isDebugEnabled()) { +545 getLog().debug("Context value not found"); +546 } +547 return null; +548 } +549 +550 /** +551 * Scans the project's artifacts and adds them to the engine's dependency +552 * list. +553 * +554 * @param project the project to scan the dependencies of +555 * @param engine the engine to use to scan the dependencies +556 */ +557 protected void scanArtifacts(MavenProject project, MavenEngine engine) { +558 for (Artifact a : project.getArtifacts()) { +559 if (excludeFromScan(a)) { +560 continue; +561 } +562 final List<Dependency> deps = engine.scan(a.getFile().getAbsoluteFile()); +563 if (deps != null) { +564 if (deps.size() == 1) { +565 final Dependency d = deps.get(0); +566 if (d != null) { +567 final MavenArtifact ma = new MavenArtifact(a.getGroupId(), a.getArtifactId(), a.getVersion()); +568 d.addAsEvidence("pom", ma, Confidence.HIGHEST); +569 d.addProjectReference(project.getName()); +570 if (getLog().isDebugEnabled()) { +571 getLog().debug(String.format("Adding project reference %s on dependency %s", project.getName(), +572 d.getDisplayFileName())); +573 } +574 } +575 } else if (getLog().isDebugEnabled()) { +576 final String msg = String.format("More then 1 dependency was identified in first pass scan of '%s:%s:%s'", +577 a.getGroupId(), a.getArtifactId(), a.getVersion()); +578 getLog().debug(msg); +579 } +580 } +581 } +582 } +583 +584 /** +585 * Executes the dependency-check scan and generates the necassary report. +586 * +587 * @throws MojoExecutionException thrown if there is an exception running +588 * the scan +589 * @throws MojoFailureException thrown if dependency-check is configured to +590 * fail the build +591 */ +592 public abstract void runCheck() throws MojoExecutionException, MojoFailureException; +593 +594 /** +595 * Sets the Reporting output directory. +596 * +597 * @param directory the output directory +598 */ +599 @Override +600 public void setReportOutputDirectory(File directory) { +601 reportOutputDirectory = directory; +602 } +603 +604 /** +605 * Returns the report output directory. +606 * +607 * @return the report output directory +608 */ +609 @Override +610 public File getReportOutputDirectory() { +611 return reportOutputDirectory; +612 } +613 +614 /** +615 * Returns the output directory. +616 * +617 * @return the output directory +618 */ +619 public File getOutputDirectory() { +620 return outputDirectory; +621 } +622 +623 /** +624 * Returns whether this is an external report. This method always returns +625 * true. +626 * +627 * @return <code>true</code> +628 */ +629 @Override +630 public final boolean isExternalReport() { +631 return true; +632 } +633 +634 /** +635 * Returns the output name. +636 * +637 * @return the output name +638 */ +639 @Override +640 public String getOutputName() { +641 if ("HTML".equalsIgnoreCase(this.format) || "ALL".equalsIgnoreCase(this.format)) { +642 return "dependency-check-report"; +643 } else if ("XML".equalsIgnoreCase(this.format)) { +644 return "dependency-check-report.xml#"; +645 } else if ("VULN".equalsIgnoreCase(this.format)) { +646 return "dependency-check-vulnerability"; +647 } else { +648 getLog().warn("Unknown report format used during site generation."); +649 return "dependency-check-report"; +650 } +651 } +652 +653 /** +654 * Returns the category name. +655 * +656 * @return the category name +657 */ +658 @Override +659 public String getCategoryName() { +660 return MavenReport.CATEGORY_PROJECT_REPORTS; 661 } -662 -663 /** -664 * Takes the properties supplied and updates the dependency-check settings. -665 * Additionally, this sets the system properties required to change the -666 * proxy url, port, and connection timeout. -667 */ -668 protected void populateSettings() { -669 Settings.initialize(); -670 InputStream mojoProperties = null; -671 try { -672 mojoProperties = this.getClass().getClassLoader().getResourceAsStream(PROPERTIES_FILE); -673 Settings.mergeProperties(mojoProperties); -674 } catch (IOException ex) { -675 getLog().warn("Unable to load the dependency-check ant task.properties file."); -676 if (getLog().isDebugEnabled()) { -677 getLog().debug("", ex); -678 } -679 } finally { -680 if (mojoProperties != null) { -681 try { -682 mojoProperties.close(); -683 } catch (IOException ex) { -684 if (getLog().isDebugEnabled()) { -685 getLog().debug("", ex); -686 } -687 } -688 } -689 } -690 Settings.setBooleanIfNotNull(Settings.KEYS.AUTO_UPDATE, autoUpdate); -691 -692 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, enableExperimental); -693 -694 if (externalReport != null) { -695 getLog().warn("The 'externalReport' option was set; this configuration option has been removed. " -696 + "Please update the dependency-check-maven plugin's configuration"); -697 } -698 -699 if (proxyUrl != null && !proxyUrl.isEmpty()) { -700 getLog().warn("Deprecated configuration detected, proxyUrl will be ignored; use the maven settings " + "to configure the proxy instead"); -701 } -702 final Proxy proxy = getMavenProxy(); -703 if (proxy != null) { -704 Settings.setString(Settings.KEYS.PROXY_SERVER, proxy.getHost()); -705 Settings.setString(Settings.KEYS.PROXY_PORT, Integer.toString(proxy.getPort())); -706 final String userName = proxy.getUsername(); -707 final String password = proxy.getPassword(); -708 Settings.setStringIfNotNull(Settings.KEYS.PROXY_USERNAME, userName); -709 Settings.setStringIfNotNull(Settings.KEYS.PROXY_PASSWORD, password); -710 Settings.setStringIfNotNull(Settings.KEYS.PROXY_NON_PROXY_HOSTS, proxy.getNonProxyHosts()); -711 } -712 -713 Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout); -714 Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile); -715 -716 //File Type Analyzer Settings -717 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_JAR_ENABLED, jarAnalyzerEnabled); -718 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, nuspecAnalyzerEnabled); -719 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, centralAnalyzerEnabled); -720 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled); -721 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl); -722 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy); -723 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, assemblyAnalyzerEnabled); -724 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, archiveAnalyzerEnabled); -725 Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions); -726 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono); -727 -728 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, pyDistributionAnalyzerEnabled); -729 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, pyPackageAnalyzerEnabled); -730 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED, rubygemsAnalyzerEnabled); -731 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, opensslAnalyzerEnabled); -732 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CMAKE_ENABLED, cmakeAnalyzerEnabled); -733 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_AUTOCONF_ENABLED, autoconfAnalyzerEnabled); -734 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED, composerAnalyzerEnabled); -735 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED, nodeAnalyzerEnabled); -736 -737 //Database configuration -738 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName); -739 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath); -740 Settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString); -741 -742 if (databaseUser == null && databasePassword == null && serverId != null) { -743 final Server server = settingsXml.getServer(serverId); -744 if (server != null) { -745 databaseUser = server.getUsername(); -746 try { -747 //The following fix was copied from: -748 // https://github.com/bsorrentino/maven-confluence-plugin/blob/master/maven-confluence-reporting-plugin/src/main/java/org/bsc/maven/confluence/plugin/AbstractBaseConfluenceMojo.java -749 // -750 // FIX to resolve -751 // org.sonatype.plexus.components.sec.dispatcher.SecDispatcherException: -752 // java.io.FileNotFoundException: ~/.settings-security.xml (No such file or directory) -753 // -754 if (securityDispatcher instanceof DefaultSecDispatcher) { -755 ((DefaultSecDispatcher) securityDispatcher).setConfigurationFile("~/.m2/settings-security.xml"); -756 } -757 -758 databasePassword = securityDispatcher.decrypt(server.getPassword()); -759 } catch (SecDispatcherException ex) { -760 if (ex.getCause() instanceof FileNotFoundException -761 || (ex.getCause() != null && ex.getCause().getCause() instanceof FileNotFoundException)) { -762 //maybe its not encrypted? -763 final String tmp = server.getPassword(); -764 if (tmp.startsWith("{") && tmp.endsWith("}")) { -765 getLog().error(String.format( -766 "Unable to decrypt the server password for server id '%s' in settings.xml%n\tCause: %s", -767 serverId, ex.getMessage())); -768 } else { -769 databasePassword = tmp; -770 } -771 } else { -772 getLog().error(String.format( -773 "Unable to decrypt the server password for server id '%s' in settings.xml%n\tCause: %s", -774 serverId, ex.getMessage())); -775 } -776 } -777 } else { -778 getLog().error(String.format("Server '%s' not found in the settings.xml file", serverId)); -779 } -780 } -781 -782 Settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser); -783 Settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword); -784 Settings.setStringIfNotEmpty(Settings.KEYS.DATA_DIRECTORY, dataDirectory); -785 -786 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_12_URL, cveUrl12Modified); -787 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_20_URL, cveUrl20Modified); -788 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_1_2, cveUrl12Base); -789 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_2_0, cveUrl20Base); -790 Settings.setIntIfNotNull(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, cveValidForHours); -791 -792 } -793 -794 /** -795 * Returns the maven proxy. -796 * -797 * @return the maven proxy -798 */ -799 private Proxy getMavenProxy() { -800 if (mavenSettings != null) { -801 final List<Proxy> proxies = mavenSettings.getProxies(); -802 if (proxies != null && !proxies.isEmpty()) { -803 if (mavenSettingsProxyId != null) { -804 for (Proxy proxy : proxies) { -805 if (mavenSettingsProxyId.equalsIgnoreCase(proxy.getId())) { -806 return proxy; -807 } -808 } -809 } else if (proxies.size() == 1) { -810 return proxies.get(0); -811 } else { -812 getLog().warn("Multiple proxy definitions exist in the Maven settings. In the dependency-check " -813 + "configuration set the mavenSettingsProxyId so that the correct proxy will be used."); -814 throw new IllegalStateException("Ambiguous proxy definition"); -815 } -816 } -817 } -818 return null; -819 } -820 -821 /** -822 * Tests is the artifact should be included in the scan (i.e. is the -823 * dependency in a scope that is being scanned). -824 * -825 * @param a the Artifact to test -826 * @return <code>true</code> if the artifact is in an excluded scope; -827 * otherwise <code>false</code> -828 */ -829 protected boolean excludeFromScan(Artifact a) { -830 if (skipTestScope && Artifact.SCOPE_TEST.equals(a.getScope())) { -831 return true; -832 } -833 if (skipProvidedScope && Artifact.SCOPE_PROVIDED.equals(a.getScope())) { -834 return true; -835 } -836 if (skipRuntimeScope && !Artifact.SCOPE_RUNTIME.equals(a.getScope())) { -837 return true; -838 } -839 return false; -840 } -841 -842 /** -843 * Returns a reference to the current project. This method is used instead -844 * of auto-binding the project via component annotation in concrete -845 * implementations of this. If the child has a -846 * <code>@Component MavenProject project;</code> defined then the abstract -847 * class (i.e. this class) will not have access to the current project (just -848 * the way Maven works with the binding). -849 * -850 * @return returns a reference to the current project -851 */ -852 protected MavenProject getProject() { -853 return project; -854 } -855 -856 /** -857 * Returns the list of Maven Projects in this build. -858 * -859 * @return the list of Maven Projects in this build -860 */ -861 protected List<MavenProject> getReactorProjects() { -862 return reactorProjects; -863 } -864 -865 /** -866 * Returns the report format. -867 * -868 * @return the report format -869 */ -870 protected String getFormat() { -871 return format; -872 } -873 -874 /** -875 * Generates the reports for a given dependency-check engine. -876 * -877 * @param engine a dependency-check engine -878 * @param p the maven project -879 * @param outputDir the directory path to write the report(s). -880 */ -881 protected void writeReports(Engine engine, MavenProject p, File outputDir) { -882 DatabaseProperties prop = null; -883 CveDB cve = null; -884 try { -885 cve = new CveDB(); -886 cve.open(); -887 prop = cve.getDatabaseProperties(); -888 } catch (DatabaseException ex) { -889 if (getLog().isDebugEnabled()) { -890 getLog().debug("Unable to retrieve DB Properties", ex); -891 } -892 } finally { -893 if (cve != null) { -894 cve.close(); -895 } -896 } -897 final ReportGenerator r = new ReportGenerator(p.getName(), engine.getDependencies(), engine.getAnalyzers(), prop); +662 //</editor-fold> +663 +664 /** +665 * Initializes a new <code>MavenEngine</code> that can be used for scanning. +666 * +667 * @return a newly instantiated <code>MavenEngine</code> +668 * @throws DatabaseException thrown if there is a database exception +669 */ +670 protected MavenEngine initializeEngine() throws DatabaseException { +671 populateSettings(); +672 return new MavenEngine(this.project, +673 this.reactorProjects); +674 } +675 +676 /** +677 * Takes the properties supplied and updates the dependency-check settings. +678 * Additionally, this sets the system properties required to change the +679 * proxy url, port, and connection timeout. +680 */ +681 protected void populateSettings() { +682 Settings.initialize(); +683 InputStream mojoProperties = null; +684 try { +685 mojoProperties = this.getClass().getClassLoader().getResourceAsStream(PROPERTIES_FILE); +686 Settings.mergeProperties(mojoProperties); +687 } catch (IOException ex) { +688 getLog().warn("Unable to load the dependency-check ant task.properties file."); +689 if (getLog().isDebugEnabled()) { +690 getLog().debug("", ex); +691 } +692 } finally { +693 if (mojoProperties != null) { +694 try { +695 mojoProperties.close(); +696 } catch (IOException ex) { +697 if (getLog().isDebugEnabled()) { +698 getLog().debug("", ex); +699 } +700 } +701 } +702 } +703 Settings.setBooleanIfNotNull(Settings.KEYS.AUTO_UPDATE, autoUpdate); +704 +705 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, enableExperimental); +706 +707 if (externalReport != null) { +708 getLog().warn("The 'externalReport' option was set; this configuration option has been removed. " +709 + "Please update the dependency-check-maven plugin's configuration"); +710 } +711 +712 if (proxyUrl != null && !proxyUrl.isEmpty()) { +713 getLog().warn("Deprecated configuration detected, proxyUrl will be ignored; use the maven settings " + "to configure the proxy instead"); +714 } +715 final Proxy proxy = getMavenProxy(); +716 if (proxy != null) { +717 Settings.setString(Settings.KEYS.PROXY_SERVER, proxy.getHost()); +718 Settings.setString(Settings.KEYS.PROXY_PORT, Integer.toString(proxy.getPort())); +719 final String userName = proxy.getUsername(); +720 final String password = proxy.getPassword(); +721 Settings.setStringIfNotNull(Settings.KEYS.PROXY_USERNAME, userName); +722 Settings.setStringIfNotNull(Settings.KEYS.PROXY_PASSWORD, password); +723 Settings.setStringIfNotNull(Settings.KEYS.PROXY_NON_PROXY_HOSTS, proxy.getNonProxyHosts()); +724 } +725 +726 Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout); +727 Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile); +728 +729 //File Type Analyzer Settings +730 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_JAR_ENABLED, jarAnalyzerEnabled); +731 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, nuspecAnalyzerEnabled); +732 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, centralAnalyzerEnabled); +733 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled); +734 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl); +735 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy); +736 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, assemblyAnalyzerEnabled); +737 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, archiveAnalyzerEnabled); +738 Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions); +739 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono); +740 +741 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, pyDistributionAnalyzerEnabled); +742 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, pyPackageAnalyzerEnabled); +743 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED, rubygemsAnalyzerEnabled); +744 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, opensslAnalyzerEnabled); +745 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CMAKE_ENABLED, cmakeAnalyzerEnabled); +746 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_AUTOCONF_ENABLED, autoconfAnalyzerEnabled); +747 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED, composerAnalyzerEnabled); +748 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED, nodeAnalyzerEnabled); +749 +750 //Database configuration +751 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName); +752 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath); +753 Settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString); +754 +755 if (databaseUser == null && databasePassword == null && serverId != null) { +756 final Server server = settingsXml.getServer(serverId); +757 if (server != null) { +758 databaseUser = server.getUsername(); +759 try { +760 //The following fix was copied from: +761 // https://github.com/bsorrentino/maven-confluence-plugin/blob/master/maven-confluence-reporting-plugin/src/main/java/org/bsc/maven/confluence/plugin/AbstractBaseConfluenceMojo.java +762 // +763 // FIX to resolve +764 // org.sonatype.plexus.components.sec.dispatcher.SecDispatcherException: +765 // java.io.FileNotFoundException: ~/.settings-security.xml (No such file or directory) +766 // +767 if (securityDispatcher instanceof DefaultSecDispatcher) { +768 ((DefaultSecDispatcher) securityDispatcher).setConfigurationFile("~/.m2/settings-security.xml"); +769 } +770 +771 databasePassword = securityDispatcher.decrypt(server.getPassword()); +772 } catch (SecDispatcherException ex) { +773 if (ex.getCause() instanceof FileNotFoundException +774 || (ex.getCause() != null && ex.getCause().getCause() instanceof FileNotFoundException)) { +775 //maybe its not encrypted? +776 final String tmp = server.getPassword(); +777 if (tmp.startsWith("{") && tmp.endsWith("}")) { +778 getLog().error(String.format( +779 "Unable to decrypt the server password for server id '%s' in settings.xml%n\tCause: %s", +780 serverId, ex.getMessage())); +781 } else { +782 databasePassword = tmp; +783 } +784 } else { +785 getLog().error(String.format( +786 "Unable to decrypt the server password for server id '%s' in settings.xml%n\tCause: %s", +787 serverId, ex.getMessage())); +788 } +789 } +790 } else { +791 getLog().error(String.format("Server '%s' not found in the settings.xml file", serverId)); +792 } +793 } +794 +795 Settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser); +796 Settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword); +797 Settings.setStringIfNotEmpty(Settings.KEYS.DATA_DIRECTORY, dataDirectory); +798 +799 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_12_URL, cveUrl12Modified); +800 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_20_URL, cveUrl20Modified); +801 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_1_2, cveUrl12Base); +802 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_2_0, cveUrl20Base); +803 Settings.setIntIfNotNull(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, cveValidForHours); +804 +805 } +806 +807 /** +808 * Returns the maven proxy. +809 * +810 * @return the maven proxy +811 */ +812 private Proxy getMavenProxy() { +813 if (mavenSettings != null) { +814 final List<Proxy> proxies = mavenSettings.getProxies(); +815 if (proxies != null && !proxies.isEmpty()) { +816 if (mavenSettingsProxyId != null) { +817 for (Proxy proxy : proxies) { +818 if (mavenSettingsProxyId.equalsIgnoreCase(proxy.getId())) { +819 return proxy; +820 } +821 } +822 } else if (proxies.size() == 1) { +823 return proxies.get(0); +824 } else { +825 getLog().warn("Multiple proxy definitions exist in the Maven settings. In the dependency-check " +826 + "configuration set the mavenSettingsProxyId so that the correct proxy will be used."); +827 throw new IllegalStateException("Ambiguous proxy definition"); +828 } +829 } +830 } +831 return null; +832 } +833 +834 /** +835 * Tests is the artifact should be included in the scan (i.e. is the +836 * dependency in a scope that is being scanned). +837 * +838 * @param a the Artifact to test +839 * @return <code>true</code> if the artifact is in an excluded scope; +840 * otherwise <code>false</code> +841 */ +842 protected boolean excludeFromScan(Artifact a) { +843 if (skipTestScope && Artifact.SCOPE_TEST.equals(a.getScope())) { +844 return true; +845 } +846 if (skipProvidedScope && Artifact.SCOPE_PROVIDED.equals(a.getScope())) { +847 return true; +848 } +849 if (skipRuntimeScope && !Artifact.SCOPE_RUNTIME.equals(a.getScope())) { +850 return true; +851 } +852 return false; +853 } +854 +855 /** +856 * Returns a reference to the current project. This method is used instead +857 * of auto-binding the project via component annotation in concrete +858 * implementations of this. If the child has a +859 * <code>@Component MavenProject project;</code> defined then the abstract +860 * class (i.e. this class) will not have access to the current project (just +861 * the way Maven works with the binding). +862 * +863 * @return returns a reference to the current project +864 */ +865 protected MavenProject getProject() { +866 return project; +867 } +868 +869 /** +870 * Returns the list of Maven Projects in this build. +871 * +872 * @return the list of Maven Projects in this build +873 */ +874 protected List<MavenProject> getReactorProjects() { +875 return reactorProjects; +876 } +877 +878 /** +879 * Returns the report format. +880 * +881 * @return the report format +882 */ +883 protected String getFormat() { +884 return format; +885 } +886 +887 /** +888 * Generates the reports for a given dependency-check engine. +889 * +890 * @param engine a dependency-check engine +891 * @param p the Maven project +892 * @param outputDir the directory path to write the report(s) +893 * @throws ReportException thrown if there is an error writing the report +894 */ +895 protected void writeReports(MavenEngine engine, MavenProject p, File outputDir) throws ReportException { +896 DatabaseProperties prop = null; +897 CveDB cve = null; 898 try { -899 r.generateReports(outputDir.getAbsolutePath(), format); -900 } catch (IOException ex) { -901 getLog().error( -902 "Unexpected exception occurred during analysis; please see the verbose error log for more details."); +899 cve = new CveDB(); +900 cve.open(); +901 prop = cve.getDatabaseProperties(); +902 } catch (DatabaseException ex) { 903 if (getLog().isDebugEnabled()) { -904 getLog().debug("", ex); +904 getLog().debug("Unable to retrieve DB Properties", ex); 905 } -906 } catch (Throwable ex) { -907 getLog().error( -908 "Unexpected exception occurred during analysis; please see the verbose error log for more details."); -909 if (getLog().isDebugEnabled()) { -910 getLog().debug("", ex); -911 } -912 } -913 } -914 -915 //<editor-fold defaultstate="collapsed" desc="Methods to fail build or show summary"> -916 /** -917 * Checks to see if a vulnerability has been identified with a CVSS score -918 * that is above the threshold set in the configuration. -919 * -920 * @param dependencies the list of dependency objects -921 * @throws MojoFailureException thrown if a CVSS score is found that is -922 * higher then the threshold set -923 */ -924 protected void checkForFailure(List<Dependency> dependencies) throws MojoFailureException { -925 if (failBuildOnCVSS <= 10) { -926 final StringBuilder ids = new StringBuilder(); -927 for (Dependency d : dependencies) { -928 boolean addName = true; -929 for (Vulnerability v : d.getVulnerabilities()) { -930 if (v.getCvssScore() >= failBuildOnCVSS) { -931 if (addName) { -932 addName = false; -933 ids.append(NEW_LINE).append(d.getFileName()).append(": "); -934 ids.append(v.getName()); -935 } else { -936 ids.append(", ").append(v.getName()); -937 } -938 } -939 } -940 } -941 if (ids.length() > 0) { -942 final String msg = String.format("%n%nDependency-Check Failure:%n" -943 + "One or more dependencies were identified with vulnerabilities that have a CVSS score greater then '%.1f': %s%n" -944 + "See the dependency-check report for more details.%n%n", failBuildOnCVSS, ids.toString()); -945 throw new MojoFailureException(msg); +906 } finally { +907 if (cve != null) { +908 cve.close(); +909 } +910 } +911 final ReportGenerator r = new ReportGenerator(p.getName(), engine.getDependencies(), engine.getAnalyzers(), prop); +912 try { +913 r.generateReports(outputDir.getAbsolutePath(), format); +914 } catch (ReportException ex) { +915 final String msg = String.format("Error generating the report for %s", p.getName()); +916 throw new ReportException(msg, ex); +917 } +918 +919 } +920 +921 //<editor-fold defaultstate="collapsed" desc="Methods to fail build or show summary"> +922 /** +923 * Checks to see if a vulnerability has been identified with a CVSS score +924 * that is above the threshold set in the configuration. +925 * +926 * @param dependencies the list of dependency objects +927 * @throws MojoFailureException thrown if a CVSS score is found that is +928 * higher then the threshold set +929 */ +930 protected void checkForFailure(List<Dependency> dependencies) throws MojoFailureException { +931 if (failBuildOnCVSS <= 10) { +932 final StringBuilder ids = new StringBuilder(); +933 for (Dependency d : dependencies) { +934 boolean addName = true; +935 for (Vulnerability v : d.getVulnerabilities()) { +936 if (v.getCvssScore() >= failBuildOnCVSS) { +937 if (addName) { +938 addName = false; +939 ids.append(NEW_LINE).append(d.getFileName()).append(": "); +940 ids.append(v.getName()); +941 } else { +942 ids.append(", ").append(v.getName()); +943 } +944 } +945 } 946 } -947 } -948 } -949 -950 /** -951 * Generates a warning message listing a summary of dependencies and their -952 * associated CPE and CVE entries. -953 * -954 * @param mp the Maven project for which the summary is shown -955 * @param dependencies a list of dependency objects -956 */ -957 protected void showSummary(MavenProject mp, List<Dependency> dependencies) { -958 if (showSummary) { -959 final StringBuilder summary = new StringBuilder(); -960 for (Dependency d : dependencies) { -961 boolean firstEntry = true; -962 final StringBuilder ids = new StringBuilder(); -963 for (Vulnerability v : d.getVulnerabilities()) { -964 if (firstEntry) { -965 firstEntry = false; -966 } else { -967 ids.append(", "); -968 } -969 ids.append(v.getName()); -970 } -971 if (ids.length() > 0) { -972 summary.append(d.getFileName()).append(" ("); -973 firstEntry = true; -974 for (Identifier id : d.getIdentifiers()) { -975 if (firstEntry) { -976 firstEntry = false; -977 } else { -978 summary.append(", "); -979 } -980 summary.append(id.getValue()); -981 } -982 summary.append(") : ").append(ids).append(NEW_LINE); -983 } -984 } -985 if (summary.length() > 0) { -986 final String msg = String.format("%n%n" + "One or more dependencies were identified with known vulnerabilities in %s:%n%n%s" -987 + "%n%nSee the dependency-check report for more details.%n%n", mp.getName(), summary.toString()); -988 getLog().warn(msg); -989 } -990 } -991 } -992 -993 //</editor-fold> -994 //<editor-fold defaultstate="collapsed" desc="Methods to read/write the serialized data file"> -995 /** -996 * Returns the key used to store the path to the data file that is saved by -997 * <code>writeDataFile()</code>. This key is used in the -998 * <code>MavenProject.(set|get)ContextValue</code>. -999 * -1000 * @return the key used to store the path to the data file -1001 */ -1002 protected String getDataFileContextKey() { -1003 return "dependency-check-path-" + dataFileName; -1004 } -1005 -1006 /** -1007 * Returns the key used to store the path to the output directory. When -1008 * generating the report in the <code>executeAggregateReport()</code> the -1009 * output directory should be obtained by using this key. -1010 * -1011 * @return the key used to store the path to the output directory -1012 */ -1013 protected String getOutputDirectoryContextKey() { -1014 return "dependency-output-dir-" + dataFileName; -1015 } -1016 -1017 /** -1018 * Writes the scan data to disk. This is used to serialize the scan data -1019 * between the "check" and "aggregate" phase. -1020 * -1021 * @param mp the mMven project for which the data file was created -1022 * @param writeTo the directory to write the data file -1023 * @param dependencies the list of dependencies to serialize -1024 */ -1025 protected void writeDataFile(MavenProject mp, File writeTo, List<Dependency> dependencies) { -1026 File file; -1027 //check to see if this was already written out -1028 if (mp.getContextValue(this.getDataFileContextKey()) == null) { -1029 if (writeTo == null) { -1030 file = new File(mp.getBuild().getDirectory()); -1031 file = new File(file, dataFileName); -1032 } else { -1033 file = new File(writeTo, dataFileName); -1034 } -1035 final File parent = file.getParentFile(); -1036 if (!parent.isDirectory() && !parent.mkdirs()) { -1037 getLog().error(String.format("Directory '%s' does not exist and cannot be created; unable to write data file.", -1038 parent.getAbsolutePath())); -1039 } -1040 -1041 ObjectOutputStream out = null; -1042 try { -1043 if (dependencies != null) { -1044 out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file))); -1045 out.writeObject(dependencies); -1046 } -1047 if (getLog().isDebugEnabled()) { -1048 getLog().debug(String.format("Serialized data file written to '%s' for %s, referenced by key %s", -1049 file.getAbsolutePath(), mp.getName(), this.getDataFileContextKey())); -1050 } -1051 mp.setContextValue(this.getDataFileContextKey(), file.getAbsolutePath()); -1052 } catch (IOException ex) { -1053 getLog().warn("Unable to create data file used for report aggregation; " -1054 + "if report aggregation is being used the results may be incomplete."); -1055 if (getLog().isDebugEnabled()) { -1056 getLog().debug(ex.getMessage(), ex); -1057 } -1058 } finally { -1059 if (out != null) { -1060 try { -1061 out.close(); -1062 } catch (IOException ex) { -1063 if (getLog().isDebugEnabled()) { -1064 getLog().debug("ignore", ex); -1065 } -1066 } -1067 } -1068 } -1069 } -1070 } -1071 -1072 /** -1073 * Reads the serialized scan data from disk. This is used to serialize the -1074 * scan data between the "check" and "aggregate" phase. -1075 * -1076 * @param project the Maven project to read the data file from -1077 * @return a <code>Engine</code> object populated with dependencies if the -1078 * serialized data file exists; otherwise <code>null</code> is returned -1079 */ -1080 protected List<Dependency> readDataFile(MavenProject project) { -1081 final Object oPath = project.getContextValue(this.getDataFileContextKey()); -1082 if (oPath == null) { -1083 return null; -1084 } -1085 List<Dependency> ret = null; -1086 final String path = (String) oPath; -1087 //ObjectInputStream ois = null; -1088 ExpectedOjectInputStream ois = null; -1089 try { -1090 //ois = new ObjectInputStream(new FileInputStream(path)); -1091 ois = new ExpectedOjectInputStream(new FileInputStream(path), -1092 "java.util.ArrayList", -1093 "java.util.HashSet", -1094 "java.util.TreeSet", -1095 "java.lang.AbstractSet", -1096 "java.lang.AbstractCollection", -1097 "java.lang.Enum", -1098 "org.owasp.dependencycheck.dependency.Confidence", -1099 "org.owasp.dependencycheck.dependency.Dependency", -1100 "org.owasp.dependencycheck.dependency.Evidence", -1101 "org.owasp.dependencycheck.dependency.EvidenceCollection", -1102 "org.owasp.dependencycheck.dependency.Identifier", -1103 "org.owasp.dependencycheck.dependency.Reference", -1104 "org.owasp.dependencycheck.dependency.Vulnerability", -1105 "org.owasp.dependencycheck.dependency.VulnerabilityComparator", -1106 "org.owasp.dependencycheck.dependency.VulnerableSoftware", -1107 "org.owasp.dependencycheck.data.cpe.IndexEntry"); -1108 @SuppressWarnings("unchecked") -1109 final List<Dependency> depList = (List<Dependency>) ois.readObject(); -1110 ret = depList; -1111 } catch (FileNotFoundException ex) { -1112 //TODO fix logging -1113 getLog().error("", ex); -1114 } catch (IOException ex) { -1115 getLog().error("", ex); -1116 } catch (ClassNotFoundException ex) { -1117 getLog().error("", ex); -1118 } finally { -1119 if (ois != null) { -1120 try { -1121 ois.close(); -1122 } catch (IOException ex) { -1123 getLog().error("", ex); -1124 } -1125 } -1126 } -1127 return ret; -1128 } -1129 //</editor-fold> -1130 } +947 if (ids.length() > 0) { +948 final String msg = String.format("%n%nDependency-Check Failure:%n" +949 + "One or more dependencies were identified with vulnerabilities that have a CVSS score greater then '%.1f': %s%n" +950 + "See the dependency-check report for more details.%n%n", failBuildOnCVSS, ids.toString()); +951 throw new MojoFailureException(msg); +952 } +953 } +954 } +955 +956 /** +957 * Generates a warning message listing a summary of dependencies and their +958 * associated CPE and CVE entries. +959 * +960 * @param mp the Maven project for which the summary is shown +961 * @param dependencies a list of dependency objects +962 */ +963 protected void showSummary(MavenProject mp, List<Dependency> dependencies) { +964 if (showSummary) { +965 final StringBuilder summary = new StringBuilder(); +966 for (Dependency d : dependencies) { +967 boolean firstEntry = true; +968 final StringBuilder ids = new StringBuilder(); +969 for (Vulnerability v : d.getVulnerabilities()) { +970 if (firstEntry) { +971 firstEntry = false; +972 } else { +973 ids.append(", "); +974 } +975 ids.append(v.getName()); +976 } +977 if (ids.length() > 0) { +978 summary.append(d.getFileName()).append(" ("); +979 firstEntry = true; +980 for (Identifier id : d.getIdentifiers()) { +981 if (firstEntry) { +982 firstEntry = false; +983 } else { +984 summary.append(", "); +985 } +986 summary.append(id.getValue()); +987 } +988 summary.append(") : ").append(ids).append(NEW_LINE); +989 } +990 } +991 if (summary.length() > 0) { +992 final String msg = String.format("%n%n" + "One or more dependencies were identified with known vulnerabilities in %s:%n%n%s" +993 + "%n%nSee the dependency-check report for more details.%n%n", mp.getName(), summary.toString()); +994 getLog().warn(msg); +995 } +996 } +997 } +998 +999 //</editor-fold> +1000 //<editor-fold defaultstate="collapsed" desc="Methods to read/write the serialized data file"> +1001 /** +1002 * Returns the key used to store the path to the data file that is saved by +1003 * <code>writeDataFile()</code>. This key is used in the +1004 * <code>MavenProject.(set|get)ContextValue</code>. +1005 * +1006 * @return the key used to store the path to the data file +1007 */ +1008 protected String getDataFileContextKey() { +1009 return "dependency-check-path-" + dataFileName; +1010 } +1011 +1012 /** +1013 * Returns the key used to store the path to the output directory. When +1014 * generating the report in the <code>executeAggregateReport()</code> the +1015 * output directory should be obtained by using this key. +1016 * +1017 * @return the key used to store the path to the output directory +1018 */ +1019 protected String getOutputDirectoryContextKey() { +1020 return "dependency-output-dir-" + dataFileName; +1021 } +1022 +1023 /** +1024 * Writes the scan data to disk. This is used to serialize the scan data +1025 * between the "check" and "aggregate" phase. +1026 * +1027 * @param mp the mMven project for which the data file was created +1028 * @param writeTo the directory to write the data file +1029 * @param dependencies the list of dependencies to serialize +1030 */ +1031 protected void writeDataFile(MavenProject mp, File writeTo, List<Dependency> dependencies) { +1032 File file; +1033 //check to see if this was already written out +1034 if (mp.getContextValue(this.getDataFileContextKey()) == null) { +1035 if (writeTo == null) { +1036 file = new File(mp.getBuild().getDirectory()); +1037 file = new File(file, dataFileName); +1038 } else { +1039 file = new File(writeTo, dataFileName); +1040 } +1041 final File parent = file.getParentFile(); +1042 if (!parent.isDirectory() && !parent.mkdirs()) { +1043 getLog().error(String.format("Directory '%s' does not exist and cannot be created; unable to write data file.", +1044 parent.getAbsolutePath())); +1045 } +1046 +1047 ObjectOutputStream out = null; +1048 try { +1049 if (dependencies != null) { +1050 out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file))); +1051 out.writeObject(dependencies); +1052 } +1053 if (getLog().isDebugEnabled()) { +1054 getLog().debug(String.format("Serialized data file written to '%s' for %s, referenced by key %s", +1055 file.getAbsolutePath(), mp.getName(), this.getDataFileContextKey())); +1056 } +1057 mp.setContextValue(this.getDataFileContextKey(), file.getAbsolutePath()); +1058 } catch (IOException ex) { +1059 getLog().warn("Unable to create data file used for report aggregation; " +1060 + "if report aggregation is being used the results may be incomplete."); +1061 if (getLog().isDebugEnabled()) { +1062 getLog().debug(ex.getMessage(), ex); +1063 } +1064 } finally { +1065 if (out != null) { +1066 try { +1067 out.close(); +1068 } catch (IOException ex) { +1069 if (getLog().isDebugEnabled()) { +1070 getLog().debug("ignore", ex); +1071 } +1072 } +1073 } +1074 } +1075 } +1076 } +1077 +1078 /** +1079 * Reads the serialized scan data from disk. This is used to serialize the +1080 * scan data between the "check" and "aggregate" phase. +1081 * +1082 * @param project the Maven project to read the data file from +1083 * @return a <code>MavenEngine</code> object populated with dependencies if +1084 * the serialized data file exists; otherwise <code>null</code> is returned +1085 */ +1086 protected List<Dependency> readDataFile(MavenProject project) { +1087 final Object oPath = project.getContextValue(this.getDataFileContextKey()); +1088 if (oPath == null) { +1089 return null; +1090 } +1091 List<Dependency> ret = null; +1092 final String path = (String) oPath; +1093 //ObjectInputStream ois = null; +1094 ExpectedOjectInputStream ois = null; +1095 try { +1096 //ois = new ObjectInputStream(new FileInputStream(path)); +1097 ois = new ExpectedOjectInputStream(new FileInputStream(path), +1098 "java.util.ArrayList", +1099 "java.util.HashSet", +1100 "java.util.TreeSet", +1101 "java.lang.AbstractSet", +1102 "java.lang.AbstractCollection", +1103 "java.lang.Enum", +1104 "org.owasp.dependencycheck.dependency.Confidence", +1105 "org.owasp.dependencycheck.dependency.Dependency", +1106 "org.owasp.dependencycheck.dependency.Evidence", +1107 "org.owasp.dependencycheck.dependency.EvidenceCollection", +1108 "org.owasp.dependencycheck.dependency.Identifier", +1109 "org.owasp.dependencycheck.dependency.Reference", +1110 "org.owasp.dependencycheck.dependency.Vulnerability", +1111 "org.owasp.dependencycheck.dependency.VulnerabilityComparator", +1112 "org.owasp.dependencycheck.dependency.VulnerableSoftware", +1113 "org.owasp.dependencycheck.data.cpe.IndexEntry"); +1114 @SuppressWarnings("unchecked") +1115 final List<Dependency> depList = (List<Dependency>) ois.readObject(); +1116 ret = depList; +1117 } catch (FileNotFoundException ex) { +1118 //TODO fix logging +1119 getLog().error("", ex); +1120 } catch (IOException ex) { +1121 getLog().error("", ex); +1122 } catch (ClassNotFoundException ex) { +1123 getLog().error("", ex); +1124 } finally { +1125 if (ois != null) { +1126 try { +1127 ois.close(); +1128 } catch (IOException ex) { +1129 getLog().error("", ex); +1130 } +1131 } +1132 } +1133 return ret; +1134 } +1135 //</editor-fold> +1136 }
      diff --git a/dependency-check-maven/xref/org/owasp/dependencycheck/maven/CheckMojo.html b/dependency-check-maven/xref/org/owasp/dependencycheck/maven/CheckMojo.html index f07703ed8..9139db03e 100644 --- a/dependency-check-maven/xref/org/owasp/dependencycheck/maven/CheckMojo.html +++ b/dependency-check-maven/xref/org/owasp/dependencycheck/maven/CheckMojo.html @@ -34,101 +34,138 @@ 26 import org.apache.maven.plugins.annotations.Parameter; 27 import org.apache.maven.plugins.annotations.ResolutionScope; 28 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; -29 import org.owasp.dependencycheck.utils.Settings; -30 -31 /** -32 * Maven Plugin that checks the project dependencies to see if they have any known published vulnerabilities. -33 * -34 * @author Jeremy Long -35 */ -36 @Mojo( -37 name = "check", -38 defaultPhase = LifecyclePhase.VERIFY, -39 threadSafe = false, -40 requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME, -41 requiresOnline = true -42 ) -43 public class CheckMojo extends BaseDependencyCheckMojo { -44 -45 /** -46 * Returns whether or not a the report can be generated. -47 * -48 * @return <code>true</code> if the report can be generated; otherwise <code>false</code> -49 */ -50 @Override -51 public boolean canGenerateReport() { -52 boolean isCapable = false; -53 for (Artifact a : getProject().getArtifacts()) { -54 if (!excludeFromScan(a)) { -55 isCapable = true; -56 break; -57 } -58 } -59 return isCapable; -60 } -61 -62 /** -63 * Executes the dependency-check engine on the project's dependencies and generates the report. -64 * -65 * @throws MojoExecutionException thrown if there is an exception executing the goal -66 * @throws MojoFailureException thrown if dependency-check is configured to fail the build -67 */ -68 @Override -69 public void runCheck() throws MojoExecutionException, MojoFailureException { -70 final Engine engine; -71 try { -72 engine = initializeEngine(); -73 } catch (DatabaseException ex) { -74 if (getLog().isDebugEnabled()) { -75 getLog().debug("Database connection error", ex); -76 } -77 throw new MojoExecutionException("An exception occured connecting to the local database. Please see the log file for more details.", ex); -78 } -79 scanArtifacts(getProject(), engine); -80 if (engine.getDependencies().isEmpty()) { -81 getLog().info("No dependencies were identified that could be analyzed by dependency-check"); -82 } else { -83 engine.analyzeDependencies(); -84 writeReports(engine, getProject(), getCorrectOutputDirectory()); -85 writeDataFile(getProject(), null, engine.getDependencies()); -86 showSummary(getProject(), engine.getDependencies()); -87 checkForFailure(engine.getDependencies()); -88 } -89 engine.cleanup(); -90 Settings.cleanup(); -91 } -92 -93 /** -94 * The name of the report in the site. -95 */ -96 @SuppressWarnings("CanBeFinal") -97 @Parameter(property = "name", defaultValue = "dependency-check", required = true) -98 private String name = "dependency-check"; -99 -100 /** -101 * Returns the report name. -102 * -103 * @param locale the location -104 * @return the report name -105 */ -106 @Override -107 public String getName(Locale locale) { -108 return name; -109 } -110 -111 /** -112 * Gets the description of the Dependency-Check report to be displayed in the Maven Generated Reports page. -113 * -114 * @param locale The Locale to get the description for -115 * @return the description -116 */ -117 @Override -118 public String getDescription(Locale locale) { -119 return "Generates a report providing details on any published vulnerabilities within project dependencies. " -120 + "This report is a best effort and may contain false positives and false negatives."; -121 } -122 -123 } +29 import org.owasp.dependencycheck.exception.ExceptionCollection; +30 import org.owasp.dependencycheck.exception.ReportException; +31 import org.owasp.dependencycheck.utils.Settings; +32 +33 /** +34 * Maven Plugin that checks the project dependencies to see if they have any +35 * known published vulnerabilities. +36 * +37 * @author Jeremy Long +38 */ +39 @Mojo( +40 name = "check", +41 defaultPhase = LifecyclePhase.VERIFY, +42 threadSafe = false, +43 requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME, +44 requiresOnline = true +45 ) +46 public class CheckMojo extends BaseDependencyCheckMojo { +47 +48 /** +49 * Returns whether or not a the report can be generated. +50 * +51 * @return <code>true</code> if the report can be generated; otherwise +52 * <code>false</code> +53 */ +54 @Override +55 public boolean canGenerateReport() { +56 boolean isCapable = false; +57 for (Artifact a : getProject().getArtifacts()) { +58 if (!excludeFromScan(a)) { +59 isCapable = true; +60 break; +61 } +62 } +63 return isCapable; +64 } +65 +66 /** +67 * Executes the dependency-check engine on the project's dependencies and +68 * generates the report. +69 * +70 * @throws MojoExecutionException thrown if there is an exception executing +71 * the goal +72 * @throws MojoFailureException thrown if dependency-check is configured to +73 * fail the build +74 */ +75 @Override +76 public void runCheck() throws MojoExecutionException, MojoFailureException { +77 MavenEngine engine = null; +78 try { +79 engine = initializeEngine(); +80 } catch (DatabaseException ex) { +81 if (getLog().isDebugEnabled()) { +82 getLog().debug("Database connection error", ex); +83 } +84 final String msg = "An exception occured connecting to the local database. Please see the log file for more details."; +85 if (this.isFailOnError()) { +86 throw new MojoExecutionException(msg, ex); +87 } +88 getLog().error(msg); +89 } +90 if (engine != null) { +91 scanArtifacts(getProject(), engine); +92 if (engine.getDependencies().isEmpty()) { +93 getLog().info("No dependencies were identified that could be analyzed by dependency-check"); +94 } else { +95 ExceptionCollection exCol = null; +96 try { +97 engine.analyzeDependencies(); +98 } catch (ExceptionCollection ex) { +99 if (this.isFailOnError() && ex.isFatal()) { +100 throw new MojoExecutionException("One or more exceptions occured during analysis", ex); +101 } +102 exCol = ex; +103 } +104 if (exCol == null || !exCol.isFatal()) { +105 try { +106 writeReports(engine, getProject(), getCorrectOutputDirectory()); +107 } catch (ReportException ex) { +108 if (this.isFailOnError()) { +109 if (exCol != null) { +110 exCol.addException(ex); +111 } else { +112 exCol = new ExceptionCollection("Unable to write the dependency-check report", ex); +113 } +114 } +115 } +116 writeDataFile(getProject(), null, engine.getDependencies()); +117 showSummary(getProject(), engine.getDependencies()); +118 checkForFailure(engine.getDependencies()); +119 if (exCol != null && this.isFailOnError()) { +120 throw new MojoExecutionException("One or more exceptions occured during dependency-check analysis", exCol); +121 } +122 } +123 } +124 engine.cleanup(); +125 } +126 Settings.cleanup(); +127 } +128 +129 /** +130 * The name of the report in the site. +131 */ +132 @SuppressWarnings("CanBeFinal") +133 @Parameter(property = "name", defaultValue = "dependency-check", required = true) +134 private String name = "dependency-check"; +135 +136 /** +137 * Returns the report name. +138 * +139 * @param locale the location +140 * @return the report name +141 */ +142 @Override +143 public String getName(Locale locale) { +144 return name; +145 } +146 +147 /** +148 * Gets the description of the Dependency-Check report to be displayed in +149 * the Maven Generated Reports page. +150 * +151 * @param locale The Locale to get the description for +152 * @return the description +153 */ +154 @Override +155 public String getDescription(Locale locale) { +156 return "Generates a report providing details on any published vulnerabilities within project dependencies. " +157 + "This report is a best effort and may contain false positives and false negatives."; +158 } +159 +160 }
      diff --git a/dependency-check-maven/xref/org/owasp/dependencycheck/maven/MavenEngine.html b/dependency-check-maven/xref/org/owasp/dependencycheck/maven/MavenEngine.html new file mode 100644 index 000000000..3c4838794 --- /dev/null +++ b/dependency-check-maven/xref/org/owasp/dependencycheck/maven/MavenEngine.html @@ -0,0 +1,255 @@ + + + +MavenEngine xref + + + +
      +1   /*
      +2    * This file is part of dependency-check-maven.
      +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) 2014 Jeremy Long. All Rights Reserved.
      +17   */
      +18  package org.owasp.dependencycheck.maven;
      +19  
      +20  import java.util.List;
      +21  import org.apache.maven.project.MavenProject;
      +22  import org.owasp.dependencycheck.analyzer.Analyzer;
      +23  import org.owasp.dependencycheck.analyzer.CPEAnalyzer;
      +24  import org.owasp.dependencycheck.analyzer.FileTypeAnalyzer;
      +25  import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
      +26  import org.owasp.dependencycheck.data.update.exception.UpdateException;
      +27  import org.owasp.dependencycheck.exception.ExceptionCollection;
      +28  import org.owasp.dependencycheck.exception.InitializationException;
      +29  import org.owasp.dependencycheck.utils.Settings;
      +30  import org.slf4j.Logger;
      +31  import org.slf4j.LoggerFactory;
      +32  
      +33  /**
      +34   * A modified version of the core engine specifically designed to persist some
      +35   * data between multiple executions of a multi-module Maven project.
      +36   *
      +37   * @author Jeremy Long
      +38   */
      +39  public class MavenEngine extends org.owasp.dependencycheck.Engine {
      +40  
      +41      /**
      +42       * The logger.
      +43       */
      +44      private static final transient Logger LOGGER = LoggerFactory.getLogger(MavenEngine.class);
      +45      /**
      +46       * A key used to persist an object in the MavenProject.
      +47       */
      +48      private static final String CPE_ANALYZER_KEY = "dependency-check-CPEAnalyzer";
      +49      /**
      +50       * The current MavenProject.
      +51       */
      +52      private MavenProject currentProject;
      +53      /**
      +54       * The list of MavenProjects that are part of the current build.
      +55       */
      +56      private List<MavenProject> reactorProjects;
      +57      /**
      +58       * Key used in the MavenProject context values to note whether or not an
      +59       * update has been executed.
      +60       */
      +61      public static final String UPDATE_EXECUTED_FLAG = "dependency-check-update-executed";
      +62  
      +63      /**
      +64       * Creates a new Engine to perform analysis on dependencies.
      +65       *
      +66       * @param project the current Maven project
      +67       * @param reactorProjects the reactor projects for the current Maven
      +68       * execution
      +69       * @throws DatabaseException thrown if there is an issue connecting to the
      +70       * database
      +71       */
      +72      public MavenEngine(MavenProject project, List<MavenProject> reactorProjects) throws DatabaseException {
      +73          this.currentProject = project;
      +74          this.reactorProjects = reactorProjects;
      +75          initializeEngine();
      +76      }
      +77  
      +78      /**
      +79       * Runs the analyzers against all of the dependencies.
      +80       *
      +81       * @throws ExceptionCollection thrown if an exception occurred; contains a
      +82       * collection of exceptions that occurred during analysis.
      +83       */
      +84      @Override
      +85      public void analyzeDependencies() throws ExceptionCollection {
      +86          final MavenProject root = getExecutionRoot();
      +87          if (root != null) {
      +88              LOGGER.debug("Checking root project, {}, if updates have already been completed", root.getArtifactId());
      +89          } else {
      +90              LOGGER.debug("Checking root project, null, if updates have already been completed");
      +91          }
      +92          if (root != null && root.getContextValue(UPDATE_EXECUTED_FLAG) != null) {
      +93              System.setProperty(Settings.KEYS.AUTO_UPDATE, Boolean.FALSE.toString());
      +94          }
      +95          super.analyzeDependencies();
      +96          if (root != null) {
      +97              root.setContextValue(UPDATE_EXECUTED_FLAG, Boolean.TRUE);
      +98          }
      +99      }
      +100 
      +101     /**
      +102      * Runs the update steps of dependency-check.
      +103      *
      +104      * @throws UpdateException thrown if there is an exception
      +105      */
      +106     public void update() throws UpdateException {
      +107         final MavenProject root = getExecutionRoot();
      +108         if (root != null && root.getContextValue(UPDATE_EXECUTED_FLAG) != null) {
      +109             System.setProperty(Settings.KEYS.AUTO_UPDATE, Boolean.FALSE.toString());
      +110         }
      +111         this.doUpdates();
      +112     }
      +113 
      +114     /**
      +115      * This constructor should not be called. Use Engine(MavenProject) instead.
      +116      *
      +117      * @throws DatabaseException thrown if there is an issue connecting to the
      +118      * database
      +119      */
      +120     private MavenEngine() throws DatabaseException {
      +121     }
      +122 
      +123     /**
      +124      * Initializes the given analyzer. This skips the initialization of the
      +125      * CPEAnalyzer if it has been initialized by a previous execution.
      +126      *
      +127      * @param analyzer the analyzer to initialize
      +128      * @return the initialized analyzer
      +129      */
      +130     @Override
      +131     protected Analyzer initializeAnalyzer(Analyzer analyzer) throws InitializationException {
      +132         if (analyzer instanceof CPEAnalyzer) {
      +133             CPEAnalyzer cpe = getPreviouslyLoadedCPEAnalyzer();
      +134             if (cpe != null && cpe.isOpen()) {
      +135                 return cpe;
      +136             }
      +137             cpe = (CPEAnalyzer) super.initializeAnalyzer(analyzer);
      +138             storeCPEAnalyzer(cpe);
      +139         }
      +140         return super.initializeAnalyzer(analyzer);
      +141     }
      +142 
      +143     /**
      +144      * Releases resources used by the analyzers by calling close() on each
      +145      * analyzer.
      +146      */
      +147     @Override
      +148     public void cleanup() {
      +149         super.cleanup();
      +150         if (currentProject == null || reactorProjects == null) {
      +151             return;
      +152         }
      +153         if (this.currentProject == reactorProjects.get(reactorProjects.size() - 1)) {
      +154             final CPEAnalyzer cpe = getPreviouslyLoadedCPEAnalyzer();
      +155             if (cpe != null) {
      +156                 cpe.close();
      +157             }
      +158         }
      +159     }
      +160 
      +161     /**
      +162      * Closes the given analyzer. This skips closing the CPEAnalyzer.
      +163      *
      +164      * @param analyzer the analyzer to close
      +165      */
      +166     @Override
      +167     protected void closeAnalyzer(Analyzer analyzer) {
      +168         if (analyzer instanceof CPEAnalyzer) {
      +169             if (getPreviouslyLoadedCPEAnalyzer() == null) {
      +170                 super.closeAnalyzer(analyzer);
      +171             }
      +172         } else {
      +173             super.closeAnalyzer(analyzer);
      +174         }
      +175     }
      +176 
      +177     /**
      +178      * Gets the CPEAnalyzer from the root Maven Project.
      +179      *
      +180      * @return an initialized CPEAnalyzer
      +181      */
      +182     private CPEAnalyzer getPreviouslyLoadedCPEAnalyzer() {
      +183         CPEAnalyzer cpe = null;
      +184         final MavenProject project = getExecutionRoot();
      +185         if (project != null) {
      +186             final Object obj = project.getContextValue(CPE_ANALYZER_KEY);
      +187             if (obj != null && obj instanceof CPEAnalyzer) {
      +188                 cpe = (CPEAnalyzer) project.getContextValue(CPE_ANALYZER_KEY);
      +189             }
      +190         }
      +191         return cpe;
      +192     }
      +193 
      +194     /**
      +195      * Stores a CPEAnalyzer in the root Maven Project.
      +196      *
      +197      * @param cpe the CPEAnalyzer to store
      +198      */
      +199     private void storeCPEAnalyzer(CPEAnalyzer cpe) {
      +200         final MavenProject p = getExecutionRoot();
      +201         if (p != null) {
      +202             p.setContextValue(CPE_ANALYZER_KEY, cpe);
      +203         }
      +204     }
      +205 
      +206     /**
      +207      * Returns the root Maven Project.
      +208      *
      +209      * @return the root Maven Project
      +210      */
      +211     MavenProject getExecutionRoot() {
      +212         if (reactorProjects == null) {
      +213             return null;
      +214         }
      +215         for (MavenProject p : reactorProjects) {
      +216             if (p.isExecutionRoot()) {
      +217                 return p;
      +218             }
      +219         }
      +220         //the following should  never run, but leaving it as a failsafe.
      +221         if (this.currentProject == null) {
      +222             return null;
      +223         }
      +224         MavenProject p = this.currentProject;
      +225         while (p.getParent() != null) {
      +226             p = p.getParent();
      +227         }
      +228         return p;
      +229     }
      +230 
      +231     /**
      +232      * Resets the file type analyzers so that they can be re-used to scan
      +233      * additional directories. Without the reset the analyzer might be disabled
      +234      * because the first scan/analyze did not identify any files that could be
      +235      * processed by the analyzer.
      +236      */
      +237     public void resetFileTypeAnalyzers() {
      +238         for (FileTypeAnalyzer a : getFileTypeAnalyzers()) {
      +239             a.reset();
      +240         }
      +241     }
      +242 }
      +
      +
      + + + diff --git a/dependency-check-maven/xref/org/owasp/dependencycheck/maven/PurgeMojo.html b/dependency-check-maven/xref/org/owasp/dependencycheck/maven/PurgeMojo.html index 513fd589f..b31c447ac 100644 --- a/dependency-check-maven/xref/org/owasp/dependencycheck/maven/PurgeMojo.html +++ b/dependency-check-maven/xref/org/owasp/dependencycheck/maven/PurgeMojo.html @@ -62,58 +62,77 @@ 54 /** 55 * Purges the local copy of the NVD. 56 * -57 * @throws MojoExecutionException thrown if there is an exception executing the goal -58 * @throws MojoFailureException thrown if dependency-check is configured to fail the build -59 */ -60 @Override -61 public void runCheck() throws MojoExecutionException, MojoFailureException { -62 -63 if (getConnectionString() != null && !getConnectionString().isEmpty()) { -64 getLog().error("Unable to purge the local NVD when using a non-default connection string"); -65 } else { -66 populateSettings(); -67 File db; -68 try { -69 db = new File(Settings.getDataDirectory(), "dc.h2.db"); -70 if (db.exists()) { -71 if (db.delete()) { -72 getLog().info("Database file purged; local copy of the NVD has been removed"); -73 } else { -74 getLog().error(String.format("Unable to delete '%s'; please delete the file manually", db.getAbsolutePath())); -75 } -76 } else { -77 getLog().error(String.format("Unable to purge database; the database file does not exists: %s", db.getAbsolutePath())); -78 } -79 } catch (IOException ex) { -80 getLog().error("Unable to delete the database"); -81 } -82 Settings.cleanup(); -83 } -84 } -85 -86 /** -87 * Returns the report name. -88 * -89 * @param locale the location -90 * @return the report name -91 */ -92 @Override -93 public String getName(Locale locale) { -94 return "dependency-check-purge"; -95 } -96 -97 /** -98 * Gets the description of the Dependency-Check report to be displayed in the Maven Generated Reports page. -99 * -100 * @param locale The Locale to get the description for -101 * @return the description -102 */ -103 @Override -104 public String getDescription(Locale locale) { -105 return "Purges the local cache of the NVD dataT."; -106 } -107 -108 } +57 * @throws MojoExecutionException thrown if there is an exception executing +58 * the goal +59 * @throws MojoFailureException thrown if dependency-check is configured to +60 * fail the build +61 */ +62 @Override +63 public void runCheck() throws MojoExecutionException, MojoFailureException { +64 +65 if (getConnectionString() != null && !getConnectionString().isEmpty()) { +66 final String msg = "Unable to purge the local NVD when using a non-default connection string"; +67 if (this.isFailOnError()) { +68 throw new MojoFailureException(msg); +69 } +70 getLog().error(msg); +71 } else { +72 populateSettings(); +73 File db; +74 try { +75 db = new File(Settings.getDataDirectory(), "dc.h2.db"); +76 if (db.exists()) { +77 if (db.delete()) { +78 getLog().info("Database file purged; local copy of the NVD has been removed"); +79 } else { +80 final String msg = String.format("Unable to delete '%s'; please delete the file manually", db.getAbsolutePath()); +81 if (this.isFailOnError()) { +82 throw new MojoFailureException(msg); +83 } +84 getLog().error(msg); +85 } +86 } else { +87 final String msg = String.format("Unable to purge database; the database file does not exists: %s", db.getAbsolutePath()); +88 if (this.isFailOnError()) { +89 throw new MojoFailureException(msg); +90 } +91 getLog().error(msg); +92 } +93 } catch (IOException ex) { +94 final String msg = "Unable to delete the database"; +95 if (this.isFailOnError()) { +96 throw new MojoExecutionException(msg, ex); +97 } +98 getLog().error(msg); +99 } +100 Settings.cleanup(); +101 } +102 } +103 +104 /** +105 * Returns the report name. +106 * +107 * @param locale the location +108 * @return the report name +109 */ +110 @Override +111 public String getName(Locale locale) { +112 return "dependency-check-purge"; +113 } +114 +115 /** +116 * Gets the description of the Dependency-Check report to be displayed in +117 * the Maven Generated Reports page. +118 * +119 * @param locale The Locale to get the description for +120 * @return the description +121 */ +122 @Override +123 public String getDescription(Locale locale) { +124 return "Purges the local cache of the NVD dataT."; +125 } +126 +127 }
      diff --git a/dependency-check-maven/xref/org/owasp/dependencycheck/maven/UpdateMojo.html b/dependency-check-maven/xref/org/owasp/dependencycheck/maven/UpdateMojo.html index de7630925..08592eb8f 100644 --- a/dependency-check-maven/xref/org/owasp/dependencycheck/maven/UpdateMojo.html +++ b/dependency-check-maven/xref/org/owasp/dependencycheck/maven/UpdateMojo.html @@ -32,77 +32,94 @@ 24 import org.apache.maven.plugins.annotations.Mojo; 25 import org.apache.maven.plugins.annotations.ResolutionScope; 26 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; -27 import org.owasp.dependencycheck.utils.Settings; -28 -29 /** -30 * Maven Plugin that checks the project dependencies to see if they have any known published vulnerabilities. -31 * -32 * @author Jeremy Long -33 */ -34 @Mojo( -35 name = "update-only", -36 defaultPhase = LifecyclePhase.GENERATE_RESOURCES, -37 threadSafe = false, -38 requiresDependencyResolution = ResolutionScope.NONE, -39 requiresOnline = true -40 ) -41 public class UpdateMojo extends BaseDependencyCheckMojo { -42 -43 /** -44 * Returns false; this mojo cannot generate a report. -45 * -46 * @return <code>false</code> -47 */ -48 @Override -49 public boolean canGenerateReport() { -50 return false; -51 } -52 -53 /** -54 * Executes the dependency-check engine on the project's dependencies and generates the report. -55 * -56 * @throws MojoExecutionException thrown if there is an exception executing the goal -57 * @throws MojoFailureException thrown if dependency-check is configured to fail the build -58 */ -59 @Override -60 public void runCheck() throws MojoExecutionException, MojoFailureException { -61 final Engine engine; -62 try { -63 engine = initializeEngine(); -64 engine.update(); -65 } catch (DatabaseException ex) { -66 if (getLog().isDebugEnabled()) { -67 getLog().debug("Database connection error", ex); -68 } -69 throw new MojoExecutionException("An exception occured connecting to the local database. Please see the log file for more details.", ex); -70 } -71 engine.cleanup(); -72 Settings.cleanup(); -73 } -74 -75 /** -76 * Returns the report name. -77 * -78 * @param locale the location -79 * @return the report name -80 */ -81 @Override -82 public String getName(Locale locale) { -83 return "dependency-check-update"; -84 } -85 -86 /** -87 * Gets the description of the Dependency-Check report to be displayed in the Maven Generated Reports page. -88 * -89 * @param locale The Locale to get the description for -90 * @return the description -91 */ -92 @Override -93 public String getDescription(Locale locale) { -94 return "Updates the local cache of the NVD data from NIST."; -95 } -96 -97 } +27 import org.owasp.dependencycheck.data.update.exception.UpdateException; +28 import org.owasp.dependencycheck.utils.Settings; +29 +30 /** +31 * Maven Plugin that checks the project dependencies to see if they have any +32 * known published vulnerabilities. +33 * +34 * @author Jeremy Long +35 */ +36 @Mojo( +37 name = "update-only", +38 defaultPhase = LifecyclePhase.GENERATE_RESOURCES, +39 threadSafe = false, +40 requiresDependencyResolution = ResolutionScope.NONE, +41 requiresOnline = true +42 ) +43 public class UpdateMojo extends BaseDependencyCheckMojo { +44 +45 /** +46 * Returns false; this mojo cannot generate a report. +47 * +48 * @return <code>false</code> +49 */ +50 @Override +51 public boolean canGenerateReport() { +52 return false; +53 } +54 +55 /** +56 * Executes the dependency-check engine on the project's dependencies and +57 * generates the report. +58 * +59 * @throws MojoExecutionException thrown if there is an exception executing +60 * the goal +61 * @throws MojoFailureException thrown if dependency-check is configured to +62 * fail the build +63 */ +64 @Override +65 public void runCheck() throws MojoExecutionException, MojoFailureException { +66 MavenEngine engine = null; +67 try { +68 engine = initializeEngine(); +69 engine.update(); +70 } catch (DatabaseException ex) { +71 if (getLog().isDebugEnabled()) { +72 getLog().debug("Database connection error", ex); +73 } +74 final String msg = "An exception occured connecting to the local database. Please see the log file for more details."; +75 if (this.isFailOnError()) { +76 throw new MojoExecutionException(msg, ex); +77 } +78 getLog().error(msg); +79 } catch (UpdateException ex) { +80 final String msg = "An exception occured while downloading updates. Please see the log file for more details."; +81 if (this.isFailOnError()) { +82 throw new MojoExecutionException(msg, ex); +83 } +84 getLog().error(msg); +85 } +86 if (engine != null) { +87 engine.cleanup(); +88 } +89 Settings.cleanup(); +90 } +91 +92 /** +93 * Returns the report name. +94 * +95 * @param locale the location +96 * @return the report name +97 */ +98 @Override +99 public String getName(Locale locale) { +100 return "dependency-check-update"; +101 } +102 +103 /** +104 * Gets the description of the Dependency-Check report to be displayed in +105 * the Maven Generated Reports page. +106 * +107 * @param locale The Locale to get the description for +108 * @return the description +109 */ +110 @Override +111 public String getDescription(Locale locale) { +112 return "Updates the local cache of the NVD data from NIST."; +113 } +114 }
      diff --git a/dependency-check-maven/xref/org/owasp/dependencycheck/maven/package-frame.html b/dependency-check-maven/xref/org/owasp/dependencycheck/maven/package-frame.html index eaec0b773..6996bd345 100644 --- a/dependency-check-maven/xref/org/owasp/dependencycheck/maven/package-frame.html +++ b/dependency-check-maven/xref/org/owasp/dependencycheck/maven/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Maven Plugin 1.4.0 Reference Package org.owasp.dependencycheck.maven + Dependency-Check Maven Plugin 1.4.2 Reference Package org.owasp.dependencycheck.maven @@ -25,10 +25,10 @@ CheckMojo
    264. - Engine + HelpMojo
    265. - HelpMojo + MavenEngine
    266. PurgeMojo diff --git a/dependency-check-maven/xref/org/owasp/dependencycheck/maven/package-summary.html b/dependency-check-maven/xref/org/owasp/dependencycheck/maven/package-summary.html index 5f9b4788e..9b36b300c 100644 --- a/dependency-check-maven/xref/org/owasp/dependencycheck/maven/package-summary.html +++ b/dependency-check-maven/xref/org/owasp/dependencycheck/maven/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Maven Plugin 1.4.0 Reference Package org.owasp.dependencycheck.maven + Dependency-Check Maven Plugin 1.4.2 Reference Package org.owasp.dependencycheck.maven @@ -52,12 +52,12 @@
    267. diff --git a/dependency-check-maven/xref/org/owasp/dependencycheck/maven/slf4j/package-frame.html b/dependency-check-maven/xref/org/owasp/dependencycheck/maven/slf4j/package-frame.html index 9964aef60..1382db0f0 100644 --- a/dependency-check-maven/xref/org/owasp/dependencycheck/maven/slf4j/package-frame.html +++ b/dependency-check-maven/xref/org/owasp/dependencycheck/maven/slf4j/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Maven Plugin 1.4.0 Reference Package org.owasp.dependencycheck.maven.slf4j + Dependency-Check Maven Plugin 1.4.2 Reference Package org.owasp.dependencycheck.maven.slf4j diff --git a/dependency-check-maven/xref/org/owasp/dependencycheck/maven/slf4j/package-summary.html b/dependency-check-maven/xref/org/owasp/dependencycheck/maven/slf4j/package-summary.html index 797175efb..76c5f8a77 100644 --- a/dependency-check-maven/xref/org/owasp/dependencycheck/maven/slf4j/package-summary.html +++ b/dependency-check-maven/xref/org/owasp/dependencycheck/maven/slf4j/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Maven Plugin 1.4.0 Reference Package org.owasp.dependencycheck.maven.slf4j + Dependency-Check Maven Plugin 1.4.2 Reference Package org.owasp.dependencycheck.maven.slf4j diff --git a/dependency-check-maven/xref/org/slf4j/impl/package-frame.html b/dependency-check-maven/xref/org/slf4j/impl/package-frame.html index fdd586e97..518b29fff 100644 --- a/dependency-check-maven/xref/org/slf4j/impl/package-frame.html +++ b/dependency-check-maven/xref/org/slf4j/impl/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Maven Plugin 1.4.0 Reference Package org.slf4j.impl + Dependency-Check Maven Plugin 1.4.2 Reference Package org.slf4j.impl diff --git a/dependency-check-maven/xref/org/slf4j/impl/package-summary.html b/dependency-check-maven/xref/org/slf4j/impl/package-summary.html index 9cc4a5306..2aefe5e2e 100644 --- a/dependency-check-maven/xref/org/slf4j/impl/package-summary.html +++ b/dependency-check-maven/xref/org/slf4j/impl/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Maven Plugin 1.4.0 Reference Package org.slf4j.impl + Dependency-Check Maven Plugin 1.4.2 Reference Package org.slf4j.impl diff --git a/dependency-check-maven/xref/overview-frame.html b/dependency-check-maven/xref/overview-frame.html index a8f16b895..8f0bd2d6b 100644 --- a/dependency-check-maven/xref/overview-frame.html +++ b/dependency-check-maven/xref/overview-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Maven Plugin 1.4.0 Reference + Dependency-Check Maven Plugin 1.4.2 Reference diff --git a/dependency-check-maven/xref/overview-summary.html b/dependency-check-maven/xref/overview-summary.html index 57365031d..4db770908 100644 --- a/dependency-check-maven/xref/overview-summary.html +++ b/dependency-check-maven/xref/overview-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Maven Plugin 1.4.0 Reference + Dependency-Check Maven Plugin 1.4.2 Reference @@ -24,7 +24,7 @@ -

      Dependency-Check Maven Plugin 1.4.0 Reference

      +

      Dependency-Check Maven Plugin 1.4.2 Reference

      - Engine + HelpMojo
      - HelpMojo + MavenEngine
      diff --git a/dependency-check-utils/apidocs/allclasses-frame.html b/dependency-check-utils/apidocs/allclasses-frame.html index f4d4aa5e2..b27af7476 100644 --- a/dependency-check-utils/apidocs/allclasses-frame.html +++ b/dependency-check-utils/apidocs/allclasses-frame.html @@ -2,10 +2,10 @@ - + -All Classes (Dependency-Check Utils 1.4.0 API) - +All Classes (Dependency-Check Utils 1.4.2 API) + @@ -22,6 +22,7 @@
    268. InvalidSettingException
    269. Settings
    270. Settings.KEYS
    271. +
    272. SSLSocketFactoryEx
    273. URLConnectionFactory
    274. URLConnectionFailureException
    275. diff --git a/dependency-check-utils/apidocs/allclasses-noframe.html b/dependency-check-utils/apidocs/allclasses-noframe.html index a5b1f115b..f6b807c3c 100644 --- a/dependency-check-utils/apidocs/allclasses-noframe.html +++ b/dependency-check-utils/apidocs/allclasses-noframe.html @@ -2,10 +2,10 @@ - + -All Classes (Dependency-Check Utils 1.4.0 API) - +All Classes (Dependency-Check Utils 1.4.2 API) + @@ -22,6 +22,7 @@
    276. InvalidSettingException
    277. Settings
    278. Settings.KEYS
    279. +
    280. SSLSocketFactoryEx
    281. URLConnectionFactory
    282. URLConnectionFailureException
    283. diff --git a/dependency-check-utils/apidocs/constant-values.html b/dependency-check-utils/apidocs/constant-values.html index b509cfd06..684e68228 100644 --- a/dependency-check-utils/apidocs/constant-values.html +++ b/dependency-check-utils/apidocs/constant-values.html @@ -2,10 +2,10 @@ - + -Constant Field Values (Dependency-Check Utils 1.4.0 API) - +Constant Field Values (Dependency-Check Utils 1.4.2 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ + + + + + + + + + +
      +
      org.owasp.dependencycheck.utils
      +

      Class SSLSocketFactoryEx

      +
      +
      + +
      +
        +
      • +
        +
        +
        public class SSLSocketFactoryEx
        +extends SSLSocketFactory
        +
        This class is used to enable additional ciphers used by the SSL Socket. This + is specifically because the NVD stopped supporting TLS 1.0 and Java 6 and 7 + clients by default were unable to connect to download the NVD data feeds. + + The following code was copied from + http://stackoverflow.com/questions/1037590/which-cipher-suites-to-enable-for-ssl-socket/23365536#23365536
        +
        +
        Author:
        +
        jww
        +
        +
      • +
      +
      +
      +
        +
      • + +
          +
        • + + +

          Constructor Summary

          +
      + + + + + + + + + + + + + +
      Constructors 
      Constructor and Description
      SSLSocketFactoryEx() +
      Constructs a new SSLSocketFactory.
      +
      SSLSocketFactoryEx(KeyManager[] km, + TrustManager[] tm, + SecureRandom random) +
      Constructs a new SSLSocketFactory.
      +
      SSLSocketFactoryEx(SSLContext ctx) +
      Constructs a new SSLSocketFactory.
      +
      + + + + + + + +
      +
        +
      • + + + +
          +
        • + + +

          Method Detail

          + + + + + + + + + + + +
            +
          • +

            getDefaultProtocols

            +
            public String[] getDefaultProtocols()
            +
            Returns the default protocols.
            +
            +
            Returns:
            +
            the default protocols
            +
            +
          • +
          + + + +
            +
          • +

            getSupportedProtocols

            +
            public String[] getSupportedProtocols()
            +
            Returns the supported protocols.
            +
            +
            Returns:
            +
            the supported protocols
            +
            +
          • +
          + + + +
            +
          • +

            createSocket

            +
            public Socket createSocket(Socket s,
            +                           String host,
            +                           int port,
            +                           boolean autoClose)
            +                    throws IOException
            +
            Creates an SSL Socket.
            +
            +
            Specified by:
            +
            createSocket in class SSLSocketFactory
            +
            Parameters:
            +
            s - the base socket
            +
            host - the host
            +
            port - the port
            +
            autoClose - if the socket should auto-close
            +
            Returns:
            +
            the SSL Socket
            +
            Throws:
            +
            IOException - thrown if the creation fails
            +
            +
          • +
          + + + +
            +
          • +

            createSocket

            +
            public Socket createSocket(InetAddress address,
            +                           int port,
            +                           InetAddress localAddress,
            +                           int localPort)
            +                    throws IOException
            +
            Creates a new SSL Socket.
            +
            +
            Specified by:
            +
            createSocket in class SocketFactory
            +
            Parameters:
            +
            address - the address to connect to
            +
            port - the port number
            +
            localAddress - the local address
            +
            localPort - the local port
            +
            Returns:
            +
            the SSL Socket
            +
            Throws:
            +
            IOException - thrown if the creation fails
            +
            +
          • +
          + + + +
            +
          • +

            createSocket

            +
            public Socket createSocket(String host,
            +                           int port,
            +                           InetAddress localHost,
            +                           int localPort)
            +                    throws IOException
            +
            Creates a new SSL Socket.
            +
            +
            Specified by:
            +
            createSocket in class SocketFactory
            +
            Parameters:
            +
            host - the host to connect to
            +
            port - the port to connect to
            +
            localHost - the local host
            +
            localPort - the local port
            +
            Returns:
            +
            the SSL Socket
            +
            Throws:
            +
            IOException - thrown if the creation fails
            +
            +
          • +
          + + + +
            +
          • +

            createSocket

            +
            public Socket createSocket(InetAddress host,
            +                           int port)
            +                    throws IOException
            +
            Creates a new SSL Socket.
            +
            +
            Specified by:
            +
            createSocket in class SocketFactory
            +
            Parameters:
            +
            host - the host to connect to
            +
            port - the port to connect to
            +
            Returns:
            +
            the SSL Socket
            +
            Throws:
            +
            IOException - thrown if the creation fails
            +
            +
          • +
          + + + +
            +
          • +

            createSocket

            +
            public Socket createSocket(String host,
            +                           int port)
            +                    throws IOException
            +
            Creates a new SSL Socket.
            +
            +
            Specified by:
            +
            createSocket in class SocketFactory
            +
            Parameters:
            +
            host - the host to connect to
            +
            port - the port to connect to
            +
            Returns:
            +
            the SSL Socket
            +
            Throws:
            +
            IOException - thrown if the creation fails
            +
            +
          • +
          + + + +
            +
          • +

            getProtocolList

            +
            protected String[] getProtocolList()
            +
            Returns the protocol list.
            +
            +
            Returns:
            +
            the protocol list
            +
            +
          • +
          + + + +
            +
          • +

            getCipherList

            +
            protected String[] getCipherList()
            +
            Returns the cipher list.
            +
            +
            Returns:
            +
            the cipher list
            +
            +
          • +
          +
        • +
        +
      • +
      +
      + + + + + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-utils/apidocs/org/owasp/dependencycheck/utils/Settings.KEYS.html b/dependency-check-utils/apidocs/org/owasp/dependencycheck/utils/Settings.KEYS.html index fd699928e..e79c2c7db 100644 --- a/dependency-check-utils/apidocs/org/owasp/dependencycheck/utils/Settings.KEYS.html +++ b/dependency-check-utils/apidocs/org/owasp/dependencycheck/utils/Settings.KEYS.html @@ -2,10 +2,10 @@ - + -Settings.KEYS (Dependency-Check Utils 1.4.0 API) - +Settings.KEYS (Dependency-Check Utils 1.4.2 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ + + + + + + + + +
      +

      Uses of Class
      org.owasp.dependencycheck.utils.SSLSocketFactoryEx

      +
      +
      No usage of org.owasp.dependencycheck.utils.SSLSocketFactoryEx
      + + + + +

      Copyright? 2012-15 Jeremy Long. All Rights Reserved.

      + + diff --git a/dependency-check-utils/apidocs/org/owasp/dependencycheck/utils/class-use/Settings.KEYS.html b/dependency-check-utils/apidocs/org/owasp/dependencycheck/utils/class-use/Settings.KEYS.html index d5701672b..1ae45587d 100644 --- a/dependency-check-utils/apidocs/org/owasp/dependencycheck/utils/class-use/Settings.KEYS.html +++ b/dependency-check-utils/apidocs/org/owasp/dependencycheck/utils/class-use/Settings.KEYS.html @@ -2,10 +2,10 @@ - + -Uses of Class org.owasp.dependencycheck.utils.Settings.KEYS (Dependency-Check Utils 1.4.0 API) - +Uses of Class org.owasp.dependencycheck.utils.Settings.KEYS (Dependency-Check Utils 1.4.2 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -20,6 +20,7 @@
    284. FileUtils
    285. Settings
    286. Settings.KEYS
    287. +
    288. SSLSocketFactoryEx
    289. URLConnectionFactory
    290. Exceptions

      diff --git a/dependency-check-utils/apidocs/org/owasp/dependencycheck/utils/package-summary.html b/dependency-check-utils/apidocs/org/owasp/dependencycheck/utils/package-summary.html index 45effd9e4..8b424852f 100644 --- a/dependency-check-utils/apidocs/org/owasp/dependencycheck/utils/package-summary.html +++ b/dependency-check-utils/apidocs/org/owasp/dependencycheck/utils/package-summary.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.utils (Dependency-Check Utils 1.4.0 API) - +org.owasp.dependencycheck.utils (Dependency-Check Utils 1.4.2 API) + @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@ - + diff --git a/dependency-check-utils/cobertura/frame-summary.html b/dependency-check-utils/cobertura/frame-summary.html index 5c10ae294..d03af4595 100644 --- a/dependency-check-utils/cobertura/frame-summary.html +++ b/dependency-check-utils/cobertura/frame-summary.html @@ -16,8 +16,8 @@ - - + +
      Package # Classes Line Coverage Branch Coverage Complexity
      All Packages12
      28%
      135/473
      21%
      37/176
      3.082
      org.owasp.dependencycheck.utils12
      28%
      135/473
      21%
      37/176
      3.082
      All Packages13
      23%
      136/579
      19%
      37/194
      2.857
      org.owasp.dependencycheck.utils13
      23%
      136/579
      19%
      37/194
      2.857
      - + diff --git a/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.Checksum.html b/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.Checksum.html index 962af8c4f..479893e89 100644 --- a/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.Checksum.html +++ b/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.Checksum.html @@ -99,7 +99,7 @@
            * The logger.
       41  
            */
      -  42  2
           private static final Logger LOGGER = LoggerFactory.getLogger(Checksum.class);
      +  42  1
           private static final Logger LOGGER = LoggerFactory.getLogger(Checksum.class);
       43  
       
       44   @@ -134,44 +134,44 @@
            */
       60  
           public static byte[] getChecksum(String algorithm, File file) throws NoSuchAlgorithmException, IOException {
      -  61  10
               MessageDigest digest = MessageDigest.getInstance(algorithm);
      -  62  8
               FileInputStream fis = null;
      +  61  5
               MessageDigest digest = MessageDigest.getInstance(algorithm);
      +  62  4
               FileInputStream fis = null;
       63  
               try {
      -  64  8
                   fis = new FileInputStream(file);
      -  65  6
                   FileChannel ch = fis.getChannel();
      -  66  6
                   long remainingToRead = file.length();
      -  67  6
                   long start = 0;
      -  68  12
                   while (remainingToRead > 0) {
      +  64  4
                   fis = new FileInputStream(file);
      +  65  3
                   FileChannel ch = fis.getChannel();
      +  66  3
                   long remainingToRead = file.length();
      +  67  3
                   long start = 0;
      +  68  6
                   while (remainingToRead > 0) {
       69  
                       long amountToRead;
      -  70  6
                       if (remainingToRead > Integer.MAX_VALUE) {
      +  70  3
                       if (remainingToRead > Integer.MAX_VALUE) {
       71  0
                           remainingToRead -= Integer.MAX_VALUE;
       72  0
                           amountToRead = Integer.MAX_VALUE;
       73  
                       } else {
      -  74  6
                           amountToRead = remainingToRead;
      -  75  6
                           remainingToRead = 0;
      +  74  3
                           amountToRead = remainingToRead;
      +  75  3
                           remainingToRead = 0;
       76  
                       }
      -  77  6
                       MappedByteBuffer byteBuffer = ch.map(FileChannel.MapMode.READ_ONLY, start, amountToRead);
      -  78  6
                       digest.update(byteBuffer);
      -  79  6
                       start += amountToRead;
      -  80  6
                   }
      +  77  3
                       MappedByteBuffer byteBuffer = ch.map(FileChannel.MapMode.READ_ONLY, start, amountToRead);
      +  78  3
                       digest.update(byteBuffer);
      +  79  3
                       start += amountToRead;
      +  80  3
                   }
       81  
               } finally {
      -  82  8
                   if (fis != null) {
      +  82  4
                   if (fis != null) {
       83  
                       try {
      -  84  6
                           fis.close();
      +  84  3
                           fis.close();
       85  0
                       } catch (IOException ex) {
       86  0
                           LOGGER.trace("Error closing file '{}'.", file.getName(), ex);
      -  87  8
                       }
      +  87  4
                       }
       88  
                   }
       89  
               }
      -  90  6
               return digest.digest();
      +  90  3
               return digest.digest();
       91  
           }
       92   @@ -194,8 +194,8 @@
            */
       101  
           public static String getMD5Checksum(File file) throws IOException, NoSuchAlgorithmException {
      -  102  2
               byte[] b = getChecksum("MD5", file);
      -  103  2
               return getHex(b);
      +  102  1
               byte[] b = getChecksum("MD5", file);
      +  103  1
               return getHex(b);
       104  
           }
       105   @@ -218,8 +218,8 @@
            */
       114  
           public static String getSHA1Checksum(File file) throws IOException, NoSuchAlgorithmException {
      -  115  2
               byte[] b = getChecksum("SHA1", file);
      -  116  2
               return getHex(b);
      +  115  1
               byte[] b = getChecksum("SHA1", file);
      +  116  1
               return getHex(b);
       117  
           }
       118   @@ -256,22 +256,22 @@
            */
       134  
           public static String getHex(byte[] raw) {
      -  135  6
               if (raw == null) {
      +  135  3
               if (raw == null) {
       136  0
                   return null;
       137  
               }
      -  138  6
               final StringBuilder hex = new StringBuilder(2 * raw.length);
      -  139  112
               for (final byte b : raw) {
      -  140  106
                   hex.append(HEXES.charAt((b & 0xF0) >> 4)).append(HEXES.charAt(b & 0x0F));
      +  138  3
               final StringBuilder hex = new StringBuilder(2 * raw.length);
      +  139  56
               for (final byte b : raw) {
      +  140  53
                   hex.append(HEXES.charAt((b & 0xF0) >> 4)).append(HEXES.charAt(b & 0x0F));
       141  
               }
      -  142  6
               return hex.toString();
      +  142  3
               return hex.toString();
       143  
           }
       144  
       }
      - + diff --git a/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.DownloadFailedException.html b/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.DownloadFailedException.html index 38cd2492c..91f8792ee 100644 --- a/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.DownloadFailedException.html +++ b/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.DownloadFailedException.html @@ -147,6 +147,6 @@
       }
      - + diff --git a/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.Downloader.html b/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.Downloader.html index 1ed19286e..7a22c1583 100644 --- a/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.Downloader.html +++ b/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.Downloader.html @@ -12,7 +12,7 @@
       
      - +
      Classes in this File Line Coverage Branch Coverage Complexity
      Downloader
      5%
      8/141
      2%
      1/46
      7.857
      Downloader
      6%
      9/150
      1%
      1/52
      7.5
       
      @@ -84,36 +84,36 @@  33  
       import java.util.zip.InflaterInputStream;
       34   -
       
      -  35  
       import static java.lang.String.format;
      +  35   +
       
       36   -
       
      -  37  
       /**
      -  38   +  37  
        * A utility to download files from the Internet.
      -  39   +  38  
        *
      -  40   +  39  
        * @author Jeremy Long
      -  41   +  40  
        */
      -  42   +  41  
       public final class Downloader {
      -  43   +  42  
       
      +  43   +
           /**
       44   -
           /**
      -  45  
            * The logger.
      -  46   +  45  
            */
      -  47  2
           private static final Logger LOGGER = LoggerFactory.getLogger(Downloader.class);
      -  48   +  46  1
           private static final Logger LOGGER = LoggerFactory.getLogger(Downloader.class);
      +  47  
           /**
      +  48   +
            * The maximum number of redirects that will be followed when attempting to
       49   -
            * The maximum number of redirects that will be followed when attempting to download a file.
      +
            * download a file.
       50  
            */
       51   @@ -161,357 +161,416 @@  73  
            * @param outputPath the path to the save the file to
       74   -
            * @throws DownloadFailedException is thrown if there is an error downloading the file
      +
            * @throws DownloadFailedException is thrown if there is an error
       75   -
            */
      +
            * downloading the file
       76   +
            */
      +  77  
           public static void fetchFile(URL url, File outputPath) throws DownloadFailedException {
      -  77  0
               fetchFile(url, outputPath, true);
      -  78  0
           }
      -  79   -
       
      +  78  0
               fetchFile(url, outputPath, true);
      +  79  0
           }
       80   -
           /**
      +
       
       81   -
            * Retrieves a file from a given URL and saves it to the outputPath.
      +
           /**
       82   -
            *
      +
            * Retrieves a file from a given URL and saves it to the outputPath.
       83   -
            * @param url the URL of the file to download
      +
            *
       84   -
            * @param outputPath the path to the save the file to
      +
            * @param url the URL of the file to download
       85   -
            * @param useProxy whether to use the configured proxy when downloading files
      +
            * @param outputPath the path to the save the file to
       86   -
            * @throws DownloadFailedException is thrown if there is an error downloading the file
      +
            * @param useProxy whether to use the configured proxy when downloading
       87   -
            */
      +
            * files
       88   -
           public static void fetchFile(URL url, File outputPath, boolean useProxy) throws DownloadFailedException {
      -  89  0
               if ("file".equalsIgnoreCase(url.getProtocol())) {
      +
            * @throws DownloadFailedException is thrown if there is an error
      +  89   +
            * downloading the file
       90   -
                   File file;
      +
            */
       91   +
           public static void fetchFile(URL url, File outputPath, boolean useProxy) throws DownloadFailedException {
      +  92  0
               if ("file".equalsIgnoreCase(url.getProtocol())) {
      +  93   +
                   File file;
      +  94  
                   try {
      -  92  0
                       file = new File(url.toURI());
      -  93  0
                   } catch (URISyntaxException ex) {
      -  94  0
                       final String msg = format("Download failed, unable to locate '%s'", url.toString());
      -  95  0
                       throw new DownloadFailedException(msg);
      -  96  0
                   }
      -  97  0
                   if (file.exists()) {
      -  98   +  95  0
                       file = new File(url.toURI());
      +  96  0
                   } catch (URISyntaxException ex) {
      +  97  0
                       final String msg = format("Download failed, unable to locate '%s'", url.toString());
      +  98  0
                       throw new DownloadFailedException(msg);
      +  99  0
                   }
      +  100  0
                   if (file.exists()) {
      +  101  
                       try {
      -  99  0
                           org.apache.commons.io.FileUtils.copyFile(file, outputPath);
      -  100  0
                       } catch (IOException ex) {
      -  101  0
                           final String msg = format("Download failed, unable to copy '%s' to '%s'", url.toString(), outputPath.getAbsolutePath());
      -  102  0
                           throw new DownloadFailedException(msg);
      -  103  0
                       }
      -  104   -
                   } else {
      -  105  0
                       final String msg = format("Download failed, file ('%s') does not exist", url.toString());
      -  106  0
                       throw new DownloadFailedException(msg);
      +  102  0
                           org.apache.commons.io.FileUtils.copyFile(file, outputPath);
      +  103  0
                       } catch (IOException ex) {
      +  104  0
                           final String msg = format("Download failed, unable to copy '%s' to '%s'", url.toString(), outputPath.getAbsolutePath());
      +  105  0
                           throw new DownloadFailedException(msg);
      +  106  0
                       }
       107   -
                   }
      -  108  0
               } else {
      -  109  0
                   HttpURLConnection conn = null;
      +
                   } else {
      +  108  0
                       final String msg = format("Download failed, file ('%s') does not exist", url.toString());
      +  109  0
                       throw new DownloadFailedException(msg);
       110   -
                   try {
      -  111  0
                       LOGGER.debug("Attempting download of {}", url.toString());
      -  112  0
                       conn = URLConnectionFactory.createHttpURLConnection(url, useProxy);
      -  113  0
                       conn.setRequestProperty("Accept-Encoding", "gzip, deflate");
      -  114  0
                       conn.connect();
      -  115  0
                       int status = conn.getResponseCode();
      -  116  0
                       int redirectCount = 0;
      -  117  0
                       while ((status == HttpURLConnection.HTTP_MOVED_TEMP
      -  118   -
                               || status == HttpURLConnection.HTTP_MOVED_PERM
      -  119   -
                               || status == HttpURLConnection.HTTP_SEE_OTHER)
      -  120   -
                               && MAX_REDIRECT_ATTEMPTS > redirectCount++) {
      -  121  0
                           final String location = conn.getHeaderField("Location");
      -  122   -
                           try {
      -  123  0
                               conn.disconnect();
      -  124   -
                           } finally {
      -  125  0
                               conn = null;
      -  126  0
                           }
      -  127  0
                           LOGGER.debug("Download is being redirected from {} to {}", url.toString(), location);
      -  128  0
                           conn = URLConnectionFactory.createHttpURLConnection(new URL(location), useProxy);
      -  129  0
                           conn.setRequestProperty("Accept-Encoding", "gzip, deflate");
      -  130  0
                           conn.connect();
      -  131  0
                           status = conn.getResponseCode();
      -  132  0
                       }
      -  133  0
                       if (status != 200) {
      -  134   -
                           try {
      -  135  0
                               conn.disconnect();
      -  136   -
                           } finally {
      -  137  0
                               conn = null;
      -  138  0
                           }
      -  139  0
                           final String msg = format("Error downloading file %s; received response code %s.", url.toString(), status);
      -  140  0
                           throw new DownloadFailedException(msg);
      -  141   -
       
      -  142   -
                       }
      -  143  0
                   } catch (IOException ex) {
      -  144   -
                       try {
      -  145  0
                           if (conn != null) {
      -  146  0
                               conn.disconnect();
      -  147   -
                           }
      -  148   -
                       } finally {
      -  149  0
                           conn = null;
      -  150  0
                       }
      -  151  0
                       final String msg = format("Error downloading file %s; unable to connect.", url.toString());
      -  152  0
                       throw new DownloadFailedException(msg, ex);
      -  153  0
                   }
      -  154   -
       
      -  155  0
                   final String encoding = conn.getContentEncoding();
      -  156  0
                   BufferedOutputStream writer = null;
      -  157  0
                   InputStream reader = null;
      -  158   -
                   try {
      -  159  0
                       if (encoding != null && "gzip".equalsIgnoreCase(encoding)) {
      -  160  0
                           reader = new GZIPInputStream(conn.getInputStream());
      -  161  0
                       } else if (encoding != null && "deflate".equalsIgnoreCase(encoding)) {
      -  162  0
                           reader = new InflaterInputStream(conn.getInputStream());
      -  163   -
                       } else {
      -  164  0
                           reader = conn.getInputStream();
      -  165   -
                       }
      -  166   -
       
      -  167  0
                       writer = new BufferedOutputStream(new FileOutputStream(outputPath));
      -  168  0
                       final byte[] buffer = new byte[4096];
      -  169   -
                       int bytesRead;
      -  170  0
                       while ((bytesRead = reader.read(buffer)) > 0) {
      -  171  0
                           writer.write(buffer, 0, bytesRead);
      -  172   -
                       }
      -  173  0
                       LOGGER.debug("Download of {} complete", url.toString());
      -  174  0
                   } catch (IOException ex) {
      -  175  0
                       analyzeException(ex);
      -  176  0
                       final String msg = format("Error saving '%s' to file '%s'%nConnection Timeout: %d%nEncoding: %s%n",
      -  177  0
                               url.toString(), outputPath.getAbsolutePath(), conn.getConnectTimeout(), encoding);
      -  178  0
                       throw new DownloadFailedException(msg, ex);
      -  179  0
                   } catch (Throwable ex) {
      -  180  0
                       final String msg = format("Unexpected exception saving '%s' to file '%s'%nConnection Timeout: %d%nEncoding: %s%n",
      -  181  0
                               url.toString(), outputPath.getAbsolutePath(), conn.getConnectTimeout(), encoding);
      -  182  0
                       throw new DownloadFailedException(msg, ex);
      -  183   -
                   } finally {
      -  184  0
                       if (writer != null) {
      -  185   -
                           try {
      -  186  0
                               writer.close();
      -  187  0
                           } catch (IOException ex) {
      -  188  0
                               LOGGER.trace("Error closing the writer in Downloader.", ex);
      -  189  0
                           }
      -  190   -
                       }
      -  191  0
                       if (reader != null) {
      -  192   -
                           try {
      -  193  0
                               reader.close();
      -  194  0
                           } catch (IOException ex) {
      -  195  0
                               LOGGER.trace("Error closing the reader in Downloader.", ex);
      -  196  0
                           }
      -  197   -
                       }
      -  198   -
                       try {
      -  199  0
                           conn.disconnect();
      -  200   -
                       } finally {
      -  201  0
                           conn = null;
      -  202  0
                       }
      -  203  0
                   }
      -  204   -
               }
      -  205  0
           }
      -  206   -
       
      -  207   -
           /**
      -  208   -
            * Makes an HTTP Head request to retrieve the last modified date of the given URL. If the file:// protocol is specified, then
      -  209   -
            * the lastTimestamp of the file is returned.
      -  210   -
            *
      -  211   -
            * @param url the URL to retrieve the timestamp from
      -  212   -
            * @return an epoch timestamp
      -  213   -
            * @throws DownloadFailedException is thrown if an exception occurs making the HTTP request
      -  214   -
            */
      -  215   -
           public static long getLastModified(URL url) throws DownloadFailedException {
      -  216  2
               long timestamp = 0;
      -  217   -
               //TODO add the FTP protocol?
      -  218  2
               if ("file".equalsIgnoreCase(url.getProtocol())) {
      -  219   -
                   File lastModifiedFile;
      -  220   -
                   try {
      -  221  2
                       lastModifiedFile = new File(url.toURI());
      -  222  0
                   } catch (URISyntaxException ex) {
      -  223  0
                       final String msg = format("Unable to locate '%s'", url.toString());
      -  224  0
                       throw new DownloadFailedException(msg);
      -  225  2
                   }
      -  226  2
                   timestamp = lastModifiedFile.lastModified();
      -  227  2
               } else {
      -  228  0
                   final String httpMethod = determineHttpMethod();
      -  229  0
                   HttpURLConnection conn = null;
      -  230   -
                   try {
      -  231  0
                       conn = URLConnectionFactory.createHttpURLConnection(url);
      -  232  0
                       conn.setRequestMethod(httpMethod);
      -  233  0
                       conn.connect();
      -  234  0
                       final int t = conn.getResponseCode();
      -  235  0
                       if (t >= 200 && t < 300) {
      -  236  0
                           timestamp = conn.getLastModified();
      -  237   -
                       } else {
      -  238  0
                           throw new DownloadFailedException(format("%s request returned a non-200 status code", httpMethod));
      -  239   -
                       }
      -  240  0
                   } catch (URLConnectionFailureException ex) {
      -  241  0
                       throw new DownloadFailedException(format("Error creating URL Connection for HTTP %s request.", httpMethod), ex);
      -  242  0
                   } catch (IOException ex) {
      -  243  0
                       analyzeException(ex);
      -  244   -
                       try {
      -  245   -
                           //retry
      -  246  0
                           if (!Settings.getBoolean(Settings.KEYS.DOWNLOADER_QUICK_QUERY_TIMESTAMP)) {
      -  247  0
                               Settings.setBoolean(Settings.KEYS.DOWNLOADER_QUICK_QUERY_TIMESTAMP, true);
      -  248  0
                               return getLastModified(url);
      -  249   -
                           }
      -  250  0
                       } catch (InvalidSettingException ex1) {
      -  251  0
                           LOGGER.debug("invalid setting?", ex);
      -  252  0
                       }
      -  253   -
       
      -  254  0
                       throw new DownloadFailedException(format("Error making HTTP %s request.", httpMethod), ex);
      -  255   -
                   } finally {
      -  256  0
                       if (conn != null) {
      -  257   -
                           try {
      -  258  0
                               conn.disconnect();
      -  259   -
                           } finally {
      -  260  0
                               conn = null;
      -  261  0
                           }
      -  262   -
                       }
      -  263  
                   }
      -  264   -
               }
      -  265  2
               return timestamp;
      -  266   -
           }
      -  267   +  111  0
               } else {
      +  112  0
                   HttpURLConnection conn = null;
      +  113   +
                   try {
      +  114  0
                       LOGGER.debug("Attempting download of {}", url.toString());
      +  115  0
                       conn = URLConnectionFactory.createHttpURLConnection(url, useProxy);
      +  116  0
                       conn.setRequestProperty("Accept-Encoding", "gzip, deflate");
      +  117  0
                       conn.connect();
      +  118  0
                       int status = conn.getResponseCode();
      +  119  0
                       int redirectCount = 0;
      +  120  0
                       while ((status == HttpURLConnection.HTTP_MOVED_TEMP
      +  121   +
                               || status == HttpURLConnection.HTTP_MOVED_PERM
      +  122   +
                               || status == HttpURLConnection.HTTP_SEE_OTHER)
      +  123   +
                               && MAX_REDIRECT_ATTEMPTS > redirectCount++) {
      +  124  0
                           final String location = conn.getHeaderField("Location");
      +  125   +
                           try {
      +  126  0
                               conn.disconnect();
      +  127   +
                           } finally {
      +  128  0
                               conn = null;
      +  129  0
                           }
      +  130  0
                           LOGGER.debug("Download is being redirected from {} to {}", url.toString(), location);
      +  131  0
                           conn = URLConnectionFactory.createHttpURLConnection(new URL(location), useProxy);
      +  132  0
                           conn.setRequestProperty("Accept-Encoding", "gzip, deflate");
      +  133  0
                           conn.connect();
      +  134  0
                           status = conn.getResponseCode();
      +  135  0
                       }
      +  136  0
                       if (status != 200) {
      +  137   +
                           try {
      +  138  0
                               conn.disconnect();
      +  139   +
                           } finally {
      +  140  0
                               conn = null;
      +  141  0
                           }
      +  142  0
                           final String msg = format("Error downloading file %s; received response code %s.", url.toString(), status);
      +  143  0
                           throw new DownloadFailedException(msg);
      +  144  
       
      -  268   +  145   +
                       }
      +  146  0
                   } catch (IOException ex) {
      +  147   +
                       try {
      +  148  0
                           if (conn != null) {
      +  149  0
                               conn.disconnect();
      +  150   +
                           }
      +  151   +
                       } finally {
      +  152  0
                           conn = null;
      +  153  0
                       }
      +  154  0
                       final String msg = format("Error downloading file %s; unable to connect.", url.toString());
      +  155  0
                       throw new DownloadFailedException(msg, ex);
      +  156  0
                   }
      +  157   +
       
      +  158  0
                   final String encoding = conn.getContentEncoding();
      +  159  0
                   BufferedOutputStream writer = null;
      +  160  0
                   InputStream reader = null;
      +  161   +
                   try {
      +  162  0
                       if (encoding != null && "gzip".equalsIgnoreCase(encoding)) {
      +  163  0
                           reader = new GZIPInputStream(conn.getInputStream());
      +  164  0
                       } else if (encoding != null && "deflate".equalsIgnoreCase(encoding)) {
      +  165  0
                           reader = new InflaterInputStream(conn.getInputStream());
      +  166   +
                       } else {
      +  167  0
                           reader = conn.getInputStream();
      +  168   +
                       }
      +  169   +
       
      +  170  0
                       writer = new BufferedOutputStream(new FileOutputStream(outputPath));
      +  171  0
                       final byte[] buffer = new byte[4096];
      +  172   +
                       int bytesRead;
      +  173  0
                       while ((bytesRead = reader.read(buffer)) > 0) {
      +  174  0
                           writer.write(buffer, 0, bytesRead);
      +  175   +
                       }
      +  176  0
                       LOGGER.debug("Download of {} complete", url.toString());
      +  177  0
                   } catch (IOException ex) {
      +  178  0
                       checkForCommonExceptionTypes(ex);
      +  179  0
                       final String msg = format("Error saving '%s' to file '%s'%nConnection Timeout: %d%nEncoding: %s%n",
      +  180  0
                               url.toString(), outputPath.getAbsolutePath(), conn.getConnectTimeout(), encoding);
      +  181  0
                       throw new DownloadFailedException(msg, ex);
      +  182  0
                   } catch (Throwable ex) {
      +  183  0
                       final String msg = format("Unexpected exception saving '%s' to file '%s'%nConnection Timeout: %d%nEncoding: %s%n",
      +  184  0
                               url.toString(), outputPath.getAbsolutePath(), conn.getConnectTimeout(), encoding);
      +  185  0
                       throw new DownloadFailedException(msg, ex);
      +  186   +
                   } finally {
      +  187  0
                       if (writer != null) {
      +  188   +
                           try {
      +  189  0
                               writer.close();
      +  190  0
                           } catch (IOException ex) {
      +  191  0
                               LOGGER.trace("Error closing the writer in Downloader.", ex);
      +  192  0
                           }
      +  193   +
                       }
      +  194  0
                       if (reader != null) {
      +  195   +
                           try {
      +  196  0
                               reader.close();
      +  197  0
                           } catch (IOException ex) {
      +  198  0
                               LOGGER.trace("Error closing the reader in Downloader.", ex);
      +  199  0
                           }
      +  200   +
                       }
      +  201   +
                       try {
      +  202  0
                           conn.disconnect();
      +  203   +
                       } finally {
      +  204  0
                           conn = null;
      +  205  0
                       }
      +  206  0
                   }
      +  207   +
               }
      +  208  0
           }
      +  209   +
       
      +  210  
           /**
      -  269   -
            * Analyzes the IOException, logs the appropriate information for debugging purposes, and then throws a
      -  270   -
            * DownloadFailedException that wraps the IO Exception.
      -  271   +  211   +
            * Makes an HTTP Head request to retrieve the last modified date of the
      +  212   +
            * given URL. If the file:// protocol is specified, then the lastTimestamp
      +  213   +
            * of the file is returned.
      +  214  
            *
      -  272   -
            * @param ex the original exception
      -  273   -
            * @throws DownloadFailedException a wrapper exception that contains the original exception as the cause
      -  274   +  215   +
            * @param url the URL to retrieve the timestamp from
      +  216   +
            * @return an epoch timestamp
      +  217   +
            * @throws DownloadFailedException is thrown if an exception occurs making
      +  218   +
            * the HTTP request
      +  219  
            */
      +  220   +
           public static long getLastModified(URL url) throws DownloadFailedException {
      +  221  1
               return getLastModified(url, false);
      +  222   +
           }
      +  223   +
       
      +  224   +
           /**
      +  225   +
            * Makes an HTTP Head request to retrieve the last modified date of the
      +  226   +
            * given URL. If the file:// protocol is specified, then the lastTimestamp
      +  227   +
            * of the file is returned.
      +  228   +
            *
      +  229   +
            * @param url the URL to retrieve the timestamp from
      +  230   +
            * @param isRetry indicates if this is a retry - to prevent endless loop and
      +  231   +
            * stack overflow
      +  232   +
            * @return an epoch timestamp
      +  233   +
            * @throws DownloadFailedException is thrown if an exception occurs making
      +  234   +
            * the HTTP request
      +  235   +
            */
      +  236   +
           private static long getLastModified(URL url, boolean isRetry) throws DownloadFailedException {
      +  237  1
               long timestamp = 0;
      +  238   +
               //TODO add the FTP protocol?
      +  239  1
               if ("file".equalsIgnoreCase(url.getProtocol())) {
      +  240   +
                   File lastModifiedFile;
      +  241   +
                   try {
      +  242  1
                       lastModifiedFile = new File(url.toURI());
      +  243  0
                   } catch (URISyntaxException ex) {
      +  244  0
                       final String msg = format("Unable to locate '%s'", url.toString());
      +  245  0
                       throw new DownloadFailedException(msg);
      +  246  1
                   }
      +  247  1
                   timestamp = lastModifiedFile.lastModified();
      +  248  1
               } else {
      +  249  0
                   final String httpMethod = determineHttpMethod();
      +  250  0
                   HttpURLConnection conn = null;
      +  251   +
                   try {
      +  252  0
                       conn = URLConnectionFactory.createHttpURLConnection(url);
      +  253  0
                       conn.setRequestMethod(httpMethod);
      +  254  0
                       conn.connect();
      +  255  0
                       final int t = conn.getResponseCode();
      +  256  0
                       if (t >= 200 && t < 300) {
      +  257  0
                           timestamp = conn.getLastModified();
      +  258   +
                       } else {
      +  259  0
                           throw new DownloadFailedException(format("%s request returned a non-200 status code", httpMethod));
      +  260   +
                       }
      +  261  0
                   } catch (URLConnectionFailureException ex) {
      +  262  0
                       throw new DownloadFailedException(format("Error creating URL Connection for HTTP %s request.", httpMethod), ex);
      +  263  0
                   } catch (IOException ex) {
      +  264  0
                       checkForCommonExceptionTypes(ex);
      +  265  0
                       LOGGER.error("IO Exception: " + ex.getMessage());
      +  266  0
                       LOGGER.debug("Exception details", ex);
      +  267  0
                       if (ex.getCause() != null) {
      +  268  0
                           LOGGER.debug("IO Exception cause: " + ex.getCause().getMessage(), ex.getCause());
      +  269   +
                       }
      +  270   +
                       try {
      +  271   +
                           //retry
      +  272  0
                           if (!isRetry && Settings.getBoolean(Settings.KEYS.DOWNLOADER_QUICK_QUERY_TIMESTAMP)) {
      +  273  0
                               Settings.setBoolean(Settings.KEYS.DOWNLOADER_QUICK_QUERY_TIMESTAMP, false);
      +  274  0
                               return getLastModified(url, true);
       275   -
           protected static void analyzeException(IOException ex) throws DownloadFailedException {
      -  276  0
               Throwable cause = ex;
      -  277  0
               while (cause != null) {
      -  278  0
                   if (cause instanceof InvalidAlgorithmParameterException) {
      -  279  0
                       final String keystore = System.getProperty("javax.net.ssl.keyStore");
      -  280  0
                       final String version = System.getProperty("java.version");
      -  281  0
                       final String vendor = System.getProperty("java.vendor");
      -  282  0
                       LOGGER.info("Error making HTTPS request - InvalidAlgorithmParameterException");
      -  283  0
                       LOGGER.info("There appears to be an issue with the installation of Java and the cacerts."
      +
                           }
      +  276  0
                       } catch (InvalidSettingException ex1) {
      +  277  0
                           LOGGER.debug("invalid setting?", ex);
      +  278  0
                       }
      +  279  0
                       throw new DownloadFailedException(format("Error making HTTP %s request.", httpMethod), ex);
      +  280   +
                   } finally {
      +  281  0
                       if (conn != null) {
      +  282   +
                           try {
      +  283  0
                               conn.disconnect();
       284   -
                               + "See closed issue #177 here: https://github.com/jeremylong/DependencyCheck/issues/177");
      -  285  0
                       LOGGER.info("Java Info:\njavax.net.ssl.keyStore='{}'\njava.version='{}'\njava.vendor='{}'",
      -  286   -
                               keystore, version, vendor);
      -  287  0
                       throw new DownloadFailedException("Error making HTTPS request. Please see the log for more details.");
      +
                           } finally {
      +  285  0
                               conn = null;
      +  286  0
                           }
      +  287   +
                       }
       288  
                   }
      -  289  0
                   cause = cause.getCause();
      -  290   +  289  
               }
      -  291  0
           }
      +  290  1
               return timestamp;
      +  291   +
           }
       292  
       
       293  
           /**
       294   -
            * Returns the HEAD or GET HTTP method. HEAD is the default.
      +
            * Analyzes the IOException, logs the appropriate information for debugging
       295   -
            *
      +
            * purposes, and then throws a DownloadFailedException that wraps the IO
       296   -
            * @return the HTTP method to use
      +
            * Exception for common IO Exceptions. This is to provide additional details
       297   -
            */
      +
            * to assist in resolution of the exception.
       298   -
           private static String determineHttpMethod() {
      -  299  0
               return isQuickQuery() ? HEAD : GET;
      -  300   -
           }
      -  301   -
       
      -  302   -
           /**
      -  303   -
            * Determines if the HTTP method GET or HEAD should be used to check the timestamp on external resources.
      -  304  
            *
      -  305   -
            * @return true if configured to use HEAD requests
      -  306   +  299   +
            * @param ex the original exception
      +  300   +
            * @throws DownloadFailedException a wrapper exception that contains the
      +  301   +
            * original exception as the cause
      +  302  
            */
      -  307   -
           private static boolean isQuickQuery() {
      -  308   -
               boolean quickQuery;
      -  309   -
       
      +  303   +
           protected static void checkForCommonExceptionTypes(IOException ex) throws DownloadFailedException {
      +  304  0
               Throwable cause = ex;
      +  305  0
               while (cause != null) {
      +  306  0
                   if (cause instanceof java.net.UnknownHostException) {
      +  307  0
                       final String msg = String.format("Unable to resolve domain '%s'", cause.getMessage());
      +  308  0
                       LOGGER.error(msg);
      +  309  0
                       throw new DownloadFailedException(msg);
       310   -
               try {
      -  311  0
                   quickQuery = Settings.getBoolean(Settings.KEYS.DOWNLOADER_QUICK_QUERY_TIMESTAMP, true);
      -  312  0
               } catch (InvalidSettingException e) {
      -  313  0
                   quickQuery = true;
      -  314  0
               }
      -  315  0
               return quickQuery;
      -  316   -
           }
      +
                   }
      +  311  0
                   if (cause instanceof InvalidAlgorithmParameterException) {
      +  312  0
                       final String keystore = System.getProperty("javax.net.ssl.keyStore");
      +  313  0
                       final String version = System.getProperty("java.version");
      +  314  0
                       final String vendor = System.getProperty("java.vendor");
      +  315  0
                       LOGGER.info("Error making HTTPS request - InvalidAlgorithmParameterException");
      +  316  0
                       LOGGER.info("There appears to be an issue with the installation of Java and the cacerts."
       317   +
                               + "See closed issue #177 here: https://github.com/jeremylong/DependencyCheck/issues/177");
      +  318  0
                       LOGGER.info("Java Info:\njavax.net.ssl.keyStore='{}'\njava.version='{}'\njava.vendor='{}'",
      +  319   +
                               keystore, version, vendor);
      +  320  0
                       throw new DownloadFailedException("Error making HTTPS request. Please see the log for more details.");
      +  321   +
                   }
      +  322  0
                   cause = cause.getCause();
      +  323   +
               }
      +  324  0
           }
      +  325   +
       
      +  326   +
           /**
      +  327   +
            * Returns the HEAD or GET HTTP method. HEAD is the default.
      +  328   +
            *
      +  329   +
            * @return the HTTP method to use
      +  330   +
            */
      +  331   +
           private static String determineHttpMethod() {
      +  332  0
               return isQuickQuery() ? HEAD : GET;
      +  333   +
           }
      +  334   +
       
      +  335   +
           /**
      +  336   +
            * Determines if the HTTP method GET or HEAD should be used to check the
      +  337   +
            * timestamp on external resources.
      +  338   +
            *
      +  339   +
            * @return true if configured to use HEAD requests
      +  340   +
            */
      +  341   +
           private static boolean isQuickQuery() {
      +  342   +
               boolean quickQuery;
      +  343   +
       
      +  344   +
               try {
      +  345  0
                   quickQuery = Settings.getBoolean(Settings.KEYS.DOWNLOADER_QUICK_QUERY_TIMESTAMP, true);
      +  346  0
               } catch (InvalidSettingException e) {
      +  347  0
                   quickQuery = true;
      +  348  0
               }
      +  349  0
               return quickQuery;
      +  350   +
           }
      +  351  
       }
      - + diff --git a/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.ExpectedOjectInputStream.html b/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.ExpectedOjectInputStream.html index 147048543..28021cd52 100644 --- a/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.ExpectedOjectInputStream.html +++ b/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.ExpectedOjectInputStream.html @@ -93,7 +93,7 @@
            * The list of fully qualified class names that are able to be deserialized.
       38  
            */
      -  39  4
           private List<String> expected = new ArrayList<String>();
      +  39  2
           private List<String> expected = new ArrayList<String>();
       40  
       
       41   @@ -114,9 +114,9 @@
            */
       49  
           public ExpectedOjectInputStream(InputStream inputStream, String... expected) throws IOException {
      -  50  4
               super(inputStream);
      -  51  4
               this.expected.addAll(Arrays.asList(expected));
      -  52  4
           }
      +  50  2
               super(inputStream);
      +  51  2
               this.expected.addAll(Arrays.asList(expected));
      +  52  2
           }
       53  
       
       54   @@ -141,17 +141,17 @@
           @Override
       64  
           protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
      -  65  14
               if (!this.expected.contains(desc.getName())) {
      -  66  2
                   throw new InvalidClassException("Unexpected deserialization ", desc.getName());
      +  65  7
               if (!this.expected.contains(desc.getName())) {
      +  66  1
                   throw new InvalidClassException("Unexpected deserialization ", desc.getName());
       67  
               }
      -  68  12
               return super.resolveClass(desc);
      +  68  6
               return super.resolveClass(desc);
       69  
           }
       70  
       }
      - + diff --git a/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.ExtractionException.html b/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.ExtractionException.html index 5ae133f3e..d673467da 100644 --- a/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.ExtractionException.html +++ b/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.ExtractionException.html @@ -147,6 +147,6 @@
       }
      - + diff --git a/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.FileUtils.html b/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.FileUtils.html index 032bd35c1..83166717c 100644 --- a/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.FileUtils.html +++ b/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.FileUtils.html @@ -91,7 +91,7 @@
            * The logger.
       37  
            */
      -  38  2
           private static final Logger LOGGER = LoggerFactory.getLogger(FileUtils.class);
      +  38  1
           private static final Logger LOGGER = LoggerFactory.getLogger(FileUtils.class);
       39  
           /**
       40   @@ -136,8 +136,8 @@
            */
       61  
           public static String getFileExtension(String fileName) {
      -  62  6
               final String fileExt = FilenameUtils.getExtension(fileName);
      -  63  6
               return null == fileExt || fileExt.isEmpty() ? null : fileExt.toLowerCase();
      +  62  3
               final String fileExt = FilenameUtils.getExtension(fileName);
      +  63  3
               return null == fileExt || fileExt.isEmpty() ? null : fileExt.toLowerCase();
       64  
           }
       65   @@ -156,13 +156,13 @@
            */
       72  
           public static boolean delete(File file) {
      -  73  6
               final boolean success = org.apache.commons.io.FileUtils.deleteQuietly(file);
      -  74  6
               if (!success) {
      +  73  3
               final boolean success = org.apache.commons.io.FileUtils.deleteQuietly(file);
      +  74  3
               if (!success) {
       75  0
                   LOGGER.debug("Failed to delete file: {}; attempting to delete on exit.", file.getPath());
       76  0
                   file.deleteOnExit();
       77  
               }
      -  78  6
               return success;
      +  78  3
               return success;
       79  
           }
       80   @@ -222,6 +222,6 @@
       }
      - + diff --git a/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.InvalidSettingException.html b/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.InvalidSettingException.html index 1f94a2fab..39a4f8f8b 100644 --- a/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.InvalidSettingException.html +++ b/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.InvalidSettingException.html @@ -107,8 +107,8 @@
            */
       46  
           public InvalidSettingException(String msg) {
      -  47  2
               super(msg);
      -  48  2
           }
      +  47  1
               super(msg);
      +  48  1
           }
       49  
       
       50   @@ -147,6 +147,6 @@
       }
      - + diff --git a/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.SSLSocketFactoryEx.html b/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.SSLSocketFactoryEx.html new file mode 100644 index 000000000..dfe30d962 --- /dev/null +++ b/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.SSLSocketFactoryEx.html @@ -0,0 +1,710 @@ + + + + +Coverage Report + + + + +
      Coverage Report - org.owasp.dependencycheck.utils.SSLSocketFactoryEx
      +
       
      + + + + +
      Classes in this File Line Coverage Branch Coverage Complexity
      SSLSocketFactoryEx
      0%
      0/84
      0%
      0/10
      1.625
      +
       
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
       1  
       package org.owasp.dependencycheck.utils;
       2  
       
       3  
       import java.io.IOException;
       4  
       import java.net.InetAddress;
       5  
       import java.net.Socket;
       6  
       import java.security.KeyManagementException;
       7  
       import java.security.NoSuchAlgorithmException;
       8  
       import java.security.SecureRandom;
       9  
       import java.util.ArrayList;
       10  
       import java.util.Arrays;
       11  
       import java.util.List;
       12  
       import javax.net.ssl.KeyManager;
       13  
       import javax.net.ssl.SSLContext;
       14  
       import javax.net.ssl.SSLSocket;
       15  
       import javax.net.ssl.SSLSocketFactory;
       16  
       import javax.net.ssl.TrustManager;
       17  
       import org.slf4j.Logger;
       18  
       import org.slf4j.LoggerFactory;
       19  
       
       20  
       /**
       21  
        * This class is used to enable additional ciphers used by the SSL Socket. This
       22  
        * is specifically because the NVD stopped supporting TLS 1.0 and Java 6 and 7
       23  
        * clients by default were unable to connect to download the NVD data feeds.
       24  
        *
       25  
        * The following code was copied from
       26  
        * http://stackoverflow.com/questions/1037590/which-cipher-suites-to-enable-for-ssl-socket/23365536#23365536
       27  
        *
       28  
        * @author <a href="http://stackoverflow.com/users/608639/jww">jww</a>
       29  
        */
       30  
       public class SSLSocketFactoryEx extends SSLSocketFactory {
       31  
       
       32  
           /**
       33  
            * The Logger for use throughout the class.
       34  
            */
       35  0
           private static final Logger LOGGER = LoggerFactory.getLogger(SSLSocketFactoryEx.class);
       36  
       
       37  
           /**
       38  
            * Constructs a new SSLSocketFactory.
       39  
            *
       40  
            * @throws NoSuchAlgorithmException thrown when an algorithm is not
       41  
            * supported
       42  
            * @throws KeyManagementException thrown if initialization fails
       43  
            */
       44  0
           public SSLSocketFactoryEx() throws NoSuchAlgorithmException, KeyManagementException {
       45  0
               initSSLSocketFactoryEx(null, null, null);
       46  0
           }
       47  
       
       48  
           /**
       49  
            * Constructs a new SSLSocketFactory.
       50  
            *
       51  
            * @param km the key manager
       52  
            * @param tm the trust manager
       53  
            * @param random secure random
       54  
            * @throws NoSuchAlgorithmException thrown when an algorithm is not
       55  
            * supported
       56  
            * @throws KeyManagementException thrown if initialization fails
       57  
            */
       58  0
           public SSLSocketFactoryEx(KeyManager[] km, TrustManager[] tm, SecureRandom random) throws NoSuchAlgorithmException, KeyManagementException {
       59  0
               initSSLSocketFactoryEx(km, tm, random);
       60  0
           }
       61  
       
       62  
           /**
       63  
            * Constructs a new SSLSocketFactory.
       64  
            *
       65  
            * @param ctx the SSL context
       66  
            * @throws NoSuchAlgorithmException thrown when an algorithm is not
       67  
            * supported
       68  
            * @throws KeyManagementException thrown if initialization fails
       69  
            */
       70  0
           public SSLSocketFactoryEx(SSLContext ctx) throws NoSuchAlgorithmException, KeyManagementException {
       71  0
               initSSLSocketFactoryEx(ctx);
       72  0
           }
       73  
       
       74  
           /**
       75  
            * Returns the default cipher suites.
       76  
            *
       77  
            * @return the default cipher suites
       78  
            */
       79  
           @Override
       80  
           public String[] getDefaultCipherSuites() {
       81  0
               return Arrays.copyOf(ciphers, ciphers.length);
       82  
           }
       83  
       
       84  
           /**
       85  
            * Returns the supported cipher suites.
       86  
            *
       87  
            * @return the supported cipher suites
       88  
            */
       89  
           @Override
       90  
           public String[] getSupportedCipherSuites() {
       91  0
               return Arrays.copyOf(ciphers, ciphers.length);
       92  
           }
       93  
       
       94  
           /**
       95  
            * Returns the default protocols.
       96  
            *
       97  
            * @return the default protocols
       98  
            */
       99  
           public String[] getDefaultProtocols() {
       100  0
               return Arrays.copyOf(protocols, protocols.length);
       101  
           }
       102  
       
       103  
           /**
       104  
            * Returns the supported protocols.
       105  
            *
       106  
            * @return the supported protocols
       107  
            */
       108  
           public String[] getSupportedProtocols() {
       109  0
               return Arrays.copyOf(protocols, protocols.length);
       110  
           }
       111  
       
       112  
           /**
       113  
            * Creates an SSL Socket.
       114  
            *
       115  
            * @param s the base socket
       116  
            * @param host the host
       117  
            * @param port the port
       118  
            * @param autoClose if the socket should auto-close
       119  
            * @return the SSL Socket
       120  
            * @throws IOException thrown if the creation fails
       121  
            */
       122  
           @Override
       123  
           public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
       124  0
               final SSLSocketFactory factory = sslCtxt.getSocketFactory();
       125  0
               final SSLSocket ss = (SSLSocket) factory.createSocket(s, host, port, autoClose);
       126  
       
       127  0
               ss.setEnabledProtocols(protocols);
       128  0
               ss.setEnabledCipherSuites(ciphers);
       129  
       
       130  0
               return ss;
       131  
           }
       132  
       
       133  
           /**
       134  
            * Creates a new SSL Socket.
       135  
            *
       136  
            * @param address the address to connect to
       137  
            * @param port the port number
       138  
            * @param localAddress the local address
       139  
            * @param localPort the local port
       140  
            * @return the SSL Socket
       141  
            * @throws IOException thrown if the creation fails
       142  
            */
       143  
           @Override
       144  
           public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
       145  0
               final SSLSocketFactory factory = sslCtxt.getSocketFactory();
       146  0
               final SSLSocket ss = (SSLSocket) factory.createSocket(address, port, localAddress, localPort);
       147  
       
       148  0
               ss.setEnabledProtocols(protocols);
       149  0
               ss.setEnabledCipherSuites(ciphers);
       150  
       
       151  0
               return ss;
       152  
           }
       153  
       
       154  
           /**
       155  
            * Creates a new SSL Socket.
       156  
            *
       157  
            * @param host the host to connect to
       158  
            * @param port the port to connect to
       159  
            * @param localHost the local host
       160  
            * @param localPort the local port
       161  
            * @return the SSL Socket
       162  
            * @throws IOException thrown if the creation fails
       163  
            */
       164  
           @Override
       165  
           public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException {
       166  0
               final SSLSocketFactory factory = sslCtxt.getSocketFactory();
       167  0
               final SSLSocket ss = (SSLSocket) factory.createSocket(host, port, localHost, localPort);
       168  
       
       169  0
               ss.setEnabledProtocols(protocols);
       170  0
               ss.setEnabledCipherSuites(ciphers);
       171  
       
       172  0
               return ss;
       173  
           }
       174  
       
       175  
           /**
       176  
            * Creates a new SSL Socket.
       177  
            *
       178  
            * @param host the host to connect to
       179  
            * @param port the port to connect to
       180  
            * @return the SSL Socket
       181  
            * @throws IOException thrown if the creation fails
       182  
            */
       183  
           @Override
       184  
           public Socket createSocket(InetAddress host, int port) throws IOException {
       185  0
               final SSLSocketFactory factory = sslCtxt.getSocketFactory();
       186  0
               final SSLSocket ss = (SSLSocket) factory.createSocket(host, port);
       187  
       
       188  0
               ss.setEnabledProtocols(protocols);
       189  0
               ss.setEnabledCipherSuites(ciphers);
       190  
       
       191  0
               return ss;
       192  
           }
       193  
       
       194  
           /**
       195  
            * Creates a new SSL Socket.
       196  
            *
       197  
            * @param host the host to connect to
       198  
            * @param port the port to connect to
       199  
            * @return the SSL Socket
       200  
            * @throws IOException thrown if the creation fails
       201  
            */
       202  
           @Override
       203  
           public Socket createSocket(String host, int port) throws IOException {
       204  0
               final SSLSocketFactory factory = sslCtxt.getSocketFactory();
       205  0
               final SSLSocket ss = (SSLSocket) factory.createSocket(host, port);
       206  
       
       207  0
               ss.setEnabledProtocols(protocols);
       208  0
               ss.setEnabledCipherSuites(ciphers);
       209  
       
       210  0
               return ss;
       211  
           }
       212  
       
       213  
           /**
       214  
            * Initializes the SSL Socket Factory Extension.
       215  
            *
       216  
            * @param km the key managers
       217  
            * @param tm the trust managers
       218  
            * @param random the secure random number generator
       219  
            * @throws NoSuchAlgorithmException thrown when an algorithm is not
       220  
            * supported
       221  
            * @throws KeyManagementException thrown if initialization fails
       222  
            */
       223  
           private void initSSLSocketFactoryEx(KeyManager[] km, TrustManager[] tm, SecureRandom random)
       224  
                   throws NoSuchAlgorithmException, KeyManagementException {
       225  0
               sslCtxt = SSLContext.getInstance("TLS");
       226  0
               sslCtxt.init(km, tm, random);
       227  
       
       228  0
               protocols = getProtocolList();
       229  0
               ciphers = getCipherList();
       230  0
           }
       231  
       
       232  
           /**
       233  
            * Initializes the SSL Socket Factory Extension.
       234  
            *
       235  
            * @param ctx the SSL context
       236  
            * @throws NoSuchAlgorithmException thrown when an algorithm is not
       237  
            * supported
       238  
            * @throws KeyManagementException thrown if initialization fails
       239  
            */
       240  
           private void initSSLSocketFactoryEx(SSLContext ctx)
       241  
                   throws NoSuchAlgorithmException, KeyManagementException {
       242  0
               sslCtxt = ctx;
       243  
       
       244  0
               protocols = getProtocolList();
       245  0
               ciphers = getCipherList();
       246  0
           }
       247  
       
       248  
           /**
       249  
            * Returns the protocol list.
       250  
            *
       251  
            * @return the protocol list
       252  
            */
       253  
           protected String[] getProtocolList() {
       254  0
               final String[] preferredProtocols = {"TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3"};
       255  0
               String[] availableProtocols = null;
       256  
       
       257  0
               SSLSocket socket = null;
       258  
       
       259  
               try {
       260  0
                   final SSLSocketFactory factory = sslCtxt.getSocketFactory();
       261  0
                   socket = (SSLSocket) factory.createSocket();
       262  
       
       263  0
                   availableProtocols = socket.getSupportedProtocols();
       264  0
                   Arrays.sort(availableProtocols);
       265  0
               } catch (Exception ex) {
       266  0
                   LOGGER.debug("Error getting protocol list, using TLSv1", ex);
       267  0
                   return new String[]{"TLSv1"};
       268  
               } finally {
       269  0
                   if (socket != null) {
       270  
                       try {
       271  0
                           socket.close();
       272  0
                       } catch (IOException ex) {
       273  0
                           LOGGER.trace("Error closing socket", ex);
       274  0
                       }
       275  
                   }
       276  
               }
       277  
       
       278  0
               final List<String> aa = new ArrayList<String>();
       279  0
               for (String preferredProtocol : preferredProtocols) {
       280  0
                   final int idx = Arrays.binarySearch(availableProtocols, preferredProtocol);
       281  0
                   if (idx >= 0) {
       282  0
                       aa.add(preferredProtocol);
       283  
                   }
       284  
               }
       285  
       
       286  0
               return aa.toArray(new String[0]);
       287  
           }
       288  
       
       289  
           /**
       290  
            * Returns the cipher list.
       291  
            *
       292  
            * @return the cipher list
       293  
            */
       294  
           protected String[] getCipherList() {
       295  0
               final String[] preferredCiphers = {
       296  
                   // *_CHACHA20_POLY1305 are 3x to 4x faster than existing cipher suites.
       297  
                   //   http://googleonlinesecurity.blogspot.com/2014/04/speeding-up-and-strengthening-https.html
       298  
                   // Use them if available. Normative names can be found at (TLS spec depends on IPSec spec):
       299  
                   //   http://tools.ietf.org/html/draft-nir-ipsecme-chacha20-poly1305-01
       300  
                   //   http://tools.ietf.org/html/draft-mavrogiannopoulos-chacha-tls-02
       301  
                   "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305",
       302  
                   "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305",
       303  
                   "TLS_ECDHE_ECDSA_WITH_CHACHA20_SHA",
       304  
                   "TLS_ECDHE_RSA_WITH_CHACHA20_SHA",
       305  
                   "TLS_DHE_RSA_WITH_CHACHA20_POLY1305",
       306  
                   "TLS_RSA_WITH_CHACHA20_POLY1305",
       307  
                   "TLS_DHE_RSA_WITH_CHACHA20_SHA",
       308  
                   "TLS_RSA_WITH_CHACHA20_SHA",
       309  
                   // Done with bleeding edge, back to TLS v1.2 and below
       310  
                   "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384",
       311  
                   "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384",
       312  
                   "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
       313  
                   "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
       314  
                   "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
       315  
                   "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384",
       316  
                   "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
       317  
                   "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256",
       318  
                   // TLS v1.0 (with some SSLv3 interop)
       319  
                   "TLS_DHE_RSA_WITH_AES_256_CBC_SHA384",
       320  
                   "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256",
       321  
                   "TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
       322  
                   "TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
       323  
                   "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
       324  
                   "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA",
       325  
                   "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA",
       326  
                   "SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA",
       327  
                   // RSA key transport sucks, but they are needed as a fallback.
       328  
                   // For example, microsoft.com fails under all versions of TLS
       329  
                   // if they are not included. If only TLS 1.0 is available at
       330  
                   // the client, then google.com will fail too. TLS v1.3 is
       331  
                   // trying to deprecate them, so it will be interesteng to see
       332  
                   // what happens.
       333  
                   "TLS_RSA_WITH_AES_256_CBC_SHA256",
       334  
                   "TLS_RSA_WITH_AES_256_CBC_SHA",
       335  
                   "TLS_RSA_WITH_AES_128_CBC_SHA256",
       336  
                   "TLS_RSA_WITH_AES_128_CBC_SHA",
       337  
               };
       338  
       
       339  
               String[] availableCiphers;
       340  
       
       341  
               try {
       342  0
                   final SSLSocketFactory factory = sslCtxt.getSocketFactory();
       343  0
                   availableCiphers = factory.getSupportedCipherSuites();
       344  0
                   Arrays.sort(availableCiphers);
       345  0
               } catch (Exception e) {
       346  0
                   LOGGER.debug("Error retrieving ciphers", e);
       347  0
                   return new String[]{
       348  
                       "TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
       349  
                       "TLS_DHE_DSS_WITH_AES_256_CBC_SHA",
       350  
                       "TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
       351  
                       "TLS_DHE_RSA_WITH_AES_256_CBC_SHA",
       352  
                       "TLS_RSA_WITH_AES_256_CBC_SHA256",
       353  
                       "TLS_RSA_WITH_AES_256_CBC_SHA",
       354  
                       "TLS_RSA_WITH_AES_128_CBC_SHA256",
       355  
                       "TLS_RSA_WITH_AES_128_CBC_SHA",
       356  
                       "TLS_EMPTY_RENEGOTIATION_INFO_SCSV",
       357  
                   };
       358  0
               }
       359  
       
       360  0
               final List<String> aa = new ArrayList<String>();
       361  0
               for (String preferredCipher : preferredCiphers) {
       362  0
                   final int idx = Arrays.binarySearch(availableCiphers, preferredCipher);
       363  0
                   if (idx >= 0) {
       364  0
                       aa.add(preferredCipher);
       365  
                   }
       366  
               }
       367  
       
       368  0
               aa.add("TLS_EMPTY_RENEGOTIATION_INFO_SCSV");
       369  
       
       370  0
               return aa.toArray(new String[0]);
       371  
           }
       372  
       
       373  
           /**
       374  
            * The SSL context.
       375  
            */
       376  
           private SSLContext sslCtxt;
       377  
           /**
       378  
            * The cipher suites.
       379  
            */
       380  
           private String[] ciphers;
       381  
           /**
       382  
            * The protocols.
       383  
            */
       384  
           private String[] protocols;
       385  
       }
      + + + + diff --git a/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.Settings.html b/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.Settings.html index e13e176ea..b25fc89a5 100644 --- a/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.Settings.html +++ b/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.Settings.html @@ -115,1447 +115,1583 @@  48  
               /**
       49   -
                * private constructor because this is a "utility" class containing constants
      +
                * private constructor because this is a "utility" class containing
       50   +
                * constants
      +  51  
                */
      -  51  0
               private KEYS() {
      -  52   +  52  0
               private KEYS() {
      +  53  
                   //do nothing
      -  53  0
               }
      -  54   -
               /**
      +  54  0
               }
       55   -
                * The key to obtain the application name.
      +
               /**
       56   -
                */
      +
                * The key to obtain the application name.
       57   -
               public static final String APPLICATION_VAME = "application.name";
      +
                */
       58   -
               /**
      +
               public static final String APPLICATION_VAME = "application.name";
       59   -
                * The key to obtain the application version.
      +
               /**
       60   -
                */
      +
                * The key to obtain the application version.
       61   -
               public static final String APPLICATION_VERSION = "application.version";
      +
                */
       62   -
               /**
      +
               public static final String APPLICATION_VERSION = "application.version";
       63   -
                * The key to obtain the URL to retrieve the current release version from.
      +
               /**
       64   -
                */
      +
                * The key to obtain the URL to retrieve the current release version
       65   -
               public static final String ENGINE_VERSION_CHECK_URL = "engine.version.url";
      +
                * from.
       66   -
               /**
      +
                */
       67   -
                * The properties key indicating whether or not the cached data sources should be updated.
      +
               public static final String ENGINE_VERSION_CHECK_URL = "engine.version.url";
       68   -
                */
      +
               /**
       69   -
               public static final String AUTO_UPDATE = "autoupdate";
      +
                * The properties key indicating whether or not the cached data sources
       70   -
               /**
      +
                * should be updated.
       71   -
                * The database driver class name. If this is not in the properties file the embedded database is used.
      -  72  
                */
      +  72   +
               public static final String AUTO_UPDATE = "autoupdate";
       73   -
               public static final String DB_DRIVER_NAME = "data.driver_name";
      -  74  
               /**
      +  74   +
                * The database driver class name. If this is not in the properties file
       75   -
                * The database driver class name. If this is not in the properties file the embedded database is used.
      +
                * the embedded database is used.
       76  
                */
       77   -
               public static final String DB_DRIVER_PATH = "data.driver_path";
      +
               public static final String DB_DRIVER_NAME = "data.driver_name";
       78  
               /**
       79   -
                * The database connection string. If this is not in the properties file the embedded database is used.
      +
                * The database driver class name. If this is not in the properties file
       80   -
                */
      +
                * the embedded database is used.
       81   -
               public static final String DB_CONNECTION_STRING = "data.connection_string";
      +
                */
       82   -
               /**
      +
               public static final String DB_DRIVER_PATH = "data.driver_path";
       83   -
                * The username to use when connecting to the database.
      +
               /**
       84   -
                */
      +
                * The database connection string. If this is not in the properties file
       85   -
               public static final String DB_USER = "data.user";
      +
                * the embedded database is used.
       86   -
               /**
      +
                */
       87   -
                * The password to authenticate to the database.
      +
               public static final String DB_CONNECTION_STRING = "data.connection_string";
       88   -
                */
      +
               /**
       89   -
               public static final String DB_PASSWORD = "data.password";
      +
                * The username to use when connecting to the database.
       90   -
               /**
      +
                */
       91   -
                * The base path to use for the data directory (for embedded db).
      +
               public static final String DB_USER = "data.user";
       92   -
                */
      +
               /**
       93   -
               public static final String DATA_DIRECTORY = "data.directory";
      +
                * The password to authenticate to the database.
       94   -
               /**
      +
                */
       95   -
                * The database file name.
      +
               public static final String DB_PASSWORD = "data.password";
       96   -
                */
      +
               /**
       97   -
               public static final String DB_FILE_NAME = "data.file_name";
      +
                * The base path to use for the data directory (for embedded db).
       98   -
               /**
      +
                */
       99   -
                * The database schema version.
      +
               public static final String DATA_DIRECTORY = "data.directory";
       100   -
                */
      +
               /**
       101   -
               public static final String DB_VERSION = "data.version";
      +
                * The database file name.
       102   -
               /**
      +
                */
       103   -
                * The properties key for the URL to retrieve the "meta" data from about the CVE entries.
      +
               public static final String DB_FILE_NAME = "data.file_name";
       104   -
                */
      +
               /**
       105   -
               public static final String CVE_META_URL = "cve.url.meta";
      +
                * The database schema version.
       106   -
               /**
      -  107   -
                * The properties key for the URL to retrieve the recently modified and added CVE entries (last 8 days) using the 2.0
      -  108   -
                * schema.
      -  109  
                */
      -  110   -
               public static final String CVE_MODIFIED_20_URL = "cve.url-2.0.modified";
      -  111   +  107   +
               public static final String DB_VERSION = "data.version";
      +  108  
               /**
      +  109   +
                * The starts with filter used to exclude CVE entries from the database.
      +  110   +
                * By default this is set to 'cpe:/a:' which limits the CVEs imported to
      +  111   +
                * just those that are related to applications. If this were set to just
       112   -
                * The properties key for the URL to retrieve the recently modified and added CVE entries (last 8 days) using the 1.2
      +
                * 'cpe:' the OS, hardware, and application related CVEs would be
       113   -
                * schema.
      +
                * imported.
       114  
                */
       115   -
               public static final String CVE_MODIFIED_12_URL = "cve.url-1.2.modified";
      +
               public static final String CVE_CPE_STARTS_WITH_FILTER = "cve.cpe.startswith.filter";
       116  
               /**
       117   -
                * The properties key for the URL to retrieve the recently modified and added CVE entries (last 8 days).
      +
                * The properties key for the URL to retrieve the "meta" data from about
       118   -
                */
      +
                * the CVE entries.
       119   -
               public static final String CVE_MODIFIED_VALID_FOR_DAYS = "cve.url.modified.validfordays";
      +
                */
       120   -
               /**
      +
               public static final String CVE_META_URL = "cve.url.meta";
       121   -
                * The properties key to control the skipping of the check for CVE updates.
      +
               /**
       122   -
                */
      +
                * The properties key for the URL to retrieve the recently modified and
       123   -
               public static final String CVE_CHECK_VALID_FOR_HOURS = "cve.check.validforhours";
      +
                * added CVE entries (last 8 days) using the 2.0 schema.
       124   -
               /**
      +
                */
       125   -
                * The properties key for the telling us how many cve.url.* URLs exists. This is used in combination with CVE_BASE_URL to
      +
               public static final String CVE_MODIFIED_20_URL = "cve.url-2.0.modified";
       126   -
                * be able to retrieve the URLs for all of the files that make up the NVD CVE listing.
      +
               /**
       127   -
                */
      +
                * The properties key for the URL to retrieve the recently modified and
       128   -
               public static final String CVE_START_YEAR = "cve.startyear";
      +
                * added CVE entries (last 8 days) using the 1.2 schema.
       129   -
               /**
      +
                */
       130   -
                * The properties key for the CVE schema version 1.2.
      +
               public static final String CVE_MODIFIED_12_URL = "cve.url-1.2.modified";
       131   -
                */
      +
               /**
       132   -
               public static final String CVE_SCHEMA_1_2 = "cve.url-1.2.base";
      +
                * The properties key for the URL to retrieve the recently modified and
       133   -
               /**
      +
                * added CVE entries (last 8 days).
       134   -
                * The properties key for the CVE schema version 2.0.
      -  135  
                */
      +  135   +
               public static final String CVE_MODIFIED_VALID_FOR_DAYS = "cve.url.modified.validfordays";
       136   -
               public static final String CVE_SCHEMA_2_0 = "cve.url-2.0.base";
      -  137  
               /**
      +  137   +
                * The properties key to control the skipping of the check for CVE
       138   -
                * The properties key that indicates how often the CPE data needs to be updated.
      +
                * updates.
       139  
                */
       140   -
               public static final String CPE_MODIFIED_VALID_FOR_DAYS = "cpe.validfordays";
      +
               public static final String CVE_CHECK_VALID_FOR_HOURS = "cve.check.validforhours";
       141  
               /**
       142   -
                * The properties key for the URL to retrieve the CPE.
      +
                * The properties key for the telling us how many cve.url.* URLs exists.
       143   -
                */
      +
                * This is used in combination with CVE_BASE_URL to be able to retrieve
       144   -
               public static final String CPE_URL = "cpe.url";
      +
                * the URLs for all of the files that make up the NVD CVE listing.
       145   -
               /**
      +
                */
       146   -
                * The properties key for the proxy server.
      +
               public static final String CVE_START_YEAR = "cve.startyear";
       147   -
                *
      +
               /**
       148   -
                * @deprecated use {@link org.owasp.dependencycheck.utils.Settings.KEYS#PROXY_SERVER} instead.
      +
                * The properties key for the CVE schema version 1.2.
       149  
                */
       150   -
               @Deprecated
      +
               public static final String CVE_SCHEMA_1_2 = "cve.url-1.2.base";
       151   -
               public static final String PROXY_URL = "proxy.server";
      +
               /**
       152   -
               /**
      +
                * The properties key for the CVE schema version 2.0.
       153   -
                * The properties key for the proxy server.
      -  154  
                */
      +  154   +
               public static final String CVE_SCHEMA_2_0 = "cve.url-2.0.base";
       155   -
               public static final String PROXY_SERVER = "proxy.server";
      -  156  
               /**
      +  156   +
                * The properties key that indicates how often the CPE data needs to be
       157   -
                * The properties key for the proxy port - this must be an integer value.
      +
                * updated.
       158  
                */
       159   -
               public static final String PROXY_PORT = "proxy.port";
      +
               public static final String CPE_MODIFIED_VALID_FOR_DAYS = "cpe.validfordays";
       160  
               /**
       161   -
                * The properties key for the proxy username.
      +
                * The properties key for the URL to retrieve the CPE.
       162  
                */
       163   -
               public static final String PROXY_USERNAME = "proxy.username";
      +
               public static final String CPE_URL = "cpe.url";
       164  
               /**
       165   -
                * The properties key for the proxy password.
      +
                * The properties key for the proxy server.
       166   -
                */
      +
                *
       167   -
               public static final String PROXY_PASSWORD = "proxy.password";
      +
                * @deprecated use
       168   -
               /**
      +
                * {@link org.owasp.dependencycheck.utils.Settings.KEYS#PROXY_SERVER}
       169   -
                * The properties key for the non proxy hosts.
      +
                * instead.
       170  
                */
       171   -
               public static final String PROXY_NON_PROXY_HOSTS = "proxy.nonproxyhosts";
      +
               @Deprecated
       172   -
               /**
      +
               public static final String PROXY_URL = "proxy.server";
       173   -
                * The properties key for the connection timeout.
      +
               /**
       174   -
                */
      +
                * The properties key for the proxy server.
       175   -
               public static final String CONNECTION_TIMEOUT = "connection.timeout";
      +
                */
       176   -
               /**
      +
               public static final String PROXY_SERVER = "proxy.server";
       177   -
                * The location of the temporary directory.
      +
               /**
       178   -
                */
      +
                * The properties key for the proxy port - this must be an integer
       179   -
               public static final String TEMP_DIRECTORY = "temp.directory";
      +
                * value.
       180   -
               /**
      +
                */
       181   -
                * The maximum number of threads to allocate when downloading files.
      +
               public static final String PROXY_PORT = "proxy.port";
       182   -
                */
      +
               /**
       183   -
               public static final String MAX_DOWNLOAD_THREAD_POOL_SIZE = "max.download.threads";
      +
                * The properties key for the proxy username.
       184   -
               /**
      +
                */
       185   -
                * The key for a list of suppression files.
      +
               public static final String PROXY_USERNAME = "proxy.username";
       186   -
                */
      +
               /**
       187   -
               public static final String SUPPRESSION_FILE = "suppression.file";
      +
                * The properties key for the proxy password.
       188   -
               /**
      +
                */
       189   -
                * The properties key for whether the Jar Analyzer is enabled.
      +
               public static final String PROXY_PASSWORD = "proxy.password";
       190   -
                */
      +
               /**
       191   -
               public static final String ANALYZER_JAR_ENABLED = "analyzer.jar.enabled";
      +
                * The properties key for the non proxy hosts.
       192   -
               /**
      +
                */
       193   -
                * The properties key for whether experimental analyzers are loaded.
      +
               public static final String PROXY_NON_PROXY_HOSTS = "proxy.nonproxyhosts";
       194   -
                */
      +
               /**
       195   -
               public static final String ANALYZER_EXPERIMENTAL_ENABLED = "analyzer.experimental.enabled";
      +
                * The properties key for the connection timeout.
       196   -
               /**
      +
                */
       197   -
                * The properties key for whether the Archive analyzer is enabled.
      +
               public static final String CONNECTION_TIMEOUT = "connection.timeout";
       198   -
                */
      +
               /**
       199   -
               public static final String ANALYZER_ARCHIVE_ENABLED = "analyzer.archive.enabled";
      +
                * The location of the temporary directory.
       200   -
               /**
      +
                */
       201   -
                * The properties key for whether the node.js package analyzer is enabled.
      +
               public static final String TEMP_DIRECTORY = "temp.directory";
       202   -
                */
      +
               /**
       203   -
               public static final String ANALYZER_NODE_PACKAGE_ENABLED = "analyzer.node.package.enabled";
      +
                * The maximum number of threads to allocate when downloading files.
       204   -
               /**
      +
                */
       205   -
                * The properties key for whether the composer lock file analyzer is enabled.
      +
               public static final String MAX_DOWNLOAD_THREAD_POOL_SIZE = "max.download.threads";
       206   -
                */
      +
               /**
       207   -
               public static final String ANALYZER_COMPOSER_LOCK_ENABLED = "analyzer.composer.lock.enabled";
      +
                * The key for the suppression file.
       208   -
               /**
      +
                */
       209   -
                * The properties key for whether the Python Distribution analyzer is enabled.
      +
               public static final String SUPPRESSION_FILE = "suppression.file";
       210   -
                */
      +
               /**
       211   -
               public static final String ANALYZER_PYTHON_DISTRIBUTION_ENABLED = "analyzer.python.distribution.enabled";
      +
                * The key for the hint file.
       212   -
               /**
      +
                */
       213   -
                * The properties key for whether the Python Package analyzer is enabled.
      +
               public static final String HINTS_FILE = "hints.file";
       214   -
                */
      +
               /**
       215   -
               public static final String ANALYZER_PYTHON_PACKAGE_ENABLED = "analyzer.python.package.enabled";
      +
                * The properties key for whether the Jar Analyzer is enabled.
       216   -
               /**
      +
                */
       217   -
                * The properties key for whether the Ruby Gemspec Analyzer is enabled.
      +
               public static final String ANALYZER_JAR_ENABLED = "analyzer.jar.enabled";
       218   -
                */
      +
               /**
       219   -
               public static final String ANALYZER_RUBY_GEMSPEC_ENABLED = "analyzer.ruby.gemspec.enabled";
      +
                * The properties key for whether experimental analyzers are loaded.
       220   -
               /**
      +
                */
       221   -
                * The properties key for whether the Autoconf analyzer is enabled.
      +
               public static final String ANALYZER_EXPERIMENTAL_ENABLED = "analyzer.experimental.enabled";
       222   -
                */
      +
               /**
       223   -
               public static final String ANALYZER_AUTOCONF_ENABLED = "analyzer.autoconf.enabled";
      +
                * The properties key for whether the Archive analyzer is enabled.
       224   -
               /**
      +
                */
       225   -
                * The properties key for whether the CMake analyzer is enabled.
      +
               public static final String ANALYZER_ARCHIVE_ENABLED = "analyzer.archive.enabled";
       226   -
                */
      +
               /**
       227   -
               public static final String ANALYZER_CMAKE_ENABLED = "analyzer.cmake.enabled";
      +
                * The properties key for whether the node.js package analyzer is
       228   -
               /**
      +
                * enabled.
       229   -
                * The properties key for whether the Ruby Bundler Audit analyzer is enabled.
      -  230  
                */
      +  230   +
               public static final String ANALYZER_NODE_PACKAGE_ENABLED = "analyzer.node.package.enabled";
       231   -
               public static final String ANALYZER_BUNDLE_AUDIT_ENABLED = "analyzer.bundle.audit.enabled";
      -  232  
               /**
      +  232   +
                * The properties key for whether the composer lock file analyzer is
       233   -
                * The properties key for whether the .NET Assembly analyzer is enabled.
      +
                * enabled.
       234  
                */
       235   -
               public static final String ANALYZER_ASSEMBLY_ENABLED = "analyzer.assembly.enabled";
      +
               public static final String ANALYZER_COMPOSER_LOCK_ENABLED = "analyzer.composer.lock.enabled";
       236  
               /**
       237   -
                * The properties key for whether the .NET Nuspec analyzer is enabled.
      +
                * The properties key for whether the Python Distribution analyzer is
       238   -
                */
      +
                * enabled.
       239   -
               public static final String ANALYZER_NUSPEC_ENABLED = "analyzer.nuspec.enabled";
      +
                */
       240   -
               /**
      +
               public static final String ANALYZER_PYTHON_DISTRIBUTION_ENABLED = "analyzer.python.distribution.enabled";
       241   -
                * The properties key for whether the Nexus analyzer is enabled.
      +
               /**
       242   -
                */
      +
                * The properties key for whether the Python Package analyzer is
       243   -
               public static final String ANALYZER_NEXUS_ENABLED = "analyzer.nexus.enabled";
      +
                * enabled.
       244   -
               /**
      +
                */
       245   -
                * The properties key for the Nexus search URL.
      +
               public static final String ANALYZER_PYTHON_PACKAGE_ENABLED = "analyzer.python.package.enabled";
       246   -
                */
      +
               /**
       247   -
               public static final String ANALYZER_NEXUS_URL = "analyzer.nexus.url";
      +
                * The properties key for whether the Ruby Gemspec Analyzer is enabled.
       248   -
               /**
      +
                */
       249   -
                * The properties key for using the proxy to reach Nexus.
      +
               public static final String ANALYZER_RUBY_GEMSPEC_ENABLED = "analyzer.ruby.gemspec.enabled";
       250   -
                */
      +
               /**
       251   -
               public static final String ANALYZER_NEXUS_USES_PROXY = "analyzer.nexus.proxy";
      +
                * The properties key for whether the Autoconf analyzer is enabled.
       252   -
               /**
      +
                */
       253   -
                * The properties key for whether the Central analyzer is enabled.
      +
               public static final String ANALYZER_AUTOCONF_ENABLED = "analyzer.autoconf.enabled";
       254   -
                */
      +
               /**
       255   -
               public static final String ANALYZER_CENTRAL_ENABLED = "analyzer.central.enabled";
      +
                * The properties key for whether the CMake analyzer is enabled.
       256   -
               /**
      +
                */
       257   -
                * The properties key for whether the OpenSSL analyzer is enabled.
      +
               public static final String ANALYZER_CMAKE_ENABLED = "analyzer.cmake.enabled";
       258   -
                */
      +
               /**
       259   -
               public static final String ANALYZER_OPENSSL_ENABLED = "analyzer.openssl.enabled";
      +
                * The properties key for whether the Ruby Bundler Audit analyzer is
       260   -
               /**
      +
                * enabled.
       261   -
                * The properties key for the Central search URL.
      +
                */
       262   -
                */
      +
               public static final String ANALYZER_BUNDLE_AUDIT_ENABLED = "analyzer.bundle.audit.enabled";
       263   -
               public static final String ANALYZER_CENTRAL_URL = "analyzer.central.url";
      +
               /**
       264   -
               /**
      +
                * The properties key for whether the .NET Assembly analyzer is enabled.
       265   -
                * The path to mono, if available.
      +
                */
       266   -
                */
      +
               public static final String ANALYZER_ASSEMBLY_ENABLED = "analyzer.assembly.enabled";
       267   -
               public static final String ANALYZER_ASSEMBLY_MONO_PATH = "analyzer.assembly.mono.path";
      +
               /**
       268   -
               /**
      +
                * The properties key for whether the .NET Nuspec analyzer is enabled.
       269   -
                * The path to bundle-audit, if available.
      +
                */
       270   -
                */
      +
               public static final String ANALYZER_NUSPEC_ENABLED = "analyzer.nuspec.enabled";
       271   -
               public static final String ANALYZER_BUNDLE_AUDIT_PATH = "analyzer.bundle.audit.path";
      +
               /**
       272   -
               /**
      +
                * The properties key for whether the Nexus analyzer is enabled.
       273   -
                * The additional configured zip file extensions, if available.
      +
                */
       274   -
                */
      +
               public static final String ANALYZER_NEXUS_ENABLED = "analyzer.nexus.enabled";
       275   -
               public static final String ADDITIONAL_ZIP_EXTENSIONS = "extensions.zip";
      +
               /**
       276   -
               /**
      +
                * The properties key for the Nexus search URL.
       277   -
                * The key to obtain the path to the VFEED data file.
      +
                */
       278   -
                */
      +
               public static final String ANALYZER_NEXUS_URL = "analyzer.nexus.url";
       279   -
               public static final String VFEED_DATA_FILE = "vfeed.data_file";
      +
               /**
       280   -
               /**
      +
                * The properties key for using the proxy to reach Nexus.
       281   -
                * The key to obtain the VFEED connection string.
      +
                */
       282   -
                */
      +
               public static final String ANALYZER_NEXUS_USES_PROXY = "analyzer.nexus.proxy";
       283   -
               public static final String VFEED_CONNECTION_STRING = "vfeed.connection_string";
      +
               /**
       284   -
       
      +
                * The properties key for whether the Central analyzer is enabled.
       285   -
               /**
      +
                */
       286   -
                * The key to obtain the base download URL for the VFeed data file.
      +
               public static final String ANALYZER_CENTRAL_ENABLED = "analyzer.central.enabled";
       287   -
                */
      +
               /**
       288   -
               public static final String VFEED_DOWNLOAD_URL = "vfeed.download_url";
      +
                * The properties key for whether the OpenSSL analyzer is enabled.
       289   -
               /**
      +
                */
       290   -
                * The key to obtain the download file name for the VFeed data.
      +
               public static final String ANALYZER_OPENSSL_ENABLED = "analyzer.openssl.enabled";
       291   -
                */
      +
               /**
       292   -
               public static final String VFEED_DOWNLOAD_FILE = "vfeed.download_file";
      +
                * The properties key for the Central search URL.
       293   -
               /**
      +
                */
       294   -
                * The key to obtain the VFeed update status.
      +
               public static final String ANALYZER_CENTRAL_URL = "analyzer.central.url";
       295   -
                */
      -  296   -
               public static final String VFEED_UPDATE_STATUS = "vfeed.update_status";
      -  297   -
       
      -  298  
               /**
      -  299   -
                * The HTTP request method for query last modified date.
      -  300   +  296   +
                * The path to mono, if available.
      +  297  
                */
      +  298   +
               public static final String ANALYZER_ASSEMBLY_MONO_PATH = "analyzer.assembly.mono.path";
      +  299   +
               /**
      +  300   +
                * The path to bundle-audit, if available.
       301   -
               public static final String DOWNLOADER_QUICK_QUERY_TIMESTAMP = "downloader.quick.query.timestamp";
      +
                */
       302   -
           }
      +
               public static final String ANALYZER_BUNDLE_AUDIT_PATH = "analyzer.bundle.audit.path";
       303   -
           //</editor-fold>
      +
               /**
       304   -
       
      +
                * The additional configured zip file extensions, if available.
       305   -
           /**
      +
                */
       306   -
            * The logger.
      +
               public static final String ADDITIONAL_ZIP_EXTENSIONS = "extensions.zip";
       307   -
            */
      -  308  2
           private static final Logger LOGGER = LoggerFactory.getLogger(Settings.class);
      +
               /**
      +  308   +
                * The key to obtain the path to the VFEED data file.
       309   -
           /**
      +
                */
       310   -
            * The properties file location.
      +
               public static final String VFEED_DATA_FILE = "vfeed.data_file";
       311   -
            */
      +
               /**
       312   -
           private static final String PROPERTIES_FILE = "dependencycheck.properties";
      +
                * The key to obtain the VFEED connection string.
       313   -
           /**
      +
                */
       314   -
            * Thread local settings.
      +
               public static final String VFEED_CONNECTION_STRING = "vfeed.connection_string";
       315   -
            */
      -  316  2
           private static final ThreadLocal<Settings> LOCAL_SETTINGS = new ThreadLocal<Settings>();
      +
       
      +  316   +
               /**
       317   -
           /**
      +
                * The key to obtain the base download URL for the VFeed data file.
       318   -
            * The properties.
      +
                */
       319   -
            */
      -  320  4
           private Properties props = null;
      +
               public static final String VFEED_DOWNLOAD_URL = "vfeed.download_url";
      +  320   +
               /**
       321   -
       
      +
                * The key to obtain the download file name for the VFeed data.
       322   -
           /**
      +
                */
       323   -
            * Private constructor for the Settings class. This class loads the properties files.
      +
               public static final String VFEED_DOWNLOAD_FILE = "vfeed.download_file";
       324   -
            *
      +
               /**
       325   -
            * @param propertiesFilePath the path to the base properties file to load
      +
                * The key to obtain the VFeed update status.
       326   -
            */
      -  327  4
           private Settings(String propertiesFilePath) {
      -  328  4
               InputStream in = null;
      -  329  4
               props = new Properties();
      -  330   -
               try {
      -  331  4
                   in = this.getClass().getClassLoader().getResourceAsStream(propertiesFilePath);
      -  332  4
                   props.load(in);
      -  333  0
               } catch (IOException ex) {
      -  334  0
                   LOGGER.error("Unable to load default settings.");
      -  335  0
                   LOGGER.debug("", ex);
      -  336   -
               } finally {
      -  337  4
                   if (in != null) {
      -  338   -
                       try {
      -  339  4
                           in.close();
      -  340  0
                       } catch (IOException ex) {
      -  341  0
                           LOGGER.trace("", ex);
      -  342  4
                       }
      -  343   -
                   }
      -  344   -
               }
      -  345  4
               logProperties("Properties loaded", props);
      -  346  4
           }
      -  347   +
                */
      +  327   +
               public static final String VFEED_UPDATE_STATUS = "vfeed.update_status";
      +  328  
       
      +  329   +
               /**
      +  330   +
                * The HTTP request method for query last modified date.
      +  331   +
                */
      +  332   +
               public static final String DOWNLOADER_QUICK_QUERY_TIMESTAMP = "downloader.quick.query.timestamp";
      +  333   +
           }
      +  334   +
           //</editor-fold>
      +  335   +
       
      +  336   +
           /**
      +  337   +
            * The logger.
      +  338   +
            */
      +  339  1
           private static final Logger LOGGER = LoggerFactory.getLogger(Settings.class);
      +  340   +
           /**
      +  341   +
            * The properties file location.
      +  342   +
            */
      +  343   +
           private static final String PROPERTIES_FILE = "dependencycheck.properties";
      +  344   +
           /**
      +  345   +
            * Thread local settings.
      +  346   +
            */
      +  347  1
           private static final ThreadLocal<Settings> LOCAL_SETTINGS = new ThreadLocal<Settings>();
       348  
           /**
       349   -
            * Initializes the thread local settings object. Note, to use the settings object you must call this method. However, you must
      +
            * The properties.
       350   -
            * also call Settings.cleanup() to properly release resources.
      -  351  
            */
      +  351  2
           private Properties props = null;
       352   -
           public static void initialize() {
      -  353  4
               LOCAL_SETTINGS.set(new Settings(PROPERTIES_FILE));
      -  354  4
           }
      +
       
      +  353   +
           /**
      +  354   +
            * Private constructor for the Settings class. This class loads the
       355   -
       
      +
            * properties files.
       356   -
           /**
      +
            *
       357   -
            * Initializes the thread local settings object. Note, to use the settings object you must call this method. However, you must
      -  358   -
            * also call Settings.cleanup() to properly release resources.
      -  359   -
            *
      -  360  
            * @param propertiesFilePath the path to the base properties file to load
      -  361   +  358  
            */
      +  359  2
           private Settings(String propertiesFilePath) {
      +  360  2
               InputStream in = null;
      +  361  2
               props = new Properties();
       362   -
           public static void initialize(String propertiesFilePath) {
      -  363  0
               LOCAL_SETTINGS.set(new Settings(propertiesFilePath));
      -  364  0
           }
      -  365   -
       
      -  366   -
           /**
      -  367   -
            * Cleans up resources to prevent memory leaks.
      -  368   -
            *
      -  369   -
            */
      -  370   -
           public static void cleanup() {
      -  371  0
               cleanup(true);
      -  372  0
           }
      -  373   -
       
      -  374   -
           /**
      -  375   -
            * Cleans up resources to prevent memory leaks.
      -  376   -
            *
      -  377   -
            * @param deleteTemporary flag indicating whether any temporary directories generated should be removed
      -  378   -
            */
      -  379   -
           public static void cleanup(boolean deleteTemporary) {
      -  380  4
               if (deleteTemporary && tempDirectory != null && tempDirectory.exists()) {
      -  381  4
                   FileUtils.delete(tempDirectory);
      -  382  4
                   if (tempDirectory.exists()) {
      -  383   -
                       try {
      -  384  0
                           Thread.sleep(2000);
      -  385  0
                       } catch (InterruptedException ex) {
      -  386  0
                           LOGGER.trace("ignore", ex);
      -  387  0
                       }
      -  388  0
                       FileUtils.delete(tempDirectory);
      -  389   -
                   }
      -  390   -
               }
      -  391  
               try {
      -  392  4
                   LOCAL_SETTINGS.remove();
      -  393  0
               } catch (Throwable ex) {
      -  394  0
                   LOGGER.debug("Error cleaning up Settings", ex);
      -  395  4
               }
      -  396  4
           }
      -  397   -
       
      -  398   -
           /**
      -  399   -
            * Gets the underlying instance of the Settings object.
      -  400   -
            *
      -  401   -
            * @return the Settings object
      -  402   -
            */
      -  403   -
           public static Settings getInstance() {
      -  404  0
               return LOCAL_SETTINGS.get();
      -  405   -
           }
      -  406   -
       
      -  407   -
           /**
      -  408   -
            * Sets the instance of the Settings object to use in this thread.
      -  409   -
            *
      -  410   -
            * @param instance the instance of the settings object to use in this thread
      -  411   -
            */
      -  412   -
           public static void setInstance(Settings instance) {
      -  413  0
               LOCAL_SETTINGS.set(instance);
      -  414  0
           }
      -  415   -
       
      -  416   -
           /**
      -  417   -
            * Logs the properties. This will not log any properties that contain 'password' in the key.
      -  418   -
            *
      -  419   -
            * @param header the header to print with the log message
      -  420   -
            * @param properties the properties to log
      -  421   -
            */
      -  422   -
           private static void logProperties(String header, Properties properties) {
      -  423  6
               if (LOGGER.isDebugEnabled()) {
      -  424  0
                   final StringWriter sw = new StringWriter();
      -  425  0
                   PrintWriter pw = null;
      -  426   -
                   try {
      -  427  0
                       pw = new PrintWriter(sw);
      -  428  0
                       pw.format("%s:%n%n", header);
      -  429  0
                       final Enumeration<?> e = properties.propertyNames();
      -  430  0
                       while (e.hasMoreElements()) {
      -  431  0
                           final String key = (String) e.nextElement();
      -  432  0
                           if (key.contains("password")) {
      -  433  0
                               pw.format("%s='*****'%n", key);
      -  434   -
                           } else {
      -  435  0
                               final String value = properties.getProperty(key);
      -  436  0
                               if (value != null) {
      -  437  0
                                   pw.format("%s='%s'%n", key, value);
      -  438   -
                               }
      -  439   -
                           }
      -  440  0
                       }
      -  441  0
                       pw.flush();
      -  442  0
                       LOGGER.debug(sw.toString());
      -  443   -
                   } finally {
      -  444  0
                       if (pw != null) {
      -  445  0
                           pw.close();
      -  446   -
                       }
      -  447   +  363  2
                   in = this.getClass().getClassLoader().getResourceAsStream(propertiesFilePath);
      +  364  2
                   props.load(in);
      +  365  0
               } catch (IOException ex) {
      +  366  0
                   LOGGER.error("Unable to load default settings.");
      +  367  0
                   LOGGER.debug("", ex);
      +  368   +
               } finally {
      +  369  2
                   if (in != null) {
      +  370   +
                       try {
      +  371  2
                           in.close();
      +  372  0
                       } catch (IOException ex) {
      +  373  0
                           LOGGER.trace("", ex);
      +  374  2
                       }
      +  375  
                   }
      -  448   -
       
      -  449   +  376  
               }
      -  450  6
           }
      -  451   +  377  2
               logProperties("Properties loaded", props);
      +  378  2
           }
      +  379  
       
      -  452   +  380  
           /**
      +  381   +
            * Initializes the thread local settings object. Note, to use the settings
      +  382   +
            * object you must call this method. However, you must also call
      +  383   +
            * Settings.cleanup() to properly release resources.
      +  384   +
            */
      +  385   +
           public static void initialize() {
      +  386  2
               LOCAL_SETTINGS.set(new Settings(PROPERTIES_FILE));
      +  387  2
           }
      +  388   +
       
      +  389   +
           /**
      +  390   +
            * Initializes the thread local settings object. Note, to use the settings
      +  391   +
            * object you must call this method. However, you must also call
      +  392   +
            * Settings.cleanup() to properly release resources.
      +  393   +
            *
      +  394   +
            * @param propertiesFilePath the path to the base properties file to load
      +  395   +
            */
      +  396   +
           public static void initialize(String propertiesFilePath) {
      +  397  0
               LOCAL_SETTINGS.set(new Settings(propertiesFilePath));
      +  398  0
           }
      +  399   +
       
      +  400   +
           /**
      +  401   +
            * Cleans up resources to prevent memory leaks.
      +  402   +
            *
      +  403   +
            */
      +  404   +
           public static void cleanup() {
      +  405  0
               cleanup(true);
      +  406  0
           }
      +  407   +
       
      +  408   +
           /**
      +  409   +
            * Cleans up resources to prevent memory leaks.
      +  410   +
            *
      +  411   +
            * @param deleteTemporary flag indicating whether any temporary directories
      +  412   +
            * generated should be removed
      +  413   +
            */
      +  414   +
           public static void cleanup(boolean deleteTemporary) {
      +  415  2
               if (deleteTemporary && tempDirectory != null && tempDirectory.exists()) {
      +  416  2
                   FileUtils.delete(tempDirectory);
      +  417  2
                   if (tempDirectory.exists()) {
      +  418   +
                       try {
      +  419  0
                           Thread.sleep(2000);
      +  420  0
                       } catch (InterruptedException ex) {
      +  421  0
                           LOGGER.trace("ignore", ex);
      +  422  0
                       }
      +  423  0
                       FileUtils.delete(tempDirectory);
      +  424   +
                   }
      +  425   +
               }
      +  426   +
               try {
      +  427  2
                   LOCAL_SETTINGS.remove();
      +  428  0
               } catch (Throwable ex) {
      +  429  0
                   LOGGER.debug("Error cleaning up Settings", ex);
      +  430  2
               }
      +  431  2
           }
      +  432   +
       
      +  433   +
           /**
      +  434   +
            * Gets the underlying instance of the Settings object.
      +  435   +
            *
      +  436   +
            * @return the Settings object
      +  437   +
            */
      +  438   +
           public static Settings getInstance() {
      +  439  0
               return LOCAL_SETTINGS.get();
      +  440   +
           }
      +  441   +
       
      +  442   +
           /**
      +  443   +
            * Sets the instance of the Settings object to use in this thread.
      +  444   +
            *
      +  445   +
            * @param instance the instance of the settings object to use in this thread
      +  446   +
            */
      +  447   +
           public static void setInstance(Settings instance) {
      +  448  0
               LOCAL_SETTINGS.set(instance);
      +  449  0
           }
      +  450   +
       
      +  451   +
           /**
      +  452   +
            * Logs the properties. This will not log any properties that contain
       453   -
            * Sets a property value.
      +
            * 'password' in the key.
       454  
            *
       455   -
            * @param key the key for the property
      +
            * @param header the header to print with the log message
       456   -
            * @param value the value for the property
      +
            * @param properties the properties to log
       457  
            */
       458   -
           public static void setString(String key, String value) {
      -  459  16
               LOCAL_SETTINGS.get().props.setProperty(key, value);
      -  460  16
               LOGGER.debug("Setting: {}='{}'", key, value);
      -  461  16
           }
      +
           private static void logProperties(String header, Properties properties) {
      +  459  3
               if (LOGGER.isDebugEnabled()) {
      +  460  0
                   final StringWriter sw = new StringWriter();
      +  461  0
                   PrintWriter pw = null;
       462   -
       
      -  463   -
           /**
      -  464   -
            * Sets a property value only if the value is not null.
      -  465   -
            *
      -  466   -
            * @param key the key for the property
      -  467   -
            * @param value the value for the property
      -  468   -
            */
      -  469   -
           public static void setStringIfNotNull(String key, String value) {
      -  470  2
               if (null != value) {
      -  471  0
                   setString(key, value);
      -  472   -
               }
      -  473  2
           }
      +
                   try {
      +  463  0
                       pw = new PrintWriter(sw);
      +  464  0
                       pw.format("%s:%n%n", header);
      +  465  0
                       final Enumeration<?> e = properties.propertyNames();
      +  466  0
                       while (e.hasMoreElements()) {
      +  467  0
                           final String key = (String) e.nextElement();
      +  468  0
                           if (key.contains("password")) {
      +  469  0
                               pw.format("%s='*****'%n", key);
      +  470   +
                           } else {
      +  471  0
                               final String value = properties.getProperty(key);
      +  472  0
                               if (value != null) {
      +  473  0
                                   pw.format("%s='%s'%n", key, value);
       474   -
       
      +
                               }
       475   -
           /**
      -  476   -
            * Sets a property value only if the value is not null and not empty.
      -  477   -
            *
      -  478   -
            * @param key the key for the property
      +
                           }
      +  476  0
                       }
      +  477  0
                       pw.flush();
      +  478  0
                       LOGGER.debug(sw.toString());
       479   -
            * @param value the value for the property
      -  480   -
            */
      -  481   -
           public static void setStringIfNotEmpty(String key, String value) {
      -  482  2
               if (null != value && !value.isEmpty()) {
      -  483  0
                   setString(key, value);
      +
                   } finally {
      +  480  0
                       if (pw != null) {
      +  481  0
                           pw.close();
      +  482   +
                       }
      +  483   +
                   }
       484   -
               }
      -  485  2
           }
      -  486  
       
      +  485   +
               }
      +  486  3
           }
       487   -
           /**
      +
       
       488   -
            * Sets a property value.
      +
           /**
       489   -
            *
      -  490   -
            * @param key the key for the property
      -  491   -
            * @param value the value for the property
      -  492   -
            */
      -  493   -
           public static void setBoolean(String key, boolean value) {
      -  494  0
               setString(key, Boolean.toString(value));
      -  495  0
           }
      -  496   -
       
      -  497   -
           /**
      -  498   -
            * Sets a property value only if the value is not null.
      -  499   -
            *
      -  500   -
            * @param key the key for the property
      -  501   -
            * @param value the value for the property
      -  502   -
            */
      -  503   -
           public static void setBooleanIfNotNull(String key, Boolean value) {
      -  504  0
               if (null != value) {
      -  505  0
                   setBoolean(key, value);
      -  506   -
               }
      -  507  0
           }
      -  508   -
       
      -  509   -
           /**
      -  510  
            * Sets a property value.
      -  511   +  490  
            *
      -  512   +  491  
            * @param key the key for the property
      -  513   +  492  
            * @param value the value for the property
      -  514   +  493  
            */
      -  515   -
           public static void setInt(String key, int value) {
      -  516  0
               LOCAL_SETTINGS.get().props.setProperty(key, String.valueOf(value));
      -  517  0
               LOGGER.debug("Setting: {}='{}'", key, value);
      -  518  0
           }
      -  519   +  494   +
           public static void setString(String key, String value) {
      +  495  8
               LOCAL_SETTINGS.get().props.setProperty(key, value);
      +  496  8
               LOGGER.debug("Setting: {}='{}'", key, value);
      +  497  8
           }
      +  498  
       
      -  520   +  499  
           /**
      -  521   +  500  
            * Sets a property value only if the value is not null.
      -  522   +  501  
            *
      -  523   +  502  
            * @param key the key for the property
      -  524   +  503  
            * @param value the value for the property
      +  504   +
            */
      +  505   +
           public static void setStringIfNotNull(String key, String value) {
      +  506  1
               if (null != value) {
      +  507  0
                   setString(key, value);
      +  508   +
               }
      +  509  1
           }
      +  510   +
       
      +  511   +
           /**
      +  512   +
            * Sets a property value only if the value is not null and not empty.
      +  513   +
            *
      +  514   +
            * @param key the key for the property
      +  515   +
            * @param value the value for the property
      +  516   +
            */
      +  517   +
           public static void setStringIfNotEmpty(String key, String value) {
      +  518  1
               if (null != value && !value.isEmpty()) {
      +  519  0
                   setString(key, value);
      +  520   +
               }
      +  521  1
           }
      +  522   +
       
      +  523   +
           /**
      +  524   +
            * Sets a property value.
       525   -
            */
      +
            *
       526   -
           public static void setIntIfNotNull(String key, Integer value) {
      -  527  0
               if (null != value) {
      -  528  0
                   setInt(key, value);
      +
            * @param key the key for the property
      +  527   +
            * @param value the value for the property
      +  528   +
            */
       529   -
               }
      -  530  0
           }
      -  531   -
       
      +
           public static void setBoolean(String key, boolean value) {
      +  530  0
               setString(key, Boolean.toString(value));
      +  531  0
           }
       532   -
           /**
      +
       
       533   -
            * Merges a new properties file into the current properties. This method allows for the loading of a user provided properties
      +
           /**
       534   -
            * file.<br><br>
      +
            * Sets a property value only if the value is not null.
       535   -
            * <b>Note</b>: even if using this method - system properties will be loaded before properties loaded from files.
      +
            *
       536   -
            *
      +
            * @param key the key for the property
       537   -
            * @param filePath the path to the properties file to merge.
      +
            * @param value the value for the property
       538   -
            * @throws FileNotFoundException is thrown when the filePath points to a non-existent file
      +
            */
       539   -
            * @throws IOException is thrown when there is an exception loading/merging the properties
      -  540   -
            */
      -  541   -
           public static void mergeProperties(File filePath) throws FileNotFoundException, IOException {
      -  542  0
               FileInputStream fis = null;
      -  543   -
               try {
      -  544  0
                   fis = new FileInputStream(filePath);
      -  545  0
                   mergeProperties(fis);
      +
           public static void setBooleanIfNotNull(String key, Boolean value) {
      +  540  0
               if (null != value) {
      +  541  0
                   setBoolean(key, value);
      +  542   +
               }
      +  543  0
           }
      +  544   +
       
      +  545   +
           /**
       546   -
               } finally {
      -  547  0
                   if (fis != null) {
      +
            * Sets a property value.
      +  547   +
            *
       548   -
                       try {
      -  549  0
                           fis.close();
      -  550  0
                       } catch (IOException ex) {
      -  551  0
                           LOGGER.trace("close error", ex);
      -  552  0
                       }
      -  553   -
                   }
      -  554   -
               }
      -  555  0
           }
      +
            * @param key the key for the property
      +  549   +
            * @param value the value for the property
      +  550   +
            */
      +  551   +
           public static void setInt(String key, int value) {
      +  552  0
               LOCAL_SETTINGS.get().props.setProperty(key, String.valueOf(value));
      +  553  0
               LOGGER.debug("Setting: {}='{}'", key, value);
      +  554  0
           }
      +  555   +
       
       556   -
       
      +
           /**
       557   -
           /**
      +
            * Sets a property value only if the value is not null.
       558   -
            * Merges a new properties file into the current properties. This method allows for the loading of a user provided properties
      +
            *
       559   -
            * file.<br><br>
      +
            * @param key the key for the property
       560   -
            * Note: even if using this method - system properties will be loaded before properties loaded from files.
      +
            * @param value the value for the property
       561   -
            *
      +
            */
       562   -
            * @param filePath the path to the properties file to merge.
      -  563   -
            * @throws FileNotFoundException is thrown when the filePath points to a non-existent file
      -  564   -
            * @throws IOException is thrown when there is an exception loading/merging the properties
      +
           public static void setIntIfNotNull(String key, Integer value) {
      +  563  0
               if (null != value) {
      +  564  0
                   setInt(key, value);
       565   -
            */
      -  566   -
           public static void mergeProperties(String filePath) throws FileNotFoundException, IOException {
      -  567  2
               FileInputStream fis = null;
      +
               }
      +  566  0
           }
      +  567   +
       
       568   -
               try {
      -  569  2
                   fis = new FileInputStream(filePath);
      -  570  2
                   mergeProperties(fis);
      +
           /**
      +  569   +
            * Merges a new properties file into the current properties. This method
      +  570   +
            * allows for the loading of a user provided properties file.<br><br>
       571   -
               } finally {
      -  572  2
                   if (fis != null) {
      +
            * <b>Note</b>: even if using this method - system properties will be loaded
      +  572   +
            * before properties loaded from files.
       573   -
                       try {
      -  574  2
                           fis.close();
      -  575  0
                       } catch (IOException ex) {
      -  576  0
                           LOGGER.trace("close error", ex);
      -  577  2
                       }
      +
            *
      +  574   +
            * @param filePath the path to the properties file to merge.
      +  575   +
            * @throws FileNotFoundException is thrown when the filePath points to a
      +  576   +
            * non-existent file
      +  577   +
            * @throws IOException is thrown when there is an exception loading/merging
       578   -
                   }
      +
            * the properties
       579   -
               }
      -  580  2
           }
      -  581   -
       
      +
            */
      +  580   +
           public static void mergeProperties(File filePath) throws FileNotFoundException, IOException {
      +  581  0
               FileInputStream fis = null;
       582   -
           /**
      -  583   -
            * Merges a new properties file into the current properties. This method allows for the loading of a user provided properties
      -  584   -
            * file.<br><br>
      -  585   -
            * <b>Note</b>: even if using this method - system properties will be loaded before properties loaded from files.
      -  586   -
            *
      -  587   -
            * @param stream an Input Stream pointing at a properties file to merge
      -  588   -
            * @throws IOException is thrown when there is an exception loading/merging the properties
      -  589   -
            */
      -  590   -
           public static void mergeProperties(InputStream stream) throws IOException {
      -  591  2
               LOCAL_SETTINGS.get().props.load(stream);
      -  592  2
               logProperties("Properties updated via merge", LOCAL_SETTINGS.get().props);
      -  593  2
           }
      -  594   -
       
      -  595   -
           /**
      -  596   -
            * Returns a value from the properties file as a File object. If the value was specified as a system property or passed in via
      -  597   -
            * the -Dprop=value argument - this method will return the value from the system properties before the values in the contained
      -  598   -
            * configuration file.
      -  599   -
            *
      -  600   -
            * @param key the key to lookup within the properties file
      -  601   -
            * @return the property from the properties file converted to a File object
      -  602   -
            */
      -  603   -
           public static File getFile(String key) {
      -  604  0
               final String file = getString(key);
      -  605  0
               if (file == null) {
      -  606  0
                   return null;
      -  607   -
               }
      -  608  0
               return new File(file);
      -  609   -
           }
      -  610   -
       
      -  611   -
           /**
      -  612   -
            * Returns a value from the properties file as a File object. If the value was specified as a system property or passed in via
      -  613   -
            * the -Dprop=value argument - this method will return the value from the system properties before the values in the contained
      -  614   -
            * configuration file.
      -  615   -
            *
      -  616   -
            * This method will check the configured base directory and will use this as the base of the file path. Additionally, if the
      -  617   -
            * base directory begins with a leading "[JAR]\" sequence with the path to the folder containing the JAR file containing this
      -  618   -
            * class.
      -  619   -
            *
      -  620   -
            * @param key the key to lookup within the properties file
      -  621   -
            * @return the property from the properties file converted to a File object
      -  622   -
            */
      -  623   -
           protected static File getDataFile(String key) {
      -  624  4
               final String file = getString(key);
      -  625  4
               LOGGER.debug("Settings.getDataFile() - file: '{}'", file);
      -  626  4
               if (file == null) {
      -  627  0
                   return null;
      -  628   -
               }
      -  629  4
               if (file.startsWith("[JAR]")) {
      -  630  0
                   LOGGER.debug("Settings.getDataFile() - transforming filename");
      -  631  0
                   final File jarPath = getJarPath();
      -  632  0
                   LOGGER.debug("Settings.getDataFile() - jar file: '{}'", jarPath.toString());
      -  633  0
                   final File retVal = new File(jarPath, file.substring(6));
      -  634  0
                   LOGGER.debug("Settings.getDataFile() - returning: '{}'", retVal.toString());
      -  635  0
                   return retVal;
      -  636   -
               }
      -  637  4
               return new File(file);
      -  638   -
           }
      -  639   -
       
      -  640   -
           /**
      -  641   -
            * Attempts to retrieve the folder containing the Jar file containing the Settings class.
      -  642   -
            *
      -  643   -
            * @return a File object
      -  644   -
            */
      -  645   -
           private static File getJarPath() {
      -  646  0
               final String jarPath = Settings.class.getProtectionDomain().getCodeSource().getLocation().getPath();
      -  647  0
               String decodedPath = ".";
      -  648  
               try {
      -  649  0
                   decodedPath = URLDecoder.decode(jarPath, "UTF-8");
      -  650  0
               } catch (UnsupportedEncodingException ex) {
      -  651  0
                   LOGGER.trace("", ex);
      -  652  0
               }
      -  653   -
       
      -  654  0
               final File path = new File(decodedPath);
      -  655  0
               if (path.getName().toLowerCase().endsWith(".jar")) {
      -  656  0
                   return path.getParentFile();
      -  657   -
               } else {
      -  658  0
                   return new File(".");
      -  659   +  583  0
                   fis = new FileInputStream(filePath);
      +  584  0
                   mergeProperties(fis);
      +  585   +
               } finally {
      +  586  0
                   if (fis != null) {
      +  587   +
                       try {
      +  588  0
                           fis.close();
      +  589  0
                       } catch (IOException ex) {
      +  590  0
                           LOGGER.trace("close error", ex);
      +  591  0
                       }
      +  592   +
                   }
      +  593  
               }
      -  660   -
           }
      -  661   +  594  0
           }
      +  595  
       
      -  662   +  596  
           /**
      +  597   +
            * Merges a new properties file into the current properties. This method
      +  598   +
            * allows for the loading of a user provided properties file.<br><br>
      +  599   +
            * Note: even if using this method - system properties will be loaded before
      +  600   +
            * properties loaded from files.
      +  601   +
            *
      +  602   +
            * @param filePath the path to the properties file to merge.
      +  603   +
            * @throws FileNotFoundException is thrown when the filePath points to a
      +  604   +
            * non-existent file
      +  605   +
            * @throws IOException is thrown when there is an exception loading/merging
      +  606   +
            * the properties
      +  607   +
            */
      +  608   +
           public static void mergeProperties(String filePath) throws FileNotFoundException, IOException {
      +  609  1
               FileInputStream fis = null;
      +  610   +
               try {
      +  611  1
                   fis = new FileInputStream(filePath);
      +  612  1
                   mergeProperties(fis);
      +  613   +
               } finally {
      +  614  1
                   if (fis != null) {
      +  615   +
                       try {
      +  616  1
                           fis.close();
      +  617  0
                       } catch (IOException ex) {
      +  618  0
                           LOGGER.trace("close error", ex);
      +  619  1
                       }
      +  620   +
                   }
      +  621   +
               }
      +  622  1
           }
      +  623   +
       
      +  624   +
           /**
      +  625   +
            * Merges a new properties file into the current properties. This method
      +  626   +
            * allows for the loading of a user provided properties file.<br><br>
      +  627   +
            * <b>Note</b>: even if using this method - system properties will be loaded
      +  628   +
            * before properties loaded from files.
      +  629   +
            *
      +  630   +
            * @param stream an Input Stream pointing at a properties file to merge
      +  631   +
            * @throws IOException is thrown when there is an exception loading/merging
      +  632   +
            * the properties
      +  633   +
            */
      +  634   +
           public static void mergeProperties(InputStream stream) throws IOException {
      +  635  1
               LOCAL_SETTINGS.get().props.load(stream);
      +  636  1
               logProperties("Properties updated via merge", LOCAL_SETTINGS.get().props);
      +  637  1
           }
      +  638   +
       
      +  639   +
           /**
      +  640   +
            * Returns a value from the properties file as a File object. If the value
      +  641   +
            * was specified as a system property or passed in via the -Dprop=value
      +  642   +
            * argument - this method will return the value from the system properties
      +  643   +
            * before the values in the contained configuration file.
      +  644   +
            *
      +  645   +
            * @param key the key to lookup within the properties file
      +  646   +
            * @return the property from the properties file converted to a File object
      +  647   +
            */
      +  648   +
           public static File getFile(String key) {
      +  649  0
               final String file = getString(key);
      +  650  0
               if (file == null) {
      +  651  0
                   return null;
      +  652   +
               }
      +  653  0
               return new File(file);
      +  654   +
           }
      +  655   +
       
      +  656   +
           /**
      +  657   +
            * Returns a value from the properties file as a File object. If the value
      +  658   +
            * was specified as a system property or passed in via the -Dprop=value
      +  659   +
            * argument - this method will return the value from the system properties
      +  660   +
            * before the values in the contained configuration file.
      +  661   +
            *
      +  662   +
            * This method will check the configured base directory and will use this as
       663   -
            * Returns a value from the properties file. If the value was specified as a system property or passed in via the -Dprop=value
      +
            * the base of the file path. Additionally, if the base directory begins
       664   -
            * argument - this method will return the value from the system properties before the values in the contained configuration
      +
            * with a leading "[JAR]\" sequence with the path to the folder containing
       665   -
            * file.
      +
            * the JAR file containing this class.
       666  
            *
       667  
            * @param key the key to lookup within the properties file
       668   -
            * @param defaultValue the default value for the requested property
      +
            * @return the property from the properties file converted to a File object
       669   -
            * @return the property from the properties file
      +
            */
       670   -
            */
      -  671   -
           public static String getString(String key, String defaultValue) {
      -  672  12
               final String str = System.getProperty(key, LOCAL_SETTINGS.get().props.getProperty(key, defaultValue));
      -  673  12
               return str;
      -  674   -
           }
      +
           protected static File getDataFile(String key) {
      +  671  2
               final String file = getString(key);
      +  672  2
               LOGGER.debug("Settings.getDataFile() - file: '{}'", file);
      +  673  2
               if (file == null) {
      +  674  0
                   return null;
       675   -
       
      -  676   -
           /**
      -  677   -
            * A reference to the temporary directory; used incase it needs to be deleted during cleanup.
      -  678   -
            */
      -  679  2
           private static File tempDirectory = null;
      -  680   -
       
      -  681   -
           /**
      -  682   -
            * Returns the temporary directory.
      +
               }
      +  676  2
               if (file.startsWith("[JAR]")) {
      +  677  0
                   LOGGER.debug("Settings.getDataFile() - transforming filename");
      +  678  0
                   final File jarPath = getJarPath();
      +  679  0
                   LOGGER.debug("Settings.getDataFile() - jar file: '{}'", jarPath.toString());
      +  680  0
                   final File retVal = new File(jarPath, file.substring(6));
      +  681  0
                   LOGGER.debug("Settings.getDataFile() - returning: '{}'", retVal.toString());
      +  682  0
                   return retVal;
       683   -
            *
      -  684   -
            * @return the temporary directory
      +
               }
      +  684  2
               return new File(file);
       685   -
            * @throws java.io.IOException thrown if the temporary directory does not exist and cannot be created
      +
           }
       686   -
            */
      +
       
       687   -
           public static File getTempDirectory() throws IOException {
      -  688  4
               final File tmpDir = new File(Settings.getString(Settings.KEYS.TEMP_DIRECTORY, System.getProperty("java.io.tmpdir")), "dctemp");
      -  689  4
               if (!tmpDir.exists() && !tmpDir.mkdirs()) {
      -  690  0
                   final String msg = String.format("Unable to make a temporary folder '%s'", tmpDir.getPath());
      -  691  0
                   throw new IOException(msg);
      +
           /**
      +  688   +
            * Attempts to retrieve the folder containing the Jar file containing the
      +  689   +
            * Settings class.
      +  690   +
            *
      +  691   +
            * @return a File object
       692   -
               }
      -  693  4
               tempDirectory = tmpDir;
      -  694  4
               return tmpDir;
      -  695   -
           }
      +
            */
      +  693   +
           private static File getJarPath() {
      +  694  0
               final String jarPath = Settings.class.getProtectionDomain().getCodeSource().getLocation().getPath();
      +  695  0
               String decodedPath = ".";
       696   -
       
      -  697   -
           /**
      -  698   -
            * Returns a value from the properties file. If the value was specified as a system property or passed in via the -Dprop=value
      -  699   -
            * argument - this method will return the value from the system properties before the values in the contained configuration
      -  700   -
            * file.
      +
               try {
      +  697  0
                   decodedPath = URLDecoder.decode(jarPath, "UTF-8");
      +  698  0
               } catch (UnsupportedEncodingException ex) {
      +  699  0
                   LOGGER.trace("", ex);
      +  700  0
               }
       701   -
            *
      -  702   -
            * @param key the key to lookup within the properties file
      -  703   -
            * @return the property from the properties file
      -  704   -
            */
      +
       
      +  702  0
               final File path = new File(decodedPath);
      +  703  0
               if (path.getName().toLowerCase().endsWith(".jar")) {
      +  704  0
                   return path.getParentFile();
       705   -
           public static String getString(String key) {
      -  706  38
               return System.getProperty(key, LOCAL_SETTINGS.get().props.getProperty(key));
      +
               } else {
      +  706  0
                   return new File(".");
       707   -
           }
      -  708   -
       
      -  709   -
           /**
      -  710   -
            * Removes a property from the local properties collection. This is mainly used in test cases.
      -  711   -
            *
      -  712   -
            * @param key the property key to remove
      -  713   -
            */
      -  714   -
           public static void removeProperty(String key) {
      -  715  2
               LOCAL_SETTINGS.get().props.remove(key);
      -  716  2
           }
      -  717   -
       
      -  718   -
           /**
      -  719   -
            * Returns an int value from the properties file. If the value was specified as a system property or passed in via the
      -  720   -
            * -Dprop=value argument - this method will return the value from the system properties before the values in the contained
      -  721   -
            * configuration file.
      -  722   -
            *
      -  723   -
            * @param key the key to lookup within the properties file
      -  724   -
            * @return the property from the properties file
      -  725   -
            * @throws InvalidSettingException is thrown if there is an error retrieving the setting
      -  726   -
            */
      -  727   -
           public static int getInt(String key) throws InvalidSettingException {
      -  728   -
               try {
      -  729  2
                   return Integer.parseInt(Settings.getString(key));
      -  730  0
               } catch (NumberFormatException ex) {
      -  731  0
                   throw new InvalidSettingException("Could not convert property '" + key + "' to an int.", ex);
      -  732  
               }
      -  733   +  708  
           }
      -  734   +  709  
       
      -  735   +  710  
           /**
      -  736   -
            * Returns an int value from the properties file. If the value was specified as a system property or passed in via the
      -  737   -
            * -Dprop=value argument - this method will return the value from the system properties before the values in the contained
      -  738   -
            * configuration file.
      -  739   +  711   +
            * Returns a value from the properties file. If the value was specified as a
      +  712   +
            * system property or passed in via the -Dprop=value argument - this method
      +  713   +
            * will return the value from the system properties before the values in the
      +  714   +
            * contained configuration file.
      +  715  
            *
      -  740   +  716  
            * @param key the key to lookup within the properties file
      -  741   -
            * @param defaultValue the default value to return
      -  742   -
            * @return the property from the properties file or the defaultValue if the property does not exist or cannot be converted to
      -  743   -
            * an integer
      -  744   -
            */
      -  745   -
           public static int getInt(String key, int defaultValue) {
      -  746   -
               int value;
      -  747   -
               try {
      -  748  2
                   value = Integer.parseInt(Settings.getString(key));
      -  749  2
               } catch (NumberFormatException ex) {
      -  750  2
                   if (!Settings.getString(key, "").isEmpty()) {
      -  751  2
                       LOGGER.debug("Could not convert property '{}={}' to an int; using {} instead.", key, Settings.getString(key), defaultValue);
      -  752   -
                   }
      -  753  2
                   value = defaultValue;
      -  754  0
               }
      -  755  2
               return value;
      -  756   -
           }
      -  757   -
       
      -  758   -
           /**
      -  759   -
            * Returns a long value from the properties file. If the value was specified as a system property or passed in via the
      -  760   -
            * -Dprop=value argument - this method will return the value from the system properties before the values in the contained
      -  761   -
            * configuration file.
      -  762   -
            *
      -  763   -
            * @param key the key to lookup within the properties file
      -  764   +  717   +
            * @param defaultValue the default value for the requested property
      +  718  
            * @return the property from the properties file
      +  719   +
            */
      +  720   +
           public static String getString(String key, String defaultValue) {
      +  721  6
               final String str = System.getProperty(key, LOCAL_SETTINGS.get().props.getProperty(key, defaultValue));
      +  722  6
               return str;
      +  723   +
           }
      +  724   +
       
      +  725   +
           /**
      +  726   +
            * A reference to the temporary directory; used incase it needs to be
      +  727   +
            * deleted during cleanup.
      +  728   +
            */
      +  729  1
           private static File tempDirectory = null;
      +  730   +
       
      +  731   +
           /**
      +  732   +
            * Returns the temporary directory.
      +  733   +
            *
      +  734   +
            * @return the temporary directory
      +  735   +
            * @throws java.io.IOException thrown if the temporary directory does not
      +  736   +
            * exist and cannot be created
      +  737   +
            */
      +  738   +
           public static File getTempDirectory() throws IOException {
      +  739  2
               final File tmpDir = new File(Settings.getString(Settings.KEYS.TEMP_DIRECTORY, System.getProperty("java.io.tmpdir")), "dctemp");
      +  740  2
               if (!tmpDir.exists() && !tmpDir.mkdirs()) {
      +  741  0
                   final String msg = String.format("Unable to make a temporary folder '%s'", tmpDir.getPath());
      +  742  0
                   throw new IOException(msg);
      +  743   +
               }
      +  744  2
               tempDirectory = tmpDir;
      +  745  2
               return tmpDir;
      +  746   +
           }
      +  747   +
       
      +  748   +
           /**
      +  749   +
            * Returns a value from the properties file. If the value was specified as a
      +  750   +
            * system property or passed in via the -Dprop=value argument - this method
      +  751   +
            * will return the value from the system properties before the values in the
      +  752   +
            * contained configuration file.
      +  753   +
            *
      +  754   +
            * @param key the key to lookup within the properties file
      +  755   +
            * @return the property from the properties file
      +  756   +
            */
      +  757   +
           public static String getString(String key) {
      +  758  19
               return System.getProperty(key, LOCAL_SETTINGS.get().props.getProperty(key));
      +  759   +
           }
      +  760   +
       
      +  761   +
           /**
      +  762   +
            * Removes a property from the local properties collection. This is mainly
      +  763   +
            * used in test cases.
      +  764   +
            *
       765   -
            * @throws InvalidSettingException is thrown if there is an error retrieving the setting
      +
            * @param key the property key to remove
       766  
            */
       767   -
           public static long getLong(String key) throws InvalidSettingException {
      -  768   -
               try {
      -  769  2
                   return Long.parseLong(Settings.getString(key));
      -  770  0
               } catch (NumberFormatException ex) {
      -  771  0
                   throw new InvalidSettingException("Could not convert property '" + key + "' to a long.", ex);
      +
           public static void removeProperty(String key) {
      +  768  1
               LOCAL_SETTINGS.get().props.remove(key);
      +  769  1
           }
      +  770   +
       
      +  771   +
           /**
       772   -
               }
      +
            * Returns an int value from the properties file. If the value was specified
       773   -
           }
      +
            * as a system property or passed in via the -Dprop=value argument - this
       774   -
       
      +
            * method will return the value from the system properties before the values
       775   -
           /**
      +
            * in the contained configuration file.
       776   -
            * Returns a boolean value from the properties file. If the value was specified as a system property or passed in via the
      +
            *
       777   -
            * <code>-Dprop=value</code> argument this method will return the value from the system properties before the values in the
      +
            * @param key the key to lookup within the properties file
       778   -
            * contained configuration file.
      +
            * @return the property from the properties file
       779   -
            *
      +
            * @throws InvalidSettingException is thrown if there is an error retrieving
       780   -
            * @param key the key to lookup within the properties file
      +
            * the setting
       781   -
            * @return the property from the properties file
      +
            */
       782   -
            * @throws InvalidSettingException is thrown if there is an error retrieving the setting
      +
           public static int getInt(String key) throws InvalidSettingException {
       783   -
            */
      -  784   -
           public static boolean getBoolean(String key) throws InvalidSettingException {
      -  785  2
               return Boolean.parseBoolean(Settings.getString(key));
      -  786   -
           }
      +
               try {
      +  784  1
                   return Integer.parseInt(Settings.getString(key));
      +  785  0
               } catch (NumberFormatException ex) {
      +  786  0
                   throw new InvalidSettingException("Could not convert property '" + key + "' to an int.", ex);
       787   -
       
      +
               }
       788   -
           /**
      +
           }
       789   -
            * Returns a boolean value from the properties file. If the value was specified as a system property or passed in via the
      +
       
       790   -
            * <code>-Dprop=value</code> argument this method will return the value from the system properties before the values in the
      +
           /**
       791   -
            * contained configuration file.
      +
            * Returns an int value from the properties file. If the value was specified
       792   -
            *
      +
            * as a system property or passed in via the -Dprop=value argument - this
       793   -
            * @param key the key to lookup within the properties file
      +
            * method will return the value from the system properties before the values
       794   -
            * @param defaultValue the default value to return if the setting does not exist
      +
            * in the contained configuration file.
       795   -
            * @return the property from the properties file
      +
            *
       796   -
            * @throws InvalidSettingException is thrown if there is an error retrieving the setting
      +
            * @param key the key to lookup within the properties file
       797   -
            */
      +
            * @param defaultValue the default value to return
       798   -
           public static boolean getBoolean(String key, boolean defaultValue) throws InvalidSettingException {
      -  799  2
               return Boolean.parseBoolean(Settings.getString(key, Boolean.toString(defaultValue)));
      +
            * @return the property from the properties file or the defaultValue if the
      +  799   +
            * property does not exist or cannot be converted to an integer
       800   -
           }
      +
            */
       801   -
       
      +
           public static int getInt(String key, int defaultValue) {
       802   -
           /**
      +
               int value;
       803   -
            * Returns a connection string from the configured properties. If the connection string contains a %s, this method will
      -  804   -
            * determine the 'data' directory and replace the %s with the path to the data directory. If the data directory does not
      -  805   -
            * exists it will be created.
      -  806   -
            *
      -  807   -
            * @param connectionStringKey the property file key for the connection string
      +
               try {
      +  804  1
                   value = Integer.parseInt(Settings.getString(key));
      +  805  1
               } catch (NumberFormatException ex) {
      +  806  1
                   if (!Settings.getString(key, "").isEmpty()) {
      +  807  1
                       LOGGER.debug("Could not convert property '{}={}' to an int; using {} instead.", key, Settings.getString(key), defaultValue);
       808   -
            * @param dbFileNameKey the settings key for the db filename
      -  809   -
            * @return the connection string
      -  810   -
            * @throws IOException thrown the data directory cannot be created
      -  811   -
            * @throws InvalidSettingException thrown if there is an invalid setting
      +
                   }
      +  809  1
                   value = defaultValue;
      +  810  0
               }
      +  811  1
               return value;
       812   -
            */
      +
           }
       813   -
           public static String getConnectionString(String connectionStringKey, String dbFileNameKey)
      -  814   -
                   throws IOException, InvalidSettingException {
      -  815  4
               final String connStr = Settings.getString(connectionStringKey);
      -  816  4
               if (connStr == null) {
      -  817  2
                   final String msg = String.format("Invalid properties file; %s is missing.", connectionStringKey);
      -  818  2
                   throw new InvalidSettingException(msg);
      -  819   -
               }
      -  820  2
               if (connStr.contains("%s")) {
      -  821  2
                   final File directory = getDataDirectory();
      -  822  2
                   String fileName = null;
      -  823  2
                   if (dbFileNameKey != null) {
      -  824  2
                       fileName = Settings.getString(dbFileNameKey);
      -  825   -
                   }
      -  826  2
                   if (fileName == null) {
      -  827  0
                       final String msg = String.format("Invalid properties file to get a file based connection string; '%s' must be defined.",
      -  828   -
                               dbFileNameKey);
      -  829  0
                       throw new InvalidSettingException(msg);
      -  830   -
                   }
      -  831  2
                   if (connStr.startsWith("jdbc:h2:file:") && fileName.endsWith(".h2.db")) {
      -  832  2
                       fileName = fileName.substring(0, fileName.length() - 6);
      -  833   -
                   }
      -  834   -
                   // yes, for H2 this path won't actually exists - but this is sufficient to get the value needed
      -  835  2
                   final File dbFile = new File(directory, fileName);
      -  836  2
                   final String cString = String.format(connStr, dbFile.getCanonicalPath());
      -  837  2
                   LOGGER.debug("Connection String: '{}'", cString);
      -  838  2
                   return cString;
      -  839   -
               }
      -  840  0
               return connStr;
      -  841   -
           }
      -  842  
       
      -  843   +  814  
           /**
      -  844   -
            * Retrieves the directory that the JAR file exists in so that we can ensure we always use a common data directory for the
      -  845   -
            * embedded H2 database. This is public solely for some unit tests; otherwise this should be private.
      -  846   +  815   +
            * Returns a long value from the properties file. If the value was specified
      +  816   +
            * as a system property or passed in via the -Dprop=value argument - this
      +  817   +
            * method will return the value from the system properties before the values
      +  818   +
            * in the contained configuration file.
      +  819  
            *
      -  847   -
            * @return the data directory to store data files
      -  848   -
            * @throws IOException is thrown if an IOException occurs of course...
      -  849   +  820   +
            * @param key the key to lookup within the properties file
      +  821   +
            * @return the property from the properties file
      +  822   +
            * @throws InvalidSettingException is thrown if there is an error retrieving
      +  823   +
            * the setting
      +  824  
            */
      -  850   -
           public static File getDataDirectory() throws IOException {
      -  851  2
               final File path = Settings.getDataFile(Settings.KEYS.DATA_DIRECTORY);
      -  852  2
               if (path.exists() || path.mkdirs()) {
      -  853  2
                   return path;
      -  854   +  825   +
           public static long getLong(String key) throws InvalidSettingException {
      +  826   +
               try {
      +  827  1
                   return Long.parseLong(Settings.getString(key));
      +  828  0
               } catch (NumberFormatException ex) {
      +  829  0
                   throw new InvalidSettingException("Could not convert property '" + key + "' to a long.", ex);
      +  830  
               }
      -  855  0
               throw new IOException(String.format("Unable to create the data directory '%s'", path.getAbsolutePath()));
      -  856   +  831  
           }
      +  832   +
       
      +  833   +
           /**
      +  834   +
            * Returns a boolean value from the properties file. If the value was
      +  835   +
            * specified as a system property or passed in via the
      +  836   +
            * <code>-Dprop=value</code> argument this method will return the value from
      +  837   +
            * the system properties before the values in the contained configuration
      +  838   +
            * file.
      +  839   +
            *
      +  840   +
            * @param key the key to lookup within the properties file
      +  841   +
            * @return the property from the properties file
      +  842   +
            * @throws InvalidSettingException is thrown if there is an error retrieving
      +  843   +
            * the setting
      +  844   +
            */
      +  845   +
           public static boolean getBoolean(String key) throws InvalidSettingException {
      +  846  1
               return Boolean.parseBoolean(Settings.getString(key));
      +  847   +
           }
      +  848   +
       
      +  849   +
           /**
      +  850   +
            * Returns a boolean value from the properties file. If the value was
      +  851   +
            * specified as a system property or passed in via the
      +  852   +
            * <code>-Dprop=value</code> argument this method will return the value from
      +  853   +
            * the system properties before the values in the contained configuration
      +  854   +
            * file.
      +  855   +
            *
      +  856   +
            * @param key the key to lookup within the properties file
       857   +
            * @param defaultValue the default value to return if the setting does not
      +  858   +
            * exist
      +  859   +
            * @return the property from the properties file
      +  860   +
            * @throws InvalidSettingException is thrown if there is an error retrieving
      +  861   +
            * the setting
      +  862   +
            */
      +  863   +
           public static boolean getBoolean(String key, boolean defaultValue) throws InvalidSettingException {
      +  864  1
               return Boolean.parseBoolean(Settings.getString(key, Boolean.toString(defaultValue)));
      +  865   +
           }
      +  866   +
       
      +  867   +
           /**
      +  868   +
            * Returns a connection string from the configured properties. If the
      +  869   +
            * connection string contains a %s, this method will determine the 'data'
      +  870   +
            * directory and replace the %s with the path to the data directory. If the
      +  871   +
            * data directory does not exists it will be created.
      +  872   +
            *
      +  873   +
            * @param connectionStringKey the property file key for the connection
      +  874   +
            * string
      +  875   +
            * @param dbFileNameKey the settings key for the db filename
      +  876   +
            * @return the connection string
      +  877   +
            * @throws IOException thrown the data directory cannot be created
      +  878   +
            * @throws InvalidSettingException thrown if there is an invalid setting
      +  879   +
            */
      +  880   +
           public static String getConnectionString(String connectionStringKey, String dbFileNameKey)
      +  881   +
                   throws IOException, InvalidSettingException {
      +  882  2
               final String connStr = Settings.getString(connectionStringKey);
      +  883  2
               if (connStr == null) {
      +  884  1
                   final String msg = String.format("Invalid properties file; %s is missing.", connectionStringKey);
      +  885  1
                   throw new InvalidSettingException(msg);
      +  886   +
               }
      +  887  1
               if (connStr.contains("%s")) {
      +  888  1
                   final File directory = getDataDirectory();
      +  889  1
                   String fileName = null;
      +  890  1
                   if (dbFileNameKey != null) {
      +  891  1
                       fileName = Settings.getString(dbFileNameKey);
      +  892   +
                   }
      +  893  1
                   if (fileName == null) {
      +  894  0
                       final String msg = String.format("Invalid properties file to get a file based connection string; '%s' must be defined.",
      +  895   +
                               dbFileNameKey);
      +  896  0
                       throw new InvalidSettingException(msg);
      +  897   +
                   }
      +  898  1
                   if (connStr.startsWith("jdbc:h2:file:") && fileName.endsWith(".h2.db")) {
      +  899  1
                       fileName = fileName.substring(0, fileName.length() - 6);
      +  900   +
                   }
      +  901   +
                   // yes, for H2 this path won't actually exists - but this is sufficient to get the value needed
      +  902  1
                   final File dbFile = new File(directory, fileName);
      +  903  1
                   final String cString = String.format(connStr, dbFile.getCanonicalPath());
      +  904  1
                   LOGGER.debug("Connection String: '{}'", cString);
      +  905  1
                   return cString;
      +  906   +
               }
      +  907  0
               return connStr;
      +  908   +
           }
      +  909   +
       
      +  910   +
           /**
      +  911   +
            * Retrieves the directory that the JAR file exists in so that we can ensure
      +  912   +
            * we always use a common data directory for the embedded H2 database. This
      +  913   +
            * is public solely for some unit tests; otherwise this should be private.
      +  914   +
            *
      +  915   +
            * @return the data directory to store data files
      +  916   +
            * @throws IOException is thrown if an IOException occurs of course...
      +  917   +
            */
      +  918   +
           public static File getDataDirectory() throws IOException {
      +  919  1
               final File path = Settings.getDataFile(Settings.KEYS.DATA_DIRECTORY);
      +  920  1
               if (path.exists() || path.mkdirs()) {
      +  921  1
                   return path;
      +  922   +
               }
      +  923  0
               throw new IOException(String.format("Unable to create the data directory '%s'", path.getAbsolutePath()));
      +  924   +
           }
      +  925  
       }
      - + diff --git a/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.URLConnectionFactory.html b/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.URLConnectionFactory.html index 382e4075d..98050befb 100644 --- a/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.URLConnectionFactory.html +++ b/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.URLConnectionFactory.html @@ -12,8 +12,8 @@
       
      - - + +
      Classes in this File Line Coverage Branch Coverage Complexity
      URLConnectionFactory
      0%
      0/57
      0%
      0/42
      7.4
      URLConnectionFactory$1
      0%
      0/4
      0%
      0/2
      7.4
      URLConnectionFactory
      0%
      0/70
      0%
      0/44
      6.833
      URLConnectionFactory$1
      0%
      0/4
      0%
      0/2
      6.833
       
      @@ -79,219 +79,282 @@  30  
       import java.net.URL;
       31   -
       
      +
       import java.security.KeyManagementException;
       32   -
       /**
      +
       import java.security.NoSuchAlgorithmException;
       33   -
        * A URLConnection Factory to create new connections. This encapsulates several configuration checks to ensure that the connection
      +
       import javax.net.ssl.HttpsURLConnection;
       34   -
        * uses the correct proxy settings.
      +
       import org.slf4j.Logger;
       35   -
        *
      +
       import org.slf4j.LoggerFactory;
       36   -
        * @author Jeremy Long
      -  37   -
        */
      -  38   -
       public final class URLConnectionFactory {
      -  39  
       
      +  37   +
       /**
      +  38   +
        * A URLConnection Factory to create new connections. This encapsulates several
      +  39   +
        * configuration checks to ensure that the connection uses the correct proxy
       40   -
           /**
      +
        * settings.
       41   -
            * Private constructor for this factory.
      +
        *
       42   -
            */
      -  43  0
           private URLConnectionFactory() {
      -  44  0
           }
      +
        * @author Jeremy Long
      +  43   +
        */
      +  44   +
       public final class URLConnectionFactory {
       45  
       
       46  
           /**
       47   -
            * Utility method to create an HttpURLConnection. If the application is configured to use a proxy this method will retrieve
      +
            * The logger.
       48   -
            * the proxy settings and use them when setting up the connection.
      -  49   -
            *
      +
            */
      +  49  0
           private static final Logger LOGGER = LoggerFactory.getLogger(URLConnectionFactory.class);
       50   -
            * @param url the url to connect to
      +
       
       51   -
            * @return an HttpURLConnection
      +
           /**
       52   -
            * @throws URLConnectionFailureException thrown if there is an exception
      +
            * Private constructor for this factory.
       53  
            */
      -  54   -
           @SuppressFBWarnings(value = "RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE", justification = "Just being extra safe")
      -  55   -
           public static HttpURLConnection createHttpURLConnection(URL url) throws URLConnectionFailureException {
      -  56  0
               HttpURLConnection conn = null;
      -  57  0
               final String proxyUrl = Settings.getString(Settings.KEYS.PROXY_SERVER);
      +  54  0
           private URLConnectionFactory() {
      +  55  0
           }
      +  56   +
       
      +  57   +
           /**
       58   -
       
      +
            * Utility method to create an HttpURLConnection. If the application is
       59   -
               try {
      -  60  0
                   if (proxyUrl != null && !matchNonProxy(url)) {
      -  61  0
                       final int proxyPort = Settings.getInt(Settings.KEYS.PROXY_PORT);
      -  62  0
                       final SocketAddress address = new InetSocketAddress(proxyUrl, proxyPort);
      -  63   -
       
      -  64  0
                       final String username = Settings.getString(Settings.KEYS.PROXY_USERNAME);
      -  65  0
                       final String password = Settings.getString(Settings.KEYS.PROXY_PASSWORD);
      -  66   -
       
      -  67  0
                       if (username != null && password != null) {
      -  68  0
                           final Authenticator auth = new Authenticator() {
      -  69   -
                               @Override
      -  70   -
                               public PasswordAuthentication getPasswordAuthentication() {
      -  71  0
                                   if (getRequestorType().equals(Authenticator.RequestorType.PROXY)) {
      -  72  0
                                       return new PasswordAuthentication(username, password.toCharArray());
      -  73   -
                                   }
      -  74  0
                                   return super.getPasswordAuthentication();
      -  75   -
                               }
      -  76   -
                           };
      -  77  0
                           Authenticator.setDefault(auth);
      -  78   -
                       }
      -  79   -
       
      -  80  0
                       final Proxy proxy = new Proxy(Proxy.Type.HTTP, address);
      -  81  0
                       conn = (HttpURLConnection) url.openConnection(proxy);
      -  82  0
                   } else {
      -  83  0
                       conn = (HttpURLConnection) url.openConnection();
      -  84   -
                   }
      -  85  0
                   final int timeout = Settings.getInt(Settings.KEYS.CONNECTION_TIMEOUT, 10000);
      -  86  0
                   conn.setConnectTimeout(timeout);
      -  87  0
                   conn.setInstanceFollowRedirects(true);
      -  88  0
               } catch (IOException ex) {
      -  89  0
                   if (conn != null) {
      -  90   -
                       try {
      -  91  0
                           conn.disconnect();
      -  92   -
                       } finally {
      -  93  0
                           conn = null;
      -  94  0
                       }
      -  95   -
                   }
      -  96  0
                   throw new URLConnectionFailureException("Error getting connection.", ex);
      -  97  0
               }
      -  98  0
               return conn;
      -  99   -
           }
      -  100   -
       
      -  101   -
           /**
      -  102   -
            * Check if hostname matches nonProxy settings
      -  103   +
            * configured to use a proxy this method will retrieve the proxy settings
      +  60   +
            * and use them when setting up the connection.
      +  61  
            *
      -  104   +  62  
            * @param url the url to connect to
      -  105   -
            * @return matching result. true: match nonProxy
      -  106   -
            */
      -  107   -
           private static boolean matchNonProxy(final URL url) {
      -  108  0
               final String host = url.getHost();
      -  109   -
       
      -  110   -
               // code partially from org.apache.maven.plugins.site.AbstractDeployMojo#getProxyInfo
      -  111  0
               final String nonProxyHosts = Settings.getString(Settings.KEYS.PROXY_NON_PROXY_HOSTS);
      -  112  0
               if (null != nonProxyHosts) {
      -  113  0
                   final String[] nonProxies = nonProxyHosts.split("(,)|(;)|(\\|)");
      -  114  0
                   for (final String nonProxyHost : nonProxies) {
      -  115   -
                       //if ( StringUtils.contains( nonProxyHost, "*" ) )
      -  116  0
                       if (null != nonProxyHost && nonProxyHost.contains("*")) {
      -  117   -
                           // Handle wildcard at the end, beginning or middle of the nonProxyHost
      -  118  0
                           final int pos = nonProxyHost.indexOf('*');
      -  119  0
                           final String nonProxyHostPrefix = nonProxyHost.substring(0, pos);
      -  120  0
                           final String nonProxyHostSuffix = nonProxyHost.substring(pos + 1);
      -  121   -
                           // prefix*
      -  122  0
                           if (!StringUtils.isEmpty(nonProxyHostPrefix) && host.startsWith(nonProxyHostPrefix) && StringUtils.isEmpty(nonProxyHostSuffix)) {
      -  123  0
                               return true;
      -  124   -
                           }
      -  125   -
                           // *suffix
      -  126  0
                           if (StringUtils.isEmpty(nonProxyHostPrefix) && !StringUtils.isEmpty(nonProxyHostSuffix) && host.endsWith(nonProxyHostSuffix)) {
      -  127  0
                               return true;
      -  128   -
                           }
      -  129   -
                           // prefix*suffix
      -  130  0
                           if (!StringUtils.isEmpty(nonProxyHostPrefix) && host.startsWith(nonProxyHostPrefix) && !StringUtils.isEmpty(nonProxyHostSuffix)
      -  131  0
                                   && host.endsWith(nonProxyHostSuffix)) {
      -  132  0
                               return true;
      -  133   -
                           }
      -  134  0
                       } else if (host.equals(nonProxyHost)) {
      -  135  0
                           return true;
      -  136   -
                       }
      -  137   -
                   }
      -  138   -
               }
      -  139  0
               return false;
      -  140   -
           }
      -  141   -
       
      -  142   -
           /**
      -  143   -
            * Utility method to create an HttpURLConnection. The use of a proxy here is optional as there may be cases where a proxy is
      -  144   -
            * configured but we don't want to use it (for example, if there's an internal repository configured)
      -  145   -
            *
      -  146   -
            * @param url the URL to connect to
      -  147   -
            * @param proxy whether to use the proxy (if configured)
      -  148   -
            * @return a newly constructed HttpURLConnection
      -  149   +  63   +
            * @return an HttpURLConnection
      +  64  
            * @throws URLConnectionFailureException thrown if there is an exception
      -  150   +  65  
            */
      -  151   -
           public static HttpURLConnection createHttpURLConnection(URL url, boolean proxy) throws URLConnectionFailureException {
      -  152  0
               if (proxy) {
      -  153  0
                   return createHttpURLConnection(url);
      -  154   -
               }
      -  155  0
               HttpURLConnection conn = null;
      -  156   +  66   +
           @SuppressFBWarnings(value = "RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE", justification = "Just being extra safe")
      +  67   +
           public static HttpURLConnection createHttpURLConnection(URL url) throws URLConnectionFailureException {
      +  68  0
               HttpURLConnection conn = null;
      +  69  0
               final String proxyUrl = Settings.getString(Settings.KEYS.PROXY_SERVER);
      +  70   +
       
      +  71  
               try {
      -  157  0
                   conn = (HttpURLConnection) url.openConnection();
      -  158  0
                   final int timeout = Settings.getInt(Settings.KEYS.CONNECTION_TIMEOUT, 10000);
      -  159  0
                   conn.setConnectTimeout(timeout);
      -  160  0
                   conn.setInstanceFollowRedirects(true);
      -  161  0
               } catch (IOException ioe) {
      -  162  0
                   throw new URLConnectionFailureException("Error getting connection.", ioe);
      -  163  0
               }
      -  164  0
               return conn;
      -  165   +  72  0
                   if (proxyUrl != null && !matchNonProxy(url)) {
      +  73  0
                       final int proxyPort = Settings.getInt(Settings.KEYS.PROXY_PORT);
      +  74  0
                       final SocketAddress address = new InetSocketAddress(proxyUrl, proxyPort);
      +  75   +
       
      +  76  0
                       final String username = Settings.getString(Settings.KEYS.PROXY_USERNAME);
      +  77  0
                       final String password = Settings.getString(Settings.KEYS.PROXY_PASSWORD);
      +  78   +
       
      +  79  0
                       if (username != null && password != null) {
      +  80  0
                           final Authenticator auth = new Authenticator() {
      +  81   +
                               @Override
      +  82   +
                               public PasswordAuthentication getPasswordAuthentication() {
      +  83  0
                                   if (getRequestorType().equals(Authenticator.RequestorType.PROXY)) {
      +  84  0
                                       return new PasswordAuthentication(username, password.toCharArray());
      +  85   +
                                   }
      +  86  0
                                   return super.getPasswordAuthentication();
      +  87   +
                               }
      +  88   +
                           };
      +  89  0
                           Authenticator.setDefault(auth);
      +  90   +
                       }
      +  91   +
       
      +  92  0
                       final Proxy proxy = new Proxy(Proxy.Type.HTTP, address);
      +  93  0
                       conn = (HttpURLConnection) url.openConnection(proxy);
      +  94  0
                   } else {
      +  95  0
                       conn = (HttpURLConnection) url.openConnection();
      +  96   +
                   }
      +  97  0
                   final int timeout = Settings.getInt(Settings.KEYS.CONNECTION_TIMEOUT, 10000);
      +  98  0
                   conn.setConnectTimeout(timeout);
      +  99  0
                   conn.setInstanceFollowRedirects(true);
      +  100  0
               } catch (IOException ex) {
      +  101  0
                   if (conn != null) {
      +  102   +
                       try {
      +  103  0
                           conn.disconnect();
      +  104   +
                       } finally {
      +  105  0
                           conn = null;
      +  106  0
                       }
      +  107   +
                   }
      +  108  0
                   throw new URLConnectionFailureException("Error getting connection.", ex);
      +  109  0
               }
      +  110  0
               configureTLS(url, conn);
      +  111  0
               return conn;
      +  112  
           }
      +  113   +
       
      +  114   +
           /**
      +  115   +
            * Check if hostname matches nonProxy settings
      +  116   +
            *
      +  117   +
            * @param url the url to connect to
      +  118   +
            * @return matching result. true: match nonProxy
      +  119   +
            */
      +  120   +
           private static boolean matchNonProxy(final URL url) {
      +  121  0
               final String host = url.getHost();
      +  122   +
       
      +  123   +
               // code partially from org.apache.maven.plugins.site.AbstractDeployMojo#getProxyInfo
      +  124  0
               final String nonProxyHosts = Settings.getString(Settings.KEYS.PROXY_NON_PROXY_HOSTS);
      +  125  0
               if (null != nonProxyHosts) {
      +  126  0
                   final String[] nonProxies = nonProxyHosts.split("(,)|(;)|(\\|)");
      +  127  0
                   for (final String nonProxyHost : nonProxies) {
      +  128   +
                       //if ( StringUtils.contains( nonProxyHost, "*" ) )
      +  129  0
                       if (null != nonProxyHost && nonProxyHost.contains("*")) {
      +  130   +
                           // Handle wildcard at the end, beginning or middle of the nonProxyHost
      +  131  0
                           final int pos = nonProxyHost.indexOf('*');
      +  132  0
                           final String nonProxyHostPrefix = nonProxyHost.substring(0, pos);
      +  133  0
                           final String nonProxyHostSuffix = nonProxyHost.substring(pos + 1);
      +  134   +
                           // prefix*
      +  135  0
                           if (!StringUtils.isEmpty(nonProxyHostPrefix) && host.startsWith(nonProxyHostPrefix) && StringUtils.isEmpty(nonProxyHostSuffix)) {
      +  136  0
                               return true;
      +  137   +
                           }
      +  138   +
                           // *suffix
      +  139  0
                           if (StringUtils.isEmpty(nonProxyHostPrefix) && !StringUtils.isEmpty(nonProxyHostSuffix) && host.endsWith(nonProxyHostSuffix)) {
      +  140  0
                               return true;
      +  141   +
                           }
      +  142   +
                           // prefix*suffix
      +  143  0
                           if (!StringUtils.isEmpty(nonProxyHostPrefix) && host.startsWith(nonProxyHostPrefix) && !StringUtils.isEmpty(nonProxyHostSuffix)
      +  144  0
                                   && host.endsWith(nonProxyHostSuffix)) {
      +  145  0
                               return true;
      +  146   +
                           }
      +  147  0
                       } else if (host.equals(nonProxyHost)) {
      +  148  0
                           return true;
      +  149   +
                       }
      +  150   +
                   }
      +  151   +
               }
      +  152  0
               return false;
      +  153   +
           }
      +  154   +
       
      +  155   +
           /**
      +  156   +
            * Utility method to create an HttpURLConnection. The use of a proxy here is
      +  157   +
            * optional as there may be cases where a proxy is configured but we don't
      +  158   +
            * want to use it (for example, if there's an internal repository
      +  159   +
            * configured)
      +  160   +
            *
      +  161   +
            * @param url the URL to connect to
      +  162   +
            * @param proxy whether to use the proxy (if configured)
      +  163   +
            * @return a newly constructed HttpURLConnection
      +  164   +
            * @throws URLConnectionFailureException thrown if there is an exception
      +  165   +
            */
       166   +
           public static HttpURLConnection createHttpURLConnection(URL url, boolean proxy) throws URLConnectionFailureException {
      +  167  0
               if (proxy) {
      +  168  0
                   return createHttpURLConnection(url);
      +  169   +
               }
      +  170  0
               HttpURLConnection conn = null;
      +  171   +
               try {
      +  172  0
                   conn = (HttpURLConnection) url.openConnection();
      +  173  0
                   final int timeout = Settings.getInt(Settings.KEYS.CONNECTION_TIMEOUT, 10000);
      +  174  0
                   conn.setConnectTimeout(timeout);
      +  175  0
                   conn.setInstanceFollowRedirects(true);
      +  176  0
               } catch (IOException ioe) {
      +  177  0
                   throw new URLConnectionFailureException("Error getting connection.", ioe);
      +  178  0
               }
      +  179  0
               configureTLS(url, conn);
      +  180  0
               return conn;
      +  181   +
           }
      +  182   +
       
      +  183   +
           /**
      +  184   +
            * If the protocol is HTTPS, this will configure the cipher suites so that
      +  185   +
            * connections can be made to the NVD, and others, using older versions of
      +  186   +
            * Java.
      +  187   +
            *
      +  188   +
            * @param url the URL
      +  189   +
            * @param conn the connection
      +  190   +
            */
      +  191   +
           private static void configureTLS(URL url, HttpURLConnection conn) {
      +  192  0
               if ("https".equals(url.getProtocol())) {
      +  193   +
                   try {
      +  194  0
                       final HttpsURLConnection secCon = (HttpsURLConnection) conn;
      +  195  0
                       final SSLSocketFactoryEx factory = new SSLSocketFactoryEx();
      +  196  0
                       secCon.setSSLSocketFactory(factory);
      +  197  0
                   } catch (NoSuchAlgorithmException ex) {
      +  198  0
                       LOGGER.debug("Unsupported algorithm in SSLSocketFactoryEx", ex);
      +  199  0
                   } catch (KeyManagementException ex) {
      +  200  0
                       LOGGER.debug("Key mnagement eception in SSLSocketFactoryEx", ex);
      +  201  0
                   }
      +  202   +
               }
      +  203  0
           }
      +  204  
       }
      - + diff --git a/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.URLConnectionFailureException.html b/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.URLConnectionFailureException.html index 9936d3fa2..a16e65c90 100644 --- a/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.URLConnectionFailureException.html +++ b/dependency-check-utils/cobertura/org.owasp.dependencycheck.utils.URLConnectionFailureException.html @@ -147,6 +147,6 @@
       }
      - + diff --git a/dependency-check-utils/dependency-analysis.html b/dependency-check-utils/dependency-analysis.html index 6090f7431..8dd56ae26 100644 --- a/dependency-check-utils/dependency-analysis.html +++ b/dependency-check-utils/dependency-analysis.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Dependencies Report @@ -52,7 +52,7 @@ @@ -86,7 +86,7 @@ Project Information - +
    291. @@ -168,6 +168,13 @@ Checkstyle
    292. + +
    293. + + + + PMD +
    294. diff --git a/dependency-check-utils/dependency-updates-report.html b/dependency-check-utils/dependency-updates-report.html index 532360e06..6ed2406d4 100644 --- a/dependency-check-utils/dependency-updates-report.html +++ b/dependency-check-utils/dependency-updates-report.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Dependency Updates Report @@ -52,7 +52,7 @@ @@ -86,7 +86,7 @@ Project Information - +
    295. @@ -168,6 +168,13 @@ Checkstyle
    296. + +
    297. + + + + PMD +
    298. @@ -215,7 +222,7 @@ # of dependencies using the latest version available -22 +23 # of dependencies where the next version available is smaller than an incremental version update @@ -223,7 +230,7 @@ # of dependencies where the next version available is an incremental version update -1 +0 # of dependencies where the next version available is a minor version update @@ -383,7 +390,7 @@ org.apache.commons commons-compress -1.11 +1.12 jar @@ -563,24 +570,24 @@ org.jmockit jmockit -1.22 +1.24 test jar -1.23 +1.25 - + org.jsoup jsoup -1.9.1 +1.9.2 jar -1.9.2 + @@ -921,7 +928,7 @@ commons-compress Current Version -1.11 +1.12 Scope @@ -984,7 +991,7 @@ jar Newer versions -4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      6.0.0
      6.0.1 Latest Major +4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      5.5.2
      6.0.0
      6.0.1
      6.1.0 Latest Major

      org.apache.lucene:lucene-core

      @@ -1011,7 +1018,7 @@ -
      jar
      Newer versions4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      6.0.0
      6.0.1 Latest Major
      +4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      5.5.2
      6.0.0
      6.0.1
      6.1.0 Latest Major

      org.apache.lucene:lucene-queryparser

      @@ -1038,7 +1045,7 @@ -
      jar
      Newer versions4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      6.0.0
      6.0.1 Latest Major
      +4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      5.5.2
      6.0.0
      6.0.1
      6.1.0 Latest Major

      org.apache.lucene:lucene-test-framework

      @@ -1065,7 +1072,7 @@ -
      jar
      Newer versions4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      6.0.0
      6.0.1 Latest Major
      +4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      5.5.2
      6.0.0
      6.0.1
      6.1.0 Latest Major

      org.apache.maven:maven-core

      @@ -1296,7 +1303,7 @@ - + @@ -1308,13 +1315,13 @@ -
      jmockit
      Current Version1.22
      1.24
      Scope test
      jar
      Newer versions1.23 Next Minor
      1.24 Latest Minor
      +1.25 Next Minor

      org.jsoup:jsoup

      - + @@ -1323,7 +1330,7 @@ - + @@ -1332,10 +1339,7 @@ - - - -
      Status There is at least one newer incremental version available. Incremental updates are typically passive.
       No newer versions available.
      Group Id org.jsoup
      jsoup
      Current Version1.9.1
      1.9.2
      Scope
      Typejar
      Newer versions1.9.2 Next Incremental
      +jar

      org.slf4j:slf4j-api

      diff --git a/dependency-check-utils/findbugs.html b/dependency-check-utils/findbugs.html index 552106568..b0b53c089 100644 --- a/dependency-check-utils/findbugs.html +++ b/dependency-check-utils/findbugs.html @@ -1,13 +1,13 @@ - + dependency-check-ant – FindBugs Bug Detector Report @@ -52,7 +52,7 @@ @@ -86,7 +86,7 @@ Project Information - +
    299. @@ -168,6 +168,13 @@ Checkstyle
    300. + +
    301. + + + + PMD +
    302. @@ -223,7 +230,7 @@ - +
      Errors Missing Classes
      1213 0 0 0
      diff --git a/dependency-check-utils/index.html b/dependency-check-utils/index.html index e44af2a6f..609797ade 100644 --- a/dependency-check-utils/index.html +++ b/dependency-check-utils/index.html @@ -1,13 +1,13 @@ - + dependency-check-ant – About @@ -52,7 +52,7 @@ @@ -86,7 +86,7 @@ Project Information - +
    303. diff --git a/dependency-check-utils/integration.html b/dependency-check-utils/integration.html index c32bf4ced..592c68299 100644 --- a/dependency-check-utils/integration.html +++ b/dependency-check-utils/integration.html @@ -1,13 +1,13 @@ - + dependency-check-ant – CI Management @@ -52,7 +52,7 @@ @@ -135,7 +135,7 @@
    304. - +
    305. diff --git a/dependency-check-utils/issue-tracking.html b/dependency-check-utils/issue-tracking.html index f3d4e2626..ee91b4ada 100644 --- a/dependency-check-utils/issue-tracking.html +++ b/dependency-check-utils/issue-tracking.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Issue Management @@ -52,7 +52,7 @@ @@ -135,7 +135,7 @@
    306. - +
    307. diff --git a/dependency-check-utils/license.html b/dependency-check-utils/license.html index d651366f1..67e0a4a22 100644 --- a/dependency-check-utils/license.html +++ b/dependency-check-utils/license.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Project Licenses @@ -52,7 +52,7 @@ @@ -135,7 +135,7 @@
    308. - +
    309. diff --git a/dependency-check-utils/mail-lists.html b/dependency-check-utils/mail-lists.html index a58ff0a0f..4488e4581 100644 --- a/dependency-check-utils/mail-lists.html +++ b/dependency-check-utils/mail-lists.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Project Mailing Lists @@ -52,7 +52,7 @@ @@ -135,7 +135,7 @@
    310. - +
    311. diff --git a/dependency-check-utils/plugin-updates-report.html b/dependency-check-utils/plugin-updates-report.html index 05ba5c7a9..19d7d6cae 100644 --- a/dependency-check-utils/plugin-updates-report.html +++ b/dependency-check-utils/plugin-updates-report.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Plugin Updates Report @@ -52,7 +52,7 @@ @@ -86,7 +86,7 @@ Project Information
    312. - +
    313. @@ -168,6 +168,13 @@ Checkstyle
    314. + +
    315. + + + + PMD +
    316. @@ -215,7 +222,7 @@ # of plugins using the latest version available -18 +19 # of plugins where the next version available is smaller than an incremental version update @@ -231,7 +238,7 @@ # of plugins where the next version available is a major version update -1 +0 # of plugins where a dependencies section containes a dependency with an updated version @@ -353,7 +360,7 @@ org.apache.maven.plugins maven-jar-plugin -3.0.0 +3.0.2 @@ -363,7 +370,7 @@ org.apache.maven.plugins maven-javadoc-plugin -2.10.3 +2.10.4 @@ -400,14 +407,14 @@ - + org.apache.maven.plugins maven-source-plugin -2.4 +3.0.1 + -3.0.0 @@ -619,7 +626,7 @@ maven-jar-plugin Current Version -3.0.0 +3.0.2

      Plugin org.apache.maven.plugins:maven-javadoc-plugin

      @@ -634,7 +641,7 @@ -
      maven-javadoc-plugin
      Current Version2.10.3
      +2.10.4

      Plugin org.apache.maven.plugins:maven-release-plugin

      @@ -685,7 +692,7 @@
      - + @@ -694,10 +701,7 @@ - - - -
      Status There is at least one newer major version available. Major updates are rarely passive.
       No newer versions available.
      Group Id org.apache.maven.plugins
      maven-source-plugin
      Current Version2.4
      Newer versions3.0.0 Next Major
      +3.0.1

      Plugin org.apache.maven.plugins:maven-surefire-plugin

      diff --git a/dependency-check-utils/pmd.html b/dependency-check-utils/pmd.html index 05dd47389..94486ecfa 100644 --- a/dependency-check-utils/pmd.html +++ b/dependency-check-utils/pmd.html @@ -1,27 +1,26 @@ - + - dependency-check-ant - PMD Results - + dependency-check-ant – PMD Results + - + - - - - - + + @@ -29,7 +28,7 @@ - + Fork me on GitHub @@ -51,10 +50,9 @@
      - -
      Violation Line
      These nested if statements could be combined613 - 616
      +Unnecessary use of fully qualified name 'String.format' due to existing static import 'java.lang.String.format' +307 @@ -246,15 +238,13 @@
      -

      Copyright © 2012–2015 +

      Copyright © 2012–2016 OWASP. - All rights reserved. - + All rights reserved.

      -
      +
      -
      diff --git a/dependency-check-utils/project-info.html b/dependency-check-utils/project-info.html index 28656dd9e..e82713fbf 100644 --- a/dependency-check-utils/project-info.html +++ b/dependency-check-utils/project-info.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Project Information @@ -52,7 +52,7 @@ @@ -135,7 +135,7 @@ - +
    317. diff --git a/dependency-check-utils/project-reports.html b/dependency-check-utils/project-reports.html index b084c65d8..2ac76b177 100644 --- a/dependency-check-utils/project-reports.html +++ b/dependency-check-utils/project-reports.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Generated Reports @@ -52,7 +52,7 @@ @@ -86,7 +86,7 @@ Project Information
    318. - +
    319. Project Reports @@ -168,6 +168,13 @@ Checkstyle
    320. + +
    321. + + + + PMD +
    322. @@ -249,7 +256,10 @@ Provides details of the plugins used by this project which have newer versions available. Checkstyle -Report on coding style conventions. +Report on coding style conventions. + +PMD +Verification of coding rules. diff --git a/dependency-check-utils/project-summary.html b/dependency-check-utils/project-summary.html index 51a51f50e..d83387741 100644 --- a/dependency-check-utils/project-summary.html +++ b/dependency-check-utils/project-summary.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Project Summary @@ -52,7 +52,7 @@ @@ -135,7 +135,7 @@ - +
    323. @@ -223,7 +223,7 @@ dependency-check-utils Version -1.4.0 +1.4.2 Type jar diff --git a/dependency-check-utils/source-repository.html b/dependency-check-utils/source-repository.html index abecdb61a..a76e26af5 100644 --- a/dependency-check-utils/source-repository.html +++ b/dependency-check-utils/source-repository.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Source Code Management @@ -52,7 +52,7 @@ @@ -135,7 +135,7 @@
    324. - +
    325. diff --git a/dependency-check-utils/surefire-report.html b/dependency-check-utils/surefire-report.html index 321891b7b..bbf1559cf 100644 --- a/dependency-check-utils/surefire-report.html +++ b/dependency-check-utils/surefire-report.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Surefire Report @@ -52,7 +52,7 @@ @@ -86,7 +86,7 @@ Project Information
    326. - +
    327. @@ -168,6 +168,13 @@ Checkstyle
    328. + +
    329. + + + + PMD +
    330. @@ -244,7 +251,7 @@ function toggleDisplay(elementId) { 0 0 100% -0.511
      +0.602

      Note: failures are anticipated and checked for with assertions while errors are unanticipated.


      Package List

      @@ -265,7 +272,7 @@ function toggleDisplay(elementId) { 0 0 100% -0.511
      +0.602

      Note: package statistics are not computed recursively, they only sum up all of its testsuites numbers.

      org.owasp.dependencycheck.utils

      @@ -287,7 +294,7 @@ function toggleDisplay(elementId) { 0 0 100% -0.385 +0.401 DownloaderTest @@ -296,7 +303,7 @@ function toggleDisplay(elementId) { 0 0 100% -0.002 +0.016 ExpectedOjectInputStreamTest @@ -305,7 +312,7 @@ function toggleDisplay(elementId) { 0 0 100% -0.053 +0.069 FileUtilsTest @@ -314,7 +321,7 @@ function toggleDisplay(elementId) { 0 0 100% -0.068 +0.116 SettingsTest @@ -323,7 +330,7 @@ function toggleDisplay(elementId) { 0 0 100% -0.003

      +0

      Test Cases

      [Summary] [Package List] [Test Cases]

      @@ -333,11 +340,11 @@ function toggleDisplay(elementId) { testGetChecksum_NoSuchAlgorithm -0.333 +0.332 testGetChecksum -0.005 +0 testGetMD5Checksum @@ -353,7 +360,7 @@ function toggleDisplay(elementId) { testGetSHA1Checksum -0.001
      +0

      DownloaderTest

      @@ -367,11 +374,11 @@ function toggleDisplay(elementId) { - + -
      testResolveClassException0.048
      0.052
      testResolveClass0.001
      +0

      FileUtilsTest

      @@ -382,7 +389,7 @@ function toggleDisplay(elementId) { -
      testDelete0.066
      +0.116

      SettingsTest

      diff --git a/dependency-check-utils/taglist.html b/dependency-check-utils/taglist.html index 9af72b884..9b86e0ba1 100644 --- a/dependency-check-utils/taglist.html +++ b/dependency-check-utils/taglist.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Tag List report @@ -52,7 +52,7 @@ @@ -86,7 +86,7 @@ Project Information - +
    331. @@ -168,6 +168,13 @@ Checkstyle
    332. + +
    333. + + + + PMD +
    334. @@ -230,7 +237,7 @@ -
      Line
      add the FTP protocol?217
      +238 diff --git a/dependency-check-utils/team-list.html b/dependency-check-utils/team-list.html index 91b684e54..b4d6e9ebd 100644 --- a/dependency-check-utils/team-list.html +++ b/dependency-check-utils/team-list.html @@ -1,13 +1,13 @@ - + dependency-check-ant – Project Team @@ -52,7 +52,7 @@ @@ -135,7 +135,7 @@ - +
    335. diff --git a/dependency-check-utils/xref-test/index.html b/dependency-check-utils/xref-test/index.html index 82d4c0a26..adfc4bb8d 100644 --- a/dependency-check-utils/xref-test/index.html +++ b/dependency-check-utils/xref-test/index.html @@ -4,7 +4,7 @@ - Dependency-Check Utils 1.4.0 Reference + Dependency-Check Utils 1.4.2 Reference diff --git a/dependency-check-utils/xref-test/org/owasp/dependencycheck/utils/package-frame.html b/dependency-check-utils/xref-test/org/owasp/dependencycheck/utils/package-frame.html index 03cc3cb53..abb58428d 100644 --- a/dependency-check-utils/xref-test/org/owasp/dependencycheck/utils/package-frame.html +++ b/dependency-check-utils/xref-test/org/owasp/dependencycheck/utils/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Utils 1.4.0 Reference Package org.owasp.dependencycheck.utils + Dependency-Check Utils 1.4.2 Reference Package org.owasp.dependencycheck.utils diff --git a/dependency-check-utils/xref-test/org/owasp/dependencycheck/utils/package-summary.html b/dependency-check-utils/xref-test/org/owasp/dependencycheck/utils/package-summary.html index 67f115720..c3c566952 100644 --- a/dependency-check-utils/xref-test/org/owasp/dependencycheck/utils/package-summary.html +++ b/dependency-check-utils/xref-test/org/owasp/dependencycheck/utils/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Utils 1.4.0 Reference Package org.owasp.dependencycheck.utils + Dependency-Check Utils 1.4.2 Reference Package org.owasp.dependencycheck.utils diff --git a/dependency-check-utils/xref-test/overview-frame.html b/dependency-check-utils/xref-test/overview-frame.html index fa6fa0f94..516fe62e9 100644 --- a/dependency-check-utils/xref-test/overview-frame.html +++ b/dependency-check-utils/xref-test/overview-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Utils 1.4.0 Reference + Dependency-Check Utils 1.4.2 Reference diff --git a/dependency-check-utils/xref-test/overview-summary.html b/dependency-check-utils/xref-test/overview-summary.html index b26443869..02e2a205c 100644 --- a/dependency-check-utils/xref-test/overview-summary.html +++ b/dependency-check-utils/xref-test/overview-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Utils 1.4.0 Reference + Dependency-Check Utils 1.4.2 Reference @@ -24,7 +24,7 @@ -

      Dependency-Check Utils 1.4.0 Reference

      +

      Dependency-Check Utils 1.4.2 Reference

      diff --git a/dependency-check-utils/xref/allclasses-frame.html b/dependency-check-utils/xref/allclasses-frame.html index 12c24df72..ec3ce8fb0 100644 --- a/dependency-check-utils/xref/allclasses-frame.html +++ b/dependency-check-utils/xref/allclasses-frame.html @@ -34,6 +34,9 @@
    336. KEYS +
    337. +
    338. + SSLSocketFactoryEx
    339. Settings diff --git a/dependency-check-utils/xref/index.html b/dependency-check-utils/xref/index.html index 82d4c0a26..adfc4bb8d 100644 --- a/dependency-check-utils/xref/index.html +++ b/dependency-check-utils/xref/index.html @@ -4,7 +4,7 @@ - Dependency-Check Utils 1.4.0 Reference + Dependency-Check Utils 1.4.2 Reference diff --git a/dependency-check-utils/xref/org/owasp/dependencycheck/utils/Downloader.html b/dependency-check-utils/xref/org/owasp/dependencycheck/utils/Downloader.html index 553877bdc..1b5a46416 100644 --- a/dependency-check-utils/xref/org/owasp/dependencycheck/utils/Downloader.html +++ b/dependency-check-utils/xref/org/owasp/dependencycheck/utils/Downloader.html @@ -39,22 +39,22 @@ 31 import java.security.InvalidAlgorithmParameterException; 32 import java.util.zip.GZIPInputStream; 33 import java.util.zip.InflaterInputStream; -34 -35 import static java.lang.String.format; -36 -37 /** -38 * A utility to download files from the Internet. -39 * -40 * @author Jeremy Long -41 */ -42 public final class Downloader { -43 -44 /** -45 * The logger. -46 */ -47 private static final Logger LOGGER = LoggerFactory.getLogger(Downloader.class); -48 /** -49 * The maximum number of redirects that will be followed when attempting to download a file. +34 import static java.lang.String.format; +35 +36 /** +37 * A utility to download files from the Internet. +38 * +39 * @author Jeremy Long +40 */ +41 public final class Downloader { +42 +43 /** +44 * The logger. +45 */ +46 private static final Logger LOGGER = LoggerFactory.getLogger(Downloader.class); +47 /** +48 * The maximum number of redirects that will be followed when attempting to +49 * download a file. 50 */ 51 private static final int MAX_REDIRECT_ATTEMPTS = 5; 52 @@ -79,250 +79,284 @@ 71 * 72 * @param url the URL of the file to download 73 * @param outputPath the path to the save the file to -74 * @throws DownloadFailedException is thrown if there is an error downloading the file -75 */ -76 public static void fetchFile(URL url, File outputPath) throws DownloadFailedException { -77 fetchFile(url, outputPath, true); -78 } -79 -80 /** -81 * Retrieves a file from a given URL and saves it to the outputPath. -82 * -83 * @param url the URL of the file to download -84 * @param outputPath the path to the save the file to -85 * @param useProxy whether to use the configured proxy when downloading files -86 * @throws DownloadFailedException is thrown if there is an error downloading the file -87 */ -88 public static void fetchFile(URL url, File outputPath, boolean useProxy) throws DownloadFailedException { -89 if ("file".equalsIgnoreCase(url.getProtocol())) { -90 File file; -91 try { -92 file = new File(url.toURI()); -93 } catch (URISyntaxException ex) { -94 final String msg = format("Download failed, unable to locate '%s'", url.toString()); -95 throw new DownloadFailedException(msg); -96 } -97 if (file.exists()) { -98 try { -99 org.apache.commons.io.FileUtils.copyFile(file, outputPath); -100 } catch (IOException ex) { -101 final String msg = format("Download failed, unable to copy '%s' to '%s'", url.toString(), outputPath.getAbsolutePath()); -102 throw new DownloadFailedException(msg); -103 } -104 } else { -105 final String msg = format("Download failed, file ('%s') does not exist", url.toString()); -106 throw new DownloadFailedException(msg); -107 } -108 } else { -109 HttpURLConnection conn = null; -110 try { -111 LOGGER.debug("Attempting download of {}", url.toString()); -112 conn = URLConnectionFactory.createHttpURLConnection(url, useProxy); -113 conn.setRequestProperty("Accept-Encoding", "gzip, deflate"); -114 conn.connect(); -115 int status = conn.getResponseCode(); -116 int redirectCount = 0; -117 while ((status == HttpURLConnection.HTTP_MOVED_TEMP -118 || status == HttpURLConnection.HTTP_MOVED_PERM -119 || status == HttpURLConnection.HTTP_SEE_OTHER) -120 && MAX_REDIRECT_ATTEMPTS > redirectCount++) { -121 final String location = conn.getHeaderField("Location"); -122 try { -123 conn.disconnect(); -124 } finally { -125 conn = null; -126 } -127 LOGGER.debug("Download is being redirected from {} to {}", url.toString(), location); -128 conn = URLConnectionFactory.createHttpURLConnection(new URL(location), useProxy); -129 conn.setRequestProperty("Accept-Encoding", "gzip, deflate"); -130 conn.connect(); -131 status = conn.getResponseCode(); -132 } -133 if (status != 200) { -134 try { -135 conn.disconnect(); -136 } finally { -137 conn = null; -138 } -139 final String msg = format("Error downloading file %s; received response code %s.", url.toString(), status); -140 throw new DownloadFailedException(msg); -141 -142 } -143 } catch (IOException ex) { -144 try { -145 if (conn != null) { -146 conn.disconnect(); -147 } -148 } finally { -149 conn = null; -150 } -151 final String msg = format("Error downloading file %s; unable to connect.", url.toString()); -152 throw new DownloadFailedException(msg, ex); -153 } -154 -155 final String encoding = conn.getContentEncoding(); -156 BufferedOutputStream writer = null; -157 InputStream reader = null; -158 try { -159 if (encoding != null && "gzip".equalsIgnoreCase(encoding)) { -160 reader = new GZIPInputStream(conn.getInputStream()); -161 } else if (encoding != null && "deflate".equalsIgnoreCase(encoding)) { -162 reader = new InflaterInputStream(conn.getInputStream()); -163 } else { -164 reader = conn.getInputStream(); -165 } -166 -167 writer = new BufferedOutputStream(new FileOutputStream(outputPath)); -168 final byte[] buffer = new byte[4096]; -169 int bytesRead; -170 while ((bytesRead = reader.read(buffer)) > 0) { -171 writer.write(buffer, 0, bytesRead); -172 } -173 LOGGER.debug("Download of {} complete", url.toString()); -174 } catch (IOException ex) { -175 analyzeException(ex); -176 final String msg = format("Error saving '%s' to file '%s'%nConnection Timeout: %d%nEncoding: %s%n", -177 url.toString(), outputPath.getAbsolutePath(), conn.getConnectTimeout(), encoding); -178 throw new DownloadFailedException(msg, ex); -179 } catch (Throwable ex) { -180 final String msg = format("Unexpected exception saving '%s' to file '%s'%nConnection Timeout: %d%nEncoding: %s%n", -181 url.toString(), outputPath.getAbsolutePath(), conn.getConnectTimeout(), encoding); -182 throw new DownloadFailedException(msg, ex); -183 } finally { -184 if (writer != null) { -185 try { -186 writer.close(); -187 } catch (IOException ex) { -188 LOGGER.trace("Error closing the writer in Downloader.", ex); -189 } -190 } -191 if (reader != null) { -192 try { -193 reader.close(); -194 } catch (IOException ex) { -195 LOGGER.trace("Error closing the reader in Downloader.", ex); -196 } -197 } -198 try { -199 conn.disconnect(); -200 } finally { -201 conn = null; -202 } -203 } -204 } -205 } -206 -207 /** -208 * Makes an HTTP Head request to retrieve the last modified date of the given URL. If the file:// protocol is specified, then -209 * the lastTimestamp of the file is returned. -210 * -211 * @param url the URL to retrieve the timestamp from -212 * @return an epoch timestamp -213 * @throws DownloadFailedException is thrown if an exception occurs making the HTTP request -214 */ -215 public static long getLastModified(URL url) throws DownloadFailedException { -216 long timestamp = 0; -217 //TODO add the FTP protocol? -218 if ("file".equalsIgnoreCase(url.getProtocol())) { -219 File lastModifiedFile; -220 try { -221 lastModifiedFile = new File(url.toURI()); -222 } catch (URISyntaxException ex) { -223 final String msg = format("Unable to locate '%s'", url.toString()); -224 throw new DownloadFailedException(msg); -225 } -226 timestamp = lastModifiedFile.lastModified(); -227 } else { -228 final String httpMethod = determineHttpMethod(); -229 HttpURLConnection conn = null; -230 try { -231 conn = URLConnectionFactory.createHttpURLConnection(url); -232 conn.setRequestMethod(httpMethod); -233 conn.connect(); -234 final int t = conn.getResponseCode(); -235 if (t >= 200 && t < 300) { -236 timestamp = conn.getLastModified(); -237 } else { -238 throw new DownloadFailedException(format("%s request returned a non-200 status code", httpMethod)); -239 } -240 } catch (URLConnectionFailureException ex) { -241 throw new DownloadFailedException(format("Error creating URL Connection for HTTP %s request.", httpMethod), ex); -242 } catch (IOException ex) { -243 analyzeException(ex); -244 try { -245 //retry -246 if (!Settings.getBoolean(Settings.KEYS.DOWNLOADER_QUICK_QUERY_TIMESTAMP)) { -247 Settings.setBoolean(Settings.KEYS.DOWNLOADER_QUICK_QUERY_TIMESTAMP, true); -248 return getLastModified(url); -249 } -250 } catch (InvalidSettingException ex1) { -251 LOGGER.debug("invalid setting?", ex); -252 } -253 -254 throw new DownloadFailedException(format("Error making HTTP %s request.", httpMethod), ex); -255 } finally { -256 if (conn != null) { -257 try { -258 conn.disconnect(); -259 } finally { -260 conn = null; -261 } -262 } -263 } -264 } -265 return timestamp; -266 } -267 -268 /** -269 * Analyzes the IOException, logs the appropriate information for debugging purposes, and then throws a -270 * DownloadFailedException that wraps the IO Exception. -271 * -272 * @param ex the original exception -273 * @throws DownloadFailedException a wrapper exception that contains the original exception as the cause -274 */ -275 protected static void analyzeException(IOException ex) throws DownloadFailedException { -276 Throwable cause = ex; -277 while (cause != null) { -278 if (cause instanceof InvalidAlgorithmParameterException) { -279 final String keystore = System.getProperty("javax.net.ssl.keyStore"); -280 final String version = System.getProperty("java.version"); -281 final String vendor = System.getProperty("java.vendor"); -282 LOGGER.info("Error making HTTPS request - InvalidAlgorithmParameterException"); -283 LOGGER.info("There appears to be an issue with the installation of Java and the cacerts." -284 + "See closed issue #177 here: https://github.com/jeremylong/DependencyCheck/issues/177"); -285 LOGGER.info("Java Info:\njavax.net.ssl.keyStore='{}'\njava.version='{}'\njava.vendor='{}'", -286 keystore, version, vendor); -287 throw new DownloadFailedException("Error making HTTPS request. Please see the log for more details."); +74 * @throws DownloadFailedException is thrown if there is an error +75 * downloading the file +76 */ +77 public static void fetchFile(URL url, File outputPath) throws DownloadFailedException { +78 fetchFile(url, outputPath, true); +79 } +80 +81 /** +82 * Retrieves a file from a given URL and saves it to the outputPath. +83 * +84 * @param url the URL of the file to download +85 * @param outputPath the path to the save the file to +86 * @param useProxy whether to use the configured proxy when downloading +87 * files +88 * @throws DownloadFailedException is thrown if there is an error +89 * downloading the file +90 */ +91 public static void fetchFile(URL url, File outputPath, boolean useProxy) throws DownloadFailedException { +92 if ("file".equalsIgnoreCase(url.getProtocol())) { +93 File file; +94 try { +95 file = new File(url.toURI()); +96 } catch (URISyntaxException ex) { +97 final String msg = format("Download failed, unable to locate '%s'", url.toString()); +98 throw new DownloadFailedException(msg); +99 } +100 if (file.exists()) { +101 try { +102 org.apache.commons.io.FileUtils.copyFile(file, outputPath); +103 } catch (IOException ex) { +104 final String msg = format("Download failed, unable to copy '%s' to '%s'", url.toString(), outputPath.getAbsolutePath()); +105 throw new DownloadFailedException(msg); +106 } +107 } else { +108 final String msg = format("Download failed, file ('%s') does not exist", url.toString()); +109 throw new DownloadFailedException(msg); +110 } +111 } else { +112 HttpURLConnection conn = null; +113 try { +114 LOGGER.debug("Attempting download of {}", url.toString()); +115 conn = URLConnectionFactory.createHttpURLConnection(url, useProxy); +116 conn.setRequestProperty("Accept-Encoding", "gzip, deflate"); +117 conn.connect(); +118 int status = conn.getResponseCode(); +119 int redirectCount = 0; +120 while ((status == HttpURLConnection.HTTP_MOVED_TEMP +121 || status == HttpURLConnection.HTTP_MOVED_PERM +122 || status == HttpURLConnection.HTTP_SEE_OTHER) +123 && MAX_REDIRECT_ATTEMPTS > redirectCount++) { +124 final String location = conn.getHeaderField("Location"); +125 try { +126 conn.disconnect(); +127 } finally { +128 conn = null; +129 } +130 LOGGER.debug("Download is being redirected from {} to {}", url.toString(), location); +131 conn = URLConnectionFactory.createHttpURLConnection(new URL(location), useProxy); +132 conn.setRequestProperty("Accept-Encoding", "gzip, deflate"); +133 conn.connect(); +134 status = conn.getResponseCode(); +135 } +136 if (status != 200) { +137 try { +138 conn.disconnect(); +139 } finally { +140 conn = null; +141 } +142 final String msg = format("Error downloading file %s; received response code %s.", url.toString(), status); +143 throw new DownloadFailedException(msg); +144 +145 } +146 } catch (IOException ex) { +147 try { +148 if (conn != null) { +149 conn.disconnect(); +150 } +151 } finally { +152 conn = null; +153 } +154 final String msg = format("Error downloading file %s; unable to connect.", url.toString()); +155 throw new DownloadFailedException(msg, ex); +156 } +157 +158 final String encoding = conn.getContentEncoding(); +159 BufferedOutputStream writer = null; +160 InputStream reader = null; +161 try { +162 if (encoding != null && "gzip".equalsIgnoreCase(encoding)) { +163 reader = new GZIPInputStream(conn.getInputStream()); +164 } else if (encoding != null && "deflate".equalsIgnoreCase(encoding)) { +165 reader = new InflaterInputStream(conn.getInputStream()); +166 } else { +167 reader = conn.getInputStream(); +168 } +169 +170 writer = new BufferedOutputStream(new FileOutputStream(outputPath)); +171 final byte[] buffer = new byte[4096]; +172 int bytesRead; +173 while ((bytesRead = reader.read(buffer)) > 0) { +174 writer.write(buffer, 0, bytesRead); +175 } +176 LOGGER.debug("Download of {} complete", url.toString()); +177 } catch (IOException ex) { +178 checkForCommonExceptionTypes(ex); +179 final String msg = format("Error saving '%s' to file '%s'%nConnection Timeout: %d%nEncoding: %s%n", +180 url.toString(), outputPath.getAbsolutePath(), conn.getConnectTimeout(), encoding); +181 throw new DownloadFailedException(msg, ex); +182 } catch (Throwable ex) { +183 final String msg = format("Unexpected exception saving '%s' to file '%s'%nConnection Timeout: %d%nEncoding: %s%n", +184 url.toString(), outputPath.getAbsolutePath(), conn.getConnectTimeout(), encoding); +185 throw new DownloadFailedException(msg, ex); +186 } finally { +187 if (writer != null) { +188 try { +189 writer.close(); +190 } catch (IOException ex) { +191 LOGGER.trace("Error closing the writer in Downloader.", ex); +192 } +193 } +194 if (reader != null) { +195 try { +196 reader.close(); +197 } catch (IOException ex) { +198 LOGGER.trace("Error closing the reader in Downloader.", ex); +199 } +200 } +201 try { +202 conn.disconnect(); +203 } finally { +204 conn = null; +205 } +206 } +207 } +208 } +209 +210 /** +211 * Makes an HTTP Head request to retrieve the last modified date of the +212 * given URL. If the file:// protocol is specified, then the lastTimestamp +213 * of the file is returned. +214 * +215 * @param url the URL to retrieve the timestamp from +216 * @return an epoch timestamp +217 * @throws DownloadFailedException is thrown if an exception occurs making +218 * the HTTP request +219 */ +220 public static long getLastModified(URL url) throws DownloadFailedException { +221 return getLastModified(url, false); +222 } +223 +224 /** +225 * Makes an HTTP Head request to retrieve the last modified date of the +226 * given URL. If the file:// protocol is specified, then the lastTimestamp +227 * of the file is returned. +228 * +229 * @param url the URL to retrieve the timestamp from +230 * @param isRetry indicates if this is a retry - to prevent endless loop and +231 * stack overflow +232 * @return an epoch timestamp +233 * @throws DownloadFailedException is thrown if an exception occurs making +234 * the HTTP request +235 */ +236 private static long getLastModified(URL url, boolean isRetry) throws DownloadFailedException { +237 long timestamp = 0; +238 //TODO add the FTP protocol? +239 if ("file".equalsIgnoreCase(url.getProtocol())) { +240 File lastModifiedFile; +241 try { +242 lastModifiedFile = new File(url.toURI()); +243 } catch (URISyntaxException ex) { +244 final String msg = format("Unable to locate '%s'", url.toString()); +245 throw new DownloadFailedException(msg); +246 } +247 timestamp = lastModifiedFile.lastModified(); +248 } else { +249 final String httpMethod = determineHttpMethod(); +250 HttpURLConnection conn = null; +251 try { +252 conn = URLConnectionFactory.createHttpURLConnection(url); +253 conn.setRequestMethod(httpMethod); +254 conn.connect(); +255 final int t = conn.getResponseCode(); +256 if (t >= 200 && t < 300) { +257 timestamp = conn.getLastModified(); +258 } else { +259 throw new DownloadFailedException(format("%s request returned a non-200 status code", httpMethod)); +260 } +261 } catch (URLConnectionFailureException ex) { +262 throw new DownloadFailedException(format("Error creating URL Connection for HTTP %s request.", httpMethod), ex); +263 } catch (IOException ex) { +264 checkForCommonExceptionTypes(ex); +265 LOGGER.error("IO Exception: " + ex.getMessage()); +266 LOGGER.debug("Exception details", ex); +267 if (ex.getCause() != null) { +268 LOGGER.debug("IO Exception cause: " + ex.getCause().getMessage(), ex.getCause()); +269 } +270 try { +271 //retry +272 if (!isRetry && Settings.getBoolean(Settings.KEYS.DOWNLOADER_QUICK_QUERY_TIMESTAMP)) { +273 Settings.setBoolean(Settings.KEYS.DOWNLOADER_QUICK_QUERY_TIMESTAMP, false); +274 return getLastModified(url, true); +275 } +276 } catch (InvalidSettingException ex1) { +277 LOGGER.debug("invalid setting?", ex); +278 } +279 throw new DownloadFailedException(format("Error making HTTP %s request.", httpMethod), ex); +280 } finally { +281 if (conn != null) { +282 try { +283 conn.disconnect(); +284 } finally { +285 conn = null; +286 } +287 } 288 } -289 cause = cause.getCause(); -290 } +289 } +290 return timestamp; 291 } 292 293 /** -294 * Returns the HEAD or GET HTTP method. HEAD is the default. -295 * -296 * @return the HTTP method to use -297 */ -298 private static String determineHttpMethod() { -299 return isQuickQuery() ? HEAD : GET; -300 } -301 -302 /** -303 * Determines if the HTTP method GET or HEAD should be used to check the timestamp on external resources. -304 * -305 * @return true if configured to use HEAD requests -306 */ -307 private static boolean isQuickQuery() { -308 boolean quickQuery; -309 -310 try { -311 quickQuery = Settings.getBoolean(Settings.KEYS.DOWNLOADER_QUICK_QUERY_TIMESTAMP, true); -312 } catch (InvalidSettingException e) { -313 quickQuery = true; -314 } -315 return quickQuery; -316 } -317 } +294 * Analyzes the IOException, logs the appropriate information for debugging +295 * purposes, and then throws a DownloadFailedException that wraps the IO +296 * Exception for common IO Exceptions. This is to provide additional details +297 * to assist in resolution of the exception. +298 * +299 * @param ex the original exception +300 * @throws DownloadFailedException a wrapper exception that contains the +301 * original exception as the cause +302 */ +303 protected static void checkForCommonExceptionTypes(IOException ex) throws DownloadFailedException { +304 Throwable cause = ex; +305 while (cause != null) { +306 if (cause instanceof java.net.UnknownHostException) { +307 final String msg = String.format("Unable to resolve domain '%s'", cause.getMessage()); +308 LOGGER.error(msg); +309 throw new DownloadFailedException(msg); +310 } +311 if (cause instanceof InvalidAlgorithmParameterException) { +312 final String keystore = System.getProperty("javax.net.ssl.keyStore"); +313 final String version = System.getProperty("java.version"); +314 final String vendor = System.getProperty("java.vendor"); +315 LOGGER.info("Error making HTTPS request - InvalidAlgorithmParameterException"); +316 LOGGER.info("There appears to be an issue with the installation of Java and the cacerts." +317 + "See closed issue #177 here: https://github.com/jeremylong/DependencyCheck/issues/177"); +318 LOGGER.info("Java Info:\njavax.net.ssl.keyStore='{}'\njava.version='{}'\njava.vendor='{}'", +319 keystore, version, vendor); +320 throw new DownloadFailedException("Error making HTTPS request. Please see the log for more details."); +321 } +322 cause = cause.getCause(); +323 } +324 } +325 +326 /** +327 * Returns the HEAD or GET HTTP method. HEAD is the default. +328 * +329 * @return the HTTP method to use +330 */ +331 private static String determineHttpMethod() { +332 return isQuickQuery() ? HEAD : GET; +333 } +334 +335 /** +336 * Determines if the HTTP method GET or HEAD should be used to check the +337 * timestamp on external resources. +338 * +339 * @return true if configured to use HEAD requests +340 */ +341 private static boolean isQuickQuery() { +342 boolean quickQuery; +343 +344 try { +345 quickQuery = Settings.getBoolean(Settings.KEYS.DOWNLOADER_QUICK_QUERY_TIMESTAMP, true); +346 } catch (InvalidSettingException e) { +347 quickQuery = true; +348 } +349 return quickQuery; +350 } +351 }
      diff --git a/dependency-check-utils/xref/org/owasp/dependencycheck/utils/SSLSocketFactoryEx.html b/dependency-check-utils/xref/org/owasp/dependencycheck/utils/SSLSocketFactoryEx.html new file mode 100644 index 000000000..0c780ffa3 --- /dev/null +++ b/dependency-check-utils/xref/org/owasp/dependencycheck/utils/SSLSocketFactoryEx.html @@ -0,0 +1,398 @@ + + + +SSLSocketFactoryEx xref + + + +
      +1   package org.owasp.dependencycheck.utils;
      +2   
      +3   import java.io.IOException;
      +4   import java.net.InetAddress;
      +5   import java.net.Socket;
      +6   import java.security.KeyManagementException;
      +7   import java.security.NoSuchAlgorithmException;
      +8   import java.security.SecureRandom;
      +9   import java.util.ArrayList;
      +10  import java.util.Arrays;
      +11  import java.util.List;
      +12  import javax.net.ssl.KeyManager;
      +13  import javax.net.ssl.SSLContext;
      +14  import javax.net.ssl.SSLSocket;
      +15  import javax.net.ssl.SSLSocketFactory;
      +16  import javax.net.ssl.TrustManager;
      +17  import org.slf4j.Logger;
      +18  import org.slf4j.LoggerFactory;
      +19  
      +20  /**
      +21   * This class is used to enable additional ciphers used by the SSL Socket. This
      +22   * is specifically because the NVD stopped supporting TLS 1.0 and Java 6 and 7
      +23   * clients by default were unable to connect to download the NVD data feeds.
      +24   *
      +25   * The following code was copied from
      +26   * http://stackoverflow.com/questions/1037590/which-cipher-suites-to-enable-for-ssl-socket/23365536#23365536
      +27   *
      +28   * @author <a href="http://stackoverflow.com/users/608639/jww">jww</a>
      +29   */
      +30  public class SSLSocketFactoryEx extends SSLSocketFactory {
      +31  
      +32      /**
      +33       * The Logger for use throughout the class.
      +34       */
      +35      private static final Logger LOGGER = LoggerFactory.getLogger(SSLSocketFactoryEx.class);
      +36  
      +37      /**
      +38       * Constructs a new SSLSocketFactory.
      +39       *
      +40       * @throws NoSuchAlgorithmException thrown when an algorithm is not
      +41       * supported
      +42       * @throws KeyManagementException thrown if initialization fails
      +43       */
      +44      public SSLSocketFactoryEx() throws NoSuchAlgorithmException, KeyManagementException {
      +45          initSSLSocketFactoryEx(null, null, null);
      +46      }
      +47  
      +48      /**
      +49       * Constructs a new SSLSocketFactory.
      +50       *
      +51       * @param km the key manager
      +52       * @param tm the trust manager
      +53       * @param random secure random
      +54       * @throws NoSuchAlgorithmException thrown when an algorithm is not
      +55       * supported
      +56       * @throws KeyManagementException thrown if initialization fails
      +57       */
      +58      public SSLSocketFactoryEx(KeyManager[] km, TrustManager[] tm, SecureRandom random) throws NoSuchAlgorithmException, KeyManagementException {
      +59          initSSLSocketFactoryEx(km, tm, random);
      +60      }
      +61  
      +62      /**
      +63       * Constructs a new SSLSocketFactory.
      +64       *
      +65       * @param ctx the SSL context
      +66       * @throws NoSuchAlgorithmException thrown when an algorithm is not
      +67       * supported
      +68       * @throws KeyManagementException thrown if initialization fails
      +69       */
      +70      public SSLSocketFactoryEx(SSLContext ctx) throws NoSuchAlgorithmException, KeyManagementException {
      +71          initSSLSocketFactoryEx(ctx);
      +72      }
      +73  
      +74      /**
      +75       * Returns the default cipher suites.
      +76       *
      +77       * @return the default cipher suites
      +78       */
      +79      @Override
      +80      public String[] getDefaultCipherSuites() {
      +81          return Arrays.copyOf(ciphers, ciphers.length);
      +82      }
      +83  
      +84      /**
      +85       * Returns the supported cipher suites.
      +86       *
      +87       * @return the supported cipher suites
      +88       */
      +89      @Override
      +90      public String[] getSupportedCipherSuites() {
      +91          return Arrays.copyOf(ciphers, ciphers.length);
      +92      }
      +93  
      +94      /**
      +95       * Returns the default protocols.
      +96       *
      +97       * @return the default protocols
      +98       */
      +99      public String[] getDefaultProtocols() {
      +100         return Arrays.copyOf(protocols, protocols.length);
      +101     }
      +102 
      +103     /**
      +104      * Returns the supported protocols.
      +105      *
      +106      * @return the supported protocols
      +107      */
      +108     public String[] getSupportedProtocols() {
      +109         return Arrays.copyOf(protocols, protocols.length);
      +110     }
      +111 
      +112     /**
      +113      * Creates an SSL Socket.
      +114      *
      +115      * @param s the base socket
      +116      * @param host the host
      +117      * @param port the port
      +118      * @param autoClose if the socket should auto-close
      +119      * @return the SSL Socket
      +120      * @throws IOException thrown if the creation fails
      +121      */
      +122     @Override
      +123     public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
      +124         final SSLSocketFactory factory = sslCtxt.getSocketFactory();
      +125         final SSLSocket ss = (SSLSocket) factory.createSocket(s, host, port, autoClose);
      +126 
      +127         ss.setEnabledProtocols(protocols);
      +128         ss.setEnabledCipherSuites(ciphers);
      +129 
      +130         return ss;
      +131     }
      +132 
      +133     /**
      +134      * Creates a new SSL Socket.
      +135      *
      +136      * @param address the address to connect to
      +137      * @param port the port number
      +138      * @param localAddress the local address
      +139      * @param localPort the local port
      +140      * @return the SSL Socket
      +141      * @throws IOException thrown if the creation fails
      +142      */
      +143     @Override
      +144     public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
      +145         final SSLSocketFactory factory = sslCtxt.getSocketFactory();
      +146         final SSLSocket ss = (SSLSocket) factory.createSocket(address, port, localAddress, localPort);
      +147 
      +148         ss.setEnabledProtocols(protocols);
      +149         ss.setEnabledCipherSuites(ciphers);
      +150 
      +151         return ss;
      +152     }
      +153 
      +154     /**
      +155      * Creates a new SSL Socket.
      +156      *
      +157      * @param host the host to connect to
      +158      * @param port the port to connect to
      +159      * @param localHost the local host
      +160      * @param localPort the local port
      +161      * @return the SSL Socket
      +162      * @throws IOException thrown if the creation fails
      +163      */
      +164     @Override
      +165     public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException {
      +166         final SSLSocketFactory factory = sslCtxt.getSocketFactory();
      +167         final SSLSocket ss = (SSLSocket) factory.createSocket(host, port, localHost, localPort);
      +168 
      +169         ss.setEnabledProtocols(protocols);
      +170         ss.setEnabledCipherSuites(ciphers);
      +171 
      +172         return ss;
      +173     }
      +174 
      +175     /**
      +176      * Creates a new SSL Socket.
      +177      *
      +178      * @param host the host to connect to
      +179      * @param port the port to connect to
      +180      * @return the SSL Socket
      +181      * @throws IOException thrown if the creation fails
      +182      */
      +183     @Override
      +184     public Socket createSocket(InetAddress host, int port) throws IOException {
      +185         final SSLSocketFactory factory = sslCtxt.getSocketFactory();
      +186         final SSLSocket ss = (SSLSocket) factory.createSocket(host, port);
      +187 
      +188         ss.setEnabledProtocols(protocols);
      +189         ss.setEnabledCipherSuites(ciphers);
      +190 
      +191         return ss;
      +192     }
      +193 
      +194     /**
      +195      * Creates a new SSL Socket.
      +196      *
      +197      * @param host the host to connect to
      +198      * @param port the port to connect to
      +199      * @return the SSL Socket
      +200      * @throws IOException thrown if the creation fails
      +201      */
      +202     @Override
      +203     public Socket createSocket(String host, int port) throws IOException {
      +204         final SSLSocketFactory factory = sslCtxt.getSocketFactory();
      +205         final SSLSocket ss = (SSLSocket) factory.createSocket(host, port);
      +206 
      +207         ss.setEnabledProtocols(protocols);
      +208         ss.setEnabledCipherSuites(ciphers);
      +209 
      +210         return ss;
      +211     }
      +212 
      +213     /**
      +214      * Initializes the SSL Socket Factory Extension.
      +215      *
      +216      * @param km the key managers
      +217      * @param tm the trust managers
      +218      * @param random the secure random number generator
      +219      * @throws NoSuchAlgorithmException thrown when an algorithm is not
      +220      * supported
      +221      * @throws KeyManagementException thrown if initialization fails
      +222      */
      +223     private void initSSLSocketFactoryEx(KeyManager[] km, TrustManager[] tm, SecureRandom random)
      +224             throws NoSuchAlgorithmException, KeyManagementException {
      +225         sslCtxt = SSLContext.getInstance("TLS");
      +226         sslCtxt.init(km, tm, random);
      +227 
      +228         protocols = getProtocolList();
      +229         ciphers = getCipherList();
      +230     }
      +231 
      +232     /**
      +233      * Initializes the SSL Socket Factory Extension.
      +234      *
      +235      * @param ctx the SSL context
      +236      * @throws NoSuchAlgorithmException thrown when an algorithm is not
      +237      * supported
      +238      * @throws KeyManagementException thrown if initialization fails
      +239      */
      +240     private void initSSLSocketFactoryEx(SSLContext ctx)
      +241             throws NoSuchAlgorithmException, KeyManagementException {
      +242         sslCtxt = ctx;
      +243 
      +244         protocols = getProtocolList();
      +245         ciphers = getCipherList();
      +246     }
      +247 
      +248     /**
      +249      * Returns the protocol list.
      +250      *
      +251      * @return the protocol list
      +252      */
      +253     protected String[] getProtocolList() {
      +254         final String[] preferredProtocols = {"TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3"};
      +255         String[] availableProtocols = null;
      +256 
      +257         SSLSocket socket = null;
      +258 
      +259         try {
      +260             final SSLSocketFactory factory = sslCtxt.getSocketFactory();
      +261             socket = (SSLSocket) factory.createSocket();
      +262 
      +263             availableProtocols = socket.getSupportedProtocols();
      +264             Arrays.sort(availableProtocols);
      +265         } catch (Exception ex) {
      +266             LOGGER.debug("Error getting protocol list, using TLSv1", ex);
      +267             return new String[]{"TLSv1"};
      +268         } finally {
      +269             if (socket != null) {
      +270                 try {
      +271                     socket.close();
      +272                 } catch (IOException ex) {
      +273                     LOGGER.trace("Error closing socket", ex);
      +274                 }
      +275             }
      +276         }
      +277 
      +278         final List<String> aa = new ArrayList<String>();
      +279         for (String preferredProtocol : preferredProtocols) {
      +280             final int idx = Arrays.binarySearch(availableProtocols, preferredProtocol);
      +281             if (idx >= 0) {
      +282                 aa.add(preferredProtocol);
      +283             }
      +284         }
      +285 
      +286         return aa.toArray(new String[0]);
      +287     }
      +288 
      +289     /**
      +290      * Returns the cipher list.
      +291      *
      +292      * @return the cipher list
      +293      */
      +294     protected String[] getCipherList() {
      +295         final String[] preferredCiphers = {
      +296             // *_CHACHA20_POLY1305 are 3x to 4x faster than existing cipher suites.
      +297             //   http://googleonlinesecurity.blogspot.com/2014/04/speeding-up-and-strengthening-https.html
      +298             // Use them if available. Normative names can be found at (TLS spec depends on IPSec spec):
      +299             //   http://tools.ietf.org/html/draft-nir-ipsecme-chacha20-poly1305-01
      +300             //   http://tools.ietf.org/html/draft-mavrogiannopoulos-chacha-tls-02
      +301             "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305",
      +302             "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305",
      +303             "TLS_ECDHE_ECDSA_WITH_CHACHA20_SHA",
      +304             "TLS_ECDHE_RSA_WITH_CHACHA20_SHA",
      +305             "TLS_DHE_RSA_WITH_CHACHA20_POLY1305",
      +306             "TLS_RSA_WITH_CHACHA20_POLY1305",
      +307             "TLS_DHE_RSA_WITH_CHACHA20_SHA",
      +308             "TLS_RSA_WITH_CHACHA20_SHA",
      +309             // Done with bleeding edge, back to TLS v1.2 and below
      +310             "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384",
      +311             "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384",
      +312             "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
      +313             "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
      +314             "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
      +315             "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384",
      +316             "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
      +317             "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256",
      +318             // TLS v1.0 (with some SSLv3 interop)
      +319             "TLS_DHE_RSA_WITH_AES_256_CBC_SHA384",
      +320             "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256",
      +321             "TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
      +322             "TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
      +323             "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
      +324             "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA",
      +325             "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA",
      +326             "SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA",
      +327             // RSA key transport sucks, but they are needed as a fallback.
      +328             // For example, microsoft.com fails under all versions of TLS
      +329             // if they are not included. If only TLS 1.0 is available at
      +330             // the client, then google.com will fail too. TLS v1.3 is
      +331             // trying to deprecate them, so it will be interesteng to see
      +332             // what happens.
      +333             "TLS_RSA_WITH_AES_256_CBC_SHA256",
      +334             "TLS_RSA_WITH_AES_256_CBC_SHA",
      +335             "TLS_RSA_WITH_AES_128_CBC_SHA256",
      +336             "TLS_RSA_WITH_AES_128_CBC_SHA",
      +337         };
      +338 
      +339         String[] availableCiphers;
      +340 
      +341         try {
      +342             final SSLSocketFactory factory = sslCtxt.getSocketFactory();
      +343             availableCiphers = factory.getSupportedCipherSuites();
      +344             Arrays.sort(availableCiphers);
      +345         } catch (Exception e) {
      +346             LOGGER.debug("Error retrieving ciphers", e);
      +347             return new String[]{
      +348                 "TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
      +349                 "TLS_DHE_DSS_WITH_AES_256_CBC_SHA",
      +350                 "TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
      +351                 "TLS_DHE_RSA_WITH_AES_256_CBC_SHA",
      +352                 "TLS_RSA_WITH_AES_256_CBC_SHA256",
      +353                 "TLS_RSA_WITH_AES_256_CBC_SHA",
      +354                 "TLS_RSA_WITH_AES_128_CBC_SHA256",
      +355                 "TLS_RSA_WITH_AES_128_CBC_SHA",
      +356                 "TLS_EMPTY_RENEGOTIATION_INFO_SCSV",
      +357             };
      +358         }
      +359 
      +360         final List<String> aa = new ArrayList<String>();
      +361         for (String preferredCipher : preferredCiphers) {
      +362             final int idx = Arrays.binarySearch(availableCiphers, preferredCipher);
      +363             if (idx >= 0) {
      +364                 aa.add(preferredCipher);
      +365             }
      +366         }
      +367 
      +368         aa.add("TLS_EMPTY_RENEGOTIATION_INFO_SCSV");
      +369 
      +370         return aa.toArray(new String[0]);
      +371     }
      +372 
      +373     /**
      +374      * The SSL context.
      +375      */
      +376     private SSLContext sslCtxt;
      +377     /**
      +378      * The cipher suites.
      +379      */
      +380     private String[] ciphers;
      +381     /**
      +382      * The protocols.
      +383      */
      +384     private String[] protocols;
      +385 }
      +
      +
      + + + diff --git a/dependency-check-utils/xref/org/owasp/dependencycheck/utils/Settings.html b/dependency-check-utils/xref/org/owasp/dependencycheck/utils/Settings.html index f53fda40e..3dddd026c 100644 --- a/dependency-check-utils/xref/org/owasp/dependencycheck/utils/Settings.html +++ b/dependency-check-utils/xref/org/owasp/dependencycheck/utils/Settings.html @@ -54,815 +54,883 @@ 46 public static final class KEYS { 47 48 /** -49 * private constructor because this is a "utility" class containing constants -50 */ -51 private KEYS() { -52 //do nothing -53 } -54 /** -55 * The key to obtain the application name. -56 */ -57 public static final String APPLICATION_VAME = "application.name"; -58 /** -59 * The key to obtain the application version. -60 */ -61 public static final String APPLICATION_VERSION = "application.version"; -62 /** -63 * The key to obtain the URL to retrieve the current release version from. -64 */ -65 public static final String ENGINE_VERSION_CHECK_URL = "engine.version.url"; -66 /** -67 * The properties key indicating whether or not the cached data sources should be updated. -68 */ -69 public static final String AUTO_UPDATE = "autoupdate"; -70 /** -71 * The database driver class name. If this is not in the properties file the embedded database is used. -72 */ -73 public static final String DB_DRIVER_NAME = "data.driver_name"; -74 /** -75 * The database driver class name. If this is not in the properties file the embedded database is used. +49 * private constructor because this is a "utility" class containing +50 * constants +51 */ +52 private KEYS() { +53 //do nothing +54 } +55 /** +56 * The key to obtain the application name. +57 */ +58 public static final String APPLICATION_VAME = "application.name"; +59 /** +60 * The key to obtain the application version. +61 */ +62 public static final String APPLICATION_VERSION = "application.version"; +63 /** +64 * The key to obtain the URL to retrieve the current release version +65 * from. +66 */ +67 public static final String ENGINE_VERSION_CHECK_URL = "engine.version.url"; +68 /** +69 * The properties key indicating whether or not the cached data sources +70 * should be updated. +71 */ +72 public static final String AUTO_UPDATE = "autoupdate"; +73 /** +74 * The database driver class name. If this is not in the properties file +75 * the embedded database is used. 76 */ -77 public static final String DB_DRIVER_PATH = "data.driver_path"; +77 public static final String DB_DRIVER_NAME = "data.driver_name"; 78 /** -79 * The database connection string. If this is not in the properties file the embedded database is used. -80 */ -81 public static final String DB_CONNECTION_STRING = "data.connection_string"; -82 /** -83 * The username to use when connecting to the database. -84 */ -85 public static final String DB_USER = "data.user"; -86 /** -87 * The password to authenticate to the database. -88 */ -89 public static final String DB_PASSWORD = "data.password"; -90 /** -91 * The base path to use for the data directory (for embedded db). -92 */ -93 public static final String DATA_DIRECTORY = "data.directory"; -94 /** -95 * The database file name. -96 */ -97 public static final String DB_FILE_NAME = "data.file_name"; -98 /** -99 * The database schema version. -100 */ -101 public static final String DB_VERSION = "data.version"; -102 /** -103 * The properties key for the URL to retrieve the "meta" data from about the CVE entries. -104 */ -105 public static final String CVE_META_URL = "cve.url.meta"; -106 /** -107 * The properties key for the URL to retrieve the recently modified and added CVE entries (last 8 days) using the 2.0 -108 * schema. -109 */ -110 public static final String CVE_MODIFIED_20_URL = "cve.url-2.0.modified"; -111 /** -112 * The properties key for the URL to retrieve the recently modified and added CVE entries (last 8 days) using the 1.2 -113 * schema. +79 * The database driver class name. If this is not in the properties file +80 * the embedded database is used. +81 */ +82 public static final String DB_DRIVER_PATH = "data.driver_path"; +83 /** +84 * The database connection string. If this is not in the properties file +85 * the embedded database is used. +86 */ +87 public static final String DB_CONNECTION_STRING = "data.connection_string"; +88 /** +89 * The username to use when connecting to the database. +90 */ +91 public static final String DB_USER = "data.user"; +92 /** +93 * The password to authenticate to the database. +94 */ +95 public static final String DB_PASSWORD = "data.password"; +96 /** +97 * The base path to use for the data directory (for embedded db). +98 */ +99 public static final String DATA_DIRECTORY = "data.directory"; +100 /** +101 * The database file name. +102 */ +103 public static final String DB_FILE_NAME = "data.file_name"; +104 /** +105 * The database schema version. +106 */ +107 public static final String DB_VERSION = "data.version"; +108 /** +109 * The starts with filter used to exclude CVE entries from the database. +110 * By default this is set to 'cpe:/a:' which limits the CVEs imported to +111 * just those that are related to applications. If this were set to just +112 * 'cpe:' the OS, hardware, and application related CVEs would be +113 * imported. 114 */ -115 public static final String CVE_MODIFIED_12_URL = "cve.url-1.2.modified"; +115 public static final String CVE_CPE_STARTS_WITH_FILTER = "cve.cpe.startswith.filter"; 116 /** -117 * The properties key for the URL to retrieve the recently modified and added CVE entries (last 8 days). -118 */ -119 public static final String CVE_MODIFIED_VALID_FOR_DAYS = "cve.url.modified.validfordays"; -120 /** -121 * The properties key to control the skipping of the check for CVE updates. -122 */ -123 public static final String CVE_CHECK_VALID_FOR_HOURS = "cve.check.validforhours"; -124 /** -125 * The properties key for the telling us how many cve.url.* URLs exists. This is used in combination with CVE_BASE_URL to -126 * be able to retrieve the URLs for all of the files that make up the NVD CVE listing. -127 */ -128 public static final String CVE_START_YEAR = "cve.startyear"; -129 /** -130 * The properties key for the CVE schema version 1.2. -131 */ -132 public static final String CVE_SCHEMA_1_2 = "cve.url-1.2.base"; -133 /** -134 * The properties key for the CVE schema version 2.0. -135 */ -136 public static final String CVE_SCHEMA_2_0 = "cve.url-2.0.base"; -137 /** -138 * The properties key that indicates how often the CPE data needs to be updated. +117 * The properties key for the URL to retrieve the "meta" data from about +118 * the CVE entries. +119 */ +120 public static final String CVE_META_URL = "cve.url.meta"; +121 /** +122 * The properties key for the URL to retrieve the recently modified and +123 * added CVE entries (last 8 days) using the 2.0 schema. +124 */ +125 public static final String CVE_MODIFIED_20_URL = "cve.url-2.0.modified"; +126 /** +127 * The properties key for the URL to retrieve the recently modified and +128 * added CVE entries (last 8 days) using the 1.2 schema. +129 */ +130 public static final String CVE_MODIFIED_12_URL = "cve.url-1.2.modified"; +131 /** +132 * The properties key for the URL to retrieve the recently modified and +133 * added CVE entries (last 8 days). +134 */ +135 public static final String CVE_MODIFIED_VALID_FOR_DAYS = "cve.url.modified.validfordays"; +136 /** +137 * The properties key to control the skipping of the check for CVE +138 * updates. 139 */ -140 public static final String CPE_MODIFIED_VALID_FOR_DAYS = "cpe.validfordays"; +140 public static final String CVE_CHECK_VALID_FOR_HOURS = "cve.check.validforhours"; 141 /** -142 * The properties key for the URL to retrieve the CPE. -143 */ -144 public static final String CPE_URL = "cpe.url"; -145 /** -146 * The properties key for the proxy server. -147 * -148 * @deprecated use {@link org.owasp.dependencycheck.utils.Settings.KEYS#PROXY_SERVER} instead. +142 * The properties key for the telling us how many cve.url.* URLs exists. +143 * This is used in combination with CVE_BASE_URL to be able to retrieve +144 * the URLs for all of the files that make up the NVD CVE listing. +145 */ +146 public static final String CVE_START_YEAR = "cve.startyear"; +147 /** +148 * The properties key for the CVE schema version 1.2. 149 */ -150 @Deprecated -151 public static final String PROXY_URL = "proxy.server"; -152 /** -153 * The properties key for the proxy server. -154 */ -155 public static final String PROXY_SERVER = "proxy.server"; -156 /** -157 * The properties key for the proxy port - this must be an integer value. +150 public static final String CVE_SCHEMA_1_2 = "cve.url-1.2.base"; +151 /** +152 * The properties key for the CVE schema version 2.0. +153 */ +154 public static final String CVE_SCHEMA_2_0 = "cve.url-2.0.base"; +155 /** +156 * The properties key that indicates how often the CPE data needs to be +157 * updated. 158 */ -159 public static final String PROXY_PORT = "proxy.port"; +159 public static final String CPE_MODIFIED_VALID_FOR_DAYS = "cpe.validfordays"; 160 /** -161 * The properties key for the proxy username. +161 * The properties key for the URL to retrieve the CPE. 162 */ -163 public static final String PROXY_USERNAME = "proxy.username"; +163 public static final String CPE_URL = "cpe.url"; 164 /** -165 * The properties key for the proxy password. -166 */ -167 public static final String PROXY_PASSWORD = "proxy.password"; -168 /** -169 * The properties key for the non proxy hosts. +165 * The properties key for the proxy server. +166 * +167 * @deprecated use +168 * {@link org.owasp.dependencycheck.utils.Settings.KEYS#PROXY_SERVER} +169 * instead. 170 */ -171 public static final String PROXY_NON_PROXY_HOSTS = "proxy.nonproxyhosts"; -172 /** -173 * The properties key for the connection timeout. -174 */ -175 public static final String CONNECTION_TIMEOUT = "connection.timeout"; -176 /** -177 * The location of the temporary directory. -178 */ -179 public static final String TEMP_DIRECTORY = "temp.directory"; -180 /** -181 * The maximum number of threads to allocate when downloading files. -182 */ -183 public static final String MAX_DOWNLOAD_THREAD_POOL_SIZE = "max.download.threads"; -184 /** -185 * The key for a list of suppression files. -186 */ -187 public static final String SUPPRESSION_FILE = "suppression.file"; -188 /** -189 * The properties key for whether the Jar Analyzer is enabled. -190 */ -191 public static final String ANALYZER_JAR_ENABLED = "analyzer.jar.enabled"; -192 /** -193 * The properties key for whether experimental analyzers are loaded. -194 */ -195 public static final String ANALYZER_EXPERIMENTAL_ENABLED = "analyzer.experimental.enabled"; -196 /** -197 * The properties key for whether the Archive analyzer is enabled. -198 */ -199 public static final String ANALYZER_ARCHIVE_ENABLED = "analyzer.archive.enabled"; -200 /** -201 * The properties key for whether the node.js package analyzer is enabled. -202 */ -203 public static final String ANALYZER_NODE_PACKAGE_ENABLED = "analyzer.node.package.enabled"; -204 /** -205 * The properties key for whether the composer lock file analyzer is enabled. -206 */ -207 public static final String ANALYZER_COMPOSER_LOCK_ENABLED = "analyzer.composer.lock.enabled"; -208 /** -209 * The properties key for whether the Python Distribution analyzer is enabled. -210 */ -211 public static final String ANALYZER_PYTHON_DISTRIBUTION_ENABLED = "analyzer.python.distribution.enabled"; -212 /** -213 * The properties key for whether the Python Package analyzer is enabled. -214 */ -215 public static final String ANALYZER_PYTHON_PACKAGE_ENABLED = "analyzer.python.package.enabled"; -216 /** -217 * The properties key for whether the Ruby Gemspec Analyzer is enabled. -218 */ -219 public static final String ANALYZER_RUBY_GEMSPEC_ENABLED = "analyzer.ruby.gemspec.enabled"; -220 /** -221 * The properties key for whether the Autoconf analyzer is enabled. -222 */ -223 public static final String ANALYZER_AUTOCONF_ENABLED = "analyzer.autoconf.enabled"; -224 /** -225 * The properties key for whether the CMake analyzer is enabled. -226 */ -227 public static final String ANALYZER_CMAKE_ENABLED = "analyzer.cmake.enabled"; -228 /** -229 * The properties key for whether the Ruby Bundler Audit analyzer is enabled. -230 */ -231 public static final String ANALYZER_BUNDLE_AUDIT_ENABLED = "analyzer.bundle.audit.enabled"; -232 /** -233 * The properties key for whether the .NET Assembly analyzer is enabled. +171 @Deprecated +172 public static final String PROXY_URL = "proxy.server"; +173 /** +174 * The properties key for the proxy server. +175 */ +176 public static final String PROXY_SERVER = "proxy.server"; +177 /** +178 * The properties key for the proxy port - this must be an integer +179 * value. +180 */ +181 public static final String PROXY_PORT = "proxy.port"; +182 /** +183 * The properties key for the proxy username. +184 */ +185 public static final String PROXY_USERNAME = "proxy.username"; +186 /** +187 * The properties key for the proxy password. +188 */ +189 public static final String PROXY_PASSWORD = "proxy.password"; +190 /** +191 * The properties key for the non proxy hosts. +192 */ +193 public static final String PROXY_NON_PROXY_HOSTS = "proxy.nonproxyhosts"; +194 /** +195 * The properties key for the connection timeout. +196 */ +197 public static final String CONNECTION_TIMEOUT = "connection.timeout"; +198 /** +199 * The location of the temporary directory. +200 */ +201 public static final String TEMP_DIRECTORY = "temp.directory"; +202 /** +203 * The maximum number of threads to allocate when downloading files. +204 */ +205 public static final String MAX_DOWNLOAD_THREAD_POOL_SIZE = "max.download.threads"; +206 /** +207 * The key for the suppression file. +208 */ +209 public static final String SUPPRESSION_FILE = "suppression.file"; +210 /** +211 * The key for the hint file. +212 */ +213 public static final String HINTS_FILE = "hints.file"; +214 /** +215 * The properties key for whether the Jar Analyzer is enabled. +216 */ +217 public static final String ANALYZER_JAR_ENABLED = "analyzer.jar.enabled"; +218 /** +219 * The properties key for whether experimental analyzers are loaded. +220 */ +221 public static final String ANALYZER_EXPERIMENTAL_ENABLED = "analyzer.experimental.enabled"; +222 /** +223 * The properties key for whether the Archive analyzer is enabled. +224 */ +225 public static final String ANALYZER_ARCHIVE_ENABLED = "analyzer.archive.enabled"; +226 /** +227 * The properties key for whether the node.js package analyzer is +228 * enabled. +229 */ +230 public static final String ANALYZER_NODE_PACKAGE_ENABLED = "analyzer.node.package.enabled"; +231 /** +232 * The properties key for whether the composer lock file analyzer is +233 * enabled. 234 */ -235 public static final String ANALYZER_ASSEMBLY_ENABLED = "analyzer.assembly.enabled"; +235 public static final String ANALYZER_COMPOSER_LOCK_ENABLED = "analyzer.composer.lock.enabled"; 236 /** -237 * The properties key for whether the .NET Nuspec analyzer is enabled. -238 */ -239 public static final String ANALYZER_NUSPEC_ENABLED = "analyzer.nuspec.enabled"; -240 /** -241 * The properties key for whether the Nexus analyzer is enabled. -242 */ -243 public static final String ANALYZER_NEXUS_ENABLED = "analyzer.nexus.enabled"; -244 /** -245 * The properties key for the Nexus search URL. -246 */ -247 public static final String ANALYZER_NEXUS_URL = "analyzer.nexus.url"; -248 /** -249 * The properties key for using the proxy to reach Nexus. -250 */ -251 public static final String ANALYZER_NEXUS_USES_PROXY = "analyzer.nexus.proxy"; -252 /** -253 * The properties key for whether the Central analyzer is enabled. -254 */ -255 public static final String ANALYZER_CENTRAL_ENABLED = "analyzer.central.enabled"; -256 /** -257 * The properties key for whether the OpenSSL analyzer is enabled. -258 */ -259 public static final String ANALYZER_OPENSSL_ENABLED = "analyzer.openssl.enabled"; -260 /** -261 * The properties key for the Central search URL. -262 */ -263 public static final String ANALYZER_CENTRAL_URL = "analyzer.central.url"; -264 /** -265 * The path to mono, if available. -266 */ -267 public static final String ANALYZER_ASSEMBLY_MONO_PATH = "analyzer.assembly.mono.path"; -268 /** -269 * The path to bundle-audit, if available. -270 */ -271 public static final String ANALYZER_BUNDLE_AUDIT_PATH = "analyzer.bundle.audit.path"; -272 /** -273 * The additional configured zip file extensions, if available. -274 */ -275 public static final String ADDITIONAL_ZIP_EXTENSIONS = "extensions.zip"; -276 /** -277 * The key to obtain the path to the VFEED data file. -278 */ -279 public static final String VFEED_DATA_FILE = "vfeed.data_file"; -280 /** -281 * The key to obtain the VFEED connection string. -282 */ -283 public static final String VFEED_CONNECTION_STRING = "vfeed.connection_string"; -284 -285 /** -286 * The key to obtain the base download URL for the VFeed data file. -287 */ -288 public static final String VFEED_DOWNLOAD_URL = "vfeed.download_url"; -289 /** -290 * The key to obtain the download file name for the VFeed data. -291 */ -292 public static final String VFEED_DOWNLOAD_FILE = "vfeed.download_file"; -293 /** -294 * The key to obtain the VFeed update status. -295 */ -296 public static final String VFEED_UPDATE_STATUS = "vfeed.update_status"; -297 -298 /** -299 * The HTTP request method for query last modified date. -300 */ -301 public static final String DOWNLOADER_QUICK_QUERY_TIMESTAMP = "downloader.quick.query.timestamp"; -302 } -303 //</editor-fold> -304 -305 /** -306 * The logger. -307 */ -308 private static final Logger LOGGER = LoggerFactory.getLogger(Settings.class); -309 /** -310 * The properties file location. -311 */ -312 private static final String PROPERTIES_FILE = "dependencycheck.properties"; -313 /** -314 * Thread local settings. -315 */ -316 private static final ThreadLocal<Settings> LOCAL_SETTINGS = new ThreadLocal<Settings>(); -317 /** -318 * The properties. -319 */ -320 private Properties props = null; -321 -322 /** -323 * Private constructor for the Settings class. This class loads the properties files. -324 * -325 * @param propertiesFilePath the path to the base properties file to load -326 */ -327 private Settings(String propertiesFilePath) { -328 InputStream in = null; -329 props = new Properties(); -330 try { -331 in = this.getClass().getClassLoader().getResourceAsStream(propertiesFilePath); -332 props.load(in); -333 } catch (IOException ex) { -334 LOGGER.error("Unable to load default settings."); -335 LOGGER.debug("", ex); -336 } finally { -337 if (in != null) { -338 try { -339 in.close(); -340 } catch (IOException ex) { -341 LOGGER.trace("", ex); -342 } -343 } -344 } -345 logProperties("Properties loaded", props); -346 } -347 +237 * The properties key for whether the Python Distribution analyzer is +238 * enabled. +239 */ +240 public static final String ANALYZER_PYTHON_DISTRIBUTION_ENABLED = "analyzer.python.distribution.enabled"; +241 /** +242 * The properties key for whether the Python Package analyzer is +243 * enabled. +244 */ +245 public static final String ANALYZER_PYTHON_PACKAGE_ENABLED = "analyzer.python.package.enabled"; +246 /** +247 * The properties key for whether the Ruby Gemspec Analyzer is enabled. +248 */ +249 public static final String ANALYZER_RUBY_GEMSPEC_ENABLED = "analyzer.ruby.gemspec.enabled"; +250 /** +251 * The properties key for whether the Autoconf analyzer is enabled. +252 */ +253 public static final String ANALYZER_AUTOCONF_ENABLED = "analyzer.autoconf.enabled"; +254 /** +255 * The properties key for whether the CMake analyzer is enabled. +256 */ +257 public static final String ANALYZER_CMAKE_ENABLED = "analyzer.cmake.enabled"; +258 /** +259 * The properties key for whether the Ruby Bundler Audit analyzer is +260 * enabled. +261 */ +262 public static final String ANALYZER_BUNDLE_AUDIT_ENABLED = "analyzer.bundle.audit.enabled"; +263 /** +264 * The properties key for whether the .NET Assembly analyzer is enabled. +265 */ +266 public static final String ANALYZER_ASSEMBLY_ENABLED = "analyzer.assembly.enabled"; +267 /** +268 * The properties key for whether the .NET Nuspec analyzer is enabled. +269 */ +270 public static final String ANALYZER_NUSPEC_ENABLED = "analyzer.nuspec.enabled"; +271 /** +272 * The properties key for whether the Nexus analyzer is enabled. +273 */ +274 public static final String ANALYZER_NEXUS_ENABLED = "analyzer.nexus.enabled"; +275 /** +276 * The properties key for the Nexus search URL. +277 */ +278 public static final String ANALYZER_NEXUS_URL = "analyzer.nexus.url"; +279 /** +280 * The properties key for using the proxy to reach Nexus. +281 */ +282 public static final String ANALYZER_NEXUS_USES_PROXY = "analyzer.nexus.proxy"; +283 /** +284 * The properties key for whether the Central analyzer is enabled. +285 */ +286 public static final String ANALYZER_CENTRAL_ENABLED = "analyzer.central.enabled"; +287 /** +288 * The properties key for whether the OpenSSL analyzer is enabled. +289 */ +290 public static final String ANALYZER_OPENSSL_ENABLED = "analyzer.openssl.enabled"; +291 /** +292 * The properties key for the Central search URL. +293 */ +294 public static final String ANALYZER_CENTRAL_URL = "analyzer.central.url"; +295 /** +296 * The path to mono, if available. +297 */ +298 public static final String ANALYZER_ASSEMBLY_MONO_PATH = "analyzer.assembly.mono.path"; +299 /** +300 * The path to bundle-audit, if available. +301 */ +302 public static final String ANALYZER_BUNDLE_AUDIT_PATH = "analyzer.bundle.audit.path"; +303 /** +304 * The additional configured zip file extensions, if available. +305 */ +306 public static final String ADDITIONAL_ZIP_EXTENSIONS = "extensions.zip"; +307 /** +308 * The key to obtain the path to the VFEED data file. +309 */ +310 public static final String VFEED_DATA_FILE = "vfeed.data_file"; +311 /** +312 * The key to obtain the VFEED connection string. +313 */ +314 public static final String VFEED_CONNECTION_STRING = "vfeed.connection_string"; +315 +316 /** +317 * The key to obtain the base download URL for the VFeed data file. +318 */ +319 public static final String VFEED_DOWNLOAD_URL = "vfeed.download_url"; +320 /** +321 * The key to obtain the download file name for the VFeed data. +322 */ +323 public static final String VFEED_DOWNLOAD_FILE = "vfeed.download_file"; +324 /** +325 * The key to obtain the VFeed update status. +326 */ +327 public static final String VFEED_UPDATE_STATUS = "vfeed.update_status"; +328 +329 /** +330 * The HTTP request method for query last modified date. +331 */ +332 public static final String DOWNLOADER_QUICK_QUERY_TIMESTAMP = "downloader.quick.query.timestamp"; +333 } +334 //</editor-fold> +335 +336 /** +337 * The logger. +338 */ +339 private static final Logger LOGGER = LoggerFactory.getLogger(Settings.class); +340 /** +341 * The properties file location. +342 */ +343 private static final String PROPERTIES_FILE = "dependencycheck.properties"; +344 /** +345 * Thread local settings. +346 */ +347 private static final ThreadLocal<Settings> LOCAL_SETTINGS = new ThreadLocal<Settings>(); 348 /** -349 * Initializes the thread local settings object. Note, to use the settings object you must call this method. However, you must -350 * also call Settings.cleanup() to properly release resources. -351 */ -352 public static void initialize() { -353 LOCAL_SETTINGS.set(new Settings(PROPERTIES_FILE)); -354 } -355 -356 /** -357 * Initializes the thread local settings object. Note, to use the settings object you must call this method. However, you must -358 * also call Settings.cleanup() to properly release resources. -359 * -360 * @param propertiesFilePath the path to the base properties file to load -361 */ -362 public static void initialize(String propertiesFilePath) { -363 LOCAL_SETTINGS.set(new Settings(propertiesFilePath)); -364 } -365 -366 /** -367 * Cleans up resources to prevent memory leaks. -368 * -369 */ -370 public static void cleanup() { -371 cleanup(true); -372 } -373 -374 /** -375 * Cleans up resources to prevent memory leaks. -376 * -377 * @param deleteTemporary flag indicating whether any temporary directories generated should be removed -378 */ -379 public static void cleanup(boolean deleteTemporary) { -380 if (deleteTemporary && tempDirectory != null && tempDirectory.exists()) { -381 FileUtils.delete(tempDirectory); -382 if (tempDirectory.exists()) { -383 try { -384 Thread.sleep(2000); -385 } catch (InterruptedException ex) { -386 LOGGER.trace("ignore", ex); -387 } -388 FileUtils.delete(tempDirectory); -389 } -390 } -391 try { -392 LOCAL_SETTINGS.remove(); -393 } catch (Throwable ex) { -394 LOGGER.debug("Error cleaning up Settings", ex); -395 } -396 } -397 -398 /** -399 * Gets the underlying instance of the Settings object. -400 * -401 * @return the Settings object -402 */ -403 public static Settings getInstance() { -404 return LOCAL_SETTINGS.get(); -405 } -406 -407 /** -408 * Sets the instance of the Settings object to use in this thread. -409 * -410 * @param instance the instance of the settings object to use in this thread -411 */ -412 public static void setInstance(Settings instance) { -413 LOCAL_SETTINGS.set(instance); -414 } -415 -416 /** -417 * Logs the properties. This will not log any properties that contain 'password' in the key. -418 * -419 * @param header the header to print with the log message -420 * @param properties the properties to log -421 */ -422 private static void logProperties(String header, Properties properties) { -423 if (LOGGER.isDebugEnabled()) { -424 final StringWriter sw = new StringWriter(); -425 PrintWriter pw = null; -426 try { -427 pw = new PrintWriter(sw); -428 pw.format("%s:%n%n", header); -429 final Enumeration<?> e = properties.propertyNames(); -430 while (e.hasMoreElements()) { -431 final String key = (String) e.nextElement(); -432 if (key.contains("password")) { -433 pw.format("%s='*****'%n", key); -434 } else { -435 final String value = properties.getProperty(key); -436 if (value != null) { -437 pw.format("%s='%s'%n", key, value); -438 } -439 } -440 } -441 pw.flush(); -442 LOGGER.debug(sw.toString()); -443 } finally { -444 if (pw != null) { -445 pw.close(); -446 } -447 } -448 -449 } -450 } -451 -452 /** -453 * Sets a property value. +349 * The properties. +350 */ +351 private Properties props = null; +352 +353 /** +354 * Private constructor for the Settings class. This class loads the +355 * properties files. +356 * +357 * @param propertiesFilePath the path to the base properties file to load +358 */ +359 private Settings(String propertiesFilePath) { +360 InputStream in = null; +361 props = new Properties(); +362 try { +363 in = this.getClass().getClassLoader().getResourceAsStream(propertiesFilePath); +364 props.load(in); +365 } catch (IOException ex) { +366 LOGGER.error("Unable to load default settings."); +367 LOGGER.debug("", ex); +368 } finally { +369 if (in != null) { +370 try { +371 in.close(); +372 } catch (IOException ex) { +373 LOGGER.trace("", ex); +374 } +375 } +376 } +377 logProperties("Properties loaded", props); +378 } +379 +380 /** +381 * Initializes the thread local settings object. Note, to use the settings +382 * object you must call this method. However, you must also call +383 * Settings.cleanup() to properly release resources. +384 */ +385 public static void initialize() { +386 LOCAL_SETTINGS.set(new Settings(PROPERTIES_FILE)); +387 } +388 +389 /** +390 * Initializes the thread local settings object. Note, to use the settings +391 * object you must call this method. However, you must also call +392 * Settings.cleanup() to properly release resources. +393 * +394 * @param propertiesFilePath the path to the base properties file to load +395 */ +396 public static void initialize(String propertiesFilePath) { +397 LOCAL_SETTINGS.set(new Settings(propertiesFilePath)); +398 } +399 +400 /** +401 * Cleans up resources to prevent memory leaks. +402 * +403 */ +404 public static void cleanup() { +405 cleanup(true); +406 } +407 +408 /** +409 * Cleans up resources to prevent memory leaks. +410 * +411 * @param deleteTemporary flag indicating whether any temporary directories +412 * generated should be removed +413 */ +414 public static void cleanup(boolean deleteTemporary) { +415 if (deleteTemporary && tempDirectory != null && tempDirectory.exists()) { +416 FileUtils.delete(tempDirectory); +417 if (tempDirectory.exists()) { +418 try { +419 Thread.sleep(2000); +420 } catch (InterruptedException ex) { +421 LOGGER.trace("ignore", ex); +422 } +423 FileUtils.delete(tempDirectory); +424 } +425 } +426 try { +427 LOCAL_SETTINGS.remove(); +428 } catch (Throwable ex) { +429 LOGGER.debug("Error cleaning up Settings", ex); +430 } +431 } +432 +433 /** +434 * Gets the underlying instance of the Settings object. +435 * +436 * @return the Settings object +437 */ +438 public static Settings getInstance() { +439 return LOCAL_SETTINGS.get(); +440 } +441 +442 /** +443 * Sets the instance of the Settings object to use in this thread. +444 * +445 * @param instance the instance of the settings object to use in this thread +446 */ +447 public static void setInstance(Settings instance) { +448 LOCAL_SETTINGS.set(instance); +449 } +450 +451 /** +452 * Logs the properties. This will not log any properties that contain +453 * 'password' in the key. 454 * -455 * @param key the key for the property -456 * @param value the value for the property +455 * @param header the header to print with the log message +456 * @param properties the properties to log 457 */ -458 public static void setString(String key, String value) { -459 LOCAL_SETTINGS.get().props.setProperty(key, value); -460 LOGGER.debug("Setting: {}='{}'", key, value); -461 } -462 -463 /** -464 * Sets a property value only if the value is not null. -465 * -466 * @param key the key for the property -467 * @param value the value for the property -468 */ -469 public static void setStringIfNotNull(String key, String value) { -470 if (null != value) { -471 setString(key, value); -472 } -473 } -474 -475 /** -476 * Sets a property value only if the value is not null and not empty. -477 * -478 * @param key the key for the property -479 * @param value the value for the property -480 */ -481 public static void setStringIfNotEmpty(String key, String value) { -482 if (null != value && !value.isEmpty()) { -483 setString(key, value); -484 } -485 } -486 -487 /** -488 * Sets a property value. -489 * -490 * @param key the key for the property -491 * @param value the value for the property -492 */ -493 public static void setBoolean(String key, boolean value) { -494 setString(key, Boolean.toString(value)); -495 } -496 -497 /** -498 * Sets a property value only if the value is not null. -499 * -500 * @param key the key for the property -501 * @param value the value for the property -502 */ -503 public static void setBooleanIfNotNull(String key, Boolean value) { -504 if (null != value) { -505 setBoolean(key, value); -506 } -507 } -508 -509 /** -510 * Sets a property value. -511 * -512 * @param key the key for the property -513 * @param value the value for the property -514 */ -515 public static void setInt(String key, int value) { -516 LOCAL_SETTINGS.get().props.setProperty(key, String.valueOf(value)); -517 LOGGER.debug("Setting: {}='{}'", key, value); -518 } -519 -520 /** -521 * Sets a property value only if the value is not null. -522 * -523 * @param key the key for the property -524 * @param value the value for the property -525 */ -526 public static void setIntIfNotNull(String key, Integer value) { -527 if (null != value) { -528 setInt(key, value); -529 } -530 } -531 -532 /** -533 * Merges a new properties file into the current properties. This method allows for the loading of a user provided properties -534 * file.<br><br> -535 * <b>Note</b>: even if using this method - system properties will be loaded before properties loaded from files. -536 * -537 * @param filePath the path to the properties file to merge. -538 * @throws FileNotFoundException is thrown when the filePath points to a non-existent file -539 * @throws IOException is thrown when there is an exception loading/merging the properties -540 */ -541 public static void mergeProperties(File filePath) throws FileNotFoundException, IOException { -542 FileInputStream fis = null; -543 try { -544 fis = new FileInputStream(filePath); -545 mergeProperties(fis); -546 } finally { -547 if (fis != null) { -548 try { -549 fis.close(); -550 } catch (IOException ex) { -551 LOGGER.trace("close error", ex); -552 } -553 } -554 } -555 } -556 -557 /** -558 * Merges a new properties file into the current properties. This method allows for the loading of a user provided properties -559 * file.<br><br> -560 * Note: even if using this method - system properties will be loaded before properties loaded from files. -561 * -562 * @param filePath the path to the properties file to merge. -563 * @throws FileNotFoundException is thrown when the filePath points to a non-existent file -564 * @throws IOException is thrown when there is an exception loading/merging the properties -565 */ -566 public static void mergeProperties(String filePath) throws FileNotFoundException, IOException { -567 FileInputStream fis = null; -568 try { -569 fis = new FileInputStream(filePath); -570 mergeProperties(fis); -571 } finally { -572 if (fis != null) { -573 try { -574 fis.close(); -575 } catch (IOException ex) { -576 LOGGER.trace("close error", ex); -577 } -578 } -579 } -580 } -581 -582 /** -583 * Merges a new properties file into the current properties. This method allows for the loading of a user provided properties -584 * file.<br><br> -585 * <b>Note</b>: even if using this method - system properties will be loaded before properties loaded from files. -586 * -587 * @param stream an Input Stream pointing at a properties file to merge -588 * @throws IOException is thrown when there is an exception loading/merging the properties -589 */ -590 public static void mergeProperties(InputStream stream) throws IOException { -591 LOCAL_SETTINGS.get().props.load(stream); -592 logProperties("Properties updated via merge", LOCAL_SETTINGS.get().props); -593 } -594 -595 /** -596 * Returns a value from the properties file as a File object. If the value was specified as a system property or passed in via -597 * the -Dprop=value argument - this method will return the value from the system properties before the values in the contained -598 * configuration file. -599 * -600 * @param key the key to lookup within the properties file -601 * @return the property from the properties file converted to a File object -602 */ -603 public static File getFile(String key) { -604 final String file = getString(key); -605 if (file == null) { -606 return null; -607 } -608 return new File(file); -609 } -610 -611 /** -612 * Returns a value from the properties file as a File object. If the value was specified as a system property or passed in via -613 * the -Dprop=value argument - this method will return the value from the system properties before the values in the contained -614 * configuration file. -615 * -616 * This method will check the configured base directory and will use this as the base of the file path. Additionally, if the -617 * base directory begins with a leading "[JAR]\" sequence with the path to the folder containing the JAR file containing this -618 * class. -619 * -620 * @param key the key to lookup within the properties file -621 * @return the property from the properties file converted to a File object -622 */ -623 protected static File getDataFile(String key) { -624 final String file = getString(key); -625 LOGGER.debug("Settings.getDataFile() - file: '{}'", file); -626 if (file == null) { -627 return null; -628 } -629 if (file.startsWith("[JAR]")) { -630 LOGGER.debug("Settings.getDataFile() - transforming filename"); -631 final File jarPath = getJarPath(); -632 LOGGER.debug("Settings.getDataFile() - jar file: '{}'", jarPath.toString()); -633 final File retVal = new File(jarPath, file.substring(6)); -634 LOGGER.debug("Settings.getDataFile() - returning: '{}'", retVal.toString()); -635 return retVal; -636 } -637 return new File(file); -638 } -639 -640 /** -641 * Attempts to retrieve the folder containing the Jar file containing the Settings class. -642 * -643 * @return a File object -644 */ -645 private static File getJarPath() { -646 final String jarPath = Settings.class.getProtectionDomain().getCodeSource().getLocation().getPath(); -647 String decodedPath = "."; -648 try { -649 decodedPath = URLDecoder.decode(jarPath, "UTF-8"); -650 } catch (UnsupportedEncodingException ex) { -651 LOGGER.trace("", ex); +458 private static void logProperties(String header, Properties properties) { +459 if (LOGGER.isDebugEnabled()) { +460 final StringWriter sw = new StringWriter(); +461 PrintWriter pw = null; +462 try { +463 pw = new PrintWriter(sw); +464 pw.format("%s:%n%n", header); +465 final Enumeration<?> e = properties.propertyNames(); +466 while (e.hasMoreElements()) { +467 final String key = (String) e.nextElement(); +468 if (key.contains("password")) { +469 pw.format("%s='*****'%n", key); +470 } else { +471 final String value = properties.getProperty(key); +472 if (value != null) { +473 pw.format("%s='%s'%n", key, value); +474 } +475 } +476 } +477 pw.flush(); +478 LOGGER.debug(sw.toString()); +479 } finally { +480 if (pw != null) { +481 pw.close(); +482 } +483 } +484 +485 } +486 } +487 +488 /** +489 * Sets a property value. +490 * +491 * @param key the key for the property +492 * @param value the value for the property +493 */ +494 public static void setString(String key, String value) { +495 LOCAL_SETTINGS.get().props.setProperty(key, value); +496 LOGGER.debug("Setting: {}='{}'", key, value); +497 } +498 +499 /** +500 * Sets a property value only if the value is not null. +501 * +502 * @param key the key for the property +503 * @param value the value for the property +504 */ +505 public static void setStringIfNotNull(String key, String value) { +506 if (null != value) { +507 setString(key, value); +508 } +509 } +510 +511 /** +512 * Sets a property value only if the value is not null and not empty. +513 * +514 * @param key the key for the property +515 * @param value the value for the property +516 */ +517 public static void setStringIfNotEmpty(String key, String value) { +518 if (null != value && !value.isEmpty()) { +519 setString(key, value); +520 } +521 } +522 +523 /** +524 * Sets a property value. +525 * +526 * @param key the key for the property +527 * @param value the value for the property +528 */ +529 public static void setBoolean(String key, boolean value) { +530 setString(key, Boolean.toString(value)); +531 } +532 +533 /** +534 * Sets a property value only if the value is not null. +535 * +536 * @param key the key for the property +537 * @param value the value for the property +538 */ +539 public static void setBooleanIfNotNull(String key, Boolean value) { +540 if (null != value) { +541 setBoolean(key, value); +542 } +543 } +544 +545 /** +546 * Sets a property value. +547 * +548 * @param key the key for the property +549 * @param value the value for the property +550 */ +551 public static void setInt(String key, int value) { +552 LOCAL_SETTINGS.get().props.setProperty(key, String.valueOf(value)); +553 LOGGER.debug("Setting: {}='{}'", key, value); +554 } +555 +556 /** +557 * Sets a property value only if the value is not null. +558 * +559 * @param key the key for the property +560 * @param value the value for the property +561 */ +562 public static void setIntIfNotNull(String key, Integer value) { +563 if (null != value) { +564 setInt(key, value); +565 } +566 } +567 +568 /** +569 * Merges a new properties file into the current properties. This method +570 * allows for the loading of a user provided properties file.<br><br> +571 * <b>Note</b>: even if using this method - system properties will be loaded +572 * before properties loaded from files. +573 * +574 * @param filePath the path to the properties file to merge. +575 * @throws FileNotFoundException is thrown when the filePath points to a +576 * non-existent file +577 * @throws IOException is thrown when there is an exception loading/merging +578 * the properties +579 */ +580 public static void mergeProperties(File filePath) throws FileNotFoundException, IOException { +581 FileInputStream fis = null; +582 try { +583 fis = new FileInputStream(filePath); +584 mergeProperties(fis); +585 } finally { +586 if (fis != null) { +587 try { +588 fis.close(); +589 } catch (IOException ex) { +590 LOGGER.trace("close error", ex); +591 } +592 } +593 } +594 } +595 +596 /** +597 * Merges a new properties file into the current properties. This method +598 * allows for the loading of a user provided properties file.<br><br> +599 * Note: even if using this method - system properties will be loaded before +600 * properties loaded from files. +601 * +602 * @param filePath the path to the properties file to merge. +603 * @throws FileNotFoundException is thrown when the filePath points to a +604 * non-existent file +605 * @throws IOException is thrown when there is an exception loading/merging +606 * the properties +607 */ +608 public static void mergeProperties(String filePath) throws FileNotFoundException, IOException { +609 FileInputStream fis = null; +610 try { +611 fis = new FileInputStream(filePath); +612 mergeProperties(fis); +613 } finally { +614 if (fis != null) { +615 try { +616 fis.close(); +617 } catch (IOException ex) { +618 LOGGER.trace("close error", ex); +619 } +620 } +621 } +622 } +623 +624 /** +625 * Merges a new properties file into the current properties. This method +626 * allows for the loading of a user provided properties file.<br><br> +627 * <b>Note</b>: even if using this method - system properties will be loaded +628 * before properties loaded from files. +629 * +630 * @param stream an Input Stream pointing at a properties file to merge +631 * @throws IOException is thrown when there is an exception loading/merging +632 * the properties +633 */ +634 public static void mergeProperties(InputStream stream) throws IOException { +635 LOCAL_SETTINGS.get().props.load(stream); +636 logProperties("Properties updated via merge", LOCAL_SETTINGS.get().props); +637 } +638 +639 /** +640 * Returns a value from the properties file as a File object. If the value +641 * was specified as a system property or passed in via the -Dprop=value +642 * argument - this method will return the value from the system properties +643 * before the values in the contained configuration file. +644 * +645 * @param key the key to lookup within the properties file +646 * @return the property from the properties file converted to a File object +647 */ +648 public static File getFile(String key) { +649 final String file = getString(key); +650 if (file == null) { +651 return null; 652 } -653 -654 final File path = new File(decodedPath); -655 if (path.getName().toLowerCase().endsWith(".jar")) { -656 return path.getParentFile(); -657 } else { -658 return new File("."); -659 } -660 } -661 -662 /** -663 * Returns a value from the properties file. If the value was specified as a system property or passed in via the -Dprop=value -664 * argument - this method will return the value from the system properties before the values in the contained configuration -665 * file. +653 return new File(file); +654 } +655 +656 /** +657 * Returns a value from the properties file as a File object. If the value +658 * was specified as a system property or passed in via the -Dprop=value +659 * argument - this method will return the value from the system properties +660 * before the values in the contained configuration file. +661 * +662 * This method will check the configured base directory and will use this as +663 * the base of the file path. Additionally, if the base directory begins +664 * with a leading "[JAR]\" sequence with the path to the folder containing +665 * the JAR file containing this class. 666 * 667 * @param key the key to lookup within the properties file -668 * @param defaultValue the default value for the requested property -669 * @return the property from the properties file -670 */ -671 public static String getString(String key, String defaultValue) { -672 final String str = System.getProperty(key, LOCAL_SETTINGS.get().props.getProperty(key, defaultValue)); -673 return str; -674 } -675 -676 /** -677 * A reference to the temporary directory; used incase it needs to be deleted during cleanup. -678 */ -679 private static File tempDirectory = null; -680 -681 /** -682 * Returns the temporary directory. -683 * -684 * @return the temporary directory -685 * @throws java.io.IOException thrown if the temporary directory does not exist and cannot be created -686 */ -687 public static File getTempDirectory() throws IOException { -688 final File tmpDir = new File(Settings.getString(Settings.KEYS.TEMP_DIRECTORY, System.getProperty("java.io.tmpdir")), "dctemp"); -689 if (!tmpDir.exists() && !tmpDir.mkdirs()) { -690 final String msg = String.format("Unable to make a temporary folder '%s'", tmpDir.getPath()); -691 throw new IOException(msg); -692 } -693 tempDirectory = tmpDir; -694 return tmpDir; -695 } -696 -697 /** -698 * Returns a value from the properties file. If the value was specified as a system property or passed in via the -Dprop=value -699 * argument - this method will return the value from the system properties before the values in the contained configuration -700 * file. -701 * -702 * @param key the key to lookup within the properties file -703 * @return the property from the properties file -704 */ -705 public static String getString(String key) { -706 return System.getProperty(key, LOCAL_SETTINGS.get().props.getProperty(key)); -707 } -708 -709 /** -710 * Removes a property from the local properties collection. This is mainly used in test cases. -711 * -712 * @param key the property key to remove -713 */ -714 public static void removeProperty(String key) { -715 LOCAL_SETTINGS.get().props.remove(key); -716 } -717 -718 /** -719 * Returns an int value from the properties file. If the value was specified as a system property or passed in via the -720 * -Dprop=value argument - this method will return the value from the system properties before the values in the contained -721 * configuration file. -722 * -723 * @param key the key to lookup within the properties file -724 * @return the property from the properties file -725 * @throws InvalidSettingException is thrown if there is an error retrieving the setting -726 */ -727 public static int getInt(String key) throws InvalidSettingException { -728 try { -729 return Integer.parseInt(Settings.getString(key)); -730 } catch (NumberFormatException ex) { -731 throw new InvalidSettingException("Could not convert property '" + key + "' to an int.", ex); -732 } -733 } -734 -735 /** -736 * Returns an int value from the properties file. If the value was specified as a system property or passed in via the -737 * -Dprop=value argument - this method will return the value from the system properties before the values in the contained -738 * configuration file. -739 * -740 * @param key the key to lookup within the properties file -741 * @param defaultValue the default value to return -742 * @return the property from the properties file or the defaultValue if the property does not exist or cannot be converted to -743 * an integer -744 */ -745 public static int getInt(String key, int defaultValue) { -746 int value; -747 try { -748 value = Integer.parseInt(Settings.getString(key)); -749 } catch (NumberFormatException ex) { -750 if (!Settings.getString(key, "").isEmpty()) { -751 LOGGER.debug("Could not convert property '{}={}' to an int; using {} instead.", key, Settings.getString(key), defaultValue); -752 } -753 value = defaultValue; -754 } -755 return value; -756 } -757 -758 /** -759 * Returns a long value from the properties file. If the value was specified as a system property or passed in via the -760 * -Dprop=value argument - this method will return the value from the system properties before the values in the contained -761 * configuration file. -762 * -763 * @param key the key to lookup within the properties file -764 * @return the property from the properties file -765 * @throws InvalidSettingException is thrown if there is an error retrieving the setting +668 * @return the property from the properties file converted to a File object +669 */ +670 protected static File getDataFile(String key) { +671 final String file = getString(key); +672 LOGGER.debug("Settings.getDataFile() - file: '{}'", file); +673 if (file == null) { +674 return null; +675 } +676 if (file.startsWith("[JAR]")) { +677 LOGGER.debug("Settings.getDataFile() - transforming filename"); +678 final File jarPath = getJarPath(); +679 LOGGER.debug("Settings.getDataFile() - jar file: '{}'", jarPath.toString()); +680 final File retVal = new File(jarPath, file.substring(6)); +681 LOGGER.debug("Settings.getDataFile() - returning: '{}'", retVal.toString()); +682 return retVal; +683 } +684 return new File(file); +685 } +686 +687 /** +688 * Attempts to retrieve the folder containing the Jar file containing the +689 * Settings class. +690 * +691 * @return a File object +692 */ +693 private static File getJarPath() { +694 final String jarPath = Settings.class.getProtectionDomain().getCodeSource().getLocation().getPath(); +695 String decodedPath = "."; +696 try { +697 decodedPath = URLDecoder.decode(jarPath, "UTF-8"); +698 } catch (UnsupportedEncodingException ex) { +699 LOGGER.trace("", ex); +700 } +701 +702 final File path = new File(decodedPath); +703 if (path.getName().toLowerCase().endsWith(".jar")) { +704 return path.getParentFile(); +705 } else { +706 return new File("."); +707 } +708 } +709 +710 /** +711 * Returns a value from the properties file. If the value was specified as a +712 * system property or passed in via the -Dprop=value argument - this method +713 * will return the value from the system properties before the values in the +714 * contained configuration file. +715 * +716 * @param key the key to lookup within the properties file +717 * @param defaultValue the default value for the requested property +718 * @return the property from the properties file +719 */ +720 public static String getString(String key, String defaultValue) { +721 final String str = System.getProperty(key, LOCAL_SETTINGS.get().props.getProperty(key, defaultValue)); +722 return str; +723 } +724 +725 /** +726 * A reference to the temporary directory; used incase it needs to be +727 * deleted during cleanup. +728 */ +729 private static File tempDirectory = null; +730 +731 /** +732 * Returns the temporary directory. +733 * +734 * @return the temporary directory +735 * @throws java.io.IOException thrown if the temporary directory does not +736 * exist and cannot be created +737 */ +738 public static File getTempDirectory() throws IOException { +739 final File tmpDir = new File(Settings.getString(Settings.KEYS.TEMP_DIRECTORY, System.getProperty("java.io.tmpdir")), "dctemp"); +740 if (!tmpDir.exists() && !tmpDir.mkdirs()) { +741 final String msg = String.format("Unable to make a temporary folder '%s'", tmpDir.getPath()); +742 throw new IOException(msg); +743 } +744 tempDirectory = tmpDir; +745 return tmpDir; +746 } +747 +748 /** +749 * Returns a value from the properties file. If the value was specified as a +750 * system property or passed in via the -Dprop=value argument - this method +751 * will return the value from the system properties before the values in the +752 * contained configuration file. +753 * +754 * @param key the key to lookup within the properties file +755 * @return the property from the properties file +756 */ +757 public static String getString(String key) { +758 return System.getProperty(key, LOCAL_SETTINGS.get().props.getProperty(key)); +759 } +760 +761 /** +762 * Removes a property from the local properties collection. This is mainly +763 * used in test cases. +764 * +765 * @param key the property key to remove 766 */ -767 public static long getLong(String key) throws InvalidSettingException { -768 try { -769 return Long.parseLong(Settings.getString(key)); -770 } catch (NumberFormatException ex) { -771 throw new InvalidSettingException("Could not convert property '" + key + "' to a long.", ex); -772 } -773 } -774 -775 /** -776 * Returns a boolean value from the properties file. If the value was specified as a system property or passed in via the -777 * <code>-Dprop=value</code> argument this method will return the value from the system properties before the values in the -778 * contained configuration file. -779 * -780 * @param key the key to lookup within the properties file -781 * @return the property from the properties file -782 * @throws InvalidSettingException is thrown if there is an error retrieving the setting -783 */ -784 public static boolean getBoolean(String key) throws InvalidSettingException { -785 return Boolean.parseBoolean(Settings.getString(key)); -786 } -787 -788 /** -789 * Returns a boolean value from the properties file. If the value was specified as a system property or passed in via the -790 * <code>-Dprop=value</code> argument this method will return the value from the system properties before the values in the -791 * contained configuration file. -792 * -793 * @param key the key to lookup within the properties file -794 * @param defaultValue the default value to return if the setting does not exist -795 * @return the property from the properties file -796 * @throws InvalidSettingException is thrown if there is an error retrieving the setting -797 */ -798 public static boolean getBoolean(String key, boolean defaultValue) throws InvalidSettingException { -799 return Boolean.parseBoolean(Settings.getString(key, Boolean.toString(defaultValue))); -800 } -801 -802 /** -803 * Returns a connection string from the configured properties. If the connection string contains a %s, this method will -804 * determine the 'data' directory and replace the %s with the path to the data directory. If the data directory does not -805 * exists it will be created. -806 * -807 * @param connectionStringKey the property file key for the connection string -808 * @param dbFileNameKey the settings key for the db filename -809 * @return the connection string -810 * @throws IOException thrown the data directory cannot be created -811 * @throws InvalidSettingException thrown if there is an invalid setting -812 */ -813 public static String getConnectionString(String connectionStringKey, String dbFileNameKey) -814 throws IOException, InvalidSettingException { -815 final String connStr = Settings.getString(connectionStringKey); -816 if (connStr == null) { -817 final String msg = String.format("Invalid properties file; %s is missing.", connectionStringKey); -818 throw new InvalidSettingException(msg); -819 } -820 if (connStr.contains("%s")) { -821 final File directory = getDataDirectory(); -822 String fileName = null; -823 if (dbFileNameKey != null) { -824 fileName = Settings.getString(dbFileNameKey); -825 } -826 if (fileName == null) { -827 final String msg = String.format("Invalid properties file to get a file based connection string; '%s' must be defined.", -828 dbFileNameKey); -829 throw new InvalidSettingException(msg); -830 } -831 if (connStr.startsWith("jdbc:h2:file:") && fileName.endsWith(".h2.db")) { -832 fileName = fileName.substring(0, fileName.length() - 6); -833 } -834 // yes, for H2 this path won't actually exists - but this is sufficient to get the value needed -835 final File dbFile = new File(directory, fileName); -836 final String cString = String.format(connStr, dbFile.getCanonicalPath()); -837 LOGGER.debug("Connection String: '{}'", cString); -838 return cString; -839 } -840 return connStr; -841 } -842 -843 /** -844 * Retrieves the directory that the JAR file exists in so that we can ensure we always use a common data directory for the -845 * embedded H2 database. This is public solely for some unit tests; otherwise this should be private. -846 * -847 * @return the data directory to store data files -848 * @throws IOException is thrown if an IOException occurs of course... -849 */ -850 public static File getDataDirectory() throws IOException { -851 final File path = Settings.getDataFile(Settings.KEYS.DATA_DIRECTORY); -852 if (path.exists() || path.mkdirs()) { -853 return path; -854 } -855 throw new IOException(String.format("Unable to create the data directory '%s'", path.getAbsolutePath())); -856 } -857 } +767 public static void removeProperty(String key) { +768 LOCAL_SETTINGS.get().props.remove(key); +769 } +770 +771 /** +772 * Returns an int value from the properties file. If the value was specified +773 * as a system property or passed in via the -Dprop=value argument - this +774 * method will return the value from the system properties before the values +775 * in the contained configuration file. +776 * +777 * @param key the key to lookup within the properties file +778 * @return the property from the properties file +779 * @throws InvalidSettingException is thrown if there is an error retrieving +780 * the setting +781 */ +782 public static int getInt(String key) throws InvalidSettingException { +783 try { +784 return Integer.parseInt(Settings.getString(key)); +785 } catch (NumberFormatException ex) { +786 throw new InvalidSettingException("Could not convert property '" + key + "' to an int.", ex); +787 } +788 } +789 +790 /** +791 * Returns an int value from the properties file. If the value was specified +792 * as a system property or passed in via the -Dprop=value argument - this +793 * method will return the value from the system properties before the values +794 * in the contained configuration file. +795 * +796 * @param key the key to lookup within the properties file +797 * @param defaultValue the default value to return +798 * @return the property from the properties file or the defaultValue if the +799 * property does not exist or cannot be converted to an integer +800 */ +801 public static int getInt(String key, int defaultValue) { +802 int value; +803 try { +804 value = Integer.parseInt(Settings.getString(key)); +805 } catch (NumberFormatException ex) { +806 if (!Settings.getString(key, "").isEmpty()) { +807 LOGGER.debug("Could not convert property '{}={}' to an int; using {} instead.", key, Settings.getString(key), defaultValue); +808 } +809 value = defaultValue; +810 } +811 return value; +812 } +813 +814 /** +815 * Returns a long value from the properties file. If the value was specified +816 * as a system property or passed in via the -Dprop=value argument - this +817 * method will return the value from the system properties before the values +818 * in the contained configuration file. +819 * +820 * @param key the key to lookup within the properties file +821 * @return the property from the properties file +822 * @throws InvalidSettingException is thrown if there is an error retrieving +823 * the setting +824 */ +825 public static long getLong(String key) throws InvalidSettingException { +826 try { +827 return Long.parseLong(Settings.getString(key)); +828 } catch (NumberFormatException ex) { +829 throw new InvalidSettingException("Could not convert property '" + key + "' to a long.", ex); +830 } +831 } +832 +833 /** +834 * Returns a boolean value from the properties file. If the value was +835 * specified as a system property or passed in via the +836 * <code>-Dprop=value</code> argument this method will return the value from +837 * the system properties before the values in the contained configuration +838 * file. +839 * +840 * @param key the key to lookup within the properties file +841 * @return the property from the properties file +842 * @throws InvalidSettingException is thrown if there is an error retrieving +843 * the setting +844 */ +845 public static boolean getBoolean(String key) throws InvalidSettingException { +846 return Boolean.parseBoolean(Settings.getString(key)); +847 } +848 +849 /** +850 * Returns a boolean value from the properties file. If the value was +851 * specified as a system property or passed in via the +852 * <code>-Dprop=value</code> argument this method will return the value from +853 * the system properties before the values in the contained configuration +854 * file. +855 * +856 * @param key the key to lookup within the properties file +857 * @param defaultValue the default value to return if the setting does not +858 * exist +859 * @return the property from the properties file +860 * @throws InvalidSettingException is thrown if there is an error retrieving +861 * the setting +862 */ +863 public static boolean getBoolean(String key, boolean defaultValue) throws InvalidSettingException { +864 return Boolean.parseBoolean(Settings.getString(key, Boolean.toString(defaultValue))); +865 } +866 +867 /** +868 * Returns a connection string from the configured properties. If the +869 * connection string contains a %s, this method will determine the 'data' +870 * directory and replace the %s with the path to the data directory. If the +871 * data directory does not exists it will be created. +872 * +873 * @param connectionStringKey the property file key for the connection +874 * string +875 * @param dbFileNameKey the settings key for the db filename +876 * @return the connection string +877 * @throws IOException thrown the data directory cannot be created +878 * @throws InvalidSettingException thrown if there is an invalid setting +879 */ +880 public static String getConnectionString(String connectionStringKey, String dbFileNameKey) +881 throws IOException, InvalidSettingException { +882 final String connStr = Settings.getString(connectionStringKey); +883 if (connStr == null) { +884 final String msg = String.format("Invalid properties file; %s is missing.", connectionStringKey); +885 throw new InvalidSettingException(msg); +886 } +887 if (connStr.contains("%s")) { +888 final File directory = getDataDirectory(); +889 String fileName = null; +890 if (dbFileNameKey != null) { +891 fileName = Settings.getString(dbFileNameKey); +892 } +893 if (fileName == null) { +894 final String msg = String.format("Invalid properties file to get a file based connection string; '%s' must be defined.", +895 dbFileNameKey); +896 throw new InvalidSettingException(msg); +897 } +898 if (connStr.startsWith("jdbc:h2:file:") && fileName.endsWith(".h2.db")) { +899 fileName = fileName.substring(0, fileName.length() - 6); +900 } +901 // yes, for H2 this path won't actually exists - but this is sufficient to get the value needed +902 final File dbFile = new File(directory, fileName); +903 final String cString = String.format(connStr, dbFile.getCanonicalPath()); +904 LOGGER.debug("Connection String: '{}'", cString); +905 return cString; +906 } +907 return connStr; +908 } +909 +910 /** +911 * Retrieves the directory that the JAR file exists in so that we can ensure +912 * we always use a common data directory for the embedded H2 database. This +913 * is public solely for some unit tests; otherwise this should be private. +914 * +915 * @return the data directory to store data files +916 * @throws IOException is thrown if an IOException occurs of course... +917 */ +918 public static File getDataDirectory() throws IOException { +919 final File path = Settings.getDataFile(Settings.KEYS.DATA_DIRECTORY); +920 if (path.exists() || path.mkdirs()) { +921 return path; +922 } +923 throw new IOException(String.format("Unable to create the data directory '%s'", path.getAbsolutePath())); +924 } +925 }
      diff --git a/dependency-check-utils/xref/org/owasp/dependencycheck/utils/URLConnectionFactory.html b/dependency-check-utils/xref/org/owasp/dependencycheck/utils/URLConnectionFactory.html index 3271c74d6..f38bcbe57 100644 --- a/dependency-check-utils/xref/org/owasp/dependencycheck/utils/URLConnectionFactory.html +++ b/dependency-check-utils/xref/org/owasp/dependencycheck/utils/URLConnectionFactory.html @@ -36,142 +36,180 @@ 28 import java.net.Proxy; 29 import java.net.SocketAddress; 30 import java.net.URL; -31 -32 /** -33 * A URLConnection Factory to create new connections. This encapsulates several configuration checks to ensure that the connection -34 * uses the correct proxy settings. -35 * -36 * @author Jeremy Long -37 */ -38 public final class URLConnectionFactory { -39 -40 /** -41 * Private constructor for this factory. -42 */ -43 private URLConnectionFactory() { -44 } +31 import java.security.KeyManagementException; +32 import java.security.NoSuchAlgorithmException; +33 import javax.net.ssl.HttpsURLConnection; +34 import org.slf4j.Logger; +35 import org.slf4j.LoggerFactory; +36 +37 /** +38 * A URLConnection Factory to create new connections. This encapsulates several +39 * configuration checks to ensure that the connection uses the correct proxy +40 * settings. +41 * +42 * @author Jeremy Long +43 */ +44 public final class URLConnectionFactory { 45 46 /** -47 * Utility method to create an HttpURLConnection. If the application is configured to use a proxy this method will retrieve -48 * the proxy settings and use them when setting up the connection. -49 * -50 * @param url the url to connect to -51 * @return an HttpURLConnection -52 * @throws URLConnectionFailureException thrown if there is an exception +47 * The logger. +48 */ +49 private static final Logger LOGGER = LoggerFactory.getLogger(URLConnectionFactory.class); +50 +51 /** +52 * Private constructor for this factory. 53 */ -54 @SuppressFBWarnings(value = "RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE", justification = "Just being extra safe") -55 public static HttpURLConnection createHttpURLConnection(URL url) throws URLConnectionFailureException { -56 HttpURLConnection conn = null; -57 final String proxyUrl = Settings.getString(Settings.KEYS.PROXY_SERVER); -58 -59 try { -60 if (proxyUrl != null && !matchNonProxy(url)) { -61 final int proxyPort = Settings.getInt(Settings.KEYS.PROXY_PORT); -62 final SocketAddress address = new InetSocketAddress(proxyUrl, proxyPort); -63 -64 final String username = Settings.getString(Settings.KEYS.PROXY_USERNAME); -65 final String password = Settings.getString(Settings.KEYS.PROXY_PASSWORD); -66 -67 if (username != null && password != null) { -68 final Authenticator auth = new Authenticator() { -69 @Override -70 public PasswordAuthentication getPasswordAuthentication() { -71 if (getRequestorType().equals(Authenticator.RequestorType.PROXY)) { -72 return new PasswordAuthentication(username, password.toCharArray()); -73 } -74 return super.getPasswordAuthentication(); -75 } -76 }; -77 Authenticator.setDefault(auth); -78 } -79 -80 final Proxy proxy = new Proxy(Proxy.Type.HTTP, address); -81 conn = (HttpURLConnection) url.openConnection(proxy); -82 } else { -83 conn = (HttpURLConnection) url.openConnection(); -84 } -85 final int timeout = Settings.getInt(Settings.KEYS.CONNECTION_TIMEOUT, 10000); -86 conn.setConnectTimeout(timeout); -87 conn.setInstanceFollowRedirects(true); -88 } catch (IOException ex) { -89 if (conn != null) { -90 try { -91 conn.disconnect(); -92 } finally { -93 conn = null; -94 } -95 } -96 throw new URLConnectionFailureException("Error getting connection.", ex); -97 } -98 return conn; -99 } -100 -101 /** -102 * Check if hostname matches nonProxy settings -103 * -104 * @param url the url to connect to -105 * @return matching result. true: match nonProxy -106 */ -107 private static boolean matchNonProxy(final URL url) { -108 final String host = url.getHost(); -109 -110 // code partially from org.apache.maven.plugins.site.AbstractDeployMojo#getProxyInfo -111 final String nonProxyHosts = Settings.getString(Settings.KEYS.PROXY_NON_PROXY_HOSTS); -112 if (null != nonProxyHosts) { -113 final String[] nonProxies = nonProxyHosts.split("(,)|(;)|(\\|)"); -114 for (final String nonProxyHost : nonProxies) { -115 //if ( StringUtils.contains( nonProxyHost, "*" ) ) -116 if (null != nonProxyHost && nonProxyHost.contains("*")) { -117 // Handle wildcard at the end, beginning or middle of the nonProxyHost -118 final int pos = nonProxyHost.indexOf('*'); -119 final String nonProxyHostPrefix = nonProxyHost.substring(0, pos); -120 final String nonProxyHostSuffix = nonProxyHost.substring(pos + 1); -121 // prefix* -122 if (!StringUtils.isEmpty(nonProxyHostPrefix) && host.startsWith(nonProxyHostPrefix) && StringUtils.isEmpty(nonProxyHostSuffix)) { -123 return true; -124 } -125 // *suffix -126 if (StringUtils.isEmpty(nonProxyHostPrefix) && !StringUtils.isEmpty(nonProxyHostSuffix) && host.endsWith(nonProxyHostSuffix)) { -127 return true; -128 } -129 // prefix*suffix -130 if (!StringUtils.isEmpty(nonProxyHostPrefix) && host.startsWith(nonProxyHostPrefix) && !StringUtils.isEmpty(nonProxyHostSuffix) -131 && host.endsWith(nonProxyHostSuffix)) { -132 return true; -133 } -134 } else if (host.equals(nonProxyHost)) { -135 return true; -136 } -137 } -138 } -139 return false; -140 } -141 -142 /** -143 * Utility method to create an HttpURLConnection. The use of a proxy here is optional as there may be cases where a proxy is -144 * configured but we don't want to use it (for example, if there's an internal repository configured) -145 * -146 * @param url the URL to connect to -147 * @param proxy whether to use the proxy (if configured) -148 * @return a newly constructed HttpURLConnection -149 * @throws URLConnectionFailureException thrown if there is an exception -150 */ -151 public static HttpURLConnection createHttpURLConnection(URL url, boolean proxy) throws URLConnectionFailureException { -152 if (proxy) { -153 return createHttpURLConnection(url); -154 } -155 HttpURLConnection conn = null; -156 try { -157 conn = (HttpURLConnection) url.openConnection(); -158 final int timeout = Settings.getInt(Settings.KEYS.CONNECTION_TIMEOUT, 10000); -159 conn.setConnectTimeout(timeout); -160 conn.setInstanceFollowRedirects(true); -161 } catch (IOException ioe) { -162 throw new URLConnectionFailureException("Error getting connection.", ioe); -163 } -164 return conn; -165 } -166 } +54 private URLConnectionFactory() { +55 } +56 +57 /** +58 * Utility method to create an HttpURLConnection. If the application is +59 * configured to use a proxy this method will retrieve the proxy settings +60 * and use them when setting up the connection. +61 * +62 * @param url the url to connect to +63 * @return an HttpURLConnection +64 * @throws URLConnectionFailureException thrown if there is an exception +65 */ +66 @SuppressFBWarnings(value = "RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE", justification = "Just being extra safe") +67 public static HttpURLConnection createHttpURLConnection(URL url) throws URLConnectionFailureException { +68 HttpURLConnection conn = null; +69 final String proxyUrl = Settings.getString(Settings.KEYS.PROXY_SERVER); +70 +71 try { +72 if (proxyUrl != null && !matchNonProxy(url)) { +73 final int proxyPort = Settings.getInt(Settings.KEYS.PROXY_PORT); +74 final SocketAddress address = new InetSocketAddress(proxyUrl, proxyPort); +75 +76 final String username = Settings.getString(Settings.KEYS.PROXY_USERNAME); +77 final String password = Settings.getString(Settings.KEYS.PROXY_PASSWORD); +78 +79 if (username != null && password != null) { +80 final Authenticator auth = new Authenticator() { +81 @Override +82 public PasswordAuthentication getPasswordAuthentication() { +83 if (getRequestorType().equals(Authenticator.RequestorType.PROXY)) { +84 return new PasswordAuthentication(username, password.toCharArray()); +85 } +86 return super.getPasswordAuthentication(); +87 } +88 }; +89 Authenticator.setDefault(auth); +90 } +91 +92 final Proxy proxy = new Proxy(Proxy.Type.HTTP, address); +93 conn = (HttpURLConnection) url.openConnection(proxy); +94 } else { +95 conn = (HttpURLConnection) url.openConnection(); +96 } +97 final int timeout = Settings.getInt(Settings.KEYS.CONNECTION_TIMEOUT, 10000); +98 conn.setConnectTimeout(timeout); +99 conn.setInstanceFollowRedirects(true); +100 } catch (IOException ex) { +101 if (conn != null) { +102 try { +103 conn.disconnect(); +104 } finally { +105 conn = null; +106 } +107 } +108 throw new URLConnectionFailureException("Error getting connection.", ex); +109 } +110 configureTLS(url, conn); +111 return conn; +112 } +113 +114 /** +115 * Check if hostname matches nonProxy settings +116 * +117 * @param url the url to connect to +118 * @return matching result. true: match nonProxy +119 */ +120 private static boolean matchNonProxy(final URL url) { +121 final String host = url.getHost(); +122 +123 // code partially from org.apache.maven.plugins.site.AbstractDeployMojo#getProxyInfo +124 final String nonProxyHosts = Settings.getString(Settings.KEYS.PROXY_NON_PROXY_HOSTS); +125 if (null != nonProxyHosts) { +126 final String[] nonProxies = nonProxyHosts.split("(,)|(;)|(\\|)"); +127 for (final String nonProxyHost : nonProxies) { +128 //if ( StringUtils.contains( nonProxyHost, "*" ) ) +129 if (null != nonProxyHost && nonProxyHost.contains("*")) { +130 // Handle wildcard at the end, beginning or middle of the nonProxyHost +131 final int pos = nonProxyHost.indexOf('*'); +132 final String nonProxyHostPrefix = nonProxyHost.substring(0, pos); +133 final String nonProxyHostSuffix = nonProxyHost.substring(pos + 1); +134 // prefix* +135 if (!StringUtils.isEmpty(nonProxyHostPrefix) && host.startsWith(nonProxyHostPrefix) && StringUtils.isEmpty(nonProxyHostSuffix)) { +136 return true; +137 } +138 // *suffix +139 if (StringUtils.isEmpty(nonProxyHostPrefix) && !StringUtils.isEmpty(nonProxyHostSuffix) && host.endsWith(nonProxyHostSuffix)) { +140 return true; +141 } +142 // prefix*suffix +143 if (!StringUtils.isEmpty(nonProxyHostPrefix) && host.startsWith(nonProxyHostPrefix) && !StringUtils.isEmpty(nonProxyHostSuffix) +144 && host.endsWith(nonProxyHostSuffix)) { +145 return true; +146 } +147 } else if (host.equals(nonProxyHost)) { +148 return true; +149 } +150 } +151 } +152 return false; +153 } +154 +155 /** +156 * Utility method to create an HttpURLConnection. The use of a proxy here is +157 * optional as there may be cases where a proxy is configured but we don't +158 * want to use it (for example, if there's an internal repository +159 * configured) +160 * +161 * @param url the URL to connect to +162 * @param proxy whether to use the proxy (if configured) +163 * @return a newly constructed HttpURLConnection +164 * @throws URLConnectionFailureException thrown if there is an exception +165 */ +166 public static HttpURLConnection createHttpURLConnection(URL url, boolean proxy) throws URLConnectionFailureException { +167 if (proxy) { +168 return createHttpURLConnection(url); +169 } +170 HttpURLConnection conn = null; +171 try { +172 conn = (HttpURLConnection) url.openConnection(); +173 final int timeout = Settings.getInt(Settings.KEYS.CONNECTION_TIMEOUT, 10000); +174 conn.setConnectTimeout(timeout); +175 conn.setInstanceFollowRedirects(true); +176 } catch (IOException ioe) { +177 throw new URLConnectionFailureException("Error getting connection.", ioe); +178 } +179 configureTLS(url, conn); +180 return conn; +181 } +182 +183 /** +184 * If the protocol is HTTPS, this will configure the cipher suites so that +185 * connections can be made to the NVD, and others, using older versions of +186 * Java. +187 * +188 * @param url the URL +189 * @param conn the connection +190 */ +191 private static void configureTLS(URL url, HttpURLConnection conn) { +192 if ("https".equals(url.getProtocol())) { +193 try { +194 final HttpsURLConnection secCon = (HttpsURLConnection) conn; +195 final SSLSocketFactoryEx factory = new SSLSocketFactoryEx(); +196 secCon.setSSLSocketFactory(factory); +197 } catch (NoSuchAlgorithmException ex) { +198 LOGGER.debug("Unsupported algorithm in SSLSocketFactoryEx", ex); +199 } catch (KeyManagementException ex) { +200 LOGGER.debug("Key mnagement eception in SSLSocketFactoryEx", ex); +201 } +202 } +203 } +204 }
      diff --git a/dependency-check-utils/xref/org/owasp/dependencycheck/utils/package-frame.html b/dependency-check-utils/xref/org/owasp/dependencycheck/utils/package-frame.html index 23da808ad..38c8bc248 100644 --- a/dependency-check-utils/xref/org/owasp/dependencycheck/utils/package-frame.html +++ b/dependency-check-utils/xref/org/owasp/dependencycheck/utils/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Utils 1.4.0 Reference Package org.owasp.dependencycheck.utils + Dependency-Check Utils 1.4.2 Reference Package org.owasp.dependencycheck.utils @@ -38,6 +38,9 @@
    340. KEYS +
    341. +
    342. + SSLSocketFactoryEx
    343. Settings diff --git a/dependency-check-utils/xref/org/owasp/dependencycheck/utils/package-summary.html b/dependency-check-utils/xref/org/owasp/dependencycheck/utils/package-summary.html index d6d764b58..299b1fb50 100644 --- a/dependency-check-utils/xref/org/owasp/dependencycheck/utils/package-summary.html +++ b/dependency-check-utils/xref/org/owasp/dependencycheck/utils/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Utils 1.4.0 Reference Package org.owasp.dependencycheck.utils + Dependency-Check Utils 1.4.2 Reference Package org.owasp.dependencycheck.utils @@ -74,6 +74,11 @@
    344. + + +
      KEYS
      + SSLSocketFactoryEx +
      diff --git a/dependency-check-utils/xref/overview-frame.html b/dependency-check-utils/xref/overview-frame.html index fa6fa0f94..516fe62e9 100644 --- a/dependency-check-utils/xref/overview-frame.html +++ b/dependency-check-utils/xref/overview-frame.html @@ -3,7 +3,7 @@ - Dependency-Check Utils 1.4.0 Reference + Dependency-Check Utils 1.4.2 Reference diff --git a/dependency-check-utils/xref/overview-summary.html b/dependency-check-utils/xref/overview-summary.html index b26443869..02e2a205c 100644 --- a/dependency-check-utils/xref/overview-summary.html +++ b/dependency-check-utils/xref/overview-summary.html @@ -3,7 +3,7 @@ - Dependency-Check Utils 1.4.0 Reference + Dependency-Check Utils 1.4.2 Reference @@ -24,7 +24,7 @@ -

      Dependency-Check Utils 1.4.0 Reference

      +

      Dependency-Check Utils 1.4.2 Reference

      diff --git a/dependency-hint.1.0.xsd b/dependency-hint.1.0.xsd new file mode 100644 index 000000000..9fa7afb27 --- /dev/null +++ b/dependency-hint.1.0.xsd @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dependency-updates-report.html b/dependency-updates-report.html index 3c545cfd1..17950ebd0 100644 --- a/dependency-updates-report.html +++ b/dependency-updates-report.html @@ -1,13 +1,13 @@ - + dependency-check – Dependency Updates Report @@ -59,9 +59,9 @@
    345. Dependency Updates Report
    346. -
    347. | Last Published: 2016-06-16
    348. +
    349. | Last Published: 2016-07-31
    350. - Version: 1.4.0 + Version: 1.4.2
    351. @@ -197,7 +197,7 @@ - + @@ -205,7 +205,7 @@ - + @@ -365,7 +365,7 @@ - + @@ -545,24 +545,24 @@ - + - + - + - + - + @@ -903,7 +903,7 @@ - + @@ -966,7 +966,7 @@ -
      # of dependencies using the latest version available22
      23
      # of dependencies where the next version available is smaller than an incremental version update
      # of dependencies where the next version available is an incremental version update1
      0
      # of dependencies where the next version available is a minor version update org.apache.commons commons-compress1.111.12 jar org.jmockit jmockit1.221.24 test jar 1.231.25
      org.jsoup jsoup1.9.11.9.2 jar 1.9.2
      commons-compress
      Current Version1.11
      1.12
      Scope
      jar
      Newer versions4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      6.0.0
      6.0.1 Latest Major
      +
      4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      5.5.2
      6.0.0
      6.0.1
      6.1.0 Latest Major

      org.apache.lucene:lucene-core

      @@ -993,7 +993,7 @@ -
      jar
      Newer versions4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      6.0.0
      6.0.1 Latest Major
      +4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      5.5.2
      6.0.0
      6.0.1
      6.1.0 Latest Major

      org.apache.lucene:lucene-queryparser

      @@ -1020,7 +1020,7 @@ -
      jar
      Newer versions4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      6.0.0
      6.0.1 Latest Major
      +4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      5.5.2
      6.0.0
      6.0.1
      6.1.0 Latest Major

      org.apache.lucene:lucene-test-framework

      @@ -1047,7 +1047,7 @@ -
      jar
      Newer versions4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      6.0.0
      6.0.1 Latest Major
      +4.8.0 Next Minor
      4.8.1
      4.9.0
      4.9.1
      4.10.0
      4.10.1
      4.10.2
      4.10.3
      4.10.4 Latest Minor
      5.0.0 Next Major
      5.1.0
      5.2.0
      5.2.1
      5.3.0
      5.3.1
      5.3.2
      5.4.0
      5.4.1
      5.5.0
      5.5.1
      5.5.2
      6.0.0
      6.0.1
      6.1.0 Latest Major

      org.apache.maven:maven-core

      @@ -1278,7 +1278,7 @@ - + @@ -1290,13 +1290,13 @@ -
      jmockit
      Current Version1.22
      1.24
      Scope test
      jar
      Newer versions1.23 Next Minor
      1.24 Latest Minor
      +1.25 Next Minor

      org.jsoup:jsoup

      - + @@ -1305,7 +1305,7 @@ - + @@ -1314,10 +1314,7 @@ - - - -
      Status There is at least one newer incremental version available. Incremental updates are typically passive.
       No newer versions available.
      Group Id org.jsoup
      jsoup
      Current Version1.9.1
      1.9.2
      Scope
      Typejar
      Newer versions1.9.2 Next Incremental
      +jar

      org.slf4j:slf4j-api

      diff --git a/general/internals.html b/general/internals.html index b2dd55335..fbe320327 100644 --- a/general/internals.html +++ b/general/internals.html @@ -1,13 +1,13 @@ - + dependency-check – How does dependency-check work? @@ -59,9 +59,9 @@
    352. How does dependency-check work?
    353. -
    354. | Last Published: 2016-06-16
    355. +
    356. | Last Published: 2016-07-31
    357. - Version: 1.4.0 + Version: 1.4.2
    358. diff --git a/general/scan_iso.html b/general/scan_iso.html index 0133bca1c..f534a51a2 100644 --- a/general/scan_iso.html +++ b/general/scan_iso.html @@ -1,13 +1,13 @@ - + dependency-check – How to Mount ISO Files for Scanning @@ -59,9 +59,9 @@
    359. How to Mount ISO Files for Scanning
    360. -
    361. | Last Published: 2016-06-16
    362. +
    363. | Last Published: 2016-07-31
    364. - Version: 1.4.0 + Version: 1.4.2
    365. diff --git a/general/suppression.html b/general/suppression.html index 9ab3a7e38..8113b54f4 100644 --- a/general/suppression.html +++ b/general/suppression.html @@ -1,13 +1,13 @@ - + dependency-check – Suppressing False Positives @@ -59,9 +59,9 @@
    366. Suppressing False Positives
    367. -
    368. | Last Published: 2016-06-16
    369. +
    370. | Last Published: 2016-07-31
    371. - Version: 1.4.0 + Version: 1.4.2
    372. diff --git a/general/thereport.html b/general/thereport.html index 2f35a96ea..472842498 100644 --- a/general/thereport.html +++ b/general/thereport.html @@ -1,13 +1,13 @@ - + dependency-check – How To Read The Reports @@ -59,9 +59,9 @@
    373. How To Read The Reports
    374. -
    375. | Last Published: 2016-06-16
    376. +
    377. | Last Published: 2016-07-31
    378. - Version: 1.4.0 + Version: 1.4.2
    379. diff --git a/index.html b/index.html index fc1272fe9..bf0dc28ae 100644 --- a/index.html +++ b/index.html @@ -1,13 +1,13 @@ - + dependency-check – About @@ -59,9 +59,9 @@
    380. About
    381. -
    382. | Last Published: 2016-06-16
    383. +
    384. | Last Published: 2016-07-31
    385. - Version: 1.4.0 + Version: 1.4.2
    386. @@ -228,15 +228,17 @@

      For help with dependency-check the following resource can be used:

      diff --git a/integration.html b/integration.html index 2d6789635..843e2dd33 100644 --- a/integration.html +++ b/integration.html @@ -1,13 +1,13 @@ - + dependency-check – CI Management @@ -59,9 +59,9 @@
    387. CI Management
    388. -
    389. | Last Published: 2016-06-16
    390. +
    391. | Last Published: 2016-07-31
    392. - Version: 1.4.0 + Version: 1.4.2
    393. diff --git a/issue-tracking.html b/issue-tracking.html index 1bf5d23d6..3850df29e 100644 --- a/issue-tracking.html +++ b/issue-tracking.html @@ -1,13 +1,13 @@ - + dependency-check – Issue Management @@ -59,9 +59,9 @@
    394. Issue Management
    395. -
    396. | Last Published: 2016-06-16
    397. +
    398. | Last Published: 2016-07-31
    399. - Version: 1.4.0 + Version: 1.4.2
    400. diff --git a/license.html b/license.html index 03d77a0eb..2f701d6da 100644 --- a/license.html +++ b/license.html @@ -1,13 +1,13 @@ - + dependency-check – Project Licenses @@ -59,9 +59,9 @@
    401. Project Licenses
    402. -
    403. | Last Published: 2016-06-16
    404. +
    405. | Last Published: 2016-07-31
    406. - Version: 1.4.0 + Version: 1.4.2
    407. diff --git a/mail-lists.html b/mail-lists.html index 087aba6d4..16034b82b 100644 --- a/mail-lists.html +++ b/mail-lists.html @@ -1,13 +1,13 @@ - + dependency-check – Project Mailing Lists @@ -59,9 +59,9 @@
    408. Project Mailing Lists
    409. -
    410. | Last Published: 2016-06-16
    411. +
    412. | Last Published: 2016-07-31
    413. - Version: 1.4.0 + Version: 1.4.2
    414. diff --git a/modules.html b/modules.html index 903a7daa8..dd26e5483 100644 --- a/modules.html +++ b/modules.html @@ -1,13 +1,13 @@ - + dependency-check – Modules @@ -59,9 +59,9 @@
    415. Modules
    416. -
    417. | Last Published: 2016-06-16
    418. +
    419. | Last Published: 2016-07-31
    420. - Version: 1.4.0 + Version: 1.4.2
    421. @@ -258,13 +258,17 @@

      In addition, dependency-check can be executed from the command line.

      diff --git a/plugin-updates-report.html b/plugin-updates-report.html index 1a65d6c6a..134550c5e 100644 --- a/plugin-updates-report.html +++ b/plugin-updates-report.html @@ -1,13 +1,13 @@ - + dependency-check – Plugin Updates Report @@ -59,9 +59,9 @@
    422. Plugin Updates Report
    423. -
    424. | Last Published: 2016-06-16
    425. +
    426. | Last Published: 2016-07-31
    427. - Version: 1.4.0 + Version: 1.4.2
    428. @@ -197,7 +197,7 @@
      - + @@ -213,7 +213,7 @@ - + @@ -335,7 +335,7 @@ - + @@ -345,7 +345,7 @@ - + @@ -382,14 +382,14 @@ - + - + + - @@ -601,7 +601,7 @@ -
      # of plugins using the latest version available18
      19
      # of plugins where the next version available is smaller than an incremental version update
      # of plugins where the next version available is a major version update1
      0
      # of plugins where a dependencies section containes a dependency with an updated version org.apache.maven.plugins maven-jar-plugin3.0.03.0.2 org.apache.maven.plugins maven-javadoc-plugin2.10.32.10.4
      org.apache.maven.plugins maven-source-plugin2.43.0.1 3.0.0
      maven-jar-plugin
      Current Version3.0.0
      +3.0.2

      Plugin org.apache.maven.plugins:maven-javadoc-plugin

      @@ -616,7 +616,7 @@ -
      maven-javadoc-plugin
      Current Version2.10.3
      +2.10.4

      Plugin org.apache.maven.plugins:maven-release-plugin

      @@ -667,7 +667,7 @@
      - + @@ -676,10 +676,7 @@ - - - -
      Status There is at least one newer major version available. Major updates are rarely passive.
       No newer versions available.
      Group Id org.apache.maven.plugins
      maven-source-plugin
      Current Version2.4
      Newer versions3.0.0 Next Major
      +3.0.1

      Plugin org.apache.maven.plugins:maven-surefire-plugin

      diff --git a/project-info.html b/project-info.html index 4b92e9eaf..8d7428af5 100644 --- a/project-info.html +++ b/project-info.html @@ -1,13 +1,13 @@ - + dependency-check – Project Information @@ -59,9 +59,9 @@
    429. Project Information
    430. -
    431. | Last Published: 2016-06-16
    432. +
    433. | Last Published: 2016-07-31
    434. - Version: 1.4.0 + Version: 1.4.2
    435. diff --git a/project-reports.html b/project-reports.html index 51194aaa7..299e7e5d4 100644 --- a/project-reports.html +++ b/project-reports.html @@ -1,13 +1,13 @@ - + dependency-check – Generated Reports @@ -59,9 +59,9 @@
    436. Generated Reports
    437. -
    438. | Last Published: 2016-06-16
    439. +
    440. | Last Published: 2016-07-31
    441. - Version: 1.4.0 + Version: 1.4.2
    442. diff --git a/project-summary.html b/project-summary.html index 8858ca28e..fcf50868f 100644 --- a/project-summary.html +++ b/project-summary.html @@ -1,13 +1,13 @@ - + dependency-check – Project Summary @@ -59,9 +59,9 @@
    443. Project Summary
    444. -
    445. | Last Published: 2016-06-16
    446. +
    447. | Last Published: 2016-07-31
    448. - Version: 1.4.0 + Version: 1.4.2
    449. @@ -247,7 +247,7 @@ - +
      dependency-check-parent
      Version1.4.0
      1.4.2
      Type pom
      diff --git a/related.html b/related.html index a5afed529..195363e22 100644 --- a/related.html +++ b/related.html @@ -1,13 +1,13 @@ - + dependency-check – Related Work @@ -59,9 +59,9 @@
    450. Related Work
    451. -
    452. | Last Published: 2016-06-16
    453. +
    454. | Last Published: 2016-07-31
    455. - Version: 1.4.0 + Version: 1.4.2
    456. diff --git a/source-repository.html b/source-repository.html index 142f295e5..be443dea5 100644 --- a/source-repository.html +++ b/source-repository.html @@ -1,13 +1,13 @@ - + dependency-check – Source Code Management @@ -59,9 +59,9 @@
    457. Source Code Management
    458. -
    459. | Last Published: 2016-06-16
    460. +
    461. | Last Published: 2016-07-31
    462. - Version: 1.4.0 + Version: 1.4.2
    463. diff --git a/surefire-report.html b/surefire-report.html index 3fcaab6e6..c76c9679c 100644 --- a/surefire-report.html +++ b/surefire-report.html @@ -1,13 +1,13 @@ - + dependency-check – Surefire Report @@ -59,9 +59,9 @@
    464. Surefire Report
    465. -
    466. | Last Published: 2016-06-16
    467. +
    468. | Last Published: 2016-07-31
    469. - Version: 1.4.0 + Version: 1.4.2
    470. diff --git a/team-list.html b/team-list.html index f56ab10b8..1df7e2840 100644 --- a/team-list.html +++ b/team-list.html @@ -1,13 +1,13 @@ - + dependency-check – Project Team @@ -59,9 +59,9 @@
    471. Project Team
    472. -
    473. | Last Published: 2016-06-16
    474. +
    475. | Last Published: 2016-07-31
    476. - Version: 1.4.0 + Version: 1.4.2
    477. diff --git a/xref-test/allclasses-frame.html b/xref-test/allclasses-frame.html index 7d0078084..2cc3eb9bd 100644 --- a/xref-test/allclasses-frame.html +++ b/xref-test/allclasses-frame.html @@ -157,6 +157,12 @@
    478. HintAnalyzerTest +
    479. +
    480. + HintHandlerTest +
    481. +
    482. + HintParserTest
    483. IndexEntryTest @@ -198,7 +204,7 @@ PomUtilsTest
    484. - PropertyTypeTest + PropertyTypeTest
    485. PythonDistributionAnalyzerTest @@ -225,13 +231,13 @@ SimplePojo
    486. - SuppressionHandlerTest + SuppressionHandlerTest
    487. - SuppressionParserTest + SuppressionParserTest
    488. - SuppressionRuleTest + SuppressionRuleTest
    489. TokenPairConcatenatingFilterTest diff --git a/xref-test/index.html b/xref-test/index.html index b14c5d0a6..e5cd82e24 100644 --- a/xref-test/index.html +++ b/xref-test/index.html @@ -4,7 +4,7 @@ - Dependency-Check 1.4.0 Reference + Dependency-Check 1.4.2 Reference diff --git a/xref-test/org/owasp/dependencycheck/EngineIntegrationTest.html b/xref-test/org/owasp/dependencycheck/EngineIntegrationTest.html index eac332370..d8dd77140 100644 --- a/xref-test/org/owasp/dependencycheck/EngineIntegrationTest.html +++ b/xref-test/org/owasp/dependencycheck/EngineIntegrationTest.html @@ -25,45 +25,71 @@ 17 */ 18 package org.owasp.dependencycheck; 19 -20 import org.junit.After; -21 import static org.junit.Assert.assertTrue; -22 import org.junit.Before; -23 import org.junit.Test; -24 import org.owasp.dependencycheck.data.nvdcve.CveDB; -25 import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties; -26 import org.owasp.dependencycheck.reporting.ReportGenerator; -27 import org.owasp.dependencycheck.utils.Settings; -28 -29 /** -30 * -31 * @author Jeremy Long -32 */ -33 public class EngineIntegrationTest extends BaseDBTestCase { +20 import java.io.IOException; +21 import java.util.logging.Level; +22 import java.util.logging.Logger; +23 import static org.junit.Assert.assertTrue; +24 +25 import org.junit.Test; +26 import org.owasp.dependencycheck.data.nvdcve.CveDB; +27 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; +28 import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties; +29 import org.owasp.dependencycheck.exception.ExceptionCollection; +30 import org.owasp.dependencycheck.exception.ReportException; +31 import org.owasp.dependencycheck.reporting.ReportGenerator; +32 import org.owasp.dependencycheck.utils.InvalidSettingException; +33 import org.owasp.dependencycheck.utils.Settings; 34 -35 /** -36 * Test running the entire engine. -37 * -38 * @throws Exception is thrown when an exception occurs. -39 */ -40 @Test -41 public void testEngine() throws Exception { -42 String testClasses = "target/test-classes"; -43 boolean autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE); -44 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); -45 Engine instance = new Engine(); -46 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate); -47 instance.scan(testClasses); -48 assertTrue(instance.getDependencies().size() > 0); -49 instance.analyzeDependencies(); -50 CveDB cveDB = new CveDB(); -51 cveDB.open(); -52 DatabaseProperties dbProp = cveDB.getDatabaseProperties(); -53 cveDB.close(); -54 ReportGenerator rg = new ReportGenerator("DependencyCheck", instance.getDependencies(), instance.getAnalyzers(), dbProp); -55 rg.generateReports("./target/", "ALL"); -56 instance.cleanup(); -57 } -58 } +35 /** +36 * +37 * @author Jeremy Long +38 */ +39 public class EngineIntegrationTest extends BaseDBTestCase { +40 +41 /** +42 * Test running the entire engine. +43 * +44 * @throws java.io.IOException +45 * @throws org.owasp.dependencycheck.utils.InvalidSettingException +46 * @throws org.owasp.dependencycheck.data.nvdcve.DatabaseException +47 * @throws org.owasp.dependencycheck.exception.ReportException +48 * @throws org.owasp.dependencycheck.exception.ExceptionCollection +49 */ +50 @Test +51 public void testEngine() throws IOException, InvalidSettingException, DatabaseException, ReportException, ExceptionCollection { +52 String testClasses = "target/test-classes"; +53 boolean autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE); +54 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); +55 Engine instance = new Engine(); +56 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate); +57 instance.scan(testClasses); +58 assertTrue(instance.getDependencies().size() > 0); +59 try { +60 instance.analyzeDependencies(); +61 } catch (ExceptionCollection ex) { +62 if (ex.getExceptions().size()==1 && +63 (ex.getExceptions().get(0).getMessage().contains("bundle-audit") || +64 ex.getExceptions().get(0).getMessage().contains("AssemblyAnalyzer"))) { +65 //this is fine to ignore +66 } else if (ex.getExceptions().size()==2 && +67 ((ex.getExceptions().get(0).getMessage().contains("bundle-audit") && +68 ex.getExceptions().get(1).getMessage().contains("AssemblyAnalyzer")) || +69 (ex.getExceptions().get(1).getMessage().contains("bundle-audit") && +70 ex.getExceptions().get(0).getMessage().contains("AssemblyAnalyzer")))) { +71 //this is fine to ignore +72 } else { +73 throw ex; +74 } +75 } +76 CveDB cveDB = new CveDB(); +77 cveDB.open(); +78 DatabaseProperties dbProp = cveDB.getDatabaseProperties(); +79 cveDB.close(); +80 ReportGenerator rg = new ReportGenerator("DependencyCheck", instance.getDependencies(), instance.getAnalyzers(), dbProp); +81 rg.generateReports("./target/", "ALL"); +82 instance.cleanup(); +83 } +84 }
      diff --git a/xref-test/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzerTest.html b/xref-test/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzerTest.html index b19c56d9a..af40bbb41 100644 --- a/xref-test/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzerTest.html +++ b/xref-test/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzerTest.html @@ -31,18 +31,18 @@ 23 import org.owasp.dependencycheck.Engine; 24 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; 25 import org.owasp.dependencycheck.dependency.Dependency; -26 import org.owasp.dependencycheck.suppression.SuppressionParseException; -27 import org.owasp.dependencycheck.suppression.SuppressionRule; -28 import org.owasp.dependencycheck.utils.Settings; -29 import org.slf4j.LoggerFactory; -30 -31 import java.net.MalformedURLException; -32 import java.net.URISyntaxException; -33 import java.util.List; -34 import java.util.Set; -35 -36 import static org.junit.Assert.assertNull; -37 import static org.junit.Assert.assertTrue; +26 import org.owasp.dependencycheck.xml.suppression.SuppressionRule; +27 import org.owasp.dependencycheck.utils.Settings; +28 import org.slf4j.LoggerFactory; +29 +30 import java.net.MalformedURLException; +31 import java.net.URISyntaxException; +32 import java.util.List; +33 import java.util.Set; +34 +35 import static org.junit.Assert.assertNull; +36 import static org.junit.Assert.assertTrue; +37 import org.owasp.dependencycheck.exception.InitializationException; 38 39 /** 40 * @author Jeremy Long @@ -57,74 +57,77 @@ 49 } 50 51 /** -52 * Test of getSupportedExtensions method, of class AbstractSuppressionAnalyzer. -53 */ -54 @Test -55 public void testGetSupportedExtensions() { -56 Set<String> result = instance.getSupportedExtensions(); -57 assertNull(result); -58 } -59 -60 /** -61 * Test of getRules method, of class AbstractSuppressionAnalyzer for suppression file declared as URL. -62 */ -63 @Test -64 public void testGetRulesFromSuppressionFileFromURL() throws Exception { -65 setSupressionFileFromURL(); -66 instance.initialize(); -67 int expCount = 5; -68 List<SuppressionRule> result = instance.getRules(); -69 assertTrue(expCount <= result.size()); -70 } -71 -72 /** -73 * Test of getRules method, of class AbstractSuppressionAnalyzer for suppression file declared as URL. -74 */ -75 @Test -76 public void testGetRulesFromSuppressionFileInClasspath() throws Exception { -77 Settings.setString(Settings.KEYS.SUPPRESSION_FILE, "suppressions.xml"); -78 instance.initialize(); -79 int expCount = 5; -80 int currentSize = instance.getRules().size(); -81 assertTrue(expCount <= currentSize); -82 } -83 -84 @Test(expected = SuppressionParseException.class) -85 public void testFailureToLocateSuppressionFileAnywhere() throws Exception { -86 Settings.setString(Settings.KEYS.SUPPRESSION_FILE, "doesnotexist.xml"); -87 instance.initialize(); -88 } -89 -90 private void setSupressionFileFromURL() throws Exception { -91 try { -92 final String uri = this.getClass().getClassLoader().getResource("suppressions.xml").toURI().toURL().toString(); -93 Settings.setString(Settings.KEYS.SUPPRESSION_FILE, uri); -94 } catch (URISyntaxException ex) { -95 LoggerFactory.getLogger(AbstractSuppressionAnalyzerTest.class).error("", ex); -96 } catch (MalformedURLException ex) { -97 LoggerFactory.getLogger(AbstractSuppressionAnalyzerTest.class).error("", ex); -98 } -99 } -100 -101 public class AbstractSuppressionAnalyzerImpl extends AbstractSuppressionAnalyzer { -102 -103 @Override -104 public void analyze(Dependency dependency, Engine engine) throws AnalysisException { -105 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. -106 } -107 -108 @Override -109 public String getName() { -110 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. -111 } -112 -113 @Override -114 public AnalysisPhase getAnalysisPhase() { -115 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. -116 } -117 } -118 -119 } +52 * Test of getSupportedExtensions method, of class +53 * AbstractSuppressionAnalyzer. +54 */ +55 @Test +56 public void testGetSupportedExtensions() { +57 Set<String> result = instance.getSupportedExtensions(); +58 assertNull(result); +59 } +60 +61 /** +62 * Test of getRules method, of class AbstractSuppressionAnalyzer for +63 * suppression file declared as URL. +64 */ +65 @Test +66 public void testGetRulesFromSuppressionFileFromURL() throws Exception { +67 setSupressionFileFromURL(); +68 instance.initialize(); +69 int expCount = 5; +70 List<SuppressionRule> result = instance.getRules(); +71 assertTrue(expCount <= result.size()); +72 } +73 +74 /** +75 * Test of getRules method, of class AbstractSuppressionAnalyzer for +76 * suppression file declared as URL. +77 */ +78 @Test +79 public void testGetRulesFromSuppressionFileInClasspath() throws Exception { +80 Settings.setString(Settings.KEYS.SUPPRESSION_FILE, "suppressions.xml"); +81 instance.initialize(); +82 int expCount = 5; +83 int currentSize = instance.getRules().size(); +84 assertTrue(expCount <= currentSize); +85 } +86 +87 @Test(expected = InitializationException.class) +88 public void testFailureToLocateSuppressionFileAnywhere() throws Exception { +89 Settings.setString(Settings.KEYS.SUPPRESSION_FILE, "doesnotexist.xml"); +90 instance.initialize(); +91 } +92 +93 private void setSupressionFileFromURL() throws Exception { +94 try { +95 final String uri = this.getClass().getClassLoader().getResource("suppressions.xml").toURI().toURL().toString(); +96 Settings.setString(Settings.KEYS.SUPPRESSION_FILE, uri); +97 } catch (URISyntaxException ex) { +98 LoggerFactory.getLogger(AbstractSuppressionAnalyzerTest.class).error("", ex); +99 } catch (MalformedURLException ex) { +100 LoggerFactory.getLogger(AbstractSuppressionAnalyzerTest.class).error("", ex); +101 } +102 } +103 +104 public class AbstractSuppressionAnalyzerImpl extends AbstractSuppressionAnalyzer { +105 +106 @Override +107 public void analyze(Dependency dependency, Engine engine) throws AnalysisException { +108 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. +109 } +110 +111 @Override +112 public String getName() { +113 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. +114 } +115 +116 @Override +117 public AnalysisPhase getAnalysisPhase() { +118 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. +119 } +120 } +121 +122 }
      diff --git a/xref-test/org/owasp/dependencycheck/analyzer/AnalyzerServiceTest.html b/xref-test/org/owasp/dependencycheck/analyzer/AnalyzerServiceTest.html index 678736ff6..6646fbc59 100644 --- a/xref-test/org/owasp/dependencycheck/analyzer/AnalyzerServiceTest.html +++ b/xref-test/org/owasp/dependencycheck/analyzer/AnalyzerServiceTest.html @@ -25,65 +25,64 @@ 17 */ 18 package org.owasp.dependencycheck.analyzer; 19 -20 import java.util.Iterator; -21 import java.util.List; -22 import static org.junit.Assert.assertFalse; -23 import static org.junit.Assert.assertTrue; -24 import org.junit.Test; -25 import org.owasp.dependencycheck.BaseDBTestCase; -26 import org.owasp.dependencycheck.utils.Settings; -27 -28 /** -29 * -30 * @author Jeremy Long -31 */ -32 public class AnalyzerServiceTest extends BaseDBTestCase { -33 -34 /** -35 * Test of getAnalyzers method, of class AnalyzerService. -36 */ -37 @Test -38 public void testGetAnalyzers() { -39 AnalyzerService instance = new AnalyzerService(Thread.currentThread().getContextClassLoader()); -40 List<Analyzer> result = instance.getAnalyzers(); -41 -42 boolean found = false; -43 for (Analyzer a : result) { -44 if ("Jar Analyzer".equals(a.getName())) { -45 found = true; -46 } -47 } -48 assertTrue("JarAnalyzer loaded", found); -49 } -50 -51 /** -52 * Test of getAnalyzers method, of class AnalyzerService. -53 */ -54 @Test -55 public void testGetExperimentalAnalyzers() { -56 Settings.setBoolean(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, false); -57 AnalyzerService instance = new AnalyzerService(Thread.currentThread().getContextClassLoader()); -58 List<Analyzer> result = instance.getAnalyzers(); -59 String experimental = "CMake Analyzer"; -60 boolean found = false; -61 for (Analyzer a : result) { -62 if (experimental.equals(a.getName())) { -63 found = true; -64 } -65 } -66 assertFalse("Experimental analyzer loaded when set to false", found); -67 -68 Settings.setBoolean(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, true); -69 result = instance.getAnalyzers(); -70 found = false; -71 for (Analyzer a : result) { -72 if (experimental.equals(a.getName())) { -73 found = true; -74 } -75 } -76 assertTrue("Experimental analyzer not loaded when set to true", found); -77 } -78 } +20 import java.util.List; +21 import static org.junit.Assert.assertFalse; +22 import static org.junit.Assert.assertTrue; +23 import org.junit.Test; +24 import org.owasp.dependencycheck.BaseDBTestCase; +25 import org.owasp.dependencycheck.utils.Settings; +26 +27 /** +28 * +29 * @author Jeremy Long +30 */ +31 public class AnalyzerServiceTest extends BaseDBTestCase { +32 +33 /** +34 * Test of getAnalyzers method, of class AnalyzerService. +35 */ +36 @Test +37 public void testGetAnalyzers() { +38 AnalyzerService instance = new AnalyzerService(Thread.currentThread().getContextClassLoader()); +39 List<Analyzer> result = instance.getAnalyzers(); +40 +41 boolean found = false; +42 for (Analyzer a : result) { +43 if ("Jar Analyzer".equals(a.getName())) { +44 found = true; +45 } +46 } +47 assertTrue("JarAnalyzer loaded", found); +48 } +49 +50 /** +51 * Test of getAnalyzers method, of class AnalyzerService. +52 */ +53 @Test +54 public void testGetExperimentalAnalyzers() { +55 Settings.setBoolean(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, false); +56 AnalyzerService instance = new AnalyzerService(Thread.currentThread().getContextClassLoader()); +57 List<Analyzer> result = instance.getAnalyzers(); +58 String experimental = "CMake Analyzer"; +59 boolean found = false; +60 for (Analyzer a : result) { +61 if (experimental.equals(a.getName())) { +62 found = true; +63 } +64 } +65 assertFalse("Experimental analyzer loaded when set to false", found); +66 +67 Settings.setBoolean(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, true); +68 result = instance.getAnalyzers(); +69 found = false; +70 for (Analyzer a : result) { +71 if (experimental.equals(a.getName())) { +72 found = true; +73 } +74 } +75 assertTrue("Experimental analyzer not loaded when set to true", found); +76 } +77 }
      diff --git a/xref-test/org/owasp/dependencycheck/analyzer/ArchiveAnalyzerIntegrationTest.html b/xref-test/org/owasp/dependencycheck/analyzer/ArchiveAnalyzerIntegrationTest.html index e8270d3de..76195119d 100644 --- a/xref-test/org/owasp/dependencycheck/analyzer/ArchiveAnalyzerIntegrationTest.html +++ b/xref-test/org/owasp/dependencycheck/analyzer/ArchiveAnalyzerIntegrationTest.html @@ -124,138 +124,138 @@ 116 try { 117 instance.initialize(); 118 File file = BaseTest.getResourceAsFile(this, "daytrader-ear-2.1.7.ear"); -119 //File file = new File(this.getClass().getClassLoader().getResource("daytrader-ear-2.1.7.ear").getPath()); -120 Dependency dependency = new Dependency(file); -121 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); -122 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); -123 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); -124 Engine engine = new Engine(); -125 -126 int initial_size = engine.getDependencies().size(); -127 instance.analyze(dependency, engine); -128 int ending_size = engine.getDependencies().size(); -129 -130 engine.cleanup(); -131 -132 assertTrue(initial_size < ending_size); -133 -134 } finally { -135 instance.close(); -136 } -137 } -138 -139 /** -140 * Test of analyze method, of class ArchiveAnalyzer. -141 */ -142 @Test -143 public void testAnalyzeTar() throws Exception { -144 ArchiveAnalyzer instance = new ArchiveAnalyzer(); -145 //trick the analyzer into thinking it is active so that it will initialize -146 instance.accept(new File("test.tar")); -147 try { -148 instance.initialize(); -149 -150 //File file = new File(this.getClass().getClassLoader().getResource("file.tar").getPath()); -151 //File file = new File(this.getClass().getClassLoader().getResource("stagedhttp-modified.tar").getPath()); -152 File file = BaseTest.getResourceAsFile(this, "stagedhttp-modified.tar"); -153 Dependency dependency = new Dependency(file); -154 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); -155 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); -156 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); -157 Engine engine = new Engine(); +119 Dependency dependency = new Dependency(file); +120 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); +121 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); +122 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); +123 Engine engine = new Engine(); +124 +125 int initial_size = engine.getDependencies().size(); +126 instance.analyze(dependency, engine); +127 int ending_size = engine.getDependencies().size(); +128 +129 engine.cleanup(); +130 +131 assertTrue(initial_size < ending_size); +132 +133 } finally { +134 instance.close(); +135 } +136 } +137 +138 /** +139 * Test of analyze method, of class ArchiveAnalyzer, with an executable jar. +140 */ +141 @Test +142 public void testAnalyzeExecutableJar() throws Exception { +143 ArchiveAnalyzer instance = new ArchiveAnalyzer(); +144 //trick the analyzer into thinking it is active. +145 instance.accept(new File("test.ear")); +146 try { +147 instance.initialize(); +148 File file = BaseTest.getResourceAsFile(this, "bootable-0.1.0.jar"); +149 Dependency dependency = new Dependency(file); +150 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); +151 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); +152 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); +153 Engine engine = new Engine(); +154 +155 int initial_size = engine.getDependencies().size(); +156 instance.analyze(dependency, engine); +157 int ending_size = engine.getDependencies().size(); 158 -159 int initial_size = engine.getDependencies().size(); -160 instance.analyze(dependency, engine); -161 int ending_size = engine.getDependencies().size(); -162 engine.cleanup(); -163 -164 assertTrue(initial_size < ending_size); -165 -166 } finally { -167 instance.close(); -168 } -169 } -170 -171 /** -172 * Test of analyze method, of class ArchiveAnalyzer. -173 */ -174 @Test -175 public void testAnalyzeTarGz() throws Exception { -176 ArchiveAnalyzer instance = new ArchiveAnalyzer(); -177 instance.accept(new File("zip")); //ensure analyzer is "enabled" -178 try { -179 instance.initialize(); -180 -181 //File file = new File(this.getClass().getClassLoader().getResource("file.tar.gz").getPath()); -182 File file = BaseTest.getResourceAsFile(this, "file.tar.gz"); -183 //Dependency dependency = new Dependency(file); -184 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); -185 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); -186 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); -187 Engine engine = new Engine(); -188 -189 int initial_size = engine.getDependencies().size(); -190 //instance.analyze(dependency, engine); -191 engine.scan(file); -192 engine.analyzeDependencies(); -193 int ending_size = engine.getDependencies().size(); -194 engine.cleanup(); -195 assertTrue(initial_size < ending_size); -196 -197 } finally { -198 instance.close(); -199 } -200 } -201 -202 /** -203 * Test of analyze method, of class ArchiveAnalyzer. -204 */ -205 @Test -206 public void testAnalyzeTarBz2() throws Exception { -207 ArchiveAnalyzer instance = new ArchiveAnalyzer(); -208 instance.accept(new File("zip")); //ensure analyzer is "enabled" -209 try { -210 instance.initialize(); -211 File file = BaseTest.getResourceAsFile(this, "file.tar.bz2"); -212 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); -213 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); -214 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); -215 Engine engine = new Engine(); -216 int initial_size = engine.getDependencies().size(); -217 engine.scan(file); -218 engine.analyzeDependencies(); -219 int ending_size = engine.getDependencies().size(); -220 engine.cleanup(); -221 assertTrue(initial_size < ending_size); -222 } finally { -223 instance.close(); -224 } -225 } -226 -227 /** -228 * Test of analyze method, of class ArchiveAnalyzer. -229 */ -230 @Test -231 public void testAnalyzeTgz() throws Exception { -232 ArchiveAnalyzer instance = new ArchiveAnalyzer(); -233 instance.accept(new File("zip")); //ensure analyzer is "enabled" -234 try { -235 instance.initialize(); -236 -237 //File file = new File(this.getClass().getClassLoader().getResource("file.tgz").getPath()); -238 File file = BaseTest.getResourceAsFile(this, "file.tgz"); -239 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); -240 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); -241 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); -242 Engine engine = new Engine(); -243 -244 int initial_size = engine.getDependencies().size(); -245 engine.scan(file); -246 engine.analyzeDependencies(); -247 int ending_size = engine.getDependencies().size(); -248 engine.cleanup(); -249 assertTrue(initial_size < ending_size); -250 +159 engine.cleanup(); +160 +161 assertTrue(initial_size < ending_size); +162 +163 } finally { +164 instance.close(); +165 } +166 } +167 +168 /** +169 * Test of analyze method, of class ArchiveAnalyzer. +170 */ +171 @Test +172 public void testAnalyzeTar() throws Exception { +173 ArchiveAnalyzer instance = new ArchiveAnalyzer(); +174 //trick the analyzer into thinking it is active so that it will initialize +175 instance.accept(new File("test.tar")); +176 try { +177 instance.initialize(); +178 +179 //File file = new File(this.getClass().getClassLoader().getResource("file.tar").getPath()); +180 //File file = new File(this.getClass().getClassLoader().getResource("stagedhttp-modified.tar").getPath()); +181 File file = BaseTest.getResourceAsFile(this, "stagedhttp-modified.tar"); +182 Dependency dependency = new Dependency(file); +183 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); +184 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); +185 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); +186 Engine engine = new Engine(); +187 +188 int initial_size = engine.getDependencies().size(); +189 instance.analyze(dependency, engine); +190 int ending_size = engine.getDependencies().size(); +191 engine.cleanup(); +192 +193 assertTrue(initial_size < ending_size); +194 +195 } finally { +196 instance.close(); +197 } +198 } +199 +200 /** +201 * Test of analyze method, of class ArchiveAnalyzer. +202 */ +203 @Test +204 public void testAnalyzeTarGz() throws Exception { +205 ArchiveAnalyzer instance = new ArchiveAnalyzer(); +206 instance.accept(new File("zip")); //ensure analyzer is "enabled" +207 try { +208 instance.initialize(); +209 +210 //File file = new File(this.getClass().getClassLoader().getResource("file.tar.gz").getPath()); +211 File file = BaseTest.getResourceAsFile(this, "file.tar.gz"); +212 //Dependency dependency = new Dependency(file); +213 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); +214 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); +215 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); +216 Engine engine = new Engine(); +217 +218 int initial_size = engine.getDependencies().size(); +219 //instance.analyze(dependency, engine); +220 engine.scan(file); +221 engine.analyzeDependencies(); +222 int ending_size = engine.getDependencies().size(); +223 engine.cleanup(); +224 assertTrue(initial_size < ending_size); +225 +226 } finally { +227 instance.close(); +228 } +229 } +230 +231 /** +232 * Test of analyze method, of class ArchiveAnalyzer. +233 */ +234 @Test +235 public void testAnalyzeTarBz2() throws Exception { +236 ArchiveAnalyzer instance = new ArchiveAnalyzer(); +237 instance.accept(new File("zip")); //ensure analyzer is "enabled" +238 try { +239 instance.initialize(); +240 File file = BaseTest.getResourceAsFile(this, "file.tar.bz2"); +241 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); +242 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); +243 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); +244 Engine engine = new Engine(); +245 int initial_size = engine.getDependencies().size(); +246 engine.scan(file); +247 engine.analyzeDependencies(); +248 int ending_size = engine.getDependencies().size(); +249 engine.cleanup(); +250 assertTrue(initial_size < ending_size); 251 } finally { 252 instance.close(); 253 } @@ -265,59 +265,88 @@ 257 * Test of analyze method, of class ArchiveAnalyzer. 258 */ 259 @Test -260 public void testAnalyzeTbz2() throws Exception { +260 public void testAnalyzeTgz() throws Exception { 261 ArchiveAnalyzer instance = new ArchiveAnalyzer(); 262 instance.accept(new File("zip")); //ensure analyzer is "enabled" 263 try { 264 instance.initialize(); -265 File file = BaseTest.getResourceAsFile(this, "file.tbz2"); -266 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); -267 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); -268 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); -269 Engine engine = new Engine(); -270 int initial_size = engine.getDependencies().size(); -271 engine.scan(file); -272 engine.analyzeDependencies(); -273 int ending_size = engine.getDependencies().size(); -274 engine.cleanup(); -275 assertTrue(initial_size < ending_size); -276 } finally { -277 instance.close(); -278 } -279 } -280 -281 /** -282 * Test of analyze method, of class ArchiveAnalyzer. -283 */ -284 @Test -285 public void testAnalyze_badZip() throws Exception { -286 ArchiveAnalyzer instance = new ArchiveAnalyzer(); -287 try { -288 instance.initialize(); -289 -290 //File file = new File(this.getClass().getClassLoader().getResource("test.zip").getPath()); -291 File file = BaseTest.getResourceAsFile(this, "test.zip"); -292 Dependency dependency = new Dependency(file); -293 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); -294 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); -295 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); -296 Engine engine = new Engine(); -297 int initial_size = engine.getDependencies().size(); -298 // boolean failed = false; -299 // try { -300 instance.analyze(dependency, engine); -301 // } catch (java.lang.UnsupportedClassVersionError ex) { -302 // failed = true; -303 // } -304 // assertTrue(failed); -305 int ending_size = engine.getDependencies().size(); -306 engine.cleanup(); -307 assertEquals(initial_size, ending_size); -308 } finally { -309 instance.close(); -310 } -311 } -312 } +265 +266 //File file = new File(this.getClass().getClassLoader().getResource("file.tgz").getPath()); +267 File file = BaseTest.getResourceAsFile(this, "file.tgz"); +268 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); +269 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); +270 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); +271 Engine engine = new Engine(); +272 +273 int initial_size = engine.getDependencies().size(); +274 engine.scan(file); +275 engine.analyzeDependencies(); +276 int ending_size = engine.getDependencies().size(); +277 engine.cleanup(); +278 assertTrue(initial_size < ending_size); +279 +280 } finally { +281 instance.close(); +282 } +283 } +284 +285 /** +286 * Test of analyze method, of class ArchiveAnalyzer. +287 */ +288 @Test +289 public void testAnalyzeTbz2() throws Exception { +290 ArchiveAnalyzer instance = new ArchiveAnalyzer(); +291 instance.accept(new File("zip")); //ensure analyzer is "enabled" +292 try { +293 instance.initialize(); +294 File file = BaseTest.getResourceAsFile(this, "file.tbz2"); +295 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); +296 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); +297 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); +298 Engine engine = new Engine(); +299 int initial_size = engine.getDependencies().size(); +300 engine.scan(file); +301 engine.analyzeDependencies(); +302 int ending_size = engine.getDependencies().size(); +303 engine.cleanup(); +304 assertTrue(initial_size < ending_size); +305 } finally { +306 instance.close(); +307 } +308 } +309 +310 /** +311 * Test of analyze method, of class ArchiveAnalyzer. +312 */ +313 @Test +314 public void testAnalyze_badZip() throws Exception { +315 ArchiveAnalyzer instance = new ArchiveAnalyzer(); +316 try { +317 instance.initialize(); +318 +319 //File file = new File(this.getClass().getClassLoader().getResource("test.zip").getPath()); +320 File file = BaseTest.getResourceAsFile(this, "test.zip"); +321 Dependency dependency = new Dependency(file); +322 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); +323 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); +324 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); +325 Engine engine = new Engine(); +326 int initial_size = engine.getDependencies().size(); +327 // boolean failed = false; +328 // try { +329 instance.analyze(dependency, engine); +330 // } catch (java.lang.UnsupportedClassVersionError ex) { +331 // failed = true; +332 // } +333 // assertTrue(failed); +334 int ending_size = engine.getDependencies().size(); +335 engine.cleanup(); +336 assertEquals(initial_size, ending_size); +337 } finally { +338 instance.close(); +339 } +340 } +341 }
      diff --git a/xref-test/org/owasp/dependencycheck/analyzer/ArchiveAnalyzerTest.html b/xref-test/org/owasp/dependencycheck/analyzer/ArchiveAnalyzerTest.html index 00bf4b4a6..9c9004236 100644 --- a/xref-test/org/owasp/dependencycheck/analyzer/ArchiveAnalyzerTest.html +++ b/xref-test/org/owasp/dependencycheck/analyzer/ArchiveAnalyzerTest.html @@ -24,68 +24,63 @@ 16 package org.owasp.dependencycheck.analyzer; 17 18 import java.io.File; -19 import java.io.FileFilter; -20 import java.lang.reflect.InvocationTargetException; -21 import java.lang.reflect.Method; -22 import java.util.logging.Level; -23 import java.util.logging.Logger; -24 import org.junit.After; -25 import org.junit.AfterClass; -26 import org.junit.Before; -27 import org.junit.BeforeClass; -28 import org.junit.Test; -29 import static org.junit.Assert.*; -30 import static org.junit.Assume.assumeFalse; -31 import static org.junit.Assume.assumeNotNull; -32 import org.owasp.dependencycheck.BaseTest; -33 import org.owasp.dependencycheck.Engine; -34 import org.owasp.dependencycheck.dependency.Dependency; -35 import org.owasp.dependencycheck.utils.Settings; -36 -37 /** -38 * -39 * @author jeremy -40 */ -41 public class ArchiveAnalyzerTest extends BaseTest { +19 import java.lang.reflect.InvocationTargetException; +20 import java.lang.reflect.Method; +21 import java.util.logging.Level; +22 import java.util.logging.Logger; +23 +24 import org.junit.Before; +25 import org.junit.Test; +26 import static org.junit.Assert.*; +27 import static org.junit.Assume.assumeFalse; +28 +29 import org.owasp.dependencycheck.BaseTest; +30 import org.owasp.dependencycheck.utils.Settings; +31 +32 /** +33 * +34 * @author jeremy +35 */ +36 public class ArchiveAnalyzerTest extends BaseTest { +37 +38 @Before +39 public void setUp() { +40 Settings.setString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, "z2, z3"); +41 } 42 -43 @Before -44 public void setUp() { -45 Settings.setString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, "z2, z3"); -46 } -47 -48 /** -49 * Test of analyzeFileType method, of class ArchiveAnalyzer. -50 */ -51 @Test -52 public void testZippableExtensions() throws Exception { -53 assumeFalse(isPreviouslyLoaded("org.owasp.dependencycheck.analyzer.ArchiveAnalyzer")); -54 ArchiveAnalyzer instance = new ArchiveAnalyzer(); -55 assertTrue(instance.getFileFilter().accept(new File("c:/test.zip"))); -56 assertTrue(instance.getFileFilter().accept(new File("c:/test.z2"))); -57 assertTrue(instance.getFileFilter().accept(new File("c:/test.z3"))); -58 assertFalse(instance.getFileFilter().accept(new File("c:/test.z4"))); -59 } -60 -61 private boolean isPreviouslyLoaded(String className) { -62 try { -63 Method m = ClassLoader.class.getDeclaredMethod("findLoadedClass", new Class[]{String.class}); -64 m.setAccessible(true); -65 Object t = m.invoke(Thread.currentThread().getContextClassLoader(), className); -66 return t != null; -67 } catch (NoSuchMethodException ex) { -68 Logger.getLogger(ArchiveAnalyzerTest.class.getName()).log(Level.SEVERE, null, ex); -69 } catch (SecurityException ex) { -70 Logger.getLogger(ArchiveAnalyzerTest.class.getName()).log(Level.SEVERE, null, ex); -71 } catch (IllegalAccessException ex) { -72 Logger.getLogger(ArchiveAnalyzerTest.class.getName()).log(Level.SEVERE, null, ex); -73 } catch (IllegalArgumentException ex) { -74 Logger.getLogger(ArchiveAnalyzerTest.class.getName()).log(Level.SEVERE, null, ex); -75 } catch (InvocationTargetException ex) { -76 Logger.getLogger(ArchiveAnalyzerTest.class.getName()).log(Level.SEVERE, null, ex); -77 } -78 return false; -79 } -80 } +43 /** +44 * Test of analyzeFileType method, of class ArchiveAnalyzer. +45 */ +46 @Test +47 public void testZippableExtensions() throws Exception { +48 assumeFalse(isPreviouslyLoaded("org.owasp.dependencycheck.analyzer.ArchiveAnalyzer")); +49 ArchiveAnalyzer instance = new ArchiveAnalyzer(); +50 assertTrue(instance.getFileFilter().accept(new File("c:/test.zip"))); +51 assertTrue(instance.getFileFilter().accept(new File("c:/test.z2"))); +52 assertTrue(instance.getFileFilter().accept(new File("c:/test.z3"))); +53 assertFalse(instance.getFileFilter().accept(new File("c:/test.z4"))); +54 } +55 +56 private boolean isPreviouslyLoaded(String className) { +57 try { +58 Method m = ClassLoader.class.getDeclaredMethod("findLoadedClass", new Class[]{String.class}); +59 m.setAccessible(true); +60 Object t = m.invoke(Thread.currentThread().getContextClassLoader(), className); +61 return t != null; +62 } catch (NoSuchMethodException ex) { +63 Logger.getLogger(ArchiveAnalyzerTest.class.getName()).log(Level.SEVERE, null, ex); +64 } catch (SecurityException ex) { +65 Logger.getLogger(ArchiveAnalyzerTest.class.getName()).log(Level.SEVERE, null, ex); +66 } catch (IllegalAccessException ex) { +67 Logger.getLogger(ArchiveAnalyzerTest.class.getName()).log(Level.SEVERE, null, ex); +68 } catch (IllegalArgumentException ex) { +69 Logger.getLogger(ArchiveAnalyzerTest.class.getName()).log(Level.SEVERE, null, ex); +70 } catch (InvocationTargetException ex) { +71 Logger.getLogger(ArchiveAnalyzerTest.class.getName()).log(Level.SEVERE, null, ex); +72 } +73 return false; +74 } +75 }
      diff --git a/xref-test/org/owasp/dependencycheck/analyzer/AssemblyAnalyzerTest.html b/xref-test/org/owasp/dependencycheck/analyzer/AssemblyAnalyzerTest.html index d609ffcb6..5cf08bcba 100644 --- a/xref-test/org/owasp/dependencycheck/analyzer/AssemblyAnalyzerTest.html +++ b/xref-test/org/owasp/dependencycheck/analyzer/AssemblyAnalyzerTest.html @@ -39,153 +39,154 @@ 31 import org.owasp.dependencycheck.dependency.Confidence; 32 import org.owasp.dependencycheck.dependency.Dependency; 33 import org.owasp.dependencycheck.dependency.Evidence; -34 import org.owasp.dependencycheck.utils.Settings; -35 import org.slf4j.Logger; -36 import org.slf4j.LoggerFactory; -37 -38 /** -39 * Tests for the AssemblyAnalyzer. -40 * -41 * @author colezlaw -42 * -43 */ -44 public class AssemblyAnalyzerTest extends BaseTest { -45 -46 private static final Logger LOGGER = LoggerFactory.getLogger(AssemblyAnalyzerTest.class); -47 -48 private static final String LOG_KEY = "org.slf4j.simpleLogger.org.owasp.dependencycheck.analyzer.AssemblyAnalyzer"; -49 -50 AssemblyAnalyzer analyzer; -51 -52 /** -53 * Sets up the analyzer. -54 * -55 * @throws Exception if anything goes sideways -56 */ -57 @Before -58 public void setUp() throws Exception { -59 try { -60 analyzer = new AssemblyAnalyzer(); -61 analyzer.accept(new File("test.dll")); // trick into "thinking it is active" -62 analyzer.initialize(); -63 } catch (Exception e) { -64 if (e.getMessage().contains("Could not execute .NET AssemblyAnalyzer")) { -65 LOGGER.warn("Exception setting up AssemblyAnalyzer. Tests will be incomplete"); -66 } else { -67 LOGGER.warn("Exception setting up AssemblyAnalyzer. Tests will be incomplete", e); -68 } -69 Assume.assumeNoException("Is mono installed? TESTS WILL BE INCOMPLETE", e); -70 } -71 } -72 -73 /** -74 * Tests to make sure the name is correct. -75 */ -76 @Test -77 public void testGetName() { -78 assertEquals("Assembly Analyzer", analyzer.getName()); -79 } -80 -81 @Test -82 public void testAnalysis() throws Exception { -83 //File f = new File(AssemblyAnalyzerTest.class.getClassLoader().getResource("GrokAssembly.exe").getPath()); -84 File f = BaseTest.getResourceAsFile(this, "GrokAssembly.exe"); -85 Dependency d = new Dependency(f); -86 analyzer.analyze(d, null); -87 boolean foundVendor = false; -88 for (Evidence e : d.getVendorEvidence().getEvidence("grokassembly", "vendor")) { -89 if ("OWASP".equals(e.getValue())) { -90 foundVendor = true; -91 } -92 } -93 assertTrue(foundVendor); -94 -95 boolean foundProduct = false; -96 for (Evidence e : d.getProductEvidence().getEvidence("grokassembly", "product")) { -97 if ("GrokAssembly".equals(e.getValue())) { -98 foundProduct = true; -99 } -100 } -101 assertTrue(foundProduct); -102 } -103 -104 @Test -105 public void testLog4Net() throws Exception { -106 //File f = new File(AssemblyAnalyzerTest.class.getClassLoader().getResource("log4net.dll").getPath()); -107 File f = BaseTest.getResourceAsFile(this, "log4net.dll"); -108 -109 Dependency d = new Dependency(f); -110 analyzer.analyze(d, null); -111 assertTrue(d.getVersionEvidence().getEvidence().contains(new Evidence("grokassembly", "version", "1.2.13.0", Confidence.HIGHEST))); -112 assertTrue(d.getVendorEvidence().getEvidence().contains(new Evidence("grokassembly", "vendor", "The Apache Software Foundation", Confidence.HIGH))); -113 assertTrue(d.getProductEvidence().getEvidence().contains(new Evidence("grokassembly", "product", "log4net", Confidence.HIGH))); -114 } -115 -116 @Test -117 public void testNonexistent() { -118 // Tweak the log level so the warning doesn't show in the console -119 String oldProp = System.getProperty(LOG_KEY, "info"); -120 //File f = new File(AssemblyAnalyzerTest.class.getClassLoader().getResource("log4net.dll").getPath()); -121 File f = BaseTest.getResourceAsFile(this, "log4net.dll"); -122 File test = new File(f.getParent(), "nonexistent.dll"); -123 Dependency d = new Dependency(test); -124 -125 try { -126 analyzer.analyze(d, null); -127 fail("Expected an AnalysisException"); -128 } catch (AnalysisException ae) { -129 assertEquals("File does not exist", ae.getMessage()); -130 } finally { -131 System.setProperty(LOG_KEY, oldProp); -132 } -133 } -134 -135 @Test -136 public void testWithSettingMono() throws Exception { -137 -138 //This test doesn't work on Windows. -139 assumeFalse(System.getProperty("os.name").startsWith("Windows")); -140 -141 String oldValue = Settings.getString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH); -142 // if oldValue is null, that means that neither the system property nor the setting has -143 // been set. If that's the case, then we have to make it such that when we recover, -144 // null still comes back. But you can't put a null value in a HashMap, so we have to set -145 // the system property rather than the setting. -146 if (oldValue == null) { -147 System.setProperty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, "/yooser/bine/mono"); -148 } else { -149 Settings.setString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, "/yooser/bine/mono"); -150 } -151 -152 String oldProp = System.getProperty(LOG_KEY, "info"); -153 try { -154 // Tweak the logging to swallow the warning when testing -155 System.setProperty(LOG_KEY, "error"); -156 // Have to make a NEW analyzer because during setUp, it would have gotten the correct one -157 AssemblyAnalyzer aanalyzer = new AssemblyAnalyzer(); -158 aanalyzer.accept(new File("test.dll")); // trick into "thinking it is active" -159 aanalyzer.initialize(); -160 fail("Expected an AnalysisException"); -161 } catch (AnalysisException ae) { -162 assertEquals("An error occurred with the .NET AssemblyAnalyzer", ae.getMessage()); -163 } finally { -164 System.setProperty(LOG_KEY, oldProp); -165 // Recover the logger -166 // Now recover the way we came in. If we had to set a System property, delete it. Otherwise, -167 // reset the old value -168 if (oldValue == null) { -169 System.getProperties().remove(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH); -170 } else { -171 Settings.setString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, oldValue); -172 } -173 } -174 } -175 -176 @After -177 public void tearDown() throws Exception { -178 analyzer.close(); -179 } -180 } +34 import org.owasp.dependencycheck.exception.InitializationException; +35 import org.owasp.dependencycheck.utils.Settings; +36 import org.slf4j.Logger; +37 import org.slf4j.LoggerFactory; +38 +39 /** +40 * Tests for the AssemblyAnalyzer. +41 * +42 * @author colezlaw +43 * +44 */ +45 public class AssemblyAnalyzerTest extends BaseTest { +46 +47 private static final Logger LOGGER = LoggerFactory.getLogger(AssemblyAnalyzerTest.class); +48 +49 private static final String LOG_KEY = "org.slf4j.simpleLogger.org.owasp.dependencycheck.analyzer.AssemblyAnalyzer"; +50 +51 AssemblyAnalyzer analyzer; +52 +53 /** +54 * Sets up the analyzer. +55 * +56 * @throws Exception if anything goes sideways +57 */ +58 @Before +59 public void setUp() throws Exception { +60 try { +61 analyzer = new AssemblyAnalyzer(); +62 analyzer.accept(new File("test.dll")); // trick into "thinking it is active" +63 analyzer.initialize(); +64 } catch (Exception e) { +65 if (e.getMessage().contains("Could not execute .NET AssemblyAnalyzer")) { +66 LOGGER.warn("Exception setting up AssemblyAnalyzer. Tests will be incomplete"); +67 } else { +68 LOGGER.warn("Exception setting up AssemblyAnalyzer. Tests will be incomplete"); +69 } +70 Assume.assumeNoException("Is mono installed? TESTS WILL BE INCOMPLETE", e); +71 } +72 } +73 +74 /** +75 * Tests to make sure the name is correct. +76 */ +77 @Test +78 public void testGetName() { +79 assertEquals("Assembly Analyzer", analyzer.getName()); +80 } +81 +82 @Test +83 public void testAnalysis() throws Exception { +84 //File f = new File(AssemblyAnalyzerTest.class.getClassLoader().getResource("GrokAssembly.exe").getPath()); +85 File f = BaseTest.getResourceAsFile(this, "GrokAssembly.exe"); +86 Dependency d = new Dependency(f); +87 analyzer.analyze(d, null); +88 boolean foundVendor = false; +89 for (Evidence e : d.getVendorEvidence().getEvidence("grokassembly", "vendor")) { +90 if ("OWASP".equals(e.getValue())) { +91 foundVendor = true; +92 } +93 } +94 assertTrue(foundVendor); +95 +96 boolean foundProduct = false; +97 for (Evidence e : d.getProductEvidence().getEvidence("grokassembly", "product")) { +98 if ("GrokAssembly".equals(e.getValue())) { +99 foundProduct = true; +100 } +101 } +102 assertTrue(foundProduct); +103 } +104 +105 @Test +106 public void testLog4Net() throws Exception { +107 //File f = new File(AssemblyAnalyzerTest.class.getClassLoader().getResource("log4net.dll").getPath()); +108 File f = BaseTest.getResourceAsFile(this, "log4net.dll"); +109 +110 Dependency d = new Dependency(f); +111 analyzer.analyze(d, null); +112 assertTrue(d.getVersionEvidence().getEvidence().contains(new Evidence("grokassembly", "version", "1.2.13.0", Confidence.HIGHEST))); +113 assertTrue(d.getVendorEvidence().getEvidence().contains(new Evidence("grokassembly", "vendor", "The Apache Software Foundation", Confidence.HIGH))); +114 assertTrue(d.getProductEvidence().getEvidence().contains(new Evidence("grokassembly", "product", "log4net", Confidence.HIGH))); +115 } +116 +117 @Test +118 public void testNonexistent() { +119 // Tweak the log level so the warning doesn't show in the console +120 String oldProp = System.getProperty(LOG_KEY, "info"); +121 //File f = new File(AssemblyAnalyzerTest.class.getClassLoader().getResource("log4net.dll").getPath()); +122 File f = BaseTest.getResourceAsFile(this, "log4net.dll"); +123 File test = new File(f.getParent(), "nonexistent.dll"); +124 Dependency d = new Dependency(test); +125 +126 try { +127 analyzer.analyze(d, null); +128 fail("Expected an AnalysisException"); +129 } catch (AnalysisException ae) { +130 assertEquals("File does not exist", ae.getMessage()); +131 } finally { +132 System.setProperty(LOG_KEY, oldProp); +133 } +134 } +135 +136 @Test +137 public void testWithSettingMono() throws Exception { +138 +139 //This test doesn't work on Windows. +140 assumeFalse(System.getProperty("os.name").startsWith("Windows")); +141 +142 String oldValue = Settings.getString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH); +143 // if oldValue is null, that means that neither the system property nor the setting has +144 // been set. If that's the case, then we have to make it such that when we recover, +145 // null still comes back. But you can't put a null value in a HashMap, so we have to set +146 // the system property rather than the setting. +147 if (oldValue == null) { +148 System.setProperty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, "/yooser/bine/mono"); +149 } else { +150 Settings.setString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, "/yooser/bine/mono"); +151 } +152 +153 String oldProp = System.getProperty(LOG_KEY, "info"); +154 try { +155 // Tweak the logging to swallow the warning when testing +156 System.setProperty(LOG_KEY, "error"); +157 // Have to make a NEW analyzer because during setUp, it would have gotten the correct one +158 AssemblyAnalyzer aanalyzer = new AssemblyAnalyzer(); +159 aanalyzer.accept(new File("test.dll")); // trick into "thinking it is active" +160 aanalyzer.initialize(); +161 fail("Expected an InitializationException"); +162 } catch (InitializationException ae) { +163 assertEquals("An error occurred with the .NET AssemblyAnalyzer", ae.getMessage()); +164 } finally { +165 System.setProperty(LOG_KEY, oldProp); +166 // Recover the logger +167 // Now recover the way we came in. If we had to set a System property, delete it. Otherwise, +168 // reset the old value +169 if (oldValue == null) { +170 System.getProperties().remove(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH); +171 } else { +172 Settings.setString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, oldValue); +173 } +174 } +175 } +176 +177 @After +178 public void tearDown() throws Exception { +179 analyzer.close(); +180 } +181 }
      diff --git a/xref-test/org/owasp/dependencycheck/analyzer/CPEAnalyzerIntegrationTest.html b/xref-test/org/owasp/dependencycheck/analyzer/CPEAnalyzerIntegrationTest.html index 036e178cb..2f11380ef 100644 --- a/xref-test/org/owasp/dependencycheck/analyzer/CPEAnalyzerIntegrationTest.html +++ b/xref-test/org/owasp/dependencycheck/analyzer/CPEAnalyzerIntegrationTest.html @@ -37,231 +37,244 @@ 29 import org.junit.Test; 30 import org.owasp.dependencycheck.BaseTest; 31 import org.owasp.dependencycheck.BaseDBTestCase; -32 import org.owasp.dependencycheck.data.cpe.IndexEntry; -33 import org.owasp.dependencycheck.dependency.Confidence; -34 import org.owasp.dependencycheck.dependency.Dependency; -35 import org.owasp.dependencycheck.dependency.Identifier; -36 -37 /** -38 * -39 * @author Jeremy Long -40 */ -41 public class CPEAnalyzerIntegrationTest extends BaseDBTestCase { -42 -43 /** -44 * Tests of buildSearch of class CPEAnalyzer. -45 * -46 * @throws IOException is thrown when an IO Exception occurs. -47 * @throws CorruptIndexException is thrown when the index is corrupt. -48 * @throws ParseException is thrown when a parse exception occurs -49 */ -50 @Test -51 public void testBuildSearch() throws IOException, CorruptIndexException, ParseException { -52 Set<String> productWeightings = Collections.singleton("struts2"); -53 -54 Set<String> vendorWeightings = Collections.singleton("apache"); -55 -56 String vendor = "apache software foundation"; -57 String product = "struts 2 core"; -58 String version = "2.1.2"; -59 CPEAnalyzer instance = new CPEAnalyzer(); -60 -61 String queryText = instance.buildSearch(vendor, product, null, null); -62 String expResult = " product:( struts 2 core ) AND vendor:( apache software foundation ) "; -63 Assert.assertTrue(expResult.equals(queryText)); -64 -65 queryText = instance.buildSearch(vendor, product, null, productWeightings); -66 expResult = " product:( struts^5 struts2^5 2 core ) AND vendor:( apache software foundation ) "; -67 Assert.assertTrue(expResult.equals(queryText)); -68 -69 queryText = instance.buildSearch(vendor, product, vendorWeightings, null); -70 expResult = " product:( struts 2 core ) AND vendor:( apache^5 software foundation ) "; -71 Assert.assertTrue(expResult.equals(queryText)); -72 -73 queryText = instance.buildSearch(vendor, product, vendorWeightings, productWeightings); -74 expResult = " product:( struts^5 struts2^5 2 core ) AND vendor:( apache^5 software foundation ) "; -75 Assert.assertTrue(expResult.equals(queryText)); -76 } -77 -78 /** -79 * Test of determineCPE method, of class CPEAnalyzer. -80 * -81 * @throws Exception is thrown when an exception occurs -82 */ -83 @Test -84 public void testDetermineCPE_full() throws Exception { -85 CPEAnalyzer instance = new CPEAnalyzer(); -86 instance.open(); -87 FileNameAnalyzer fnAnalyzer = new FileNameAnalyzer(); -88 JarAnalyzer jarAnalyzer = new JarAnalyzer(); -89 HintAnalyzer hAnalyzer = new HintAnalyzer(); -90 FalsePositiveAnalyzer fp = new FalsePositiveAnalyzer(); -91 -92 try { -93 //callDetermineCPE_full("struts2-core-2.3.16.3.jar", "cpe:/a:apache:struts:2.3.16.3", instance, fnAnalyzer, jarAnalyzer, hAnalyzer, fp); -94 callDetermineCPE_full("hazelcast-2.5.jar", null, instance, fnAnalyzer, jarAnalyzer, hAnalyzer, fp); -95 callDetermineCPE_full("spring-context-support-2.5.5.jar", "cpe:/a:springsource:spring_framework:2.5.5", instance, fnAnalyzer, jarAnalyzer, hAnalyzer, fp); -96 callDetermineCPE_full("spring-core-3.0.0.RELEASE.jar", "cpe:/a:vmware:springsource_spring_framework:3.0.0", instance, fnAnalyzer, jarAnalyzer, hAnalyzer, fp); -97 callDetermineCPE_full("org.mortbay.jetty.jar", "cpe:/a:mortbay_jetty:jetty:4.2.27", instance, fnAnalyzer, jarAnalyzer, hAnalyzer, fp); -98 callDetermineCPE_full("jaxb-xercesImpl-1.5.jar", null, instance, fnAnalyzer, jarAnalyzer, hAnalyzer, fp); -99 callDetermineCPE_full("ehcache-core-2.2.0.jar", null, instance, fnAnalyzer, jarAnalyzer, hAnalyzer, fp); -100 } finally { -101 instance.close(); -102 } -103 } -104 -105 /** -106 * Test of determineCPE method, of class CPEAnalyzer. -107 * -108 * @throws Exception is thrown when an exception occurs -109 */ -110 public void callDetermineCPE_full(String depName, String expResult, CPEAnalyzer instance, FileNameAnalyzer fnAnalyzer, JarAnalyzer jarAnalyzer, HintAnalyzer hAnalyzer, FalsePositiveAnalyzer fp) throws Exception { -111 -112 //File file = new File(this.getClass().getClassLoader().getResource(depName).getPath()); -113 File file = BaseTest.getResourceAsFile(this, depName); -114 -115 Dependency dep = new Dependency(file); -116 -117 fnAnalyzer.analyze(dep, null); -118 jarAnalyzer.analyze(dep, null); -119 hAnalyzer.analyze(dep, null); -120 instance.analyze(dep, null); -121 fp.analyze(dep, null); +32 import org.owasp.dependencycheck.Engine; +33 import org.owasp.dependencycheck.data.cpe.IndexEntry; +34 import org.owasp.dependencycheck.dependency.Confidence; +35 import org.owasp.dependencycheck.dependency.Dependency; +36 import org.owasp.dependencycheck.dependency.Identifier; +37 +38 /** +39 * +40 * @author Jeremy Long +41 */ +42 public class CPEAnalyzerIntegrationTest extends BaseDBTestCase { +43 +44 /** +45 * Tests of buildSearch of class CPEAnalyzer. +46 * +47 * @throws IOException is thrown when an IO Exception occurs. +48 * @throws CorruptIndexException is thrown when the index is corrupt. +49 * @throws ParseException is thrown when a parse exception occurs +50 */ +51 @Test +52 public void testBuildSearch() throws IOException, CorruptIndexException, ParseException { +53 Set<String> productWeightings = Collections.singleton("struts2"); +54 +55 Set<String> vendorWeightings = Collections.singleton("apache"); +56 +57 String vendor = "apache software foundation"; +58 String product = "struts 2 core"; +59 String version = "2.1.2"; +60 CPEAnalyzer instance = new CPEAnalyzer(); +61 +62 String queryText = instance.buildSearch(vendor, product, null, null); +63 String expResult = " product:( struts 2 core ) AND vendor:( apache software foundation ) "; +64 Assert.assertTrue(expResult.equals(queryText)); +65 +66 queryText = instance.buildSearch(vendor, product, null, productWeightings); +67 expResult = " product:( struts^5 struts2^5 2 core ) AND vendor:( apache software foundation ) "; +68 Assert.assertTrue(expResult.equals(queryText)); +69 +70 queryText = instance.buildSearch(vendor, product, vendorWeightings, null); +71 expResult = " product:( struts 2 core ) AND vendor:( apache^5 software foundation ) "; +72 Assert.assertTrue(expResult.equals(queryText)); +73 +74 queryText = instance.buildSearch(vendor, product, vendorWeightings, productWeightings); +75 expResult = " product:( struts^5 struts2^5 2 core ) AND vendor:( apache^5 software foundation ) "; +76 Assert.assertTrue(expResult.equals(queryText)); +77 } +78 +79 /** +80 * Test of determineCPE method, of class CPEAnalyzer. +81 * +82 * @throws Exception is thrown when an exception occurs +83 */ +84 @Test +85 public void testDetermineCPE_full() throws Exception { +86 //update needs to be performed so that xtream can be tested +87 Engine e = new Engine(); +88 e.doUpdates(); +89 +90 CPEAnalyzer cpeAnalyzer = new CPEAnalyzer(); +91 try { +92 cpeAnalyzer.initialize(); +93 FileNameAnalyzer fnAnalyzer = new FileNameAnalyzer(); +94 fnAnalyzer.initialize(); +95 JarAnalyzer jarAnalyzer = new JarAnalyzer(); +96 jarAnalyzer.accept(new File("test.jar"));//trick analyzer into "thinking it is active" +97 jarAnalyzer.initialize(); +98 HintAnalyzer hAnalyzer = new HintAnalyzer(); +99 hAnalyzer.initialize(); +100 FalsePositiveAnalyzer fp = new FalsePositiveAnalyzer(); +101 fp.initialize(); +102 +103 callDetermineCPE_full("hazelcast-2.5.jar", null, cpeAnalyzer, fnAnalyzer, jarAnalyzer, hAnalyzer, fp); +104 callDetermineCPE_full("spring-context-support-2.5.5.jar", "cpe:/a:springsource:spring_framework:2.5.5", cpeAnalyzer, fnAnalyzer, jarAnalyzer, hAnalyzer, fp); +105 callDetermineCPE_full("spring-core-3.0.0.RELEASE.jar", "cpe:/a:vmware:springsource_spring_framework:3.0.0", cpeAnalyzer, fnAnalyzer, jarAnalyzer, hAnalyzer, fp); +106 callDetermineCPE_full("org.mortbay.jetty.jar", "cpe:/a:mortbay_jetty:jetty:4.2.27", cpeAnalyzer, fnAnalyzer, jarAnalyzer, hAnalyzer, fp); +107 callDetermineCPE_full("jaxb-xercesImpl-1.5.jar", null, cpeAnalyzer, fnAnalyzer, jarAnalyzer, hAnalyzer, fp); +108 callDetermineCPE_full("ehcache-core-2.2.0.jar", null, cpeAnalyzer, fnAnalyzer, jarAnalyzer, hAnalyzer, fp); +109 callDetermineCPE_full("xstream-1.4.8.jar", "cpe:/a:x-stream:xstream:1.4.8", cpeAnalyzer, fnAnalyzer, jarAnalyzer, hAnalyzer, fp); +110 +111 } finally { +112 cpeAnalyzer.close(); +113 } +114 } +115 +116 /** +117 * Test of determineCPE method, of class CPEAnalyzer. +118 * +119 * @throws Exception is thrown when an exception occurs +120 */ +121 public void callDetermineCPE_full(String depName, String expResult, CPEAnalyzer cpeAnalyzer, FileNameAnalyzer fnAnalyzer, JarAnalyzer jarAnalyzer, HintAnalyzer hAnalyzer, FalsePositiveAnalyzer fp) throws Exception { 122 -123 if (expResult != null) { -124 Identifier expIdentifier = new Identifier("cpe", expResult, expResult); -125 Assert.assertTrue("Incorrect match: { dep:'" + dep.getFileName() + "' }", dep.getIdentifiers().contains(expIdentifier)); -126 } else { -127 for (Identifier i : dep.getIdentifiers()) { -128 Assert.assertFalse(String.format("%s - found a CPE identifier when should have been none (found '%s')", dep.getFileName(), i.getValue()), "cpe".equals(i.getType())); -129 } -130 } -131 } -132 -133 /** -134 * Test of determineCPE method, of class CPEAnalyzer. -135 * -136 * @throws Exception is thrown when an exception occurs -137 */ -138 @Test -139 public void testDetermineCPE() throws Exception { -140 //File file = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath()); -141 File file = BaseTest.getResourceAsFile(this, "struts2-core-2.1.2.jar"); -142 //File file = new File(this.getClass().getClassLoader().getResource("axis2-adb-1.4.1.jar").getPath()); -143 Dependency struts = new Dependency(file); -144 -145 FileNameAnalyzer fnAnalyzer = new FileNameAnalyzer(); -146 fnAnalyzer.analyze(struts, null); -147 -148 HintAnalyzer hintAnalyzer = new HintAnalyzer(); -149 JarAnalyzer jarAnalyzer = new JarAnalyzer(); -150 jarAnalyzer.accept(new File("test.jar"));//trick analyzer into "thinking it is active" -151 -152 jarAnalyzer.analyze(struts, null); -153 hintAnalyzer.analyze(struts, null); -154 //File fileCommonValidator = new File(this.getClass().getClassLoader().getResource("commons-validator-1.4.0.jar").getPath()); -155 File fileCommonValidator = BaseTest.getResourceAsFile(this, "commons-validator-1.4.0.jar"); -156 Dependency commonValidator = new Dependency(fileCommonValidator); -157 jarAnalyzer.analyze(commonValidator, null); -158 hintAnalyzer.analyze(commonValidator, null); -159 -160 //File fileSpring = new File(this.getClass().getClassLoader().getResource("spring-core-2.5.5.jar").getPath()); -161 File fileSpring = BaseTest.getResourceAsFile(this, "spring-core-2.5.5.jar"); -162 Dependency spring = new Dependency(fileSpring); -163 jarAnalyzer.analyze(spring, null); -164 hintAnalyzer.analyze(spring, null); -165 -166 //File fileSpring3 = new File(this.getClass().getClassLoader().getResource("spring-core-3.0.0.RELEASE.jar").getPath()); -167 File fileSpring3 = BaseTest.getResourceAsFile(this, "spring-core-3.0.0.RELEASE.jar"); -168 Dependency spring3 = new Dependency(fileSpring3); -169 jarAnalyzer.analyze(spring3, null); -170 hintAnalyzer.analyze(spring3, null); -171 -172 CPEAnalyzer instance = new CPEAnalyzer(); -173 instance.open(); -174 instance.determineCPE(commonValidator); -175 instance.determineCPE(struts); -176 instance.determineCPE(spring); -177 instance.determineCPE(spring3); -178 instance.close(); -179 -180 String expResult = "cpe:/a:apache:struts:2.1.2"; -181 Identifier expIdentifier = new Identifier("cpe", expResult, expResult); -182 String expResultSpring = "cpe:/a:springsource:spring_framework:2.5.5"; -183 String expResultSpring3 = "cpe:/a:vmware:springsource_spring_framework:3.0.0"; +123 //File file = new File(this.getClass().getClassLoader().getResource(depName).getPath()); +124 File file = BaseTest.getResourceAsFile(this, depName); +125 +126 Dependency dep = new Dependency(file); +127 +128 fnAnalyzer.analyze(dep, null); +129 jarAnalyzer.analyze(dep, null); +130 hAnalyzer.analyze(dep, null); +131 cpeAnalyzer.analyze(dep, null); +132 fp.analyze(dep, null); +133 +134 if (expResult != null) { +135 Identifier expIdentifier = new Identifier("cpe", expResult, expResult); +136 Assert.assertTrue("Incorrect match: { dep:'" + dep.getFileName() + "' }", dep.getIdentifiers().contains(expIdentifier)); +137 } else { +138 for (Identifier i : dep.getIdentifiers()) { +139 Assert.assertFalse(String.format("%s - found a CPE identifier when should have been none (found '%s')", dep.getFileName(), i.getValue()), "cpe".equals(i.getType())); +140 } +141 } +142 } +143 +144 /** +145 * Test of determineCPE method, of class CPEAnalyzer. +146 * +147 * @throws Exception is thrown when an exception occurs +148 */ +149 @Test +150 public void testDetermineCPE() throws Exception { +151 //File file = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath()); +152 File file = BaseTest.getResourceAsFile(this, "struts2-core-2.1.2.jar"); +153 //File file = new File(this.getClass().getClassLoader().getResource("axis2-adb-1.4.1.jar").getPath()); +154 Dependency struts = new Dependency(file); +155 +156 FileNameAnalyzer fnAnalyzer = new FileNameAnalyzer(); +157 fnAnalyzer.analyze(struts, null); +158 +159 HintAnalyzer hintAnalyzer = new HintAnalyzer(); +160 hintAnalyzer.initialize(); +161 JarAnalyzer jarAnalyzer = new JarAnalyzer(); +162 jarAnalyzer.accept(new File("test.jar"));//trick analyzer into "thinking it is active" +163 jarAnalyzer.initialize(); +164 +165 jarAnalyzer.analyze(struts, null); +166 hintAnalyzer.analyze(struts, null); +167 //File fileCommonValidator = new File(this.getClass().getClassLoader().getResource("commons-validator-1.4.0.jar").getPath()); +168 File fileCommonValidator = BaseTest.getResourceAsFile(this, "commons-validator-1.4.0.jar"); +169 Dependency commonValidator = new Dependency(fileCommonValidator); +170 jarAnalyzer.analyze(commonValidator, null); +171 hintAnalyzer.analyze(commonValidator, null); +172 +173 //File fileSpring = new File(this.getClass().getClassLoader().getResource("spring-core-2.5.5.jar").getPath()); +174 File fileSpring = BaseTest.getResourceAsFile(this, "spring-core-2.5.5.jar"); +175 Dependency spring = new Dependency(fileSpring); +176 jarAnalyzer.analyze(spring, null); +177 hintAnalyzer.analyze(spring, null); +178 +179 //File fileSpring3 = new File(this.getClass().getClassLoader().getResource("spring-core-3.0.0.RELEASE.jar").getPath()); +180 File fileSpring3 = BaseTest.getResourceAsFile(this, "spring-core-3.0.0.RELEASE.jar"); +181 Dependency spring3 = new Dependency(fileSpring3); +182 jarAnalyzer.analyze(spring3, null); +183 hintAnalyzer.analyze(spring3, null); 184 -185 for (Identifier i : commonValidator.getIdentifiers()) { -186 Assert.assertFalse("Apache Common Validator - found a CPE identifier?", "cpe".equals(i.getType())); -187 } -188 -189 Assert.assertTrue("Incorrect match size - struts", struts.getIdentifiers().size() >= 1); -190 Assert.assertTrue("Incorrect match - struts", struts.getIdentifiers().contains(expIdentifier)); -191 Assert.assertTrue("Incorrect match size - spring3 - " + spring3.getIdentifiers().size(), spring3.getIdentifiers().size() >= 1); +185 CPEAnalyzer instance = new CPEAnalyzer(); +186 instance.open(); +187 instance.determineCPE(commonValidator); +188 instance.determineCPE(struts); +189 instance.determineCPE(spring); +190 instance.determineCPE(spring3); +191 instance.close(); 192 -193 //the following two only work if the HintAnalyzer is used. -194 //Assert.assertTrue("Incorrect match size - spring", spring.getIdentifiers().size() == 1); -195 //Assert.assertTrue("Incorrect match - spring", spring.getIdentifiers().get(0).getValue().equals(expResultSpring)); -196 jarAnalyzer.close(); -197 } -198 -199 /** -200 * Test of determineIdentifiers method, of class CPEAnalyzer. -201 * -202 * @throws Exception is thrown when an exception occurs -203 */ -204 @Test -205 public void testDetermineIdentifiers() throws Exception { -206 Dependency openssl = new Dependency(); -207 openssl.getVendorEvidence().addEvidence("test", "vendor", "openssl", Confidence.HIGHEST); -208 openssl.getProductEvidence().addEvidence("test", "product", "openssl", Confidence.HIGHEST); -209 openssl.getVersionEvidence().addEvidence("test", "version", "1.0.1c", Confidence.HIGHEST); -210 -211 CPEAnalyzer instance = new CPEAnalyzer(); -212 instance.open(); -213 instance.determineIdentifiers(openssl, "openssl", "openssl", Confidence.HIGHEST); -214 instance.close(); -215 -216 String expResult = "cpe:/a:openssl:openssl:1.0.1c"; -217 Identifier expIdentifier = new Identifier("cpe", expResult, expResult); -218 -219 assertTrue(openssl.getIdentifiers().contains(expIdentifier)); -220 -221 } -222 -223 /** -224 * Test of searchCPE method, of class CPEAnalyzer. -225 * -226 * @throws Exception is thrown when an exception occurs -227 */ -228 @Test -229 public void testSearchCPE() throws Exception { -230 String vendor = "apache software foundation"; -231 String product = "struts 2 core"; -232 String version = "2.1.2"; -233 String expVendor = "apache"; -234 String expProduct = "struts"; +193 String expResult = "cpe:/a:apache:struts:2.1.2"; +194 Identifier expIdentifier = new Identifier("cpe", expResult, expResult); +195 String expResultSpring = "cpe:/a:springsource:spring_framework:2.5.5"; +196 String expResultSpring3 = "cpe:/a:vmware:springsource_spring_framework:3.0.0"; +197 +198 for (Identifier i : commonValidator.getIdentifiers()) { +199 Assert.assertFalse("Apache Common Validator - found a CPE identifier?", "cpe".equals(i.getType())); +200 } +201 +202 Assert.assertTrue("Incorrect match size - struts", struts.getIdentifiers().size() >= 1); +203 Assert.assertTrue("Incorrect match - struts", struts.getIdentifiers().contains(expIdentifier)); +204 Assert.assertTrue("Incorrect match size - spring3 - " + spring3.getIdentifiers().size(), spring3.getIdentifiers().size() >= 1); +205 +206 //the following two only work if the HintAnalyzer is used. +207 //Assert.assertTrue("Incorrect match size - spring", spring.getIdentifiers().size() == 1); +208 //Assert.assertTrue("Incorrect match - spring", spring.getIdentifiers().get(0).getValue().equals(expResultSpring)); +209 jarAnalyzer.close(); +210 } +211 +212 /** +213 * Test of determineIdentifiers method, of class CPEAnalyzer. +214 * +215 * @throws Exception is thrown when an exception occurs +216 */ +217 @Test +218 public void testDetermineIdentifiers() throws Exception { +219 Dependency openssl = new Dependency(); +220 openssl.getVendorEvidence().addEvidence("test", "vendor", "openssl", Confidence.HIGHEST); +221 openssl.getProductEvidence().addEvidence("test", "product", "openssl", Confidence.HIGHEST); +222 openssl.getVersionEvidence().addEvidence("test", "version", "1.0.1c", Confidence.HIGHEST); +223 +224 CPEAnalyzer instance = new CPEAnalyzer(); +225 instance.open(); +226 instance.determineIdentifiers(openssl, "openssl", "openssl", Confidence.HIGHEST); +227 instance.close(); +228 +229 String expResult = "cpe:/a:openssl:openssl:1.0.1c"; +230 Identifier expIdentifier = new Identifier("cpe", expResult, expResult); +231 +232 assertTrue(openssl.getIdentifiers().contains(expIdentifier)); +233 +234 } 235 -236 CPEAnalyzer instance = new CPEAnalyzer(); -237 instance.open(); -238 -239 Set<String> productWeightings = Collections.singleton("struts2"); -240 -241 Set<String> vendorWeightings = Collections.singleton("apache"); -242 -243 List<IndexEntry> result = instance.searchCPE(vendor, product, vendorWeightings, productWeightings); -244 instance.close(); -245 -246 boolean found = false; -247 for (IndexEntry entry : result) { -248 if (expVendor.equals(entry.getVendor()) && expProduct.equals(entry.getProduct())) { -249 found = true; -250 break; -251 } -252 } -253 assertTrue("apache:struts was not identified", found); -254 -255 } -256 } +236 /** +237 * Test of searchCPE method, of class CPEAnalyzer. +238 * +239 * @throws Exception is thrown when an exception occurs +240 */ +241 @Test +242 public void testSearchCPE() throws Exception { +243 String vendor = "apache software foundation"; +244 String product = "struts 2 core"; +245 String version = "2.1.2"; +246 String expVendor = "apache"; +247 String expProduct = "struts"; +248 +249 CPEAnalyzer instance = new CPEAnalyzer(); +250 instance.open(); +251 +252 Set<String> productWeightings = Collections.singleton("struts2"); +253 +254 Set<String> vendorWeightings = Collections.singleton("apache"); +255 +256 List<IndexEntry> result = instance.searchCPE(vendor, product, vendorWeightings, productWeightings); +257 instance.close(); +258 +259 boolean found = false; +260 for (IndexEntry entry : result) { +261 if (expVendor.equals(entry.getVendor()) && expProduct.equals(entry.getProduct())) { +262 found = true; +263 break; +264 } +265 } +266 assertTrue("apache:struts was not identified", found); +267 +268 } +269 }
      diff --git a/xref-test/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzerTest.html b/xref-test/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzerTest.html index 2a4d163ba..12b21a093 100644 --- a/xref-test/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzerTest.html +++ b/xref-test/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzerTest.html @@ -31,84 +31,80 @@ 23 import org.owasp.dependencycheck.BaseTest; 24 import org.owasp.dependencycheck.Engine; 25 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; -26 import org.owasp.dependencycheck.dependency.Confidence; -27 import org.owasp.dependencycheck.dependency.Dependency; -28 import org.owasp.dependencycheck.dependency.Evidence; +26 import org.owasp.dependencycheck.dependency.Dependency; +27 +28 import java.io.File; 29 -30 import java.io.File; -31 -32 import static org.hamcrest.CoreMatchers.containsString; -33 import static org.hamcrest.CoreMatchers.is; -34 import static org.junit.Assert.assertEquals; -35 import static org.junit.Assert.assertThat; -36 import static org.junit.Assert.assertTrue; -37 import org.owasp.dependencycheck.BaseDBTestCase; -38 -39 /** -40 * Unit tests for NodePackageAnalyzer. -41 * -42 * @author Dale Visser -43 */ -44 public class ComposerLockAnalyzerTest extends BaseDBTestCase { +30 import static org.junit.Assert.assertEquals; +31 import static org.junit.Assert.assertTrue; +32 import org.owasp.dependencycheck.BaseDBTestCase; +33 +34 /** +35 * Unit tests for NodePackageAnalyzer. +36 * +37 * @author Dale Visser +38 */ +39 public class ComposerLockAnalyzerTest extends BaseDBTestCase { +40 +41 /** +42 * The analyzer to test. +43 */ +44 ComposerLockAnalyzer analyzer; 45 46 /** -47 * The analyzer to test. -48 */ -49 ComposerLockAnalyzer analyzer; -50 -51 /** -52 * Correctly setup the analyzer for testing. -53 * -54 * @throws Exception thrown if there is a problem -55 */ -56 @Before -57 public void setUp() throws Exception { -58 super.setUp(); -59 analyzer = new ComposerLockAnalyzer(); -60 analyzer.setFilesMatched(true); -61 analyzer.initialize(); -62 } -63 -64 /** -65 * Cleanup the analyzer's temp files, etc. -66 * -67 * @throws Exception thrown if there is a problem -68 */ -69 @After -70 public void tearDown() throws Exception { -71 analyzer.close(); -72 analyzer = null; -73 } -74 -75 /** -76 * Test of getName method, of class ComposerLockAnalyzer. -77 */ -78 @Test -79 public void testGetName() { -80 assertEquals("Composer.lock analyzer", analyzer.getName()); -81 } -82 -83 /** -84 * Test of supportsExtension method, of class ComposerLockAnalyzer. -85 */ -86 @Test -87 public void testSupportsFiles() { -88 assertTrue(analyzer.accept(new File("composer.lock"))); -89 } -90 -91 /** -92 * Test of inspect method, of class PythonDistributionAnalyzer. -93 * -94 * @throws AnalysisException is thrown when an exception occurs. -95 */ -96 @Test -97 public void testAnalyzePackageJson() throws Exception { -98 final Engine engine = new Engine(); -99 final Dependency result = new Dependency(BaseTest.getResourceAsFile(this, -100 "composer.lock")); -101 analyzer.analyze(result, engine); -102 } -103 } +47 * Correctly setup the analyzer for testing. +48 * +49 * @throws Exception thrown if there is a problem +50 */ +51 @Override +52 @Before +53 public void setUp() throws Exception { +54 super.setUp(); +55 analyzer = new ComposerLockAnalyzer(); +56 analyzer.setFilesMatched(true); +57 analyzer.initialize(); +58 } +59 +60 /** +61 * Cleanup the analyzer's temp files, etc. +62 * +63 * @throws Exception thrown if there is a problem +64 */ +65 @After +66 public void tearDown() throws Exception { +67 analyzer.close(); +68 analyzer = null; +69 } +70 +71 /** +72 * Test of getName method, of class ComposerLockAnalyzer. +73 */ +74 @Test +75 public void testGetName() { +76 assertEquals("Composer.lock analyzer", analyzer.getName()); +77 } +78 +79 /** +80 * Test of supportsExtension method, of class ComposerLockAnalyzer. +81 */ +82 @Test +83 public void testSupportsFiles() { +84 assertTrue(analyzer.accept(new File("composer.lock"))); +85 } +86 +87 /** +88 * Test of inspect method, of class PythonDistributionAnalyzer. +89 * +90 * @throws AnalysisException is thrown when an exception occurs. +91 */ +92 @Test +93 public void testAnalyzePackageJson() throws Exception { +94 final Engine engine = new Engine(); +95 final Dependency result = new Dependency(BaseTest.getResourceAsFile(this, +96 "composer.lock")); +97 analyzer.analyze(result, engine); +98 } +99 }
      diff --git a/xref-test/org/owasp/dependencycheck/analyzer/HintAnalyzerTest.html b/xref-test/org/owasp/dependencycheck/analyzer/HintAnalyzerTest.html index 966cf76a5..33ebda689 100644 --- a/xref-test/org/owasp/dependencycheck/analyzer/HintAnalyzerTest.html +++ b/xref-test/org/owasp/dependencycheck/analyzer/HintAnalyzerTest.html @@ -28,7 +28,7 @@ 20 import static org.junit.Assert.assertEquals; 21 import static org.junit.Assert.assertFalse; 22 import static org.junit.Assert.assertTrue; -23 import org.junit.Before; +23 24 import org.junit.Test; 25 import org.owasp.dependencycheck.BaseTest; 26 import org.owasp.dependencycheck.Engine; diff --git a/xref-test/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.html b/xref-test/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.html index 1a4f76d87..02d2e1b11 100644 --- a/xref-test/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.html +++ b/xref-test/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.html @@ -34,203 +34,209 @@ 26 import java.util.Iterator; 27 import java.util.List; 28 import java.util.Set; -29 -30 import org.junit.After; -31 import org.junit.Assume; -32 import org.junit.Before; -33 import org.junit.Test; -34 import org.owasp.dependencycheck.BaseDBTestCase; -35 import org.owasp.dependencycheck.BaseTest; -36 import org.owasp.dependencycheck.Engine; -37 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; -38 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; -39 import org.owasp.dependencycheck.dependency.Dependency; -40 import org.owasp.dependencycheck.dependency.Evidence; -41 import org.owasp.dependencycheck.dependency.Identifier; -42 import org.owasp.dependencycheck.dependency.Vulnerability; -43 import org.owasp.dependencycheck.utils.Settings; -44 import org.slf4j.Logger; -45 import org.slf4j.LoggerFactory; -46 -47 /** -48 * Unit tests for {@link RubyBundleAuditAnalyzer}. -49 * -50 * @author Dale Visser -51 */ -52 public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase { -53 -54 private static final Logger LOGGER = LoggerFactory.getLogger(RubyBundleAuditAnalyzerTest.class); +29 import java.util.logging.Level; +30 +31 import org.junit.After; +32 import org.junit.Assume; +33 import org.junit.Before; +34 import org.junit.Test; +35 import org.owasp.dependencycheck.BaseDBTestCase; +36 import org.owasp.dependencycheck.BaseTest; +37 import org.owasp.dependencycheck.Engine; +38 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; +39 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; +40 import org.owasp.dependencycheck.dependency.Dependency; +41 import org.owasp.dependencycheck.dependency.Evidence; +42 import org.owasp.dependencycheck.dependency.Identifier; +43 import org.owasp.dependencycheck.dependency.Vulnerability; +44 import org.owasp.dependencycheck.exception.ExceptionCollection; +45 import org.owasp.dependencycheck.utils.Settings; +46 import org.slf4j.Logger; +47 import org.slf4j.LoggerFactory; +48 +49 /** +50 * Unit tests for {@link RubyBundleAuditAnalyzer}. +51 * +52 * @author Dale Visser +53 */ +54 public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase { 55 -56 /** -57 * The analyzer to test. -58 */ -59 RubyBundleAuditAnalyzer analyzer; -60 -61 /** -62 * Correctly setup the analyzer for testing. -63 * -64 * @throws Exception thrown if there is a problem -65 */ -66 @Before -67 public void setUp() throws Exception { -68 super.setUp(); -69 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); -70 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); -71 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); -72 analyzer = new RubyBundleAuditAnalyzer(); -73 analyzer.setFilesMatched(true); -74 } -75 -76 /** -77 * Cleanup the analyzer's temp files, etc. -78 * -79 * @throws Exception thrown if there is a problem -80 */ -81 @After -82 public void tearDown() throws Exception { -83 analyzer.close(); -84 analyzer = null; -85 } -86 -87 /** -88 * Test Ruby Gemspec name. -89 */ -90 @Test -91 public void testGetName() { -92 assertThat(analyzer.getName(), is("Ruby Bundle Audit Analyzer")); -93 } -94 -95 /** -96 * Test Ruby Bundler Audit file support. -97 */ -98 @Test -99 public void testSupportsFiles() { -100 assertThat(analyzer.accept(new File("Gemfile.lock")), is(true)); -101 } -102 -103 /** -104 * Test Ruby BundlerAudit analysis. -105 * -106 * @throws AnalysisException is thrown when an exception occurs. -107 */ -108 @Test -109 public void testAnalysis() throws AnalysisException, DatabaseException { -110 try { -111 analyzer.initialize(); -112 final String resource = "ruby/vulnerable/gems/rails-4.1.15/Gemfile.lock"; -113 final Dependency result = new Dependency(BaseTest.getResourceAsFile(this, resource)); -114 final Engine engine = new Engine(); -115 analyzer.analyze(result, engine); -116 int size = engine.getDependencies().size(); -117 -118 assertTrue(size >= 1); -119 -120 Dependency dependency = engine.getDependencies().get(0); -121 assertTrue(dependency.getProductEvidence().toString().toLowerCase().contains("redcarpet")); -122 assertTrue(dependency.getVersionEvidence().toString().toLowerCase().contains("2.2.2")); -123 assertTrue(dependency.getFilePath().endsWith(resource)); -124 assertTrue(dependency.getFileName().equals("Gemfile.lock")); -125 } catch (Exception e) { -126 LOGGER.warn("Exception setting up RubyBundleAuditAnalyzer. Make sure Ruby gem bundle-audit is installed. You may also need to set property \"analyzer.bundle.audit.path\"."); -127 Assume.assumeNoException("Exception setting up RubyBundleAuditAnalyzer; bundle audit may not be installed, or property \"analyzer.bundle.audit.path\" may not be set.", e); -128 } -129 } -130 -131 /** -132 * Test Ruby addCriticalityToVulnerability -133 */ -134 @Test -135 public void testAddCriticalityToVulnerability() throws AnalysisException, DatabaseException { -136 try { -137 analyzer.initialize(); -138 -139 final Dependency result = new Dependency(BaseTest.getResourceAsFile(this, -140 "ruby/vulnerable/gems/sinatra/Gemfile.lock")); -141 final Engine engine = new Engine(); -142 analyzer.analyze(result, engine); -143 -144 Dependency dependency = engine.getDependencies().get(0); -145 Vulnerability vulnerability = dependency.getVulnerabilities().first(); -146 assertEquals(vulnerability.getCvssScore(), 5.0f, 0.0); -147 -148 } catch (Exception e) { -149 LOGGER.warn("Exception setting up RubyBundleAuditAnalyzer. Make sure Ruby gem bundle-audit is installed. You may also need to set property \"analyzer.bundle.audit.path\".", e); -150 Assume.assumeNoException("Exception setting up RubyBundleAuditAnalyzer; bundle audit may not be installed, or property \"analyzer.bundle.audit.path\" may not be set.", e); -151 } -152 } -153 -154 /** -155 * Test when Ruby bundle-audit is not available on the system. -156 * -157 * @throws AnalysisException is thrown when an exception occurs. -158 */ -159 @Test -160 public void testMissingBundleAudit() throws AnalysisException, DatabaseException { -161 //set a non-exist bundle-audit -162 Settings.setString(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH, "phantom-bundle-audit"); -163 try { -164 //initialize should fail. -165 analyzer.initialize(); -166 } catch (Exception e) { -167 //expected, so ignore. -168 } finally { -169 assertThat(analyzer.isEnabled(), is(false)); -170 LOGGER.info("phantom-bundle-audit is not available. Ruby Bundle Audit Analyzer is disabled as expected."); -171 } -172 } -173 -174 /** -175 * Test Ruby dependencies and their paths. -176 * -177 * @throws AnalysisException is thrown when an exception occurs. -178 */ -179 @Test -180 public void testDependenciesPath() throws AnalysisException, DatabaseException { -181 final Engine engine = new Engine(); -182 engine.scan(BaseTest.getResourceAsFile(this, -183 "ruby/vulnerable/gems/rails-4.1.15/")); -184 try { -185 engine.analyzeDependencies(); -186 } catch (NullPointerException ex) { -187 LOGGER.error("NPE", ex); -188 throw ex; -189 } -190 List<Dependency> dependencies = engine.getDependencies(); -191 LOGGER.info(dependencies.size() + " dependencies found."); -192 Iterator<Dependency> dIterator = dependencies.iterator(); -193 while (dIterator.hasNext()) { -194 Dependency dept = dIterator.next(); -195 LOGGER.info("dept path: " + dept.getActualFilePath()); -196 -197 Set<Identifier> identifiers = dept.getIdentifiers(); -198 Iterator<Identifier> idIterator = identifiers.iterator(); -199 while (idIterator.hasNext()) { -200 Identifier id = idIterator.next(); -201 LOGGER.info(" Identifier: " + id.getValue() + ", type=" + id.getType() + ", url=" + id.getUrl() + ", conf=" + id.getConfidence()); -202 } -203 -204 Set<Evidence> prodEv = dept.getProductEvidence().getEvidence(); -205 Iterator<Evidence> it = prodEv.iterator(); -206 while (it.hasNext()) { -207 Evidence e = it.next(); -208 LOGGER.info(" prod: name=" + e.getName() + ", value=" + e.getValue() + ", source=" + e.getSource() + ", confidence=" + e.getConfidence()); -209 } -210 Set<Evidence> versionEv = dept.getVersionEvidence().getEvidence(); -211 Iterator<Evidence> vIt = versionEv.iterator(); -212 while (vIt.hasNext()) { -213 Evidence e = vIt.next(); -214 LOGGER.info(" version: name=" + e.getName() + ", value=" + e.getValue() + ", source=" + e.getSource() + ", confidence=" + e.getConfidence()); +56 private static final Logger LOGGER = LoggerFactory.getLogger(RubyBundleAuditAnalyzerTest.class); +57 +58 /** +59 * The analyzer to test. +60 */ +61 RubyBundleAuditAnalyzer analyzer; +62 +63 /** +64 * Correctly setup the analyzer for testing. +65 * +66 * @throws Exception thrown if there is a problem +67 */ +68 @Override +69 @Before +70 public void setUp() throws Exception { +71 super.setUp(); +72 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); +73 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); +74 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); +75 analyzer = new RubyBundleAuditAnalyzer(); +76 analyzer.setFilesMatched(true); +77 } +78 +79 /** +80 * Cleanup the analyzer's temp files, etc. +81 * +82 * @throws Exception thrown if there is a problem +83 */ +84 @After +85 public void tearDown() throws Exception { +86 analyzer.close(); +87 analyzer = null; +88 } +89 +90 /** +91 * Test Ruby Gemspec name. +92 */ +93 @Test +94 public void testGetName() { +95 assertThat(analyzer.getName(), is("Ruby Bundle Audit Analyzer")); +96 } +97 +98 /** +99 * Test Ruby Bundler Audit file support. +100 */ +101 @Test +102 public void testSupportsFiles() { +103 assertThat(analyzer.accept(new File("Gemfile.lock")), is(true)); +104 } +105 +106 /** +107 * Test Ruby BundlerAudit analysis. +108 * +109 * @throws AnalysisException is thrown when an exception occurs. +110 */ +111 @Test +112 public void testAnalysis() throws AnalysisException, DatabaseException { +113 try { +114 analyzer.initialize(); +115 final String resource = "ruby/vulnerable/gems/rails-4.1.15/Gemfile.lock"; +116 final Dependency result = new Dependency(BaseTest.getResourceAsFile(this, resource)); +117 final Engine engine = new Engine(); +118 analyzer.analyze(result, engine); +119 int size = engine.getDependencies().size(); +120 +121 assertTrue(size >= 1); +122 +123 Dependency dependency = engine.getDependencies().get(0); +124 assertTrue(dependency.getProductEvidence().toString().toLowerCase().contains("redcarpet")); +125 assertTrue(dependency.getVersionEvidence().toString().toLowerCase().contains("2.2.2")); +126 assertTrue(dependency.getFilePath().endsWith(resource)); +127 assertTrue(dependency.getFileName().equals("Gemfile.lock")); +128 } catch (Exception e) { +129 LOGGER.warn("Exception setting up RubyBundleAuditAnalyzer. Make sure Ruby gem bundle-audit is installed. You may also need to set property \"analyzer.bundle.audit.path\"."); +130 Assume.assumeNoException("Exception setting up RubyBundleAuditAnalyzer; bundle audit may not be installed, or property \"analyzer.bundle.audit.path\" may not be set.", e); +131 } +132 } +133 +134 /** +135 * Test Ruby addCriticalityToVulnerability +136 */ +137 @Test +138 public void testAddCriticalityToVulnerability() throws AnalysisException, DatabaseException { +139 try { +140 analyzer.initialize(); +141 +142 final Dependency result = new Dependency(BaseTest.getResourceAsFile(this, +143 "ruby/vulnerable/gems/sinatra/Gemfile.lock")); +144 final Engine engine = new Engine(); +145 analyzer.analyze(result, engine); +146 +147 Dependency dependency = engine.getDependencies().get(0); +148 Vulnerability vulnerability = dependency.getVulnerabilities().first(); +149 assertEquals(vulnerability.getCvssScore(), 5.0f, 0.0); +150 +151 } catch (Exception e) { +152 LOGGER.warn("Exception setting up RubyBundleAuditAnalyzer. Make sure Ruby gem bundle-audit is installed. You may also need to set property \"analyzer.bundle.audit.path\"."); +153 Assume.assumeNoException("Exception setting up RubyBundleAuditAnalyzer; bundle audit may not be installed, or property \"analyzer.bundle.audit.path\" may not be set.", e); +154 } +155 } +156 +157 /** +158 * Test when Ruby bundle-audit is not available on the system. +159 * +160 * @throws AnalysisException is thrown when an exception occurs. +161 */ +162 @Test +163 public void testMissingBundleAudit() throws AnalysisException, DatabaseException { +164 //set a non-exist bundle-audit +165 Settings.setString(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH, "phantom-bundle-audit"); +166 try { +167 //initialize should fail. +168 analyzer.initialize(); +169 } catch (Exception e) { +170 //expected, so ignore. +171 } finally { +172 assertThat(analyzer.isEnabled(), is(false)); +173 LOGGER.info("phantom-bundle-audit is not available. Ruby Bundle Audit Analyzer is disabled as expected."); +174 } +175 } +176 +177 /** +178 * Test Ruby dependencies and their paths. +179 * +180 * @throws AnalysisException is thrown when an exception occurs. +181 * @throws DatabaseException thrown when an exception occurs +182 */ +183 @Test +184 public void testDependenciesPath() throws AnalysisException, DatabaseException { +185 final Engine engine = new Engine(); +186 engine.scan(BaseTest.getResourceAsFile(this, +187 "ruby/vulnerable/gems/rails-4.1.15/")); +188 try { +189 engine.analyzeDependencies(); +190 } catch (NullPointerException ex) { +191 LOGGER.error("NPE", ex); +192 throw ex; +193 } catch (ExceptionCollection ex) { +194 Assume.assumeNoException("Exception setting up RubyBundleAuditAnalyzer; bundle audit may not be installed, or property \"analyzer.bundle.audit.path\" may not be set.", ex); +195 } +196 List<Dependency> dependencies = engine.getDependencies(); +197 LOGGER.info(dependencies.size() + " dependencies found."); +198 Iterator<Dependency> dIterator = dependencies.iterator(); +199 while (dIterator.hasNext()) { +200 Dependency dept = dIterator.next(); +201 LOGGER.info("dept path: " + dept.getActualFilePath()); +202 +203 Set<Identifier> identifiers = dept.getIdentifiers(); +204 Iterator<Identifier> idIterator = identifiers.iterator(); +205 while (idIterator.hasNext()) { +206 Identifier id = idIterator.next(); +207 LOGGER.info(" Identifier: " + id.getValue() + ", type=" + id.getType() + ", url=" + id.getUrl() + ", conf=" + id.getConfidence()); +208 } +209 +210 Set<Evidence> prodEv = dept.getProductEvidence().getEvidence(); +211 Iterator<Evidence> it = prodEv.iterator(); +212 while (it.hasNext()) { +213 Evidence e = it.next(); +214 LOGGER.info(" prod: name=" + e.getName() + ", value=" + e.getValue() + ", source=" + e.getSource() + ", confidence=" + e.getConfidence()); 215 } -216 -217 Set<Evidence> vendorEv = dept.getVendorEvidence().getEvidence(); -218 Iterator<Evidence> vendorIt = vendorEv.iterator(); -219 while (vendorIt.hasNext()) { -220 Evidence e = vendorIt.next(); -221 LOGGER.info(" vendor: name=" + e.getName() + ", value=" + e.getValue() + ", source=" + e.getSource() + ", confidence=" + e.getConfidence()); -222 } -223 } -224 } -225 } +216 Set<Evidence> versionEv = dept.getVersionEvidence().getEvidence(); +217 Iterator<Evidence> vIt = versionEv.iterator(); +218 while (vIt.hasNext()) { +219 Evidence e = vIt.next(); +220 LOGGER.info(" version: name=" + e.getName() + ", value=" + e.getValue() + ", source=" + e.getSource() + ", confidence=" + e.getConfidence()); +221 } +222 +223 Set<Evidence> vendorEv = dept.getVendorEvidence().getEvidence(); +224 Iterator<Evidence> vendorIt = vendorEv.iterator(); +225 while (vendorIt.hasNext()) { +226 Evidence e = vendorIt.next(); +227 LOGGER.info(" vendor: name=" + e.getName() + ", value=" + e.getValue() + ", source=" + e.getSource() + ", confidence=" + e.getConfidence()); +228 } +229 } +230 } +231 }
      diff --git a/xref-test/org/owasp/dependencycheck/analyzer/package-frame.html b/xref-test/org/owasp/dependencycheck/analyzer/package-frame.html index eb9729874..2e2d89997 100644 --- a/xref-test/org/owasp/dependencycheck/analyzer/package-frame.html +++ b/xref-test/org/owasp/dependencycheck/analyzer/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.analyzer + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.analyzer diff --git a/xref-test/org/owasp/dependencycheck/analyzer/package-summary.html b/xref-test/org/owasp/dependencycheck/analyzer/package-summary.html index 9ac987b63..ea0130070 100644 --- a/xref-test/org/owasp/dependencycheck/analyzer/package-summary.html +++ b/xref-test/org/owasp/dependencycheck/analyzer/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.analyzer + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.analyzer diff --git a/xref-test/org/owasp/dependencycheck/data/central/package-frame.html b/xref-test/org/owasp/dependencycheck/data/central/package-frame.html index 776831710..a250635fd 100644 --- a/xref-test/org/owasp/dependencycheck/data/central/package-frame.html +++ b/xref-test/org/owasp/dependencycheck/data/central/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.central + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.central diff --git a/xref-test/org/owasp/dependencycheck/data/central/package-summary.html b/xref-test/org/owasp/dependencycheck/data/central/package-summary.html index 781eabaff..353e3789f 100644 --- a/xref-test/org/owasp/dependencycheck/data/central/package-summary.html +++ b/xref-test/org/owasp/dependencycheck/data/central/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.central + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.central diff --git a/xref-test/org/owasp/dependencycheck/data/composer/package-frame.html b/xref-test/org/owasp/dependencycheck/data/composer/package-frame.html index 57df0ae96..5e4a43030 100644 --- a/xref-test/org/owasp/dependencycheck/data/composer/package-frame.html +++ b/xref-test/org/owasp/dependencycheck/data/composer/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.composer + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.composer diff --git a/xref-test/org/owasp/dependencycheck/data/composer/package-summary.html b/xref-test/org/owasp/dependencycheck/data/composer/package-summary.html index 6a25f9329..e801768c0 100644 --- a/xref-test/org/owasp/dependencycheck/data/composer/package-summary.html +++ b/xref-test/org/owasp/dependencycheck/data/composer/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.composer + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.composer diff --git a/xref-test/org/owasp/dependencycheck/data/cpe/package-frame.html b/xref-test/org/owasp/dependencycheck/data/cpe/package-frame.html index 4f6c93411..e5f473595 100644 --- a/xref-test/org/owasp/dependencycheck/data/cpe/package-frame.html +++ b/xref-test/org/owasp/dependencycheck/data/cpe/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.cpe + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.cpe diff --git a/xref-test/org/owasp/dependencycheck/data/cpe/package-summary.html b/xref-test/org/owasp/dependencycheck/data/cpe/package-summary.html index c2d088727..7b9fa5155 100644 --- a/xref-test/org/owasp/dependencycheck/data/cpe/package-summary.html +++ b/xref-test/org/owasp/dependencycheck/data/cpe/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.cpe + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.cpe diff --git a/xref-test/org/owasp/dependencycheck/data/cwe/CweDBTest.html b/xref-test/org/owasp/dependencycheck/data/cwe/CweDBTest.html index 4ce949ccd..63fe9c951 100644 --- a/xref-test/org/owasp/dependencycheck/data/cwe/CweDBTest.html +++ b/xref-test/org/owasp/dependencycheck/data/cwe/CweDBTest.html @@ -25,66 +25,63 @@ 17 */ 18 package org.owasp.dependencycheck.data.cwe; 19 -20 import org.junit.After; -21 import org.junit.AfterClass; -22 import static org.junit.Assert.assertEquals; -23 import org.junit.Before; -24 import org.junit.BeforeClass; -25 import org.junit.Test; -26 import org.owasp.dependencycheck.BaseTest; -27 -28 /** -29 * -30 * @author Jeremy Long -31 */ -32 public class CweDBTest extends BaseTest { -33 -34 /** -35 * Method to serialize the CWE HashMap. This is not used in production; this is only used once during dev to create -36 * the serialized HashMap. -37 */ -38 // @Test -39 // public void testUpdate() throws Exception { -40 // SAXParserFactory factory = SAXParserFactory.newInstance(); -41 // SAXParser saxParser = factory.newSAXParser(); -42 // -43 // CweHandler handler = new CweHandler(); -44 // //File file = new File(this.getClass().getClassLoader().getResource("cwe.2000.xml").getPath()); -45 // File file = new File(this.getClass().getClassLoader().getResource("cwec_v2.5.xml").getPath()); -46 // -47 // saxParser.parse(file, handler); -48 // System.out.println("Found " + handler.getCwe().size() + " cwe entries."); -49 // Map<String, String> cwe = handler.getCwe(); -50 //// FileOutputStream fout = new FileOutputStream("target/current.csv"); -51 //// //FileOutputStream fout = new FileOutputStream("target/new.csv"); -52 //// PrintWriter writer = new PrintWriter(fout); -53 //// for (Map.Entry<String, String> entry : cwe.entrySet()) { -54 //// writer.print('"'); -55 //// writer.print(entry.getKey()); -56 //// writer.print('"'); -57 //// writer.print(','); -58 //// writer.print('"'); -59 //// writer.print(entry.getValue()); -60 //// writer.println('"'); -61 //// } -62 //// writer.close(); -63 // -64 // FileOutputStream fout = new FileOutputStream("src/main/resources/data/cwe.hashmap.serialized"); -65 // ObjectOutputStream objOut = new ObjectOutputStream(fout); -66 // objOut.writeObject(cwe); -67 // objOut.close(); -68 // } -69 /** -70 * Test of getCweName method, of class CweDB. -71 */ -72 @Test -73 public void testGetCweName() { -74 String cweId = "CWE-16"; -75 String expResult = "Configuration"; -76 String result = CweDB.getCweName(cweId); -77 assertEquals(expResult, result); -78 } -79 } +20 import static org.junit.Assert.assertEquals; +21 +22 import org.junit.Test; +23 import org.owasp.dependencycheck.BaseTest; +24 +25 /** +26 * +27 * @author Jeremy Long +28 */ +29 public class CweDBTest extends BaseTest { +30 +31 /** +32 * Method to serialize the CWE HashMap. This is not used in production; this is only used once during dev to create +33 * the serialized HashMap. +34 */ +35 // @Test +36 // public void testUpdate() throws Exception { +37 // SAXParserFactory factory = SAXParserFactory.newInstance(); +38 // SAXParser saxParser = factory.newSAXParser(); +39 // +40 // CweHandler handler = new CweHandler(); +41 // //File file = new File(this.getClass().getClassLoader().getResource("cwe.2000.xml").getPath()); +42 // File file = new File(this.getClass().getClassLoader().getResource("cwec_v2.5.xml").getPath()); +43 // +44 // saxParser.parse(file, handler); +45 // System.out.println("Found " + handler.getCwe().size() + " cwe entries."); +46 // Map<String, String> cwe = handler.getCwe(); +47 //// FileOutputStream fout = new FileOutputStream("target/current.csv"); +48 //// //FileOutputStream fout = new FileOutputStream("target/new.csv"); +49 //// PrintWriter writer = new PrintWriter(fout); +50 //// for (Map.Entry<String, String> entry : cwe.entrySet()) { +51 //// writer.print('"'); +52 //// writer.print(entry.getKey()); +53 //// writer.print('"'); +54 //// writer.print(','); +55 //// writer.print('"'); +56 //// writer.print(entry.getValue()); +57 //// writer.println('"'); +58 //// } +59 //// writer.close(); +60 // +61 // FileOutputStream fout = new FileOutputStream("src/main/resources/data/cwe.hashmap.serialized"); +62 // ObjectOutputStream objOut = new ObjectOutputStream(fout); +63 // objOut.writeObject(cwe); +64 // objOut.close(); +65 // } +66 /** +67 * Test of getCweName method, of class CweDB. +68 */ +69 @Test +70 public void testGetCweName() { +71 String cweId = "CWE-16"; +72 String expResult = "Configuration"; +73 String result = CweDB.getCweName(cweId); +74 assertEquals(expResult, result); +75 } +76 }
      diff --git a/xref-test/org/owasp/dependencycheck/data/cwe/package-frame.html b/xref-test/org/owasp/dependencycheck/data/cwe/package-frame.html index 481940f04..477294014 100644 --- a/xref-test/org/owasp/dependencycheck/data/cwe/package-frame.html +++ b/xref-test/org/owasp/dependencycheck/data/cwe/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.cwe + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.cwe diff --git a/xref-test/org/owasp/dependencycheck/data/cwe/package-summary.html b/xref-test/org/owasp/dependencycheck/data/cwe/package-summary.html index e5a18da6c..e86ac3a6b 100644 --- a/xref-test/org/owasp/dependencycheck/data/cwe/package-summary.html +++ b/xref-test/org/owasp/dependencycheck/data/cwe/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.cwe + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.cwe diff --git a/xref-test/org/owasp/dependencycheck/data/lucene/FieldAnalyzerTest.html b/xref-test/org/owasp/dependencycheck/data/lucene/FieldAnalyzerTest.html index 72486401a..0719ff09f 100644 --- a/xref-test/org/owasp/dependencycheck/data/lucene/FieldAnalyzerTest.html +++ b/xref-test/org/owasp/dependencycheck/data/lucene/FieldAnalyzerTest.html @@ -44,81 +44,90 @@ 36 import org.apache.lucene.search.TopScoreDocCollector; 37 import org.apache.lucene.store.Directory; 38 import org.apache.lucene.store.RAMDirectory; -39 import org.junit.After; -40 import org.junit.AfterClass; -41 import static org.junit.Assert.assertEquals; -42 import static org.junit.Assert.assertFalse; -43 import org.junit.Before; -44 import org.junit.BeforeClass; -45 import org.junit.Test; -46 import org.owasp.dependencycheck.BaseTest; -47 -48 /** -49 * -50 * @author Jeremy Long -51 */ -52 public class FieldAnalyzerTest extends BaseTest { -53 -54 @Test -55 public void testAnalyzers() throws Exception { -56 -57 Analyzer analyzer = new FieldAnalyzer(LuceneUtils.CURRENT_VERSION); -58 Directory index = new RAMDirectory(); -59 -60 String field1 = "product"; -61 String text1 = "springframework"; -62 -63 String field2 = "vendor"; -64 String text2 = "springsource"; -65 -66 createIndex(analyzer, index, field1, text1, field2, text2); -67 -68 //Analyzer searchingAnalyzer = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION); -69 String querystr = "product:\"(Spring Framework Core)\" vendor:(SpringSource)"; +39 +40 import static org.junit.Assert.assertEquals; +41 import static org.junit.Assert.assertFalse; +42 +43 import org.junit.Test; +44 import org.owasp.dependencycheck.BaseTest; +45 +46 /** +47 * +48 * @author Jeremy Long +49 */ +50 public class FieldAnalyzerTest extends BaseTest { +51 +52 @Test +53 public void testAnalyzers() throws Exception { +54 +55 Analyzer analyzer = new FieldAnalyzer(LuceneUtils.CURRENT_VERSION); +56 Directory index = new RAMDirectory(); +57 +58 String field1 = "product"; +59 String text1 = "springframework"; +60 +61 String field2 = "vendor"; +62 String text2 = "springsource"; +63 +64 IndexWriter w = createIndex(analyzer, index); +65 addDoc(w, field1, text1, field2, text2); +66 text1 = "x-stream"; +67 text2 = "xstream"; +68 addDoc(w, field1, text1, field2, text2); +69 w.close(); 70 -71 SearchFieldAnalyzer searchAnalyzerProduct = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION); -72 SearchFieldAnalyzer searchAnalyzerVendor = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION); -73 HashMap<String, Analyzer> map = new HashMap<String, Analyzer>(); -74 map.put(field1, searchAnalyzerProduct); -75 map.put(field2, searchAnalyzerVendor); -76 PerFieldAnalyzerWrapper wrapper = new PerFieldAnalyzerWrapper(new StandardAnalyzer(LuceneUtils.CURRENT_VERSION), map); -77 QueryParser parser = new QueryParser(LuceneUtils.CURRENT_VERSION, field1, wrapper); -78 -79 Query q = parser.parse(querystr); -80 //System.out.println(q.toString()); +71 //Analyzer searchingAnalyzer = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION); +72 String querystr = "product:\"(Spring Framework Core)\" vendor:(SpringSource)"; +73 +74 SearchFieldAnalyzer searchAnalyzerProduct = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION); +75 SearchFieldAnalyzer searchAnalyzerVendor = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION); +76 HashMap<String, Analyzer> map = new HashMap<String, Analyzer>(); +77 map.put(field1, searchAnalyzerProduct); +78 map.put(field2, searchAnalyzerVendor); +79 PerFieldAnalyzerWrapper wrapper = new PerFieldAnalyzerWrapper(new StandardAnalyzer(LuceneUtils.CURRENT_VERSION), map); +80 QueryParser parser = new QueryParser(LuceneUtils.CURRENT_VERSION, field1, wrapper); 81 -82 int hitsPerPage = 10; +82 Query q = parser.parse(querystr); 83 -84 IndexReader reader = DirectoryReader.open(index); -85 IndexSearcher searcher = new IndexSearcher(reader); -86 TopScoreDocCollector collector = TopScoreDocCollector.create(hitsPerPage, true); -87 searcher.search(q, collector); -88 ScoreDoc[] hits = collector.topDocs().scoreDocs; -89 -90 assertEquals("Did not find 1 document?", 1, hits.length); +84 int hitsPerPage = 10; +85 +86 IndexReader reader = DirectoryReader.open(index); +87 IndexSearcher searcher = new IndexSearcher(reader); +88 TopScoreDocCollector collector = TopScoreDocCollector.create(hitsPerPage, true); +89 searcher.search(q, collector); +90 ScoreDoc[] hits = collector.topDocs().scoreDocs; 91 -92 searchAnalyzerProduct.clear(); //ensure we don't have anything left over from the previous search. -93 searchAnalyzerVendor.clear(); -94 querystr = "product:(Apache Struts) vendor:(Apache)"; -95 Query q2 = parser.parse(querystr); -96 //System.out.println(q2.toString()); -97 assertFalse("second parsing contains previousWord from the TokenPairConcatenatingFilter", q2.toString().contains("core")); -98 } -99 -100 private void createIndex(Analyzer analyzer, Directory index, String field1, String text1, String field2, String text2) throws IOException { -101 IndexWriterConfig config = new IndexWriterConfig(LuceneUtils.CURRENT_VERSION, analyzer); -102 IndexWriter w = new IndexWriter(index, config); -103 addDoc(w, field1, text1, field2, text2); -104 w.close(); -105 } -106 -107 private static void addDoc(IndexWriter w, String field1, String text1, String field2, String text2) throws IOException { -108 Document doc = new Document(); -109 doc.add(new TextField(field1, text1, Field.Store.YES)); -110 doc.add(new TextField(field2, text2, Field.Store.YES)); -111 w.addDocument(doc); -112 } -113 } +92 assertEquals("Did not find 1 document?", 1, hits.length); +93 assertEquals("springframework", searcher.doc(hits[0].doc).get(field1)); +94 assertEquals("springsource", searcher.doc(hits[0].doc).get(field2)); +95 +96 searchAnalyzerProduct.clear(); //ensure we don't have anything left over from the previous search. +97 searchAnalyzerVendor.clear(); +98 querystr = "product:(Apache Struts) vendor:(Apache)"; +99 Query q2 = parser.parse(querystr); +100 assertFalse("second parsing contains previousWord from the TokenPairConcatenatingFilter", q2.toString().contains("core")); +101 +102 querystr = "product:( x-stream^5 ) AND vendor:( thoughtworks.xstream )"; +103 Query q3 = parser.parse(querystr); +104 collector = TopScoreDocCollector.create(hitsPerPage, true); +105 searcher.search(q3, collector); +106 hits = collector.topDocs().scoreDocs; +107 assertEquals("x-stream", searcher.doc(hits[0].doc).get(field1)); +108 assertEquals("xstream", searcher.doc(hits[0].doc).get(field2)); +109 } +110 +111 private IndexWriter createIndex(Analyzer analyzer, Directory index) throws IOException { +112 IndexWriterConfig config = new IndexWriterConfig(LuceneUtils.CURRENT_VERSION, analyzer); +113 return new IndexWriter(index, config); +114 } +115 +116 private static void addDoc(IndexWriter w, String field1, String text1, String field2, String text2) throws IOException { +117 Document doc = new Document(); +118 doc.add(new TextField(field1, text1, Field.Store.YES)); +119 doc.add(new TextField(field2, text2, Field.Store.YES)); +120 w.addDocument(doc); +121 } +122 }
      diff --git a/xref-test/org/owasp/dependencycheck/data/lucene/LuceneUtilsTest.html b/xref-test/org/owasp/dependencycheck/data/lucene/LuceneUtilsTest.html index 5ebc9bc1e..2bacc4c54 100644 --- a/xref-test/org/owasp/dependencycheck/data/lucene/LuceneUtilsTest.html +++ b/xref-test/org/owasp/dependencycheck/data/lucene/LuceneUtilsTest.html @@ -25,65 +25,62 @@ 17 */ 18 package org.owasp.dependencycheck.data.lucene; 19 -20 import org.junit.After; -21 import org.junit.AfterClass; -22 import static org.junit.Assert.assertEquals; -23 import org.junit.Before; -24 import org.junit.BeforeClass; -25 import org.junit.Test; -26 import org.owasp.dependencycheck.BaseTest; -27 -28 /** -29 * -30 * @author Jeremy Long -31 */ -32 public class LuceneUtilsTest extends BaseTest { -33 -34 /** -35 * Test of appendEscapedLuceneQuery method, of class LuceneUtils. -36 */ -37 @Test -38 public void testAppendEscapedLuceneQuery() { -39 StringBuilder buf = new StringBuilder(); -40 CharSequence text = "test encoding + - & | ! ( ) { } [ ] ^ \" ~ * ? : \\"; -41 String expResult = "test encoding \\+ \\- \\& \\| \\! \\( \\) \\{ \\} \\[ \\] \\^ \\\" \\~ \\* \\? \\: \\\\"; -42 LuceneUtils.appendEscapedLuceneQuery(buf, text); -43 assertEquals(expResult, buf.toString()); -44 } -45 -46 /** -47 * Test of appendEscapedLuceneQuery method, of class LuceneUtils. -48 */ -49 @Test -50 public void testAppendEscapedLuceneQuery_null() { -51 StringBuilder buf = new StringBuilder(); -52 CharSequence text = null; -53 LuceneUtils.appendEscapedLuceneQuery(buf, text); -54 assertEquals(0, buf.length()); -55 } -56 -57 /** -58 * Test of escapeLuceneQuery method, of class LuceneUtils. -59 */ -60 @Test -61 public void testEscapeLuceneQuery() { -62 CharSequence text = "test encoding + - & | ! ( ) { } [ ] ^ \" ~ * ? : \\"; -63 String expResult = "test encoding \\+ \\- \\& \\| \\! \\( \\) \\{ \\} \\[ \\] \\^ \\\" \\~ \\* \\? \\: \\\\"; -64 String result = LuceneUtils.escapeLuceneQuery(text); -65 assertEquals(expResult, result); -66 } -67 -68 /** -69 * Test of escapeLuceneQuery method, of class LuceneUtils. -70 */ -71 @Test -72 public void testEscapeLuceneQuery_null() { -73 CharSequence text = null; -74 String expResult = null; -75 String result = LuceneUtils.escapeLuceneQuery(text); -76 assertEquals(expResult, result); -77 } -78 } +20 import static org.junit.Assert.assertEquals; +21 +22 import org.junit.Test; +23 import org.owasp.dependencycheck.BaseTest; +24 +25 /** +26 * +27 * @author Jeremy Long +28 */ +29 public class LuceneUtilsTest extends BaseTest { +30 +31 /** +32 * Test of appendEscapedLuceneQuery method, of class LuceneUtils. +33 */ +34 @Test +35 public void testAppendEscapedLuceneQuery() { +36 StringBuilder buf = new StringBuilder(); +37 CharSequence text = "test encoding + - & | ! ( ) { } [ ] ^ \" ~ * ? : \\"; +38 String expResult = "test encoding \\+ \\- \\& \\| \\! \\( \\) \\{ \\} \\[ \\] \\^ \\\" \\~ \\* \\? \\: \\\\"; +39 LuceneUtils.appendEscapedLuceneQuery(buf, text); +40 assertEquals(expResult, buf.toString()); +41 } +42 +43 /** +44 * Test of appendEscapedLuceneQuery method, of class LuceneUtils. +45 */ +46 @Test +47 public void testAppendEscapedLuceneQuery_null() { +48 StringBuilder buf = new StringBuilder(); +49 CharSequence text = null; +50 LuceneUtils.appendEscapedLuceneQuery(buf, text); +51 assertEquals(0, buf.length()); +52 } +53 +54 /** +55 * Test of escapeLuceneQuery method, of class LuceneUtils. +56 */ +57 @Test +58 public void testEscapeLuceneQuery() { +59 CharSequence text = "test encoding + - & | ! ( ) { } [ ] ^ \" ~ * ? : \\"; +60 String expResult = "test encoding \\+ \\- \\& \\| \\! \\( \\) \\{ \\} \\[ \\] \\^ \\\" \\~ \\* \\? \\: \\\\"; +61 String result = LuceneUtils.escapeLuceneQuery(text); +62 assertEquals(expResult, result); +63 } +64 +65 /** +66 * Test of escapeLuceneQuery method, of class LuceneUtils. +67 */ +68 @Test +69 public void testEscapeLuceneQuery_null() { +70 CharSequence text = null; +71 String expResult = null; +72 String result = LuceneUtils.escapeLuceneQuery(text); +73 assertEquals(expResult, result); +74 } +75 }
      diff --git a/xref-test/org/owasp/dependencycheck/data/lucene/TokenPairConcatenatingFilterTest.html b/xref-test/org/owasp/dependencycheck/data/lucene/TokenPairConcatenatingFilterTest.html index f70d8c3ff..8dd9985c2 100644 --- a/xref-test/org/owasp/dependencycheck/data/lucene/TokenPairConcatenatingFilterTest.html +++ b/xref-test/org/owasp/dependencycheck/data/lucene/TokenPairConcatenatingFilterTest.html @@ -28,65 +28,60 @@ 20 import java.io.IOException; 21 import java.io.StringReader; 22 import org.apache.lucene.analysis.BaseTokenStreamTestCase; -23 import static org.apache.lucene.analysis.BaseTokenStreamTestCase.assertTokenStreamContents; -24 import org.apache.lucene.analysis.TokenStream; -25 import org.apache.lucene.analysis.Tokenizer; -26 import org.apache.lucene.analysis.core.WhitespaceTokenizer; -27 import org.junit.After; -28 import org.junit.AfterClass; -29 import static org.junit.Assert.assertNotNull; -30 import static org.junit.Assert.assertNull; -31 import static org.junit.Assert.assertTrue; -32 import org.junit.Before; -33 import org.junit.BeforeClass; -34 import org.junit.Test; -35 -36 /** -37 * -38 * @author Jeremy Long -39 */ -40 public class TokenPairConcatenatingFilterTest extends BaseTokenStreamTestCase { -41 -42 @Override -43 @Before -44 public void setUp() throws Exception { -45 super.setUp(); -46 } -47 -48 @Override -49 @After -50 public void tearDown() throws Exception { -51 super.tearDown(); -52 } -53 -54 /** -55 * test some examples -56 */ -57 public void testExamples() throws IOException { -58 Tokenizer wsTokenizer = new WhitespaceTokenizer(LuceneUtils.CURRENT_VERSION, new StringReader("one two three")); -59 TokenStream filter = new TokenPairConcatenatingFilter(wsTokenizer); -60 assertTokenStreamContents(filter, -61 new String[]{"one", "onetwo", "two", "twothree", "three"}); -62 } -63 -64 /** -65 * Test of clear method, of class TokenPairConcatenatingFilter. -66 * -67 * @throws java.io.IOException -68 */ -69 @Test -70 public void testClear() throws IOException { -71 -72 TokenStream ts = new WhitespaceTokenizer(LuceneUtils.CURRENT_VERSION, new StringReader("one two three")); -73 TokenPairConcatenatingFilter filter = new TokenPairConcatenatingFilter(ts); -74 assertTokenStreamContents(filter, new String[]{"one", "onetwo", "two", "twothree", "three"}); -75 -76 assertNotNull(filter.getPreviousWord()); -77 filter.clear(); -78 assertNull(filter.getPreviousWord()); -79 assertTrue(filter.getWords().isEmpty()); -80 } -81 } +23 import org.apache.lucene.analysis.TokenStream; +24 import org.apache.lucene.analysis.Tokenizer; +25 import org.apache.lucene.analysis.core.WhitespaceTokenizer; +26 import org.junit.After; +27 +28 import org.junit.Before; +29 import org.junit.Test; +30 +31 /** +32 * +33 * @author Jeremy Long +34 */ +35 public class TokenPairConcatenatingFilterTest extends BaseTokenStreamTestCase { +36 +37 @Override +38 @Before +39 public void setUp() throws Exception { +40 super.setUp(); +41 } +42 +43 @Override +44 @After +45 public void tearDown() throws Exception { +46 super.tearDown(); +47 } +48 +49 /** +50 * test some examples +51 */ +52 public void testExamples() throws IOException { +53 Tokenizer wsTokenizer = new WhitespaceTokenizer(LuceneUtils.CURRENT_VERSION, new StringReader("one two three")); +54 TokenStream filter = new TokenPairConcatenatingFilter(wsTokenizer); +55 assertTokenStreamContents(filter, +56 new String[]{"one", "onetwo", "two", "twothree", "three"}); +57 } +58 +59 /** +60 * Test of clear method, of class TokenPairConcatenatingFilter. +61 * +62 * @throws java.io.IOException +63 */ +64 @Test +65 public void testClear() throws IOException { +66 +67 TokenStream ts = new WhitespaceTokenizer(LuceneUtils.CURRENT_VERSION, new StringReader("one two three")); +68 TokenPairConcatenatingFilter filter = new TokenPairConcatenatingFilter(ts); +69 assertTokenStreamContents(filter, new String[]{"one", "onetwo", "two", "twothree", "three"}); +70 +71 assertNotNull(filter.getPreviousWord()); +72 filter.clear(); +73 assertNull(filter.getPreviousWord()); +74 assertTrue(filter.getWords().isEmpty()); +75 } +76 }
      diff --git a/xref-test/org/owasp/dependencycheck/data/lucene/package-frame.html b/xref-test/org/owasp/dependencycheck/data/lucene/package-frame.html index b8930b283..4a26dee45 100644 --- a/xref-test/org/owasp/dependencycheck/data/lucene/package-frame.html +++ b/xref-test/org/owasp/dependencycheck/data/lucene/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.lucene + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.lucene diff --git a/xref-test/org/owasp/dependencycheck/data/lucene/package-summary.html b/xref-test/org/owasp/dependencycheck/data/lucene/package-summary.html index 8f16005d1..10d526834 100644 --- a/xref-test/org/owasp/dependencycheck/data/lucene/package-summary.html +++ b/xref-test/org/owasp/dependencycheck/data/lucene/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.lucene + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.lucene diff --git a/xref-test/org/owasp/dependencycheck/data/nexus/package-frame.html b/xref-test/org/owasp/dependencycheck/data/nexus/package-frame.html index fc03279f0..29caac2d2 100644 --- a/xref-test/org/owasp/dependencycheck/data/nexus/package-frame.html +++ b/xref-test/org/owasp/dependencycheck/data/nexus/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.nexus + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.nexus diff --git a/xref-test/org/owasp/dependencycheck/data/nexus/package-summary.html b/xref-test/org/owasp/dependencycheck/data/nexus/package-summary.html index 30d1e78d6..955bd1d96 100644 --- a/xref-test/org/owasp/dependencycheck/data/nexus/package-summary.html +++ b/xref-test/org/owasp/dependencycheck/data/nexus/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.nexus + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.nexus diff --git a/xref-test/org/owasp/dependencycheck/data/nuget/package-frame.html b/xref-test/org/owasp/dependencycheck/data/nuget/package-frame.html index 81bae1ab9..09b18a862 100644 --- a/xref-test/org/owasp/dependencycheck/data/nuget/package-frame.html +++ b/xref-test/org/owasp/dependencycheck/data/nuget/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.nuget + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.nuget diff --git a/xref-test/org/owasp/dependencycheck/data/nuget/package-summary.html b/xref-test/org/owasp/dependencycheck/data/nuget/package-summary.html index 98a98d84c..a80a481e2 100644 --- a/xref-test/org/owasp/dependencycheck/data/nuget/package-summary.html +++ b/xref-test/org/owasp/dependencycheck/data/nuget/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.nuget + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.nuget diff --git a/xref-test/org/owasp/dependencycheck/data/nvdcve/ConnectionFactoryTest.html b/xref-test/org/owasp/dependencycheck/data/nvdcve/ConnectionFactoryTest.html index f5db3dddd..09164ceb7 100644 --- a/xref-test/org/owasp/dependencycheck/data/nvdcve/ConnectionFactoryTest.html +++ b/xref-test/org/owasp/dependencycheck/data/nvdcve/ConnectionFactoryTest.html @@ -25,34 +25,31 @@ 17 18 import java.sql.Connection; 19 import java.sql.SQLException; -20 import org.junit.After; -21 import org.junit.AfterClass; -22 import org.junit.Before; -23 import org.junit.BeforeClass; -24 import org.junit.Test; -25 import static org.junit.Assert.*; -26 import org.owasp.dependencycheck.BaseDBTestCase; -27 -28 /** -29 * -30 * @author jeremy -31 */ -32 public class ConnectionFactoryTest extends BaseDBTestCase { -33 -34 /** -35 * Test of initialize method, of class ConnectionFactory. -36 * -37 * @throws org.owasp.dependencycheck.data.nvdcve.DatabaseException -38 */ -39 @Test -40 public void testInitialize() throws DatabaseException, SQLException { -41 ConnectionFactory.initialize(); -42 Connection result = ConnectionFactory.getConnection(); -43 assertNotNull(result); -44 result.close(); -45 ConnectionFactory.cleanup(); -46 } -47 } +20 +21 import org.junit.Test; +22 import static org.junit.Assert.*; +23 import org.owasp.dependencycheck.BaseDBTestCase; +24 +25 /** +26 * +27 * @author jeremy +28 */ +29 public class ConnectionFactoryTest extends BaseDBTestCase { +30 +31 /** +32 * Test of initialize method, of class ConnectionFactory. +33 * +34 * @throws org.owasp.dependencycheck.data.nvdcve.DatabaseException +35 */ +36 @Test +37 public void testInitialize() throws DatabaseException, SQLException { +38 ConnectionFactory.initialize(); +39 Connection result = ConnectionFactory.getConnection(); +40 assertNotNull(result); +41 result.close(); +42 ConnectionFactory.cleanup(); +43 } +44 }
      diff --git a/xref-test/org/owasp/dependencycheck/data/nvdcve/CveDBMySQLTest.html b/xref-test/org/owasp/dependencycheck/data/nvdcve/CveDBMySQLTest.html index e861d3cbf..c19cb8801 100644 --- a/xref-test/org/owasp/dependencycheck/data/nvdcve/CveDBMySQLTest.html +++ b/xref-test/org/owasp/dependencycheck/data/nvdcve/CveDBMySQLTest.html @@ -27,77 +27,74 @@ 19 20 import java.util.List; 21 import java.util.Set; -22 import org.junit.After; -23 import org.junit.AfterClass; -24 import static org.junit.Assert.assertTrue; -25 import org.junit.Before; -26 import org.junit.BeforeClass; -27 import org.junit.Test; -28 import org.owasp.dependencycheck.BaseTest; -29 import org.owasp.dependencycheck.dependency.Vulnerability; -30 import org.owasp.dependencycheck.dependency.VulnerableSoftware; -31 import org.owasp.dependencycheck.utils.Settings; -32 -33 /** -34 * -35 * @author Jeremy Long -36 */ -37 public class CveDBMySQLTest extends BaseTest { -38 -39 /** -40 * Pretty useless tests of open, commit, and close methods, of class CveDB. -41 */ -42 @Test -43 public void testOpen() throws DatabaseException { -44 try { -45 CveDB instance = new CveDB(); -46 instance.open(); -47 instance.close(); -48 } catch (DatabaseException ex) { -49 System.out.println("Unable to connect to the My SQL database; verify that the db server is running and that the schema has been generated"); -50 throw ex; -51 } -52 } -53 -54 /** -55 * Test of getCPEs method, of class CveDB. -56 */ -57 @Test -58 public void testGetCPEs() throws Exception { -59 CveDB instance = new CveDB(); -60 try { -61 String vendor = "apache"; -62 String product = "struts"; -63 instance.open(); -64 Set<VulnerableSoftware> result = instance.getCPEs(vendor, product); -65 assertTrue("Has data been loaded into the MySQL DB? if not consider using the CLI to populate it", result.size() > 5); -66 } catch (Exception ex) { -67 System.out.println("Unable to access the My SQL database; verify that the db server is running and that the schema has been generated"); -68 throw ex; -69 } finally { -70 instance.close(); -71 } -72 } -73 -74 /** -75 * Test of getVulnerabilities method, of class CveDB. -76 */ -77 @Test -78 public void testGetVulnerabilities() throws Exception { -79 String cpeStr = "cpe:/a:apache:struts:2.1.2"; -80 CveDB instance = new CveDB(); -81 try { -82 instance.open(); -83 List<Vulnerability> result = instance.getVulnerabilities(cpeStr); -84 assertTrue(result.size() > 5); -85 } catch (Exception ex) { -86 System.out.println("Unable to access the My SQL database; verify that the db server is running and that the schema has been generated"); -87 throw ex; -88 } finally { -89 instance.close(); -90 } -91 } -92 } +22 +23 import static org.junit.Assert.assertTrue; +24 +25 import org.junit.Test; +26 import org.owasp.dependencycheck.BaseTest; +27 import org.owasp.dependencycheck.dependency.Vulnerability; +28 import org.owasp.dependencycheck.dependency.VulnerableSoftware; +29 +30 /** +31 * +32 * @author Jeremy Long +33 */ +34 public class CveDBMySQLTest extends BaseTest { +35 +36 /** +37 * Pretty useless tests of open, commit, and close methods, of class CveDB. +38 */ +39 @Test +40 public void testOpen() throws DatabaseException { +41 try { +42 CveDB instance = new CveDB(); +43 instance.open(); +44 instance.close(); +45 } catch (DatabaseException ex) { +46 System.out.println("Unable to connect to the My SQL database; verify that the db server is running and that the schema has been generated"); +47 throw ex; +48 } +49 } +50 +51 /** +52 * Test of getCPEs method, of class CveDB. +53 */ +54 @Test +55 public void testGetCPEs() throws Exception { +56 CveDB instance = new CveDB(); +57 try { +58 String vendor = "apache"; +59 String product = "struts"; +60 instance.open(); +61 Set<VulnerableSoftware> result = instance.getCPEs(vendor, product); +62 assertTrue("Has data been loaded into the MySQL DB? if not consider using the CLI to populate it", result.size() > 5); +63 } catch (Exception ex) { +64 System.out.println("Unable to access the My SQL database; verify that the db server is running and that the schema has been generated"); +65 throw ex; +66 } finally { +67 instance.close(); +68 } +69 } +70 +71 /** +72 * Test of getVulnerabilities method, of class CveDB. +73 */ +74 @Test +75 public void testGetVulnerabilities() throws Exception { +76 String cpeStr = "cpe:/a:apache:struts:2.1.2"; +77 CveDB instance = new CveDB(); +78 try { +79 instance.open(); +80 List<Vulnerability> result = instance.getVulnerabilities(cpeStr); +81 assertTrue(result.size() > 5); +82 } catch (Exception ex) { +83 System.out.println("Unable to access the My SQL database; verify that the db server is running and that the schema has been generated"); +84 throw ex; +85 } finally { +86 instance.close(); +87 } +88 } +89 }
      diff --git a/xref-test/org/owasp/dependencycheck/data/nvdcve/DriverLoaderTest.html b/xref-test/org/owasp/dependencycheck/data/nvdcve/DriverLoaderTest.html index ddf2c22d1..9934baaf6 100644 --- a/xref-test/org/owasp/dependencycheck/data/nvdcve/DriverLoaderTest.html +++ b/xref-test/org/owasp/dependencycheck/data/nvdcve/DriverLoaderTest.html @@ -28,122 +28,120 @@ 20 import java.io.File; 21 import java.sql.Driver; 22 import java.sql.DriverManager; -23 import org.junit.After; -24 import org.junit.AfterClass; -25 import static org.junit.Assert.assertNotNull; -26 import static org.junit.Assert.assertTrue; -27 import org.junit.Before; -28 import org.junit.BeforeClass; -29 import org.junit.Test; -30 import org.owasp.dependencycheck.BaseTest; -31 -32 /** -33 * -34 * @author Jeremy Long -35 */ -36 public class DriverLoaderTest extends BaseTest { -37 -38 /** -39 * Test of load method, of class DriverLoader. -40 */ -41 @Test -42 public void testLoad_String() throws Exception { -43 String className = "org.h2.Driver"; -44 Driver d = null; -45 try { -46 d = DriverLoader.load(className); -47 } finally { -48 if (d != null) { -49 DriverManager.deregisterDriver(d); -50 } -51 } -52 } -53 -54 /** -55 * Test of load method, of class DriverLoader; expecting an exception due to -56 * a bad driver class name. -57 */ -58 @Test(expected = DriverLoadException.class) -59 public void testLoad_String_ex() throws Exception { -60 String className = "bad.Driver"; -61 Driver d = DriverLoader.load(className); -62 } -63 -64 /** -65 * Test of load method, of class DriverLoader. -66 */ -67 @Test -68 public void testLoad_String_String() throws Exception { -69 String className = "com.mysql.jdbc.Driver"; -70 //we know this is in target/test-classes -71 //File testClassPath = (new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath())).getParentFile(); -72 File testClassPath = BaseTest.getResourceAsFile(this, "org.mortbay.jetty.jar").getParentFile(); -73 File driver = new File(testClassPath, "../../src/test/resources/mysql-connector-java-5.1.27-bin.jar"); -74 assertTrue("MySQL Driver JAR file not found in src/test/resources?", driver.isFile()); -75 -76 Driver d = null; -77 try { -78 d = DriverLoader.load(className, driver.getAbsolutePath()); -79 d = DriverManager.getDriver("jdbc:mysql://localhost:3306/dependencycheck"); -80 assertNotNull(d); -81 } finally { -82 if (d != null) { -83 DriverManager.deregisterDriver(d); -84 } -85 } -86 } -87 -88 /** -89 * Test of load method, of class DriverLoader. -90 */ -91 @Test -92 public void testLoad_String_String_multiple_paths() throws Exception { -93 final String className = "com.mysql.jdbc.Driver"; -94 //we know this is in target/test-classes -95 //final File testClassPath = (new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath())).getParentFile(); -96 final File testClassPath = BaseTest.getResourceAsFile(this, "org.mortbay.jetty.jar").getParentFile(); -97 final File dir1 = new File(testClassPath, "../../src/test/"); -98 final File dir2 = new File(testClassPath, "../../src/test/resources/"); -99 final String paths = String.format("%s" + File.pathSeparator + "%s", dir1.getAbsolutePath(), dir2.getAbsolutePath()); -100 -101 Driver d = null; -102 try { -103 d = DriverLoader.load(className, paths); -104 } finally { -105 if (d != null) { -106 DriverManager.deregisterDriver(d); -107 } -108 } -109 } -110 -111 /** -112 * Test of load method, of class DriverLoader with an incorrect class name. -113 */ -114 @Test(expected = DriverLoadException.class) -115 public void testLoad_String_String_badClassName() throws Exception { -116 String className = "com.mybad.jdbc.Driver"; -117 //we know this is in target/test-classes -118 //File testClassPath = (new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath())).getParentFile(); -119 File testClassPath = BaseTest.getResourceAsFile(this, "org.mortbay.jetty.jar").getParentFile(); -120 File driver = new File(testClassPath, "../../src/test/resources/mysql-connector-java-5.1.27-bin.jar"); -121 assertTrue("MySQL Driver JAR file not found in src/test/resources?", driver.isFile()); -122 -123 Driver d = DriverLoader.load(className, driver.getAbsolutePath()); -124 } -125 -126 /** -127 * Test of load method, of class DriverLoader with an incorrect class path. -128 */ -129 @Test(expected = DriverLoadException.class) -130 public void testLoad_String_String_badPath() throws Exception { -131 String className = "com.mysql.jdbc.Driver"; -132 //we know this is in target/test-classes -133 //File testClassPath = (new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath())).getParentFile(); -134 File testClassPath = BaseTest.getResourceAsFile(this, "org.mortbay.jetty.jar").getParentFile(); -135 File driver = new File(testClassPath, "../../src/test/bad/mysql-connector-java-5.1.27-bin.jar"); -136 Driver d = DriverLoader.load(className, driver.getAbsolutePath()); -137 } -138 } +23 +24 import static org.junit.Assert.assertNotNull; +25 import static org.junit.Assert.assertTrue; +26 +27 import org.junit.Test; +28 import org.owasp.dependencycheck.BaseTest; +29 +30 /** +31 * +32 * @author Jeremy Long +33 */ +34 public class DriverLoaderTest extends BaseTest { +35 +36 /** +37 * Test of load method, of class DriverLoader. +38 */ +39 @Test +40 public void testLoad_String() throws Exception { +41 String className = "org.h2.Driver"; +42 Driver d = null; +43 try { +44 d = DriverLoader.load(className); +45 } finally { +46 if (d != null) { +47 DriverManager.deregisterDriver(d); +48 } +49 } +50 } +51 +52 /** +53 * Test of load method, of class DriverLoader; expecting an exception due to +54 * a bad driver class name. +55 */ +56 @Test(expected = DriverLoadException.class) +57 public void testLoad_String_ex() throws Exception { +58 String className = "bad.Driver"; +59 Driver d = DriverLoader.load(className); +60 } +61 +62 /** +63 * Test of load method, of class DriverLoader. +64 */ +65 @Test +66 public void testLoad_String_String() throws Exception { +67 String className = "com.mysql.jdbc.Driver"; +68 //we know this is in target/test-classes +69 //File testClassPath = (new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath())).getParentFile(); +70 File testClassPath = BaseTest.getResourceAsFile(this, "org.mortbay.jetty.jar").getParentFile(); +71 File driver = new File(testClassPath, "../../src/test/resources/mysql-connector-java-5.1.27-bin.jar"); +72 assertTrue("MySQL Driver JAR file not found in src/test/resources?", driver.isFile()); +73 +74 Driver d = null; +75 try { +76 d = DriverLoader.load(className, driver.getAbsolutePath()); +77 d = DriverManager.getDriver("jdbc:mysql://localhost:3306/dependencycheck"); +78 assertNotNull(d); +79 } finally { +80 if (d != null) { +81 DriverManager.deregisterDriver(d); +82 } +83 } +84 } +85 +86 /** +87 * Test of load method, of class DriverLoader. +88 */ +89 @Test +90 public void testLoad_String_String_multiple_paths() throws Exception { +91 final String className = "com.mysql.jdbc.Driver"; +92 //we know this is in target/test-classes +93 //final File testClassPath = (new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath())).getParentFile(); +94 final File testClassPath = BaseTest.getResourceAsFile(this, "org.mortbay.jetty.jar").getParentFile(); +95 final File dir1 = new File(testClassPath, "../../src/test/"); +96 final File dir2 = new File(testClassPath, "../../src/test/resources/"); +97 final String paths = String.format("%s" + File.pathSeparator + "%s", dir1.getAbsolutePath(), dir2.getAbsolutePath()); +98 +99 Driver d = null; +100 try { +101 d = DriverLoader.load(className, paths); +102 } finally { +103 if (d != null) { +104 DriverManager.deregisterDriver(d); +105 } +106 } +107 } +108 +109 /** +110 * Test of load method, of class DriverLoader with an incorrect class name. +111 */ +112 @Test(expected = DriverLoadException.class) +113 public void testLoad_String_String_badClassName() throws Exception { +114 String className = "com.mybad.jdbc.Driver"; +115 //we know this is in target/test-classes +116 //File testClassPath = (new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath())).getParentFile(); +117 File testClassPath = BaseTest.getResourceAsFile(this, "org.mortbay.jetty.jar").getParentFile(); +118 File driver = new File(testClassPath, "../../src/test/resources/mysql-connector-java-5.1.27-bin.jar"); +119 assertTrue("MySQL Driver JAR file not found in src/test/resources?", driver.isFile()); +120 +121 Driver d = DriverLoader.load(className, driver.getAbsolutePath()); +122 } +123 +124 /** +125 * Test of load method, of class DriverLoader with an incorrect class path. +126 */ +127 @Test(expected = DriverLoadException.class) +128 public void testLoad_String_String_badPath() throws Exception { +129 String className = "com.mysql.jdbc.Driver"; +130 //we know this is in target/test-classes +131 //File testClassPath = (new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath())).getParentFile(); +132 File testClassPath = BaseTest.getResourceAsFile(this, "org.mortbay.jetty.jar").getParentFile(); +133 File driver = new File(testClassPath, "../../src/test/bad/mysql-connector-java-5.1.27-bin.jar"); +134 Driver d = DriverLoader.load(className, driver.getAbsolutePath()); +135 } +136 }
      diff --git a/xref-test/org/owasp/dependencycheck/data/nvdcve/package-frame.html b/xref-test/org/owasp/dependencycheck/data/nvdcve/package-frame.html index b55b61c9f..20cd68e90 100644 --- a/xref-test/org/owasp/dependencycheck/data/nvdcve/package-frame.html +++ b/xref-test/org/owasp/dependencycheck/data/nvdcve/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.nvdcve + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.nvdcve diff --git a/xref-test/org/owasp/dependencycheck/data/nvdcve/package-summary.html b/xref-test/org/owasp/dependencycheck/data/nvdcve/package-summary.html index f54a7bc28..2a4cd1719 100644 --- a/xref-test/org/owasp/dependencycheck/data/nvdcve/package-summary.html +++ b/xref-test/org/owasp/dependencycheck/data/nvdcve/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.nvdcve + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.nvdcve diff --git a/xref-test/org/owasp/dependencycheck/data/update/nvd/DownloadTaskTest.html b/xref-test/org/owasp/dependencycheck/data/update/nvd/DownloadTaskTest.html index 9cb360c41..5eca9f3b6 100644 --- a/xref-test/org/owasp/dependencycheck/data/update/nvd/DownloadTaskTest.html +++ b/xref-test/org/owasp/dependencycheck/data/update/nvd/DownloadTaskTest.html @@ -28,56 +28,54 @@ 20 import java.io.File; 21 import java.util.concurrent.ExecutorService; 22 import java.util.concurrent.Future; -23 import org.junit.After; -24 import org.junit.AfterClass; -25 import static org.junit.Assert.assertFalse; -26 import static org.junit.Assert.assertNull; -27 import static org.junit.Assert.assertTrue; -28 import org.junit.Before; -29 import org.junit.BeforeClass; -30 import org.junit.Test; -31 import org.owasp.dependencycheck.BaseTest; -32 import org.owasp.dependencycheck.data.nvdcve.CveDB; -33 import org.owasp.dependencycheck.utils.Settings; -34 -35 /** -36 * -37 * @author Jeremy Long -38 */ -39 public class DownloadTaskTest extends BaseTest { -40 -41 public DownloadTaskTest() { -42 } -43 -44 /** -45 * Test of call method, of class DownloadTask. -46 */ -47 @Test -48 public void testCall() throws Exception { -49 NvdCveInfo cve = new NvdCveInfo(); -50 cve.setId("modified"); -51 cve.setNeedsUpdate(true); -52 cve.setUrl(Settings.getString(Settings.KEYS.CVE_MODIFIED_20_URL)); -53 cve.setOldSchemaVersionUrl(Settings.getString(Settings.KEYS.CVE_MODIFIED_12_URL)); -54 ExecutorService processExecutor = null; -55 CveDB cveDB = null; -56 DownloadTask instance = new DownloadTask(cve, processExecutor, cveDB, Settings.getInstance()); -57 Future<ProcessTask> result = instance.call(); -58 assertNull(result); -59 } -60 -61 /** -62 * Test of isXml(file). -63 */ -64 @Test -65 public void testIsXML() { -66 File f = getResourceAsFile(this, "nvdcve-modified.xml"); -67 assertTrue(DownloadTask.isXml(f)); -68 f = getResourceAsFile(this, "file.tar.gz"); -69 assertFalse(DownloadTask.isXml(f)); -70 -71 } -72 } +23 +24 import static org.junit.Assert.assertFalse; +25 import static org.junit.Assert.assertNull; +26 import static org.junit.Assert.assertTrue; +27 +28 import org.junit.Test; +29 import org.owasp.dependencycheck.BaseTest; +30 import org.owasp.dependencycheck.data.nvdcve.CveDB; +31 import org.owasp.dependencycheck.utils.Settings; +32 +33 /** +34 * +35 * @author Jeremy Long +36 */ +37 public class DownloadTaskTest extends BaseTest { +38 +39 public DownloadTaskTest() { +40 } +41 +42 /** +43 * Test of call method, of class DownloadTask. +44 */ +45 @Test +46 public void testCall() throws Exception { +47 NvdCveInfo cve = new NvdCveInfo(); +48 cve.setId("modified"); +49 cve.setNeedsUpdate(true); +50 cve.setUrl(Settings.getString(Settings.KEYS.CVE_MODIFIED_20_URL)); +51 cve.setOldSchemaVersionUrl(Settings.getString(Settings.KEYS.CVE_MODIFIED_12_URL)); +52 ExecutorService processExecutor = null; +53 CveDB cveDB = null; +54 DownloadTask instance = new DownloadTask(cve, processExecutor, cveDB, Settings.getInstance()); +55 Future<ProcessTask> result = instance.call(); +56 assertNull(result); +57 } +58 +59 /** +60 * Test of isXml(file). +61 */ +62 @Test +63 public void testIsXML() { +64 File f = getResourceAsFile(this, "nvdcve-modified.xml"); +65 assertTrue(DownloadTask.isXml(f)); +66 f = getResourceAsFile(this, "file.tar.gz"); +67 assertFalse(DownloadTask.isXml(f)); +68 +69 } +70 }
      diff --git a/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCve_1_2_HandlerTest.html b/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCve_1_2_HandlerTest.html index 8881857a7..321476d17 100644 --- a/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCve_1_2_HandlerTest.html +++ b/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCve_1_2_HandlerTest.html @@ -31,35 +31,33 @@ 23 import java.util.Map; 24 import javax.xml.parsers.SAXParser; 25 import javax.xml.parsers.SAXParserFactory; -26 import org.junit.After; -27 import org.junit.AfterClass; -28 import static org.junit.Assert.assertTrue; -29 import org.junit.Before; -30 import org.junit.BeforeClass; -31 import org.junit.Test; -32 import org.owasp.dependencycheck.BaseTest; -33 import org.owasp.dependencycheck.dependency.VulnerableSoftware; -34 -35 /** -36 * -37 * @author Jeremy Long -38 */ -39 public class NvdCve_1_2_HandlerTest extends BaseTest { -40 -41 @Test -42 public void testParse() throws Exception { -43 SAXParserFactory factory = SAXParserFactory.newInstance(); -44 SAXParser saxParser = factory.newSAXParser(); -45 -46 //File file = new File(this.getClass().getClassLoader().getResource("nvdcve-2012.xml").getPath()); -47 File file = BaseTest.getResourceAsFile(this, "nvdcve-2012.xml"); -48 -49 NvdCve12Handler instance = new NvdCve12Handler(); -50 saxParser.parse(file, instance); -51 Map<String, List<VulnerableSoftware>> results = instance.getVulnerabilities(); -52 assertTrue("No vulnerable software identified with a previous version in 2012 CVE 1.2?", !results.isEmpty()); -53 } -54 } +26 +27 import static org.junit.Assert.assertTrue; +28 +29 import org.junit.Test; +30 import org.owasp.dependencycheck.BaseTest; +31 import org.owasp.dependencycheck.dependency.VulnerableSoftware; +32 +33 /** +34 * +35 * @author Jeremy Long +36 */ +37 public class NvdCve_1_2_HandlerTest extends BaseTest { +38 +39 @Test +40 public void testParse() throws Exception { +41 SAXParserFactory factory = SAXParserFactory.newInstance(); +42 SAXParser saxParser = factory.newSAXParser(); +43 +44 //File file = new File(this.getClass().getClassLoader().getResource("nvdcve-2012.xml").getPath()); +45 File file = BaseTest.getResourceAsFile(this, "nvdcve-2012.xml"); +46 +47 NvdCve12Handler instance = new NvdCve12Handler(); +48 saxParser.parse(file, instance); +49 Map<String, List<VulnerableSoftware>> results = instance.getVulnerabilities(); +50 assertTrue("No vulnerable software identified with a previous version in 2012 CVE 1.2?", !results.isEmpty()); +51 } +52 }
      diff --git a/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCve_2_0_HandlerTest.html b/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCve_2_0_HandlerTest.html index f892447bd..91b226a04 100644 --- a/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCve_2_0_HandlerTest.html +++ b/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCve_2_0_HandlerTest.html @@ -31,74 +31,72 @@ 23 import java.util.Map; 24 import javax.xml.parsers.SAXParser; 25 import javax.xml.parsers.SAXParserFactory; -26 import org.junit.After; -27 import org.junit.AfterClass; -28 import static org.junit.Assert.assertTrue; -29 import org.junit.Before; -30 import org.junit.BeforeClass; -31 import org.junit.Test; -32 import org.owasp.dependencycheck.BaseTest; -33 import org.owasp.dependencycheck.dependency.VulnerableSoftware; -34 -35 /** -36 * -37 * @author Jeremy Long -38 */ -39 public class NvdCve_2_0_HandlerTest extends BaseTest { -40 -41 @Test -42 public void testParse() { -43 Throwable results = null; -44 try { -45 SAXParserFactory factory = SAXParserFactory.newInstance(); -46 SAXParser saxParser = factory.newSAXParser(); -47 -48 //File file = new File(this.getClass().getClassLoader().getResource("nvdcve-2.0-2012.xml").getPath()); -49 File file = BaseTest.getResourceAsFile(this, "nvdcve-2.0-2012.xml"); +26 +27 import static org.junit.Assert.assertTrue; +28 +29 import org.junit.Test; +30 import org.owasp.dependencycheck.BaseTest; +31 import org.owasp.dependencycheck.dependency.VulnerableSoftware; +32 +33 /** +34 * +35 * @author Jeremy Long +36 */ +37 public class NvdCve_2_0_HandlerTest extends BaseTest { +38 +39 @Test +40 public void testParse() { +41 Throwable results = null; +42 try { +43 SAXParserFactory factory = SAXParserFactory.newInstance(); +44 SAXParser saxParser = factory.newSAXParser(); +45 +46 //File file = new File(this.getClass().getClassLoader().getResource("nvdcve-2.0-2012.xml").getPath()); +47 File file = BaseTest.getResourceAsFile(this, "nvdcve-2.0-2012.xml"); +48 +49 NvdCve20Handler instance = new NvdCve20Handler(); 50 -51 NvdCve20Handler instance = new NvdCve20Handler(); -52 -53 saxParser.parse(file, instance); -54 } catch (Throwable ex) { -55 ex.printStackTrace(); -56 results = ex; -57 } -58 assertTrue("Exception thrown during parse of 2012 CVE version 2.0?", results == null); -59 if (results != null) { -60 System.err.println(results); -61 } -62 } -63 -64 @Test -65 public void testParserWithPreviousVersion() { -66 Throwable results = null; -67 try { -68 SAXParserFactory factory = SAXParserFactory.newInstance(); -69 SAXParser saxParser = factory.newSAXParser(); -70 -71 File file12 = BaseTest.getResourceAsFile(this, "cve-1.2-2008_4411.xml"); -72 -73 final NvdCve12Handler cve12Handler = new NvdCve12Handler(); -74 saxParser.parse(file12, cve12Handler); -75 final Map<String, List<VulnerableSoftware>> prevVersionVulnMap = cve12Handler.getVulnerabilities(); -76 -77 //File file = new File(this.getClass().getClassLoader().getResource("nvdcve-2.0-2012.xml").getPath()); -78 File file20 = BaseTest.getResourceAsFile(this, "cve-2.0-2008_4411.xml"); -79 -80 NvdCve20Handler instance = new NvdCve20Handler(); -81 instance.setPrevVersionVulnMap(prevVersionVulnMap); -82 saxParser.parse(file20, instance); -83 -84 assertTrue(instance.getTotalNumberOfEntries()==1); -85 } catch (Throwable ex) { -86 results = ex; -87 } -88 assertTrue("Exception thrown during parse of 2012 CVE version 2.0?", results == null); -89 if (results != null) { -90 System.err.println(results); -91 } -92 } -93 } +51 saxParser.parse(file, instance); +52 } catch (Throwable ex) { +53 ex.printStackTrace(); +54 results = ex; +55 } +56 assertTrue("Exception thrown during parse of 2012 CVE version 2.0?", results == null); +57 if (results != null) { +58 System.err.println(results); +59 } +60 } +61 +62 @Test +63 public void testParserWithPreviousVersion() { +64 Throwable results = null; +65 try { +66 SAXParserFactory factory = SAXParserFactory.newInstance(); +67 SAXParser saxParser = factory.newSAXParser(); +68 +69 File file12 = BaseTest.getResourceAsFile(this, "cve-1.2-2008_4411.xml"); +70 +71 final NvdCve12Handler cve12Handler = new NvdCve12Handler(); +72 saxParser.parse(file12, cve12Handler); +73 final Map<String, List<VulnerableSoftware>> prevVersionVulnMap = cve12Handler.getVulnerabilities(); +74 +75 //File file = new File(this.getClass().getClassLoader().getResource("nvdcve-2.0-2012.xml").getPath()); +76 File file20 = BaseTest.getResourceAsFile(this, "cve-2.0-2008_4411.xml"); +77 +78 NvdCve20Handler instance = new NvdCve20Handler(); +79 instance.setPrevVersionVulnMap(prevVersionVulnMap); +80 saxParser.parse(file20, instance); +81 +82 assertTrue(instance.getTotalNumberOfEntries()==1); +83 } catch (Throwable ex) { +84 results = ex; +85 } +86 assertTrue("Exception thrown during parse of 2012 CVE version 2.0?", results == null); +87 if (results != null) { +88 System.err.println(results); +89 } +90 } +91 }
      diff --git a/xref-test/org/owasp/dependencycheck/data/update/nvd/package-frame.html b/xref-test/org/owasp/dependencycheck/data/update/nvd/package-frame.html index 789426227..951954371 100644 --- a/xref-test/org/owasp/dependencycheck/data/update/nvd/package-frame.html +++ b/xref-test/org/owasp/dependencycheck/data/update/nvd/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.update.nvd + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.update.nvd diff --git a/xref-test/org/owasp/dependencycheck/data/update/nvd/package-summary.html b/xref-test/org/owasp/dependencycheck/data/update/nvd/package-summary.html index 7d67721bb..06d04306a 100644 --- a/xref-test/org/owasp/dependencycheck/data/update/nvd/package-summary.html +++ b/xref-test/org/owasp/dependencycheck/data/update/nvd/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.update.nvd + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.update.nvd diff --git a/xref-test/org/owasp/dependencycheck/data/update/package-frame.html b/xref-test/org/owasp/dependencycheck/data/update/package-frame.html index 475a43b19..80fa232d4 100644 --- a/xref-test/org/owasp/dependencycheck/data/update/package-frame.html +++ b/xref-test/org/owasp/dependencycheck/data/update/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.update + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.update diff --git a/xref-test/org/owasp/dependencycheck/data/update/package-summary.html b/xref-test/org/owasp/dependencycheck/data/update/package-summary.html index c9cc469b5..f93a1af20 100644 --- a/xref-test/org/owasp/dependencycheck/data/update/package-summary.html +++ b/xref-test/org/owasp/dependencycheck/data/update/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.update + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.update diff --git a/xref-test/org/owasp/dependencycheck/dependency/DependencyTest.html b/xref-test/org/owasp/dependencycheck/dependency/DependencyTest.html index 5016a0f4e..90fefee8d 100644 --- a/xref-test/org/owasp/dependencycheck/dependency/DependencyTest.html +++ b/xref-test/org/owasp/dependencycheck/dependency/DependencyTest.html @@ -26,280 +26,277 @@ 18 package org.owasp.dependencycheck.dependency; 19 20 import java.io.File; -21 import java.util.List; -22 import java.util.Set; -23 import org.junit.After; -24 import org.junit.AfterClass; -25 import static org.junit.Assert.assertEquals; -26 import static org.junit.Assert.assertFalse; -27 import static org.junit.Assert.assertTrue; -28 import org.junit.Before; -29 import org.junit.BeforeClass; -30 import org.junit.Test; -31 import org.owasp.dependencycheck.BaseTest; -32 import org.owasp.dependencycheck.data.nexus.MavenArtifact; -33 -34 /** -35 * -36 * @author Jeremy Long -37 */ -38 public class DependencyTest extends BaseTest { -39 -40 /** -41 * Test of getFileName method, of class Dependency. -42 */ -43 @Test -44 public void testGetFileName() { -45 Dependency instance = new Dependency(); -46 String expResult = "filename"; -47 instance.setFileName(expResult); -48 String result = instance.getFileName(); -49 assertEquals(expResult, result); -50 } -51 -52 /** -53 * Test of setFileName method, of class Dependency. -54 */ -55 @Test -56 public void testSetFileName() { -57 String fileName = "file.tar"; -58 Dependency instance = new Dependency(); -59 instance.setFileName(fileName); -60 assertEquals(fileName, instance.getFileName()); -61 } -62 -63 /** -64 * Test of setActualFilePath method, of class Dependency. -65 */ -66 @Test -67 public void testSetActualFilePath() { -68 String actualFilePath = "file.tar"; -69 Dependency instance = new Dependency(); -70 instance.setSha1sum("non-null value"); -71 instance.setActualFilePath(actualFilePath); -72 assertEquals(actualFilePath, instance.getActualFilePath()); -73 } -74 -75 /** -76 * Test of getActualFilePath method, of class Dependency. -77 */ -78 @Test -79 public void testGetActualFilePath() { -80 Dependency instance = new Dependency(); -81 String expResult = "file.tar"; -82 instance.setSha1sum("non-null value"); -83 instance.setActualFilePath(expResult); -84 String result = instance.getActualFilePath(); -85 assertEquals(expResult, result); -86 } -87 -88 /** -89 * Test of setFilePath method, of class Dependency. -90 */ -91 @Test -92 public void testSetFilePath() { -93 String filePath = "file.tar"; -94 Dependency instance = new Dependency(); -95 instance.setFilePath(filePath); -96 assertEquals(filePath, instance.getFilePath()); -97 } -98 -99 /** -100 * Test of getFilePath method, of class Dependency. -101 */ -102 @Test -103 public void testGetFilePath() { -104 Dependency instance = new Dependency(); -105 String expResult = "file.tar"; -106 instance.setFilePath(expResult); -107 String result = instance.getFilePath(); -108 assertEquals(expResult, result); -109 } -110 -111 /** -112 * Test of getMd5sum method, of class Dependency. -113 */ -114 @Test -115 public void testGetMd5sum() { -116 //File file = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath()); -117 File file = BaseTest.getResourceAsFile(this, "struts2-core-2.1.2.jar"); -118 -119 Dependency instance = new Dependency(file); -120 //assertEquals("89CE9E36AA9A9E03F1450936D2F4F8DD0F961F8B", result.getSha1sum()); -121 //String expResult = "C30B57142E1CCBC1EFD5CD15F307358F"; -122 String expResult = "c30b57142e1ccbc1efd5cd15f307358f"; -123 String result = instance.getMd5sum(); -124 assertEquals(expResult, result); -125 } -126 -127 /** -128 * Test of setMd5sum method, of class Dependency. -129 */ -130 @Test -131 public void testSetMd5sum() { -132 String md5sum = "test"; -133 Dependency instance = new Dependency(); -134 instance.setMd5sum(md5sum); -135 assertEquals(md5sum, instance.getMd5sum()); -136 } -137 -138 /** -139 * Test of getSha1sum method, of class Dependency. -140 */ -141 @Test -142 public void testGetSha1sum() { -143 //File file = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath()); -144 File file = BaseTest.getResourceAsFile(this, "struts2-core-2.1.2.jar"); -145 Dependency instance = new Dependency(file); -146 //String expResult = "89CE9E36AA9A9E03F1450936D2F4F8DD0F961F8B"; -147 String expResult = "89ce9e36aa9a9e03f1450936d2f4f8dd0f961f8b"; -148 String result = instance.getSha1sum(); -149 assertEquals(expResult, result); -150 } -151 -152 /** -153 * Test of setSha1sum method, of class Dependency. -154 */ -155 @Test -156 public void testSetSha1sum() { -157 String sha1sum = "test"; -158 Dependency instance = new Dependency(); -159 instance.setSha1sum(sha1sum); -160 assertEquals(sha1sum, instance.getSha1sum()); -161 } -162 -163 /** -164 * Test of getIdentifiers method, of class Dependency. -165 */ -166 @Test -167 public void testGetIdentifiers() { -168 Dependency instance = new Dependency(); -169 Set<Identifier> result = instance.getIdentifiers(); +21 import java.util.Set; +22 +23 import static org.junit.Assert.assertEquals; +24 import static org.junit.Assert.assertFalse; +25 import static org.junit.Assert.assertTrue; +26 +27 import org.junit.Test; +28 import org.owasp.dependencycheck.BaseTest; +29 import org.owasp.dependencycheck.data.nexus.MavenArtifact; +30 +31 /** +32 * +33 * @author Jeremy Long +34 */ +35 public class DependencyTest extends BaseTest { +36 +37 /** +38 * Test of getFileName method, of class Dependency. +39 */ +40 @Test +41 public void testGetFileName() { +42 Dependency instance = new Dependency(); +43 String expResult = "filename"; +44 instance.setFileName(expResult); +45 String result = instance.getFileName(); +46 assertEquals(expResult, result); +47 } +48 +49 /** +50 * Test of setFileName method, of class Dependency. +51 */ +52 @Test +53 public void testSetFileName() { +54 String fileName = "file.tar"; +55 Dependency instance = new Dependency(); +56 instance.setFileName(fileName); +57 assertEquals(fileName, instance.getFileName()); +58 } +59 +60 /** +61 * Test of setActualFilePath method, of class Dependency. +62 */ +63 @Test +64 public void testSetActualFilePath() { +65 String actualFilePath = "file.tar"; +66 Dependency instance = new Dependency(); +67 instance.setSha1sum("non-null value"); +68 instance.setActualFilePath(actualFilePath); +69 assertEquals(actualFilePath, instance.getActualFilePath()); +70 } +71 +72 /** +73 * Test of getActualFilePath method, of class Dependency. +74 */ +75 @Test +76 public void testGetActualFilePath() { +77 Dependency instance = new Dependency(); +78 String expResult = "file.tar"; +79 instance.setSha1sum("non-null value"); +80 instance.setActualFilePath(expResult); +81 String result = instance.getActualFilePath(); +82 assertEquals(expResult, result); +83 } +84 +85 /** +86 * Test of setFilePath method, of class Dependency. +87 */ +88 @Test +89 public void testSetFilePath() { +90 String filePath = "file.tar"; +91 Dependency instance = new Dependency(); +92 instance.setFilePath(filePath); +93 assertEquals(filePath, instance.getFilePath()); +94 } +95 +96 /** +97 * Test of getFilePath method, of class Dependency. +98 */ +99 @Test +100 public void testGetFilePath() { +101 Dependency instance = new Dependency(); +102 String expResult = "file.tar"; +103 instance.setFilePath(expResult); +104 String result = instance.getFilePath(); +105 assertEquals(expResult, result); +106 } +107 +108 /** +109 * Test of getMd5sum method, of class Dependency. +110 */ +111 @Test +112 public void testGetMd5sum() { +113 //File file = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath()); +114 File file = BaseTest.getResourceAsFile(this, "struts2-core-2.1.2.jar"); +115 +116 Dependency instance = new Dependency(file); +117 //assertEquals("89CE9E36AA9A9E03F1450936D2F4F8DD0F961F8B", result.getSha1sum()); +118 //String expResult = "C30B57142E1CCBC1EFD5CD15F307358F"; +119 String expResult = "c30b57142e1ccbc1efd5cd15f307358f"; +120 String result = instance.getMd5sum(); +121 assertEquals(expResult, result); +122 } +123 +124 /** +125 * Test of setMd5sum method, of class Dependency. +126 */ +127 @Test +128 public void testSetMd5sum() { +129 String md5sum = "test"; +130 Dependency instance = new Dependency(); +131 instance.setMd5sum(md5sum); +132 assertEquals(md5sum, instance.getMd5sum()); +133 } +134 +135 /** +136 * Test of getSha1sum method, of class Dependency. +137 */ +138 @Test +139 public void testGetSha1sum() { +140 //File file = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath()); +141 File file = BaseTest.getResourceAsFile(this, "struts2-core-2.1.2.jar"); +142 Dependency instance = new Dependency(file); +143 //String expResult = "89CE9E36AA9A9E03F1450936D2F4F8DD0F961F8B"; +144 String expResult = "89ce9e36aa9a9e03f1450936d2f4f8dd0f961f8b"; +145 String result = instance.getSha1sum(); +146 assertEquals(expResult, result); +147 } +148 +149 /** +150 * Test of setSha1sum method, of class Dependency. +151 */ +152 @Test +153 public void testSetSha1sum() { +154 String sha1sum = "test"; +155 Dependency instance = new Dependency(); +156 instance.setSha1sum(sha1sum); +157 assertEquals(sha1sum, instance.getSha1sum()); +158 } +159 +160 /** +161 * Test of getIdentifiers method, of class Dependency. +162 */ +163 @Test +164 public void testGetIdentifiers() { +165 Dependency instance = new Dependency(); +166 Set<Identifier> result = instance.getIdentifiers(); +167 +168 assertTrue(true); //this is just a getter setter pair. +169 } 170 -171 assertTrue(true); //this is just a getter setter pair. -172 } -173 -174 /** -175 * Test of setIdentifiers method, of class Dependency. -176 */ -177 @Test -178 public void testSetIdentifiers() { -179 Set<Identifier> identifiers = null; -180 Dependency instance = new Dependency(); -181 instance.setIdentifiers(identifiers); -182 assertTrue(true); //this is just a getter setter pair. -183 } -184 -185 /** -186 * Test of addIdentifier method, of class Dependency. -187 */ -188 @Test -189 public void testAddIdentifier() { -190 String type = "cpe"; -191 String value = "cpe:/a:apache:struts:2.1.2"; -192 String url = "http://somewhere"; -193 Identifier expResult = new Identifier(type, value, url); -194 -195 Dependency instance = new Dependency(); -196 instance.addIdentifier(type, value, url); -197 assertEquals(1, instance.getIdentifiers().size()); -198 assertTrue("Identifier doesn't contain expected result.", instance.getIdentifiers().contains(expResult)); -199 } -200 -201 /** -202 * Test of getEvidence method, of class Dependency. -203 */ -204 @Test -205 public void testGetEvidence() { -206 Dependency instance = new Dependency(); -207 EvidenceCollection expResult = null; -208 EvidenceCollection result = instance.getEvidence(); -209 assertTrue(true); //this is just a getter setter pair. -210 } -211 -212 /** -213 * Test of getEvidenceUsed method, of class Dependency. -214 */ -215 @Test -216 public void testGetEvidenceUsed() { -217 Dependency instance = new Dependency(); -218 String expResult = "used"; -219 -220 instance.getProductEvidence().addEvidence("used", "used", "used", Confidence.HIGH); -221 instance.getProductEvidence().addEvidence("not", "not", "not", Confidence.MEDIUM); -222 for (Evidence e : instance.getProductEvidence().iterator(Confidence.HIGH)) { -223 String use = e.getValue(); -224 } -225 -226 EvidenceCollection result = instance.getEvidenceUsed(); -227 -228 assertEquals(1, result.size()); -229 assertTrue(result.containsUsedString(expResult)); -230 } -231 -232 /** -233 * Test of getVendorEvidence method, of class Dependency. -234 */ -235 @Test -236 public void testGetVendorEvidence() { -237 Dependency instance = new Dependency(); -238 EvidenceCollection expResult = null; -239 EvidenceCollection result = instance.getVendorEvidence(); -240 assertTrue(true); //this is just a getter setter pair. -241 } -242 -243 /** -244 * Test of getProductEvidence method, of class Dependency. -245 */ -246 @Test -247 public void testGetProductEvidence() { -248 Dependency instance = new Dependency(); -249 EvidenceCollection expResult = null; -250 EvidenceCollection result = instance.getProductEvidence(); -251 assertTrue(true); //this is just a getter setter pair. -252 } -253 -254 /** -255 * Test of getVersionEvidence method, of class Dependency. -256 */ -257 @Test -258 public void testGetVersionEvidence() { -259 Dependency instance = new Dependency(); -260 EvidenceCollection expResult = null; -261 EvidenceCollection result = instance.getVersionEvidence(); -262 assertTrue(true); //this is just a getter setter pair. -263 } -264 -265 /** -266 * Test of addAsEvidence method, of class Dependency. -267 */ -268 @Test -269 public void testAddAsEvidence() { -270 Dependency instance = new Dependency(); -271 MavenArtifact mavenArtifact = new MavenArtifact("group", "artifact", "version", "url"); -272 instance.addAsEvidence("pom", mavenArtifact, Confidence.HIGH); -273 assertTrue(instance.getEvidence().contains(Confidence.HIGH)); -274 assertFalse(instance.getEvidence().getEvidence("pom", "groupid").isEmpty()); -275 assertFalse(instance.getEvidence().getEvidence("pom", "artifactid").isEmpty()); -276 assertFalse(instance.getEvidence().getEvidence("pom", "version").isEmpty()); -277 assertFalse(instance.getIdentifiers().isEmpty()); -278 } -279 -280 /** -281 * Test of addAsEvidence method, of class Dependency. -282 */ -283 @Test -284 public void testAddAsEvidenceWithEmptyArtefact() { -285 Dependency instance = new Dependency(); -286 MavenArtifact mavenArtifact = new MavenArtifact(null, null, null, null); -287 instance.addAsEvidence("pom", mavenArtifact, Confidence.HIGH); -288 assertFalse(instance.getEvidence().contains(Confidence.HIGH)); -289 assertTrue(instance.getEvidence().getEvidence("pom", "groupid").isEmpty()); -290 assertTrue(instance.getEvidence().getEvidence("pom", "artifactid").isEmpty()); -291 assertTrue(instance.getEvidence().getEvidence("pom", "version").isEmpty()); -292 assertTrue(instance.getIdentifiers().isEmpty()); -293 } -294 } +171 /** +172 * Test of setIdentifiers method, of class Dependency. +173 */ +174 @Test +175 public void testSetIdentifiers() { +176 Set<Identifier> identifiers = null; +177 Dependency instance = new Dependency(); +178 instance.setIdentifiers(identifiers); +179 assertTrue(true); //this is just a getter setter pair. +180 } +181 +182 /** +183 * Test of addIdentifier method, of class Dependency. +184 */ +185 @Test +186 public void testAddIdentifier() { +187 String type = "cpe"; +188 String value = "cpe:/a:apache:struts:2.1.2"; +189 String url = "http://somewhere"; +190 Identifier expResult = new Identifier(type, value, url); +191 +192 Dependency instance = new Dependency(); +193 instance.addIdentifier(type, value, url); +194 assertEquals(1, instance.getIdentifiers().size()); +195 assertTrue("Identifier doesn't contain expected result.", instance.getIdentifiers().contains(expResult)); +196 } +197 +198 /** +199 * Test of getEvidence method, of class Dependency. +200 */ +201 @Test +202 public void testGetEvidence() { +203 Dependency instance = new Dependency(); +204 EvidenceCollection expResult = null; +205 EvidenceCollection result = instance.getEvidence(); +206 assertTrue(true); //this is just a getter setter pair. +207 } +208 +209 /** +210 * Test of getEvidenceUsed method, of class Dependency. +211 */ +212 @Test +213 public void testGetEvidenceUsed() { +214 Dependency instance = new Dependency(); +215 String expResult = "used"; +216 +217 instance.getProductEvidence().addEvidence("used", "used", "used", Confidence.HIGH); +218 instance.getProductEvidence().addEvidence("not", "not", "not", Confidence.MEDIUM); +219 for (Evidence e : instance.getProductEvidence().iterator(Confidence.HIGH)) { +220 String use = e.getValue(); +221 } +222 +223 EvidenceCollection result = instance.getEvidenceUsed(); +224 +225 assertEquals(1, result.size()); +226 assertTrue(result.containsUsedString(expResult)); +227 } +228 +229 /** +230 * Test of getVendorEvidence method, of class Dependency. +231 */ +232 @Test +233 public void testGetVendorEvidence() { +234 Dependency instance = new Dependency(); +235 EvidenceCollection expResult = null; +236 EvidenceCollection result = instance.getVendorEvidence(); +237 assertTrue(true); //this is just a getter setter pair. +238 } +239 +240 /** +241 * Test of getProductEvidence method, of class Dependency. +242 */ +243 @Test +244 public void testGetProductEvidence() { +245 Dependency instance = new Dependency(); +246 EvidenceCollection expResult = null; +247 EvidenceCollection result = instance.getProductEvidence(); +248 assertTrue(true); //this is just a getter setter pair. +249 } +250 +251 /** +252 * Test of getVersionEvidence method, of class Dependency. +253 */ +254 @Test +255 public void testGetVersionEvidence() { +256 Dependency instance = new Dependency(); +257 EvidenceCollection expResult = null; +258 EvidenceCollection result = instance.getVersionEvidence(); +259 assertTrue(true); //this is just a getter setter pair. +260 } +261 +262 /** +263 * Test of addAsEvidence method, of class Dependency. +264 */ +265 @Test +266 public void testAddAsEvidence() { +267 Dependency instance = new Dependency(); +268 MavenArtifact mavenArtifact = new MavenArtifact("group", "artifact", "version", "url"); +269 instance.addAsEvidence("pom", mavenArtifact, Confidence.HIGH); +270 assertTrue(instance.getEvidence().contains(Confidence.HIGH)); +271 assertFalse(instance.getEvidence().getEvidence("pom", "groupid").isEmpty()); +272 assertFalse(instance.getEvidence().getEvidence("pom", "artifactid").isEmpty()); +273 assertFalse(instance.getEvidence().getEvidence("pom", "version").isEmpty()); +274 assertFalse(instance.getIdentifiers().isEmpty()); +275 } +276 +277 /** +278 * Test of addAsEvidence method, of class Dependency. +279 */ +280 @Test +281 public void testAddAsEvidenceWithEmptyArtefact() { +282 Dependency instance = new Dependency(); +283 MavenArtifact mavenArtifact = new MavenArtifact(null, null, null, null); +284 instance.addAsEvidence("pom", mavenArtifact, Confidence.HIGH); +285 assertFalse(instance.getEvidence().contains(Confidence.HIGH)); +286 assertTrue(instance.getEvidence().getEvidence("pom", "groupid").isEmpty()); +287 assertTrue(instance.getEvidence().getEvidence("pom", "artifactid").isEmpty()); +288 assertTrue(instance.getEvidence().getEvidence("pom", "version").isEmpty()); +289 assertTrue(instance.getIdentifiers().isEmpty()); +290 } +291 }
      diff --git a/xref-test/org/owasp/dependencycheck/dependency/VulnerabilityTest.html b/xref-test/org/owasp/dependencycheck/dependency/VulnerabilityTest.html index ceb4706a0..7bfb0206e 100644 --- a/xref-test/org/owasp/dependencycheck/dependency/VulnerabilityTest.html +++ b/xref-test/org/owasp/dependencycheck/dependency/VulnerabilityTest.html @@ -26,147 +26,144 @@ 18 package org.owasp.dependencycheck.dependency; 19 20 import java.util.Set; -21 import org.junit.After; -22 import org.junit.AfterClass; -23 import static org.junit.Assert.assertEquals; -24 import static org.junit.Assert.assertTrue; -25 import static org.junit.Assert.assertFalse; -26 import org.junit.Before; -27 import org.junit.BeforeClass; -28 import org.junit.Test; -29 import org.owasp.dependencycheck.BaseTest; -30 -31 /** -32 * -33 * @author Jens Hausherr -34 */ -35 public class VulnerabilityTest extends BaseTest { -36 -37 /** -38 * Test of equals method, of class VulnerableSoftware. -39 */ -40 @Test -41 public void testDuplicateVersions() { -42 Vulnerability obj = new Vulnerability(); -43 -44 obj.addVulnerableSoftware("cpe:/a:mortbay:jetty:6.1.0"); -45 obj.addVulnerableSoftware("cpe:/a:mortbay:jetty:6.1.1"); -46 obj.addVulnerableSoftware("cpe:/a:mortbay:jetty:6.1.0"); +21 +22 import static org.junit.Assert.assertEquals; +23 import static org.junit.Assert.assertTrue; +24 +25 import org.junit.Test; +26 import org.owasp.dependencycheck.BaseTest; +27 +28 /** +29 * +30 * @author Jens Hausherr +31 */ +32 public class VulnerabilityTest extends BaseTest { +33 +34 /** +35 * Test of equals method, of class VulnerableSoftware. +36 */ +37 @Test +38 public void testDuplicateVersions() { +39 Vulnerability obj = new Vulnerability(); +40 +41 obj.addVulnerableSoftware("cpe:/a:mortbay:jetty:6.1.0"); +42 obj.addVulnerableSoftware("cpe:/a:mortbay:jetty:6.1.1"); +43 obj.addVulnerableSoftware("cpe:/a:mortbay:jetty:6.1.0"); +44 +45 assertEquals(2, obj.getVulnerableSoftware().size()); +46 } 47 -48 assertEquals(2, obj.getVulnerableSoftware().size()); -49 } -50 -51 @Test -52 public void testDpulicateVersionsWithPreviousVersion() { -53 Vulnerability obj = new Vulnerability(); -54 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-103%28a%29", null); -55 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-118", null); -56 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.3.132", null); -57 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.12-200", null); -58 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.2-127", null); -59 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.9", null); -60 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.10", null); -61 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.11", null); -62 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.12-118", null); -63 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.4-143", null); -64 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-109", null); -65 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.6-156", null); -66 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.4", null); -67 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.3", null); -68 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1", null); -69 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.10-186", null); -70 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.6", null); -71 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.5", null); -72 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.5-146", null); -73 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.8", null); -74 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.7", null); -75 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.2", null); -76 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.0.2", null); -77 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.1", null); -78 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.8-177", null); -79 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.0.1", null); -80 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.0.0", null); -81 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.7-168", null); -82 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-103", null); -83 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.11-197", null); -84 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.9-178", null); -85 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.12-200", "1"); -86 assertEquals(31, obj.getVulnerableSoftware().size()); -87 } -88 -89 @Test -90 public void testSoftwareSorting() { -91 Vulnerability obj = new Vulnerability(); -92 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-103%28a%29", null); -93 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-118", null); -94 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.3.132", null); -95 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.12-200", null); -96 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.2-127", null); -97 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.9", null); -98 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.10", null); -99 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.11", null); -100 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.12-118", null); -101 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.4-143", null); -102 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-109", null); -103 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.6-156", null); -104 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.4", null); -105 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.3", null); -106 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1", null); -107 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.10-186", null); -108 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.6", null); -109 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.5", null); -110 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.5-146", null); -111 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.8", null); -112 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.7", null); -113 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.2", null); -114 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.0.2", null); -115 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.1", null); -116 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.8-177", null); -117 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.0.1", null); -118 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.0.0", null); -119 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.7-168", null); -120 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-103", null); -121 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.11-197", null); -122 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.9-178", null); +48 @Test +49 public void testDpulicateVersionsWithPreviousVersion() { +50 Vulnerability obj = new Vulnerability(); +51 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-103%28a%29", null); +52 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-118", null); +53 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.3.132", null); +54 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.12-200", null); +55 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.2-127", null); +56 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.9", null); +57 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.10", null); +58 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.11", null); +59 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.12-118", null); +60 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.4-143", null); +61 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-109", null); +62 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.6-156", null); +63 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.4", null); +64 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.3", null); +65 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1", null); +66 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.10-186", null); +67 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.6", null); +68 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.5", null); +69 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.5-146", null); +70 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.8", null); +71 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.7", null); +72 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.2", null); +73 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.0.2", null); +74 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.1", null); +75 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.8-177", null); +76 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.0.1", null); +77 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.0.0", null); +78 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.7-168", null); +79 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-103", null); +80 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.11-197", null); +81 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.9-178", null); +82 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.12-200", "1"); +83 assertEquals(31, obj.getVulnerableSoftware().size()); +84 } +85 +86 @Test +87 public void testSoftwareSorting() { +88 Vulnerability obj = new Vulnerability(); +89 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-103%28a%29", null); +90 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-118", null); +91 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.3.132", null); +92 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.12-200", null); +93 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.2-127", null); +94 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.9", null); +95 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.10", null); +96 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.11", null); +97 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.12-118", null); +98 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.4-143", null); +99 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-109", null); +100 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.6-156", null); +101 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.4", null); +102 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.3", null); +103 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1", null); +104 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.10-186", null); +105 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.6", null); +106 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.5", null); +107 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.5-146", null); +108 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.8", null); +109 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.7", null); +110 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.2", null); +111 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.0.2", null); +112 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.1", null); +113 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.8-177", null); +114 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.0.1", null); +115 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.0.0", null); +116 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.7-168", null); +117 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.0-103", null); +118 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.11-197", null); +119 obj.addVulnerableSoftware("cpe:/a:hp:system_management_homepage:2.1.9-178", null); +120 +121 Set<VulnerableSoftware> software = obj.getVulnerableSoftware(); +122 VulnerableSoftware vs[] = software.toArray(new VulnerableSoftware[software.size()]); 123 -124 Set<VulnerableSoftware> software = obj.getVulnerableSoftware(); -125 VulnerableSoftware vs[] = software.toArray(new VulnerableSoftware[software.size()]); -126 -127 assertTrue("cpe:/a:hp:system_management_homepage:2.0.0".equals(vs[0].getName())); -128 assertTrue("cpe:/a:hp:system_management_homepage:2.0.1".equals(vs[1].getName())); -129 assertTrue("cpe:/a:hp:system_management_homepage:2.0.2".equals(vs[2].getName())); -130 assertTrue("cpe:/a:hp:system_management_homepage:2.1".equals(vs[3].getName())); -131 assertTrue("cpe:/a:hp:system_management_homepage:2.1.0-103".equals(vs[4].getName())); -132 assertTrue("cpe:/a:hp:system_management_homepage:2.1.0-103%28a%29".equals(vs[5].getName())); -133 assertTrue("cpe:/a:hp:system_management_homepage:2.1.0-109".equals(vs[6].getName())); -134 assertTrue("cpe:/a:hp:system_management_homepage:2.1.0-118".equals(vs[7].getName())); -135 assertTrue("cpe:/a:hp:system_management_homepage:2.1.1".equals(vs[8].getName())); -136 assertTrue("cpe:/a:hp:system_management_homepage:2.1.2".equals(vs[9].getName())); -137 assertTrue("cpe:/a:hp:system_management_homepage:2.1.2-127".equals(vs[10].getName())); -138 assertTrue("cpe:/a:hp:system_management_homepage:2.1.3".equals(vs[11].getName())); -139 assertTrue("cpe:/a:hp:system_management_homepage:2.1.3.132".equals(vs[12].getName())); -140 assertTrue("cpe:/a:hp:system_management_homepage:2.1.4".equals(vs[13].getName())); -141 assertTrue("cpe:/a:hp:system_management_homepage:2.1.4-143".equals(vs[14].getName())); -142 assertTrue("cpe:/a:hp:system_management_homepage:2.1.5".equals(vs[15].getName())); -143 assertTrue("cpe:/a:hp:system_management_homepage:2.1.5-146".equals(vs[16].getName())); -144 assertTrue("cpe:/a:hp:system_management_homepage:2.1.6".equals(vs[17].getName())); -145 assertTrue("cpe:/a:hp:system_management_homepage:2.1.6-156".equals(vs[18].getName())); -146 assertTrue("cpe:/a:hp:system_management_homepage:2.1.7".equals(vs[19].getName())); -147 assertTrue("cpe:/a:hp:system_management_homepage:2.1.7-168".equals(vs[20].getName())); -148 assertTrue("cpe:/a:hp:system_management_homepage:2.1.8".equals(vs[21].getName())); -149 assertTrue("cpe:/a:hp:system_management_homepage:2.1.8-177".equals(vs[22].getName())); -150 assertTrue("cpe:/a:hp:system_management_homepage:2.1.9".equals(vs[23].getName())); -151 assertTrue("cpe:/a:hp:system_management_homepage:2.1.9-178".equals(vs[24].getName())); -152 assertTrue("cpe:/a:hp:system_management_homepage:2.1.10".equals(vs[25].getName())); -153 assertTrue("cpe:/a:hp:system_management_homepage:2.1.10-186".equals(vs[26].getName())); -154 assertTrue("cpe:/a:hp:system_management_homepage:2.1.11".equals(vs[27].getName())); -155 assertTrue("cpe:/a:hp:system_management_homepage:2.1.11-197".equals(vs[28].getName())); -156 assertTrue("cpe:/a:hp:system_management_homepage:2.1.12-118".equals(vs[29].getName())); -157 assertTrue("cpe:/a:hp:system_management_homepage:2.1.12-200".equals(vs[30].getName())); -158 -159 } -160 -161 } +124 assertTrue("cpe:/a:hp:system_management_homepage:2.0.0".equals(vs[0].getName())); +125 assertTrue("cpe:/a:hp:system_management_homepage:2.0.1".equals(vs[1].getName())); +126 assertTrue("cpe:/a:hp:system_management_homepage:2.0.2".equals(vs[2].getName())); +127 assertTrue("cpe:/a:hp:system_management_homepage:2.1".equals(vs[3].getName())); +128 assertTrue("cpe:/a:hp:system_management_homepage:2.1.0-103".equals(vs[4].getName())); +129 assertTrue("cpe:/a:hp:system_management_homepage:2.1.0-103%28a%29".equals(vs[5].getName())); +130 assertTrue("cpe:/a:hp:system_management_homepage:2.1.0-109".equals(vs[6].getName())); +131 assertTrue("cpe:/a:hp:system_management_homepage:2.1.0-118".equals(vs[7].getName())); +132 assertTrue("cpe:/a:hp:system_management_homepage:2.1.1".equals(vs[8].getName())); +133 assertTrue("cpe:/a:hp:system_management_homepage:2.1.2".equals(vs[9].getName())); +134 assertTrue("cpe:/a:hp:system_management_homepage:2.1.2-127".equals(vs[10].getName())); +135 assertTrue("cpe:/a:hp:system_management_homepage:2.1.3".equals(vs[11].getName())); +136 assertTrue("cpe:/a:hp:system_management_homepage:2.1.3.132".equals(vs[12].getName())); +137 assertTrue("cpe:/a:hp:system_management_homepage:2.1.4".equals(vs[13].getName())); +138 assertTrue("cpe:/a:hp:system_management_homepage:2.1.4-143".equals(vs[14].getName())); +139 assertTrue("cpe:/a:hp:system_management_homepage:2.1.5".equals(vs[15].getName())); +140 assertTrue("cpe:/a:hp:system_management_homepage:2.1.5-146".equals(vs[16].getName())); +141 assertTrue("cpe:/a:hp:system_management_homepage:2.1.6".equals(vs[17].getName())); +142 assertTrue("cpe:/a:hp:system_management_homepage:2.1.6-156".equals(vs[18].getName())); +143 assertTrue("cpe:/a:hp:system_management_homepage:2.1.7".equals(vs[19].getName())); +144 assertTrue("cpe:/a:hp:system_management_homepage:2.1.7-168".equals(vs[20].getName())); +145 assertTrue("cpe:/a:hp:system_management_homepage:2.1.8".equals(vs[21].getName())); +146 assertTrue("cpe:/a:hp:system_management_homepage:2.1.8-177".equals(vs[22].getName())); +147 assertTrue("cpe:/a:hp:system_management_homepage:2.1.9".equals(vs[23].getName())); +148 assertTrue("cpe:/a:hp:system_management_homepage:2.1.9-178".equals(vs[24].getName())); +149 assertTrue("cpe:/a:hp:system_management_homepage:2.1.10".equals(vs[25].getName())); +150 assertTrue("cpe:/a:hp:system_management_homepage:2.1.10-186".equals(vs[26].getName())); +151 assertTrue("cpe:/a:hp:system_management_homepage:2.1.11".equals(vs[27].getName())); +152 assertTrue("cpe:/a:hp:system_management_homepage:2.1.11-197".equals(vs[28].getName())); +153 assertTrue("cpe:/a:hp:system_management_homepage:2.1.12-118".equals(vs[29].getName())); +154 assertTrue("cpe:/a:hp:system_management_homepage:2.1.12-200".equals(vs[30].getName())); +155 +156 } +157 +158 }
      diff --git a/xref-test/org/owasp/dependencycheck/dependency/VulnerableSoftwareTest.html b/xref-test/org/owasp/dependencycheck/dependency/VulnerableSoftwareTest.html index a7afdef9f..62fa8a74e 100644 --- a/xref-test/org/owasp/dependencycheck/dependency/VulnerableSoftwareTest.html +++ b/xref-test/org/owasp/dependencycheck/dependency/VulnerableSoftwareTest.html @@ -25,141 +25,138 @@ 17 */ 18 package org.owasp.dependencycheck.dependency; 19 -20 import org.junit.After; -21 import org.junit.AfterClass; -22 import static org.junit.Assert.assertEquals; -23 import static org.junit.Assert.assertTrue; -24 import static org.junit.Assert.assertFalse; -25 import org.junit.Before; -26 import org.junit.BeforeClass; -27 import org.junit.Test; -28 import org.owasp.dependencycheck.BaseTest; -29 -30 /** -31 * -32 * @author Jeremy Long -33 */ -34 public class VulnerableSoftwareTest extends BaseTest { -35 -36 /** -37 * Test of equals method, of class VulnerableSoftware. -38 */ -39 @Test -40 public void testEquals() { -41 VulnerableSoftware obj = new VulnerableSoftware(); -42 obj.setCpe("cpe:/a:mortbay:jetty:6.1.0"); -43 VulnerableSoftware instance = new VulnerableSoftware(); -44 instance.setCpe("cpe:/a:mortbay:jetty:6.1"); -45 assertFalse(instance.equals(obj)); -46 } -47 -48 /** -49 * Test of equals method, of class VulnerableSoftware. -50 */ -51 @Test -52 public void testEquals2() { -53 VulnerableSoftware obj = new VulnerableSoftware(); -54 obj.setCpe("cpe:/a:mortbay:jetty:6.1.0"); -55 VulnerableSoftware instance = new VulnerableSoftware(); -56 instance.setCpe("cpe:/a:mortbay:jetty:6.1.0"); -57 obj.setPreviousVersion("1"); -58 assertTrue(instance.equals(obj)); -59 } -60 -61 /** -62 * Test of hashCode method, of class VulnerableSoftware. -63 */ -64 @Test -65 public void testHashCode() { -66 VulnerableSoftware instance = new VulnerableSoftware(); -67 instance.setCpe("cpe:/a:mortbay:jetty:6.1"); -68 int expResult = 1849413912; -69 int result = instance.hashCode(); -70 assertEquals(expResult, result); -71 } -72 -73 /** -74 * Test of compareTo method, of class VulnerableSoftware. -75 */ -76 @Test -77 public void testCompareTo() { -78 VulnerableSoftware vs = new VulnerableSoftware(); -79 vs.setCpe("cpe:/a:mortbay:jetty:6.1.0"); -80 VulnerableSoftware instance = new VulnerableSoftware(); -81 instance.setCpe("cpe:/a:mortbay:jetty:6.1"); -82 int expResult = -2; -83 int result = instance.compareTo(vs); -84 assertEquals(expResult, result); -85 -86 vs = new VulnerableSoftware(); -87 vs.setCpe("cpe:/a:yahoo:toolbar:3.1.0.20130813024103"); -88 instance = new VulnerableSoftware(); -89 instance.setCpe("cpe:/a:yahoo:toolbar:3.1.0.20130813024104"); -90 expResult = 1; -91 result = instance.compareTo(vs); -92 assertEquals(expResult, result); -93 } -94 -95 @Test -96 public void testCompareToNonNumerical() { -97 VulnerableSoftware vs = new VulnerableSoftware(); -98 vs.setCpe("cpe:/a:mysql:mysql:5.1.23a"); -99 VulnerableSoftware vs1 = new VulnerableSoftware(); -100 vs1.setCpe("cpe:/a:mysql:mysql:5.1.23a"); -101 vs1.setPreviousVersion("1"); -102 assertEquals(0, vs.compareTo(vs1)); -103 assertEquals(0, vs1.compareTo(vs)); -104 } -105 -106 @Test -107 public void testCompareToComplex() { -108 VulnerableSoftware vs = new VulnerableSoftware(); -109 VulnerableSoftware vs1 = new VulnerableSoftware(); -110 -111 vs.setCpe("2.1"); -112 vs1.setCpe("2.1.10"); -113 assertTrue(vs.compareTo(vs1) < 0); -114 -115 vs.setCpe("cpe:/a:hp:system_management_homepage:2.1.1"); -116 vs1.setCpe("cpe:/a:hp:system_management_homepage:2.1.10"); -117 assertTrue(vs.compareTo(vs1) < 0); -118 -119 vs.setCpe("10"); -120 vs1.setCpe("10-186"); -121 assertTrue(vs.compareTo(vs1) < 0); -122 -123 vs.setCpe("2.1.10"); -124 vs1.setCpe("2.1.10-186"); -125 assertTrue(vs.compareTo(vs1) < 0); -126 -127 vs.setCpe("cpe:/a:hp:system_management_homepage:2.1.10"); -128 vs1.setCpe("cpe:/a:hp:system_management_homepage:2.1.10-186"); -129 assertTrue(vs.compareTo(vs1) < 0); -130 //assertTrue(vs1.compareTo(vs)>0); -131 } -132 -133 @Test -134 public void testEqualsPreviousVersion() { -135 VulnerableSoftware vs = new VulnerableSoftware(); -136 vs.setCpe("cpe:/a:mysql:mysql:5.1.23a"); -137 VulnerableSoftware vs1 = new VulnerableSoftware(); -138 vs1.setCpe("cpe:/a:mysql:mysql:5.1.23a"); -139 vs1.setPreviousVersion("1"); -140 assertEquals(vs, vs1); -141 assertEquals(vs1, vs); -142 -143 } -144 -145 @Test -146 public void testParseCPE() { -147 VulnerableSoftware vs = new VulnerableSoftware(); -148 /* Version for test taken from CVE-2008-2079 */ -149 vs.setCpe("cpe:/a:mysql:mysql:5.1.23a"); -150 assertEquals("mysql", vs.getVendor()); -151 assertEquals("mysql", vs.getProduct()); -152 assertEquals("5.1.23a", vs.getVersion()); -153 } -154 } +20 import static org.junit.Assert.assertEquals; +21 import static org.junit.Assert.assertTrue; +22 import static org.junit.Assert.assertFalse; +23 +24 import org.junit.Test; +25 import org.owasp.dependencycheck.BaseTest; +26 +27 /** +28 * +29 * @author Jeremy Long +30 */ +31 public class VulnerableSoftwareTest extends BaseTest { +32 +33 /** +34 * Test of equals method, of class VulnerableSoftware. +35 */ +36 @Test +37 public void testEquals() { +38 VulnerableSoftware obj = new VulnerableSoftware(); +39 obj.setCpe("cpe:/a:mortbay:jetty:6.1.0"); +40 VulnerableSoftware instance = new VulnerableSoftware(); +41 instance.setCpe("cpe:/a:mortbay:jetty:6.1"); +42 assertFalse(instance.equals(obj)); +43 } +44 +45 /** +46 * Test of equals method, of class VulnerableSoftware. +47 */ +48 @Test +49 public void testEquals2() { +50 VulnerableSoftware obj = new VulnerableSoftware(); +51 obj.setCpe("cpe:/a:mortbay:jetty:6.1.0"); +52 VulnerableSoftware instance = new VulnerableSoftware(); +53 instance.setCpe("cpe:/a:mortbay:jetty:6.1.0"); +54 obj.setPreviousVersion("1"); +55 assertTrue(instance.equals(obj)); +56 } +57 +58 /** +59 * Test of hashCode method, of class VulnerableSoftware. +60 */ +61 @Test +62 public void testHashCode() { +63 VulnerableSoftware instance = new VulnerableSoftware(); +64 instance.setCpe("cpe:/a:mortbay:jetty:6.1"); +65 int expResult = 1849413912; +66 int result = instance.hashCode(); +67 assertEquals(expResult, result); +68 } +69 +70 /** +71 * Test of compareTo method, of class VulnerableSoftware. +72 */ +73 @Test +74 public void testCompareTo() { +75 VulnerableSoftware vs = new VulnerableSoftware(); +76 vs.setCpe("cpe:/a:mortbay:jetty:6.1.0"); +77 VulnerableSoftware instance = new VulnerableSoftware(); +78 instance.setCpe("cpe:/a:mortbay:jetty:6.1"); +79 int expResult = -2; +80 int result = instance.compareTo(vs); +81 assertEquals(expResult, result); +82 +83 vs = new VulnerableSoftware(); +84 vs.setCpe("cpe:/a:yahoo:toolbar:3.1.0.20130813024103"); +85 instance = new VulnerableSoftware(); +86 instance.setCpe("cpe:/a:yahoo:toolbar:3.1.0.20130813024104"); +87 expResult = 1; +88 result = instance.compareTo(vs); +89 assertEquals(expResult, result); +90 } +91 +92 @Test +93 public void testCompareToNonNumerical() { +94 VulnerableSoftware vs = new VulnerableSoftware(); +95 vs.setCpe("cpe:/a:mysql:mysql:5.1.23a"); +96 VulnerableSoftware vs1 = new VulnerableSoftware(); +97 vs1.setCpe("cpe:/a:mysql:mysql:5.1.23a"); +98 vs1.setPreviousVersion("1"); +99 assertEquals(0, vs.compareTo(vs1)); +100 assertEquals(0, vs1.compareTo(vs)); +101 } +102 +103 @Test +104 public void testCompareToComplex() { +105 VulnerableSoftware vs = new VulnerableSoftware(); +106 VulnerableSoftware vs1 = new VulnerableSoftware(); +107 +108 vs.setCpe("2.1"); +109 vs1.setCpe("2.1.10"); +110 assertTrue(vs.compareTo(vs1) < 0); +111 +112 vs.setCpe("cpe:/a:hp:system_management_homepage:2.1.1"); +113 vs1.setCpe("cpe:/a:hp:system_management_homepage:2.1.10"); +114 assertTrue(vs.compareTo(vs1) < 0); +115 +116 vs.setCpe("10"); +117 vs1.setCpe("10-186"); +118 assertTrue(vs.compareTo(vs1) < 0); +119 +120 vs.setCpe("2.1.10"); +121 vs1.setCpe("2.1.10-186"); +122 assertTrue(vs.compareTo(vs1) < 0); +123 +124 vs.setCpe("cpe:/a:hp:system_management_homepage:2.1.10"); +125 vs1.setCpe("cpe:/a:hp:system_management_homepage:2.1.10-186"); +126 assertTrue(vs.compareTo(vs1) < 0); +127 //assertTrue(vs1.compareTo(vs)>0); +128 } +129 +130 @Test +131 public void testEqualsPreviousVersion() { +132 VulnerableSoftware vs = new VulnerableSoftware(); +133 vs.setCpe("cpe:/a:mysql:mysql:5.1.23a"); +134 VulnerableSoftware vs1 = new VulnerableSoftware(); +135 vs1.setCpe("cpe:/a:mysql:mysql:5.1.23a"); +136 vs1.setPreviousVersion("1"); +137 assertEquals(vs, vs1); +138 assertEquals(vs1, vs); +139 +140 } +141 +142 @Test +143 public void testParseCPE() { +144 VulnerableSoftware vs = new VulnerableSoftware(); +145 /* Version for test taken from CVE-2008-2079 */ +146 vs.setCpe("cpe:/a:mysql:mysql:5.1.23a"); +147 assertEquals("mysql", vs.getVendor()); +148 assertEquals("mysql", vs.getProduct()); +149 assertEquals("5.1.23a", vs.getVersion()); +150 } +151 }
      diff --git a/xref-test/org/owasp/dependencycheck/dependency/package-frame.html b/xref-test/org/owasp/dependencycheck/dependency/package-frame.html index 2ff5cb746..c27612c4a 100644 --- a/xref-test/org/owasp/dependencycheck/dependency/package-frame.html +++ b/xref-test/org/owasp/dependencycheck/dependency/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.dependency + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.dependency diff --git a/xref-test/org/owasp/dependencycheck/dependency/package-summary.html b/xref-test/org/owasp/dependencycheck/dependency/package-summary.html index b74bd7184..3bc4f2eca 100644 --- a/xref-test/org/owasp/dependencycheck/dependency/package-summary.html +++ b/xref-test/org/owasp/dependencycheck/dependency/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.dependency + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.dependency diff --git a/xref-test/org/owasp/dependencycheck/maven/BaseDependencyCheckMojoTest.html b/xref-test/org/owasp/dependencycheck/maven/BaseDependencyCheckMojoTest.html index f11b32e51..031c21559 100644 --- a/xref-test/org/owasp/dependencycheck/maven/BaseDependencyCheckMojoTest.html +++ b/xref-test/org/owasp/dependencycheck/maven/BaseDependencyCheckMojoTest.html @@ -98,7 +98,7 @@ 90 91 boolean autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE); 92 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); -93 Engine engine = new Engine(null, null); +93 MavenEngine engine = new MavenEngine(null, null); 94 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate); 95 96 assertTrue(engine.getDependencies().isEmpty()); diff --git a/xref-test/org/owasp/dependencycheck/maven/package-frame.html b/xref-test/org/owasp/dependencycheck/maven/package-frame.html index 895786b22..10d07b058 100644 --- a/xref-test/org/owasp/dependencycheck/maven/package-frame.html +++ b/xref-test/org/owasp/dependencycheck/maven/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.maven + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.maven diff --git a/xref-test/org/owasp/dependencycheck/maven/package-summary.html b/xref-test/org/owasp/dependencycheck/maven/package-summary.html index 22f65ff7a..757e9c400 100644 --- a/xref-test/org/owasp/dependencycheck/maven/package-summary.html +++ b/xref-test/org/owasp/dependencycheck/maven/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.maven + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.maven diff --git a/xref-test/org/owasp/dependencycheck/package-frame.html b/xref-test/org/owasp/dependencycheck/package-frame.html index 11d4c3dc5..23acb85bf 100644 --- a/xref-test/org/owasp/dependencycheck/package-frame.html +++ b/xref-test/org/owasp/dependencycheck/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck diff --git a/xref-test/org/owasp/dependencycheck/package-summary.html b/xref-test/org/owasp/dependencycheck/package-summary.html index f23ab7a94..52fe8c7c1 100644 --- a/xref-test/org/owasp/dependencycheck/package-summary.html +++ b/xref-test/org/owasp/dependencycheck/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck diff --git a/xref-test/org/owasp/dependencycheck/reporting/ReportGeneratorIntegrationTest.html b/xref-test/org/owasp/dependencycheck/reporting/ReportGeneratorIntegrationTest.html index 89534aafb..694f1e2bd 100644 --- a/xref-test/org/owasp/dependencycheck/reporting/ReportGeneratorIntegrationTest.html +++ b/xref-test/org/owasp/dependencycheck/reporting/ReportGeneratorIntegrationTest.html @@ -32,7 +32,7 @@ 24 import javax.xml.validation.Schema; 25 import javax.xml.validation.SchemaFactory; 26 import javax.xml.validation.Validator; -27 import org.junit.Before; +27 28 import org.junit.Test; 29 import org.owasp.dependencycheck.BaseDBTestCase; 30 import org.owasp.dependencycheck.BaseTest; diff --git a/xref-test/org/owasp/dependencycheck/reporting/package-frame.html b/xref-test/org/owasp/dependencycheck/reporting/package-frame.html index bee3f2ae9..594144a52 100644 --- a/xref-test/org/owasp/dependencycheck/reporting/package-frame.html +++ b/xref-test/org/owasp/dependencycheck/reporting/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.reporting + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.reporting diff --git a/xref-test/org/owasp/dependencycheck/reporting/package-summary.html b/xref-test/org/owasp/dependencycheck/reporting/package-summary.html index 1685ecffe..68a7e7527 100644 --- a/xref-test/org/owasp/dependencycheck/reporting/package-summary.html +++ b/xref-test/org/owasp/dependencycheck/reporting/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.reporting + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.reporting diff --git a/xref-test/org/owasp/dependencycheck/taskdefs/package-frame.html b/xref-test/org/owasp/dependencycheck/taskdefs/package-frame.html index c42369b36..bd8a2bb7a 100644 --- a/xref-test/org/owasp/dependencycheck/taskdefs/package-frame.html +++ b/xref-test/org/owasp/dependencycheck/taskdefs/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.taskdefs + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.taskdefs diff --git a/xref-test/org/owasp/dependencycheck/taskdefs/package-summary.html b/xref-test/org/owasp/dependencycheck/taskdefs/package-summary.html index efab4a3d3..067193d51 100644 --- a/xref-test/org/owasp/dependencycheck/taskdefs/package-summary.html +++ b/xref-test/org/owasp/dependencycheck/taskdefs/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.taskdefs + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.taskdefs diff --git a/xref-test/org/owasp/dependencycheck/utils/DateUtilTest.html b/xref-test/org/owasp/dependencycheck/utils/DateUtilTest.html index 998326f28..284e3835b 100644 --- a/xref-test/org/owasp/dependencycheck/utils/DateUtilTest.html +++ b/xref-test/org/owasp/dependencycheck/utils/DateUtilTest.html @@ -24,41 +24,39 @@ 16 package org.owasp.dependencycheck.utils; 17 18 import java.util.Calendar; -19 import org.junit.After; -20 import org.junit.AfterClass; -21 import static org.junit.Assert.assertEquals; -22 import org.junit.Before; -23 import org.junit.BeforeClass; -24 import org.junit.Test; -25 import org.owasp.dependencycheck.BaseTest; -26 -27 /** -28 * -29 * @author Jeremy Long -30 */ -31 public class DateUtilTest extends BaseTest { -32 -33 /** -34 * Test of withinDateRange method, of class DateUtil. -35 */ -36 @Test -37 public void testWithinDateRange() { -38 Calendar c = Calendar.getInstance(); -39 -40 long current = c.getTimeInMillis(); -41 long lastRun = c.getTimeInMillis() - (3 * (1000 * 60 * 60 * 24)); -42 int range = 7; // 7 days -43 boolean expResult = true; -44 boolean result = DateUtil.withinDateRange(lastRun, current, range); -45 assertEquals(expResult, result); -46 -47 lastRun = c.getTimeInMillis() - (8 * (1000 * 60 * 60 * 24)); -48 expResult = false; -49 result = DateUtil.withinDateRange(lastRun, current, range); -50 assertEquals(expResult, result); -51 } -52 -53 } +19 +20 import static org.junit.Assert.assertEquals; +21 +22 import org.junit.Test; +23 import org.owasp.dependencycheck.BaseTest; +24 +25 /** +26 * +27 * @author Jeremy Long +28 */ +29 public class DateUtilTest extends BaseTest { +30 +31 /** +32 * Test of withinDateRange method, of class DateUtil. +33 */ +34 @Test +35 public void testWithinDateRange() { +36 Calendar c = Calendar.getInstance(); +37 +38 long current = c.getTimeInMillis(); +39 long lastRun = c.getTimeInMillis() - (3 * (1000 * 60 * 60 * 24)); +40 int range = 7; // 7 days +41 boolean expResult = true; +42 boolean result = DateUtil.withinDateRange(lastRun, current, range); +43 assertEquals(expResult, result); +44 +45 lastRun = c.getTimeInMillis() - (8 * (1000 * 60 * 60 * 24)); +46 expResult = false; +47 result = DateUtil.withinDateRange(lastRun, current, range); +48 assertEquals(expResult, result); +49 } +50 +51 }
      diff --git a/xref-test/org/owasp/dependencycheck/utils/DependencyVersionUtilTest.html b/xref-test/org/owasp/dependencycheck/utils/DependencyVersionUtilTest.html index 9bcab3e6d..8ad9fe896 100644 --- a/xref-test/org/owasp/dependencycheck/utils/DependencyVersionUtilTest.html +++ b/xref-test/org/owasp/dependencycheck/utils/DependencyVersionUtilTest.html @@ -25,52 +25,49 @@ 17 */ 18 package org.owasp.dependencycheck.utils; 19 -20 import org.junit.After; -21 import org.junit.AfterClass; -22 import static org.junit.Assert.assertEquals; -23 import static org.junit.Assert.assertNull; -24 import org.junit.Before; -25 import org.junit.BeforeClass; -26 import org.junit.Test; -27 import org.owasp.dependencycheck.BaseTest; -28 -29 /** -30 * -31 * @author Jeremy Long -32 */ -33 public class DependencyVersionUtilTest extends BaseTest { -34 -35 /** -36 * Test of parseVersion method, of class DependencyVersionUtil. -37 */ -38 @Test -39 public void testParseVersion() { -40 final String[] fileName = {"something-0.9.5.jar", "lib2-1.1.jar", "lib1.5r4-someflag-R26.jar", -41 "lib-1.2.5-dev-20050313.jar", "testlib_V4.4.0.jar", "lib-core-2.0.0-RC1-SNAPSHOT.jar", -42 "lib-jsp-2.0.1_R114940.jar", "dev-api-2.3.11_R121413.jar", "lib-api-3.7-SNAPSHOT.jar", -43 "-", "", "1.3-beta", "6", "openssl1.0.1c", "jsf-impl-2.2.8-02.jar", -44 "plone.rfc822-1.1.1-py2-none-any.whl"}; -45 final String[] expResult = {"0.9.5", "1.1", "1.5.r4", "1.2.5", "4.4.0", "2.0.0.rc1", -46 "2.0.1.r114940", "2.3.11.r121413", "3.7", "-", null, "1.3.beta", "6", "1.0.1c", -47 "2.2.8.02", "1.1.1"}; -48 -49 for (int i = 0; i < fileName.length; i++) { -50 final DependencyVersion version = DependencyVersionUtil.parseVersion(fileName[i]); -51 String result = null; -52 if (version != null) { -53 result = version.toString(); -54 } -55 assertEquals("Failed extraction on \"" + fileName[i] + "\".", expResult[i], result); -56 } -57 -58 String[] failingNames = {"no-version-identified.jar", "somelib-04aug2000r7-dev.jar", /*"no.version15.jar",*/ -59 "lib_1.0_spec-1.1.jar", "lib-api_1.0_spec-1.0.1.jar"}; -60 for (String failingName : failingNames) { -61 final DependencyVersion version = DependencyVersionUtil.parseVersion(failingName); -62 assertNull("Found version in name that should have failed \"" + failingName + "\".", version); -63 } -64 } -65 } +20 import static org.junit.Assert.assertEquals; +21 import static org.junit.Assert.assertNull; +22 +23 import org.junit.Test; +24 import org.owasp.dependencycheck.BaseTest; +25 +26 /** +27 * +28 * @author Jeremy Long +29 */ +30 public class DependencyVersionUtilTest extends BaseTest { +31 +32 /** +33 * Test of parseVersion method, of class DependencyVersionUtil. +34 */ +35 @Test +36 public void testParseVersion() { +37 final String[] fileName = {"something-0.9.5.jar", "lib2-1.1.jar", "lib1.5r4-someflag-R26.jar", +38 "lib-1.2.5-dev-20050313.jar", "testlib_V4.4.0.jar", "lib-core-2.0.0-RC1-SNAPSHOT.jar", +39 "lib-jsp-2.0.1_R114940.jar", "dev-api-2.3.11_R121413.jar", "lib-api-3.7-SNAPSHOT.jar", +40 "-", "", "1.3-beta", "6", "openssl1.0.1c", "jsf-impl-2.2.8-02.jar", +41 "plone.rfc822-1.1.1-py2-none-any.whl"}; +42 final String[] expResult = {"0.9.5", "1.1", "1.5.r4", "1.2.5", "4.4.0", "2.0.0.rc1", +43 "2.0.1.r114940", "2.3.11.r121413", "3.7", "-", null, "1.3.beta", "6", "1.0.1c", +44 "2.2.8.02", "1.1.1"}; +45 +46 for (int i = 0; i < fileName.length; i++) { +47 final DependencyVersion version = DependencyVersionUtil.parseVersion(fileName[i]); +48 String result = null; +49 if (version != null) { +50 result = version.toString(); +51 } +52 assertEquals("Failed extraction on \"" + fileName[i] + "\".", expResult[i], result); +53 } +54 +55 String[] failingNames = {"no-version-identified.jar", "somelib-04aug2000r7-dev.jar", /*"no.version15.jar",*/ +56 "lib_1.0_spec-1.1.jar", "lib-api_1.0_spec-1.0.1.jar"}; +57 for (String failingName : failingNames) { +58 final DependencyVersion version = DependencyVersionUtil.parseVersion(failingName); +59 assertNull("Found version in name that should have failed \"" + failingName + "\".", version); +60 } +61 } +62 }
      diff --git a/xref-test/org/owasp/dependencycheck/utils/package-frame.html b/xref-test/org/owasp/dependencycheck/utils/package-frame.html index 5a93cdd95..bb0d2f2f2 100644 --- a/xref-test/org/owasp/dependencycheck/utils/package-frame.html +++ b/xref-test/org/owasp/dependencycheck/utils/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.utils + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.utils diff --git a/xref-test/org/owasp/dependencycheck/utils/package-summary.html b/xref-test/org/owasp/dependencycheck/utils/package-summary.html index 1a51ba9bf..98c97914c 100644 --- a/xref-test/org/owasp/dependencycheck/utils/package-summary.html +++ b/xref-test/org/owasp/dependencycheck/utils/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.utils + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.utils diff --git a/xref-test/org/owasp/dependencycheck/xml/hints/HintHandlerTest.html b/xref-test/org/owasp/dependencycheck/xml/hints/HintHandlerTest.html new file mode 100644 index 000000000..24a30c1b7 --- /dev/null +++ b/xref-test/org/owasp/dependencycheck/xml/hints/HintHandlerTest.html @@ -0,0 +1,90 @@ + + + +HintHandlerTest xref + + + +
      +1   /*
      +2    * This file is part of dependency-check-core.
      +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) 2016 Jeremy Long. All Rights Reserved.
      +17   */
      +18  package org.owasp.dependencycheck.xml.hints;
      +19  
      +20  import java.io.File;
      +21  import java.io.FileInputStream;
      +22  import java.io.FileNotFoundException;
      +23  import java.io.IOException;
      +24  import java.io.InputStream;
      +25  import java.io.InputStreamReader;
      +26  import java.io.Reader;
      +27  import java.io.UnsupportedEncodingException;
      +28  import java.util.List;
      +29  import javax.xml.parsers.ParserConfigurationException;
      +30  import javax.xml.parsers.SAXParser;
      +31  import javax.xml.parsers.SAXParserFactory;
      +32  import org.junit.Test;
      +33  import static org.junit.Assert.*;
      +34  import org.owasp.dependencycheck.BaseTest;
      +35  import org.owasp.dependencycheck.xml.suppression.SuppressionErrorHandler;
      +36  import org.owasp.dependencycheck.xml.suppression.SuppressionHandler;
      +37  import org.owasp.dependencycheck.xml.suppression.SuppressionParser;
      +38  import org.owasp.dependencycheck.xml.suppression.SuppressionRule;
      +39  import org.xml.sax.Attributes;
      +40  import org.xml.sax.InputSource;
      +41  import org.xml.sax.SAXException;
      +42  import org.xml.sax.SAXNotRecognizedException;
      +43  import org.xml.sax.SAXNotSupportedException;
      +44  import org.xml.sax.XMLReader;
      +45  
      +46  /**
      +47   *
      +48   * @author Jeremy Long
      +49   */
      +50  public class HintHandlerTest extends BaseTest {
      +51      
      +52      @Test
      +53      public void testHandler() throws ParserConfigurationException, SAXNotRecognizedException, SAXNotSupportedException, SAXException, FileNotFoundException, UnsupportedEncodingException, IOException {
      +54          File file = BaseTest.getResourceAsFile(this, "hints.xml");
      +55          File schema = BaseTest.getResourceAsFile(this, "schema/dependency-hint.1.0.xsd");
      +56          HintHandler handler = new HintHandler();
      +57  
      +58          SAXParserFactory factory = SAXParserFactory.newInstance();
      +59          factory.setNamespaceAware(true);
      +60          factory.setValidating(true);
      +61          SAXParser saxParser = factory.newSAXParser();
      +62          saxParser.setProperty(HintParser.JAXP_SCHEMA_LANGUAGE, HintParser.W3C_XML_SCHEMA);
      +63          saxParser.setProperty(HintParser.JAXP_SCHEMA_SOURCE, schema);
      +64          XMLReader xmlReader = saxParser.getXMLReader();
      +65          xmlReader.setErrorHandler(new HintErrorHandler());
      +66          xmlReader.setContentHandler(handler);
      +67  
      +68          InputStream inputStream = new FileInputStream(file);
      +69          Reader reader = new InputStreamReader(inputStream, "UTF-8");
      +70          InputSource in = new InputSource(reader);
      +71          xmlReader.parse(in);
      +72  
      +73          List<HintRule> result = handler.getHintRules();
      +74          assertEquals("two hint rules should have been loaded",2,result.size());
      +75      }
      +76  
      +77  }
      +
      +
      + + + diff --git a/xref-test/org/owasp/dependencycheck/xml/hints/HintParserTest.html b/xref-test/org/owasp/dependencycheck/xml/hints/HintParserTest.html new file mode 100644 index 000000000..9c6125639 --- /dev/null +++ b/xref-test/org/owasp/dependencycheck/xml/hints/HintParserTest.html @@ -0,0 +1,86 @@ + + + +HintParserTest xref + + + +
      +1   /*
      +2    * This file is part of dependency-check-core.
      +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) 2016 Jeremy Long. All Rights Reserved.
      +17   */
      +18  package org.owasp.dependencycheck.xml.hints;
      +19  
      +20  import java.io.File;
      +21  import java.io.InputStream;
      +22  import org.junit.Test;
      +23  import static org.junit.Assert.assertEquals;
      +24  import org.owasp.dependencycheck.BaseTest;
      +25  
      +26  /**
      +27   *
      +28   * @author Jeremy Long
      +29   */
      +30  public class HintParserTest extends BaseTest {
      +31  
      +32      /**
      +33       * Test of parseHints method, of class HintParser.
      +34       */
      +35      @Test
      +36      public void testParseHints_File() throws Exception {
      +37          File file = BaseTest.getResourceAsFile(this, "hints.xml");
      +38          HintParser instance = new HintParser();
      +39          Hints results = instance.parseHints(file);
      +40          assertEquals("Two duplicating hints should have been read", 2, results.getVendorDuplicatingHintRules().size());
      +41          assertEquals("Two hint rules should have been read", 2, results.getHintRules().size());
      +42      }
      +43  
      +44      /**
      +45       * Test of parseHints method, of class HintParser.
      +46       */
      +47      @Test
      +48      public void testParseHints_InputStream() throws Exception {
      +49          InputStream ins = BaseTest.getResourceAsStream(this, "hints.xml");
      +50          HintParser instance = new HintParser();
      +51          Hints results = instance.parseHints(ins);
      +52          assertEquals("Two duplicating hints should have been read", 2, results.getVendorDuplicatingHintRules().size());
      +53          assertEquals("Two hint rules should have been read", 2, results.getHintRules().size());
      +54          assertEquals("One add product should have been read", 1, results.getHintRules().get(0).getAddProduct().size());
      +55          assertEquals("One add vendor should have been read", 1, results.getHintRules().get(0).getAddVendor().size());
      +56          assertEquals("Two file name should have been read", 2, results.getHintRules().get(1).getFilenames().size());
      +57  
      +58          assertEquals("add product name not found", "add product name", results.getHintRules().get(0).getAddProduct().get(0).getName());
      +59          assertEquals("add vendor name not found", "add vendor name", results.getHintRules().get(0).getAddVendor().get(0).getName());
      +60          assertEquals("given product name not found", "given product name", results.getHintRules().get(0).getGivenProduct().get(0).getName());
      +61          assertEquals("given vendor name not found", "given vendor name", results.getHintRules().get(0).getGivenVendor().get(0).getName());
      +62  
      +63          assertEquals("spring file name not found", "spring", results.getHintRules().get(1).getFilenames().get(0).getValue());
      +64          assertEquals("file name 1 should not be case sensitive", false, results.getHintRules().get(1).getFilenames().get(0).isCaseSensitive());
      +65          assertEquals("file name 1 should not be a regex", false, results.getHintRules().get(1).getFilenames().get(0).isRegex());
      +66          assertEquals("file name 2 should be case sensitive", true, results.getHintRules().get(1).getFilenames().get(1).isCaseSensitive());
      +67          assertEquals("file name 2 should be a regex", true, results.getHintRules().get(1).getFilenames().get(1).isRegex());
      +68          
      +69          
      +70          assertEquals("sun duplicating vendor", "sun", results.getVendorDuplicatingHintRules().get(0).getValue());
      +71          assertEquals("sun duplicates vendor oracle", "oracle", results.getVendorDuplicatingHintRules().get(0).getDuplicate());
      +72      }
      +73  }
      +
      +
      + + + diff --git a/xref-test/org/owasp/dependencycheck/xml/hints/package-frame.html b/xref-test/org/owasp/dependencycheck/xml/hints/package-frame.html new file mode 100644 index 000000000..b618ed212 --- /dev/null +++ b/xref-test/org/owasp/dependencycheck/xml/hints/package-frame.html @@ -0,0 +1,27 @@ + + + + + + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.xml.hints + + + + +

      + org.owasp.dependencycheck.xml.hints +

      + +

      Classes

      + + + + + \ No newline at end of file diff --git a/xref-test/org/owasp/dependencycheck/xml/hints/package-summary.html b/xref-test/org/owasp/dependencycheck/xml/hints/package-summary.html new file mode 100644 index 000000000..0ef33de38 --- /dev/null +++ b/xref-test/org/owasp/dependencycheck/xml/hints/package-summary.html @@ -0,0 +1,74 @@ + + + + + + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.xml.hints + + + +
      + +
      +
      + +
      + +

      Package org.owasp.dependencycheck.xml.hints

      + + + + + + + + + + + + + + + +
      Class Summary
      + HintHandlerTest +
      + HintParserTest +
      + +
      + +
      +
      + +
      +
      + + + \ No newline at end of file diff --git a/xref-test/org/owasp/dependencycheck/xml/pom/package-frame.html b/xref-test/org/owasp/dependencycheck/xml/pom/package-frame.html index efcd96717..7c5eeaa7c 100644 --- a/xref-test/org/owasp/dependencycheck/xml/pom/package-frame.html +++ b/xref-test/org/owasp/dependencycheck/xml/pom/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.xml.pom + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.xml.pom diff --git a/xref-test/org/owasp/dependencycheck/xml/pom/package-summary.html b/xref-test/org/owasp/dependencycheck/xml/pom/package-summary.html index 74887e9fd..f943fc539 100644 --- a/xref-test/org/owasp/dependencycheck/xml/pom/package-summary.html +++ b/xref-test/org/owasp/dependencycheck/xml/pom/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.xml.pom + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.xml.pom diff --git a/xref-test/org/owasp/dependencycheck/xml/suppression/PropertyTypeTest.html b/xref-test/org/owasp/dependencycheck/xml/suppression/PropertyTypeTest.html new file mode 100644 index 000000000..3061732b2 --- /dev/null +++ b/xref-test/org/owasp/dependencycheck/xml/suppression/PropertyTypeTest.html @@ -0,0 +1,101 @@ + + + +PropertyTypeTest xref + + + +
      +1   /*
      +2    * This file is part of dependency-check-core.
      +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) 2013 Jeremy Long. All Rights Reserved.
      +17   */
      +18  package org.owasp.dependencycheck.xml.suppression;
      +19  
      +20  import static org.junit.Assert.assertEquals;
      +21  import static org.junit.Assert.assertFalse;
      +22  import static org.junit.Assert.assertTrue;
      +23  
      +24  import org.junit.Test;
      +25  import org.owasp.dependencycheck.BaseTest;
      +26  
      +27  /**
      +28   *
      +29   * @author Jeremy Long
      +30   */
      +31  public class PropertyTypeTest extends BaseTest {
      +32  
      +33      /**
      +34       * Test of set and getValue method, of class PropertyType.
      +35       */
      +36      @Test
      +37      public void testSetGetValue() {
      +38  
      +39          PropertyType instance = new PropertyType();
      +40          String expResult = "test";
      +41          instance.setValue(expResult);
      +42          String result = instance.getValue();
      +43          assertEquals(expResult, result);
      +44      }
      +45  
      +46      /**
      +47       * Test of isRegex method, of class PropertyType.
      +48       */
      +49      @Test
      +50      public void testIsRegex() {
      +51          PropertyType instance = new PropertyType();
      +52          boolean result = instance.isRegex();
      +53          assertFalse(instance.isRegex());
      +54          instance.setRegex(true);
      +55          assertTrue(instance.isRegex());
      +56      }
      +57  
      +58      /**
      +59       * Test of isCaseSensitive method, of class PropertyType.
      +60       */
      +61      @Test
      +62      public void testIsCaseSensitive() {
      +63          PropertyType instance = new PropertyType();
      +64          assertFalse(instance.isCaseSensitive());
      +65          instance.setCaseSensitive(true);
      +66          assertTrue(instance.isCaseSensitive());
      +67      }
      +68  
      +69      /**
      +70       * Test of matches method, of class PropertyType.
      +71       */
      +72      @Test
      +73      public void testMatches() {
      +74          String text = "Simple";
      +75  
      +76          PropertyType instance = new PropertyType();
      +77          instance.setValue("simple");
      +78          assertTrue(instance.matches(text));
      +79          instance.setCaseSensitive(true);
      +80          assertFalse(instance.matches(text));
      +81  
      +82          instance.setValue("s.*le");
      +83          instance.setRegex(true);
      +84          assertFalse(instance.matches(text));
      +85          instance.setCaseSensitive(false);
      +86          assertTrue(instance.matches(text));
      +87      }
      +88  }
      +
      +
      + + + diff --git a/xref-test/org/owasp/dependencycheck/xml/suppression/SuppressionHandlerTest.html b/xref-test/org/owasp/dependencycheck/xml/suppression/SuppressionHandlerTest.html new file mode 100644 index 000000000..e067360c1 --- /dev/null +++ b/xref-test/org/owasp/dependencycheck/xml/suppression/SuppressionHandlerTest.html @@ -0,0 +1,91 @@ + + + +SuppressionHandlerTest xref + + + +
      +1   /*
      +2    * This file is part of dependency-check-core.
      +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) 2013 Jeremy Long. All Rights Reserved.
      +17   */
      +18  package org.owasp.dependencycheck.xml.suppression;
      +19  
      +20  import java.io.File;
      +21  import java.io.FileInputStream;
      +22  import java.io.InputStream;
      +23  import java.io.InputStreamReader;
      +24  import java.io.Reader;
      +25  import java.util.List;
      +26  import javax.xml.parsers.SAXParser;
      +27  import javax.xml.parsers.SAXParserFactory;
      +28  import static org.junit.Assert.assertTrue;
      +29  import org.junit.Test;
      +30  import org.owasp.dependencycheck.BaseTest;
      +31  import org.xml.sax.InputSource;
      +32  import org.xml.sax.XMLReader;
      +33  
      +34  /**
      +35   *
      +36   * @author Jeremy Long
      +37   */
      +38  public class SuppressionHandlerTest extends BaseTest {
      +39  
      +40      /**
      +41       * Test of getSuppressionRules method, of class SuppressionHandler.
      +42       *
      +43       * @throws Exception thrown if there is an exception....
      +44       */
      +45      @Test
      +46      public void testHandler() throws Exception {
      +47          File file = BaseTest.getResourceAsFile(this, "suppressions.xml");
      +48          File schema = BaseTest.getResourceAsFile(this, "schema/suppression.xsd");
      +49          SuppressionHandler handler = new SuppressionHandler();
      +50  
      +51          SAXParserFactory factory = SAXParserFactory.newInstance();
      +52          factory.setNamespaceAware(true);
      +53          factory.setValidating(true);
      +54          SAXParser saxParser = factory.newSAXParser();
      +55          saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_LANGUAGE, SuppressionParser.W3C_XML_SCHEMA);
      +56          saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_SOURCE, schema);
      +57          XMLReader xmlReader = saxParser.getXMLReader();
      +58          xmlReader.setErrorHandler(new SuppressionErrorHandler());
      +59          xmlReader.setContentHandler(handler);
      +60  
      +61          InputStream inputStream = new FileInputStream(file);
      +62          Reader reader = new InputStreamReader(inputStream, "UTF-8");
      +63          InputSource in = new InputSource(reader);
      +64          //in.setEncoding("UTF-8");
      +65  
      +66          xmlReader.parse(in);
      +67  
      +68          List<SuppressionRule> result = handler.getSuppressionRules();
      +69          assertTrue(result.size() > 3);
      +70          int baseCount = 0;
      +71          for (SuppressionRule r : result) {
      +72              if (r.isBase()) {
      +73                  baseCount++;
      +74              }
      +75          }
      +76          assertTrue(baseCount > 0);
      +77      }
      +78  }
      +
      +
      + + + diff --git a/xref-test/org/owasp/dependencycheck/xml/suppression/SuppressionParserTest.html b/xref-test/org/owasp/dependencycheck/xml/suppression/SuppressionParserTest.html new file mode 100644 index 000000000..eeb0c44ae --- /dev/null +++ b/xref-test/org/owasp/dependencycheck/xml/suppression/SuppressionParserTest.html @@ -0,0 +1,59 @@ + + + +SuppressionParserTest xref + + + +
      +1   /*
      +2    * This file is part of dependency-check-core.
      +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) 2013 Jeremy Long. All Rights Reserved.
      +17   */
      +18  package org.owasp.dependencycheck.xml.suppression;
      +19  
      +20  import java.io.File;
      +21  import java.util.List;
      +22  
      +23  import static org.junit.Assert.assertTrue;
      +24  
      +25  import org.junit.Test;
      +26  import org.owasp.dependencycheck.BaseTest;
      +27  
      +28  /**
      +29   * Test of the suppression parser.
      +30   *
      +31   * @author Jeremy Long
      +32   */
      +33  public class SuppressionParserTest extends BaseTest {
      +34  
      +35      /**
      +36       * Test of parseSuppressionRules method, of class SuppressionParser.
      +37       */
      +38      @Test
      +39      public void testParseSuppressionRules() throws Exception {
      +40          //File file = new File(this.getClass().getClassLoader().getResource("suppressions.xml").getPath());
      +41          File file = BaseTest.getResourceAsFile(this, "suppressions.xml");
      +42          SuppressionParser instance = new SuppressionParser();
      +43          List<SuppressionRule> result = instance.parseSuppressionRules(file);
      +44          assertTrue(result.size() > 3);
      +45      }
      +46  }
      +
      +
      + + + diff --git a/xref-test/org/owasp/dependencycheck/xml/suppression/SuppressionRuleTest.html b/xref-test/org/owasp/dependencycheck/xml/suppression/SuppressionRuleTest.html new file mode 100644 index 000000000..5928e1fdf --- /dev/null +++ b/xref-test/org/owasp/dependencycheck/xml/suppression/SuppressionRuleTest.html @@ -0,0 +1,515 @@ + + + +SuppressionRuleTest xref + + + +
      +1   /*
      +2    * This file is part of dependency-check-core.
      +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) 2013 Jeremy Long. All Rights Reserved.
      +17   */
      +18  package org.owasp.dependencycheck.xml.suppression;
      +19  
      +20  import java.io.File;
      +21  import java.util.ArrayList;
      +22  import java.util.List;
      +23  import static org.junit.Assert.assertEquals;
      +24  import static org.junit.Assert.assertFalse;
      +25  import static org.junit.Assert.assertTrue;
      +26  import org.junit.Test;
      +27  import org.owasp.dependencycheck.BaseTest;
      +28  import org.owasp.dependencycheck.dependency.Dependency;
      +29  import org.owasp.dependencycheck.dependency.Identifier;
      +30  import org.owasp.dependencycheck.dependency.Vulnerability;
      +31  
      +32  /**
      +33   * Test of the suppression rule.
      +34   *
      +35   * @author Jeremy Long
      +36   */
      +37  public class SuppressionRuleTest extends BaseTest {
      +38  
      +39      //<editor-fold defaultstate="collapsed" desc="Stupid tests of properties">
      +40      /**
      +41       * Test of FilePath property, of class SuppressionRule.
      +42       */
      +43      @Test
      +44      public void testFilePath() {
      +45          SuppressionRule instance = new SuppressionRule();
      +46          PropertyType expResult = new PropertyType();
      +47          expResult.setValue("test");
      +48          instance.setFilePath(expResult);
      +49          PropertyType result = instance.getFilePath();
      +50          assertEquals(expResult, result);
      +51      }
      +52  
      +53      /**
      +54       * Test of Sha1 property, of class SuppressionRule.
      +55       */
      +56      @Test
      +57      public void testSha1() {
      +58          SuppressionRule instance = new SuppressionRule();
      +59          String expResult = "384FAA82E193D4E4B0546059CA09572654BC3970";
      +60          instance.setSha1(expResult);
      +61          String result = instance.getSha1();
      +62          assertEquals(expResult, result);
      +63      }
      +64  
      +65      /**
      +66       * Test of Cpe property, of class SuppressionRule.
      +67       */
      +68      @Test
      +69      public void testCpe() {
      +70          SuppressionRule instance = new SuppressionRule();
      +71          List<PropertyType> cpe = new ArrayList<PropertyType>();
      +72          instance.setCpe(cpe);
      +73          assertFalse(instance.hasCpe());
      +74          PropertyType pt = new PropertyType();
      +75          pt.setValue("one");
      +76          instance.addCpe(pt);
      +77          assertTrue(instance.hasCpe());
      +78          List<PropertyType> result = instance.getCpe();
      +79          assertEquals(cpe, result);
      +80  
      +81      }
      +82  
      +83      /**
      +84       * Test of CvssBelow property, of class SuppressionRule.
      +85       */
      +86      @Test
      +87      public void testGetCvssBelow() {
      +88          SuppressionRule instance = new SuppressionRule();
      +89          List<Float> cvss = new ArrayList<Float>();
      +90          instance.setCvssBelow(cvss);
      +91          assertFalse(instance.hasCvssBelow());
      +92          instance.addCvssBelow(0.7f);
      +93          assertTrue(instance.hasCvssBelow());
      +94          List<Float> result = instance.getCvssBelow();
      +95          assertEquals(cvss, result);
      +96      }
      +97  
      +98      /**
      +99       * Test of Cwe property, of class SuppressionRule.
      +100      */
      +101     @Test
      +102     public void testCwe() {
      +103         SuppressionRule instance = new SuppressionRule();
      +104         List<String> cwe = new ArrayList<String>();
      +105         instance.setCwe(cwe);
      +106         assertFalse(instance.hasCwe());
      +107         instance.addCwe("2");
      +108         assertTrue(instance.hasCwe());
      +109         List<String> result = instance.getCwe();
      +110         assertEquals(cwe, result);
      +111     }
      +112 
      +113     /**
      +114      * Test of Cve property, of class SuppressionRule.
      +115      */
      +116     @Test
      +117     public void testCve() {
      +118         SuppressionRule instance = new SuppressionRule();
      +119         List<String> cve = new ArrayList<String>();
      +120         instance.setCve(cve);
      +121         assertFalse(instance.hasCve());
      +122         instance.addCve("CVE-2013-1337");
      +123         assertTrue(instance.hasCve());
      +124         List<String> result = instance.getCve();
      +125         assertEquals(cve, result);
      +126     }
      +127 
      +128     /**
      +129      * Test of base property, of class SuppressionRule.
      +130      */
      +131     @Test
      +132     public void testBase() {
      +133         SuppressionRule instance = new SuppressionRule();
      +134         assertFalse(instance.isBase());
      +135         instance.setBase(true);
      +136         assertTrue(instance.isBase());
      +137     }
      +138     //</editor-fold>
      +139 
      +140     //<editor-fold defaultstate="collapsed" desc="Ignored duplicate tests, left in, as empty tests, so IDE doesn't re-generate them">
      +141     /**
      +142      * Test of getFilePath method, of class SuppressionRule.
      +143      */
      +144     @Test
      +145     public void testGetFilePath() {
      +146         //already tested, this is just left so the IDE doesn't recreate it.
      +147     }
      +148 
      +149     /**
      +150      * Test of setFilePath method, of class SuppressionRule.
      +151      */
      +152     @Test
      +153     public void testSetFilePath() {
      +154         //already tested, this is just left so the IDE doesn't recreate it.
      +155     }
      +156 
      +157     /**
      +158      * Test of getSha1 method, of class SuppressionRule.
      +159      */
      +160     @Test
      +161     public void testGetSha1() {
      +162         //already tested, this is just left so the IDE doesn't recreate it.
      +163     }
      +164 
      +165     /**
      +166      * Test of setSha1 method, of class SuppressionRule.
      +167      */
      +168     @Test
      +169     public void testSetSha1() {
      +170         //already tested, this is just left so the IDE doesn't recreate it.
      +171     }
      +172 
      +173     /**
      +174      * Test of getCpe method, of class SuppressionRule.
      +175      */
      +176     @Test
      +177     public void testGetCpe() {
      +178         //already tested, this is just left so the IDE doesn't recreate it.
      +179     }
      +180 
      +181     /**
      +182      * Test of setCpe method, of class SuppressionRule.
      +183      */
      +184     @Test
      +185     public void testSetCpe() {
      +186         //already tested, this is just left so the IDE doesn't recreate it.
      +187     }
      +188 
      +189     /**
      +190      * Test of addCpe method, of class SuppressionRule.
      +191      */
      +192     @Test
      +193     public void testAddCpe() {
      +194         //already tested, this is just left so the IDE doesn't recreate it.
      +195     }
      +196 
      +197     /**
      +198      * Test of hasCpe method, of class SuppressionRule.
      +199      */
      +200     @Test
      +201     public void testHasCpe() {
      +202         //already tested, this is just left so the IDE doesn't recreate it.
      +203     }
      +204 
      +205     /**
      +206      * Test of setCvssBelow method, of class SuppressionRule.
      +207      */
      +208     @Test
      +209     public void testSetCvssBelow() {
      +210         //already tested, this is just left so the IDE doesn't recreate it.
      +211     }
      +212 
      +213     /**
      +214      * Test of addCvssBelow method, of class SuppressionRule.
      +215      */
      +216     @Test
      +217     public void testAddCvssBelow() {
      +218         //already tested, this is just left so the IDE doesn't recreate it.
      +219     }
      +220 
      +221     /**
      +222      * Test of hasCvssBelow method, of class SuppressionRule.
      +223      */
      +224     @Test
      +225     public void testHasCvssBelow() {
      +226         //already tested, this is just left so the IDE doesn't recreate it.
      +227     }
      +228 
      +229     /**
      +230      * Test of getCwe method, of class SuppressionRule.
      +231      */
      +232     @Test
      +233     public void testGetCwe() {
      +234         //already tested, this is just left so the IDE doesn't recreate it.
      +235     }
      +236 
      +237     /**
      +238      * Test of setCwe method, of class SuppressionRule.
      +239      */
      +240     @Test
      +241     public void testSetCwe() {
      +242         //already tested, this is just left so the IDE doesn't recreate it.
      +243     }
      +244 
      +245     /**
      +246      * Test of addCwe method, of class SuppressionRule.
      +247      */
      +248     @Test
      +249     public void testAddCwe() {
      +250         //already tested, this is just left so the IDE doesn't recreate it.
      +251     }
      +252 
      +253     /**
      +254      * Test of hasCwe method, of class SuppressionRule.
      +255      */
      +256     @Test
      +257     public void testHasCwe() {
      +258         //already tested, this is just left so the IDE doesn't recreate it.
      +259     }
      +260 
      +261     /**
      +262      * Test of getCve method, of class SuppressionRule.
      +263      */
      +264     @Test
      +265     public void testGetCve() {
      +266         //already tested, this is just left so the IDE doesn't recreate it.
      +267     }
      +268 
      +269     /**
      +270      * Test of setCve method, of class SuppressionRule.
      +271      */
      +272     @Test
      +273     public void testSetCve() {
      +274         //already tested, this is just left so the IDE doesn't recreate it.
      +275     }
      +276 
      +277     /**
      +278      * Test of addCve method, of class SuppressionRule.
      +279      */
      +280     @Test
      +281     public void testAddCve() {
      +282         //already tested, this is just left so the IDE doesn't recreate it.
      +283     }
      +284 
      +285     /**
      +286      * Test of hasCve method, of class SuppressionRule.
      +287      */
      +288     @Test
      +289     public void testHasCve() {
      +290         //already tested, this is just left so the IDE doesn't recreate it.
      +291     }
      +292     //</editor-fold>
      +293 
      +294     /**
      +295      * Test of cpeHasNoVersion method, of class SuppressionRule.
      +296      */
      +297     @Test
      +298     public void testCpeHasNoVersion() {
      +299         PropertyType c = new PropertyType();
      +300         c.setValue("cpe:/a:microsoft:.net_framework:4.5");
      +301         SuppressionRule instance = new SuppressionRule();
      +302         assertFalse(instance.cpeHasNoVersion(c));
      +303         c.setValue("cpe:/a:microsoft:.net_framework:");
      +304         assertFalse(instance.cpeHasNoVersion(c));
      +305         c.setValue("cpe:/a:microsoft:.net_framework");
      +306         assertTrue(instance.cpeHasNoVersion(c));
      +307     }
      +308 
      +309     /**
      +310      * Test of identifierMatches method, of class SuppressionRule.
      +311      */
      +312     @Test
      +313     public void testCpeMatches() {
      +314         Identifier identifier = new Identifier("cpe", "cpe:/a:microsoft:.net_framework:4.5", "some url not needed for this test");
      +315 
      +316         PropertyType cpe = new PropertyType();
      +317         cpe.setValue("cpe:/a:microsoft:.net_framework:4.5");
      +318 
      +319         SuppressionRule instance = new SuppressionRule();
      +320         boolean expResult = true;
      +321         boolean result = instance.identifierMatches("cpe", cpe, identifier);
      +322         assertEquals(expResult, result);
      +323 
      +324         cpe.setValue("cpe:/a:microsoft:.net_framework:4.0");
      +325         expResult = false;
      +326         result = instance.identifierMatches("cpe", cpe, identifier);
      +327         assertEquals(expResult, result);
      +328 
      +329         cpe.setValue("CPE:/a:microsoft:.net_framework:4.5");
      +330         cpe.setCaseSensitive(true);
      +331         expResult = false;
      +332         result = instance.identifierMatches("cpe", cpe, identifier);
      +333         assertEquals(expResult, result);
      +334 
      +335         cpe.setValue("cpe:/a:microsoft:.net_framework");
      +336         cpe.setCaseSensitive(false);
      +337         expResult = true;
      +338         result = instance.identifierMatches("cpe", cpe, identifier);
      +339         assertEquals(expResult, result);
      +340 
      +341         cpe.setValue("cpe:/a:microsoft:.*");
      +342         cpe.setRegex(true);
      +343         expResult = true;
      +344         result = instance.identifierMatches("cpe", cpe, identifier);
      +345         assertEquals(expResult, result);
      +346 
      +347         cpe.setValue("CPE:/a:microsoft:.*");
      +348         cpe.setRegex(true);
      +349         cpe.setCaseSensitive(true);
      +350         expResult = false;
      +351         result = instance.identifierMatches("cpe", cpe, identifier);
      +352         assertEquals(expResult, result);
      +353 
      +354         cpe.setValue("cpe:/a:apache:.*");
      +355         cpe.setRegex(true);
      +356         cpe.setCaseSensitive(false);
      +357         expResult = false;
      +358         result = instance.identifierMatches("cpe", cpe, identifier);
      +359         assertEquals(expResult, result);
      +360 
      +361         identifier = new Identifier("maven", "org.springframework:spring-core:2.5.5", "https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.springframework&a=spring-core&v=2.5.5&e=jar");
      +362         cpe.setValue("org.springframework:spring-core:2.5.5");
      +363         cpe.setRegex(false);
      +364         cpe.setCaseSensitive(false);
      +365         expResult = true;
      +366         result = instance.identifierMatches("maven", cpe, identifier);
      +367         assertEquals(expResult, result);
      +368 
      +369         cpe.setValue("org\\.springframework\\.security:spring.*");
      +370         cpe.setRegex(true);
      +371         cpe.setCaseSensitive(false);
      +372         expResult = false;
      +373         result = instance.identifierMatches("maven", cpe, identifier);
      +374         assertEquals(expResult, result);
      +375     }
      +376 
      +377     /**
      +378      * Test of process method, of class SuppressionRule.
      +379      */
      +380     @Test
      +381     public void testProcess() {
      +382         //File struts = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath());
      +383         File struts = BaseTest.getResourceAsFile(this, "struts2-core-2.1.2.jar");
      +384         Dependency dependency = new Dependency(struts);
      +385         dependency.addIdentifier("cpe", "cpe:/a:microsoft:.net_framework:4.5", "some url not needed for this test");
      +386         String sha1 = dependency.getSha1sum();
      +387         dependency.setSha1sum("384FAA82E193D4E4B0546059CA09572654BC3970");
      +388         Vulnerability v = createVulnerability();
      +389         dependency.addVulnerability(v);
      +390 
      +391         //cwe
      +392         SuppressionRule instance = new SuppressionRule();
      +393         instance.setSha1(sha1);
      +394         instance.addCwe("287");
      +395         instance.process(dependency);
      +396         assertEquals(1, dependency.getVulnerabilities().size());
      +397         dependency.setSha1sum(sha1);
      +398         instance.process(dependency);
      +399         assertTrue(dependency.getVulnerabilities().isEmpty());
      +400         assertEquals(1, dependency.getSuppressedVulnerabilities().size());
      +401 
      +402         //cvss
      +403         dependency.addVulnerability(v);
      +404         instance = new SuppressionRule();
      +405         instance.addCvssBelow(5f);
      +406         instance.process(dependency);
      +407         assertEquals(1, dependency.getVulnerabilities().size());
      +408         instance.addCvssBelow(8f);
      +409         instance.process(dependency);
      +410         assertTrue(dependency.getVulnerabilities().isEmpty());
      +411         assertEquals(1, dependency.getSuppressedVulnerabilities().size());
      +412 
      +413         //cve
      +414         dependency.addVulnerability(v);
      +415         instance = new SuppressionRule();
      +416         instance.addCve("CVE-2012-1337");
      +417         instance.process(dependency);
      +418         assertEquals(1, dependency.getVulnerabilities().size());
      +419         instance.addCve("CVE-2013-1337");
      +420         instance.process(dependency);
      +421         assertTrue(dependency.getVulnerabilities().isEmpty());
      +422         assertEquals(1, dependency.getSuppressedVulnerabilities().size());
      +423 
      +424         //cpe
      +425         instance = new SuppressionRule();
      +426         PropertyType pt = new PropertyType();
      +427         pt.setValue("cpe:/a:microsoft:.net_framework:4.0");
      +428         instance.addCpe(pt);
      +429         instance.process(dependency);
      +430         assertTrue(dependency.getIdentifiers().size() == 1);
      +431         pt = new PropertyType();
      +432         pt.setValue("cpe:/a:microsoft:.net_framework:4.5");
      +433         instance.addCpe(pt);
      +434         pt = new PropertyType();
      +435         pt.setValue(".*");
      +436         pt.setRegex(true);
      +437         instance.setFilePath(pt);
      +438         instance.process(dependency);
      +439         assertTrue(dependency.getIdentifiers().isEmpty());
      +440         assertEquals(1, dependency.getSuppressedIdentifiers().size());
      +441 
      +442         instance = new SuppressionRule();
      +443         dependency.addIdentifier("cpe", "cpe:/a:microsoft:.net_framework:4.0", "some url not needed for this test");
      +444         dependency.addIdentifier("cpe", "cpe:/a:microsoft:.net_framework:4.5", "some url not needed for this test");
      +445         dependency.addIdentifier("cpe", "cpe:/a:microsoft:.net_framework:5.0", "some url not needed for this test");
      +446         pt = new PropertyType();
      +447         pt.setValue("cpe:/a:microsoft:.net_framework");
      +448         instance.addCpe(pt);
      +449         instance.setBase(true);
      +450         assertEquals(3, dependency.getIdentifiers().size());
      +451         assertEquals(1, dependency.getSuppressedIdentifiers().size());
      +452         instance.process(dependency);
      +453         assertTrue(dependency.getIdentifiers().isEmpty());
      +454         assertEquals(1, dependency.getSuppressedIdentifiers().size());
      +455     }
      +456 
      +457     /**
      +458      * Test of process method, of class SuppressionRule.
      +459      */
      +460     @Test
      +461     public void testProcessGAV() {
      +462         //File spring = new File(this.getClass().getClassLoader().getResource("spring-security-web-3.0.0.RELEASE.jar").getPath());
      +463         File spring = BaseTest.getResourceAsFile(this, "spring-security-web-3.0.0.RELEASE.jar");
      +464         Dependency dependency = new Dependency(spring);
      +465         dependency.addIdentifier("cpe", "cpe:/a:vmware:springsource_spring_framework:3.0.0", "some url not needed for this test");
      +466         dependency.addIdentifier("cpe", "cpe:/a:springsource:spring_framework:3.0.0", "some url not needed for this test");
      +467         dependency.addIdentifier("cpe", "cpe:/a:mod_security:mod_security:3.0.0", "some url not needed for this test");
      +468         dependency.addIdentifier("cpe", "cpe:/a:vmware:springsource_spring_security:3.0.0", "some url not needed for this test");
      +469         dependency.addIdentifier("maven", "org.springframework.security:spring-security-web:3.0.0.RELEASE", "some url not needed for this test");
      +470 
      +471         //cpe
      +472         SuppressionRule instance = new SuppressionRule();
      +473         PropertyType pt = new PropertyType();
      +474 
      +475         pt.setValue("org\\.springframework\\.security:spring.*");
      +476         pt.setRegex(true);
      +477         pt.setCaseSensitive(false);
      +478         instance.setGav(pt);
      +479 
      +480         pt = new PropertyType();
      +481         pt.setValue("cpe:/a:mod_security:mod_security");
      +482         instance.addCpe(pt);
      +483         pt = new PropertyType();
      +484         pt.setValue("cpe:/a:springsource:spring_framework");
      +485         instance.addCpe(pt);
      +486         pt = new PropertyType();
      +487         pt.setValue("cpe:/a:vmware:springsource_spring_framework");
      +488         instance.addCpe(pt);
      +489 
      +490         instance.process(dependency);
      +491         assertEquals(2, dependency.getIdentifiers().size());
      +492 
      +493     }
      +494 
      +495     private Vulnerability createVulnerability() {
      +496         Vulnerability v = new Vulnerability();
      +497         v.setCwe("CWE-287 Improper Authentication");
      +498         v.setName("CVE-2013-1337");
      +499         v.setCvssScore(7.5f);
      +500         return v;
      +501     }
      +502 }
      +
      +
      + + + diff --git a/xref-test/org/owasp/dependencycheck/xml/suppression/package-frame.html b/xref-test/org/owasp/dependencycheck/xml/suppression/package-frame.html new file mode 100644 index 000000000..14dc21be0 --- /dev/null +++ b/xref-test/org/owasp/dependencycheck/xml/suppression/package-frame.html @@ -0,0 +1,33 @@ + + + + + + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.xml.suppression + + + + +

      + org.owasp.dependencycheck.xml.suppression +

      + +

      Classes

      + + + + + \ No newline at end of file diff --git a/xref-test/org/owasp/dependencycheck/xml/suppression/package-summary.html b/xref-test/org/owasp/dependencycheck/xml/suppression/package-summary.html new file mode 100644 index 000000000..3159a7f72 --- /dev/null +++ b/xref-test/org/owasp/dependencycheck/xml/suppression/package-summary.html @@ -0,0 +1,84 @@ + + + + + + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.xml.suppression + + + +
      + +
      +
      + +
      + +

      Package org.owasp.dependencycheck.xml.suppression

      + + + + + + + + + + + + + + + + + + + + + +
      Class Summary
      + PropertyTypeTest +
      + SuppressionHandlerTest +
      + SuppressionParserTest +
      + SuppressionRuleTest +
      + +
      + +
      +
      + +
      +
      + + + \ No newline at end of file diff --git a/xref-test/overview-frame.html b/xref-test/overview-frame.html index 96a7f5790..28ecf9fe3 100644 --- a/xref-test/overview-frame.html +++ b/xref-test/overview-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference + Dependency-Check 1.4.2 Reference @@ -59,18 +59,21 @@
    490. org.owasp.dependencycheck.reporting -
    491. -
    492. - org.owasp.dependencycheck.suppression
    493. org.owasp.dependencycheck.taskdefs
    494. org.owasp.dependencycheck.utils +
    495. +
    496. + org.owasp.dependencycheck.xml.hints
    497. org.owasp.dependencycheck.xml.pom +
    498. +
    499. + org.owasp.dependencycheck.xml.suppression
    500. diff --git a/xref-test/overview-summary.html b/xref-test/overview-summary.html index a2c5bcb63..1fc69ec90 100644 --- a/xref-test/overview-summary.html +++ b/xref-test/overview-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference + Dependency-Check 1.4.2 Reference @@ -24,7 +24,7 @@ -

      Dependency-Check 1.4.0 Reference

      +

      Dependency-Check 1.4.2 Reference

      @@ -107,11 +107,6 @@ - - - + + + + + +
      org.owasp.dependencycheck.reporting
      - org.owasp.dependencycheck.suppression -
      @@ -122,11 +117,21 @@ org.owasp.dependencycheck.utils
      + org.owasp.dependencycheck.xml.hints +
      org.owasp.dependencycheck.xml.pom
      + org.owasp.dependencycheck.xml.suppression +
      diff --git a/xref/allclasses-frame.html b/xref/allclasses-frame.html index 87b281e17..25644da9f 100644 --- a/xref/allclasses-frame.html +++ b/xref/allclasses-frame.html @@ -198,7 +198,7 @@ Element
    501. - Engine + Engine
    502. EngineVersionCheck @@ -211,6 +211,9 @@
    503. EvidenceCollection +
    504. +
    505. + ExceptionCollection
    506. ExpectedOjectInputStream @@ -256,6 +259,24 @@
    507. HintAnalyzer +
    508. +
    509. + HintErrorHandler +
    510. +
    511. + HintHandler +
    512. +
    513. + HintParseException +
    514. +
    515. + HintParser +
    516. +
    517. + HintRule +
    518. +
    519. + Hints
    520. Identifier @@ -271,6 +292,9 @@
    521. IndexException +
    522. +
    523. + InitializationException
    524. InvalidDataException @@ -295,6 +319,9 @@
    525. MavenArtifact +
    526. +
    527. + MavenEngine
    528. MavenLoggerAdapter @@ -369,7 +396,7 @@ PropertyLookup
    529. - PropertyType + PropertyType
    530. Purge @@ -385,6 +412,9 @@
    531. Reference +
    532. +
    533. + ReportException
    534. ReportFormats @@ -400,6 +430,9 @@
    535. RubyGemspecAnalyzer +
    536. +
    537. + SSLSocketFactoryEx
    538. ScanAgentException @@ -414,19 +447,19 @@ StaticLoggerBinder
    539. - SuppressionErrorHandler + SuppressionErrorHandler
    540. - SuppressionHandler + SuppressionHandler
    541. - SuppressionParseException + SuppressionParseException
    542. - SuppressionParser + SuppressionParser
    543. - SuppressionRule + SuppressionRule
    544. TokenPairConcatenatingFilter @@ -460,6 +493,9 @@
    545. VelocityLoggerRedirect +
    546. +
    547. + VendorDuplicatingHintRule
    548. Vulnerability diff --git a/xref/index.html b/xref/index.html index b14c5d0a6..e5cd82e24 100644 --- a/xref/index.html +++ b/xref/index.html @@ -4,7 +4,7 @@ - Dependency-Check 1.4.0 Reference + Dependency-Check 1.4.2 Reference diff --git a/xref/org/owasp/dependencycheck/App.html b/xref/org/owasp/dependencycheck/App.html index 89bed5d8a..216acd54d 100644 --- a/xref/org/owasp/dependencycheck/App.html +++ b/xref/org/owasp/dependencycheck/App.html @@ -45,411 +45,485 @@ 37 import org.slf4j.Logger; 38 import org.slf4j.LoggerFactory; 39 import ch.qos.logback.core.FileAppender; -40 import org.slf4j.impl.StaticLoggerBinder; -41 -42 /** -43 * The command line interface for the DependencyCheck application. -44 * -45 * @author Jeremy Long -46 */ -47 public class App { -48 -49 /** -50 * The logger. -51 */ -52 private static final Logger LOGGER = LoggerFactory.getLogger(App.class); -53 -54 /** -55 * The main method for the application. -56 * -57 * @param args the command line arguments -58 */ -59 public static void main(String[] args) { -60 try { -61 Settings.initialize(); -62 final App app = new App(); -63 app.run(args); -64 } finally { -65 Settings.cleanup(true); -66 } -67 } -68 -69 /** -70 * Main CLI entry-point into the application. -71 * -72 * @param args the command line arguments -73 */ -74 public void run(String[] args) { -75 final CliParser cli = new CliParser(); -76 -77 try { -78 cli.parse(args); -79 } catch (FileNotFoundException ex) { -80 System.err.println(ex.getMessage()); -81 cli.printHelp(); -82 return; -83 } catch (ParseException ex) { -84 System.err.println(ex.getMessage()); -85 cli.printHelp(); -86 return; -87 } -88 -89 if (cli.getVerboseLog() != null) { -90 prepareLogger(cli.getVerboseLog()); -91 } -92 -93 if (cli.isPurge()) { -94 if (cli.getConnectionString() != null) { -95 LOGGER.error("Unable to purge the database when using a non-default connection string"); -96 } else { -97 populateSettings(cli); -98 File db; -99 try { -100 db = new File(Settings.getDataDirectory(), "dc.h2.db"); -101 if (db.exists()) { -102 if (db.delete()) { -103 LOGGER.info("Database file purged; local copy of the NVD has been removed"); -104 } else { -105 LOGGER.error("Unable to delete '{}'; please delete the file manually", db.getAbsolutePath()); -106 } -107 } else { -108 LOGGER.error("Unable to purge database; the database file does not exists: {}", db.getAbsolutePath()); -109 } -110 } catch (IOException ex) { -111 LOGGER.error("Unable to delete the database"); -112 } -113 } -114 } else if (cli.isGetVersion()) { -115 cli.printVersionInfo(); -116 } else if (cli.isUpdateOnly()) { -117 populateSettings(cli); -118 runUpdateOnly(); -119 } else if (cli.isRunScan()) { -120 populateSettings(cli); -121 try { -122 runScan(cli.getReportDirectory(), cli.getReportFormat(), cli.getProjectName(), cli.getScanFiles(), -123 cli.getExcludeList(), cli.getSymLinkDepth()); -124 } catch (InvalidScanPathException ex) { -125 LOGGER.error("An invalid scan path was detected; unable to scan '//*' paths"); -126 } -127 } else { -128 cli.printHelp(); -129 } -130 } -131 -132 /** -133 * Scans the specified directories and writes the dependency reports to the reportDirectory. -134 * -135 * @param reportDirectory the path to the directory where the reports will be written -136 * @param outputFormat the output format of the report -137 * @param applicationName the application name for the report -138 * @param files the files/directories to scan -139 * @param excludes the patterns for files/directories to exclude -140 * @param symLinkDepth the depth that symbolic links will be followed -141 * -142 * @throws InvalidScanPathException thrown if the path to scan starts with "//" -143 */ -144 private void runScan(String reportDirectory, String outputFormat, String applicationName, String[] files, -145 String[] excludes, int symLinkDepth) throws InvalidScanPathException { -146 Engine engine = null; -147 try { -148 engine = new Engine(); -149 final List<String> antStylePaths = new ArrayList<String>(); -150 for (String file : files) { -151 final String antPath = ensureCanonicalPath(file); -152 antStylePaths.add(antPath); -153 } -154 -155 final Set<File> paths = new HashSet<File>(); -156 for (String file : antStylePaths) { -157 LOGGER.debug("Scanning {}", file); -158 final DirectoryScanner scanner = new DirectoryScanner(); -159 String include = file.replace('\\', '/'); -160 File baseDir; -161 -162 if (include.startsWith("//")) { -163 throw new InvalidScanPathException("Unable to scan paths specified by //"); -164 } else { -165 final int pos = getLastFileSeparator(include); -166 final String tmpBase = include.substring(0, pos); -167 final String tmpInclude = include.substring(pos + 1); -168 if (tmpInclude.indexOf('*') >= 0 || tmpInclude.indexOf('?') >= 0 -169 || (new File(include)).isFile()) { -170 baseDir = new File(tmpBase); -171 include = tmpInclude; -172 } else { -173 baseDir = new File(tmpBase, tmpInclude); -174 include = "**/*"; -175 } -176 } -177 //LOGGER.debug("baseDir: {}", baseDir); -178 //LOGGER.debug("include: {}", include); -179 scanner.setBasedir(baseDir); -180 final String[] includes = {include}; -181 scanner.setIncludes(includes); -182 scanner.setMaxLevelsOfSymlinks(symLinkDepth); -183 if (symLinkDepth <= 0) { -184 scanner.setFollowSymlinks(false); -185 } -186 if (excludes != null && excludes.length > 0) { -187 scanner.addExcludes(excludes); -188 } -189 scanner.scan(); -190 if (scanner.getIncludedFilesCount() > 0) { -191 for (String s : scanner.getIncludedFiles()) { -192 final File f = new File(baseDir, s); -193 LOGGER.debug("Found file {}", f.toString()); -194 paths.add(f); -195 } -196 } -197 } -198 engine.scan(paths); -199 -200 engine.analyzeDependencies(); -201 final List<Dependency> dependencies = engine.getDependencies(); -202 DatabaseProperties prop = null; -203 CveDB cve = null; -204 try { -205 cve = new CveDB(); -206 cve.open(); -207 prop = cve.getDatabaseProperties(); -208 } catch (DatabaseException ex) { -209 LOGGER.debug("Unable to retrieve DB Properties", ex); -210 } finally { -211 if (cve != null) { -212 cve.close(); -213 } -214 } -215 final ReportGenerator report = new ReportGenerator(applicationName, dependencies, engine.getAnalyzers(), prop); -216 try { -217 report.generateReports(reportDirectory, outputFormat); -218 } catch (IOException ex) { -219 LOGGER.error("There was an IO error while attempting to generate the report."); -220 LOGGER.debug("", ex); -221 } catch (Throwable ex) { -222 LOGGER.error("There was an error while attempting to generate the report."); -223 LOGGER.debug("", ex); -224 } -225 } catch (DatabaseException ex) { -226 LOGGER.error("Unable to connect to the dependency-check database; analysis has stopped"); -227 LOGGER.debug("", ex); -228 } finally { -229 if (engine != null) { -230 engine.cleanup(); -231 } -232 } -233 } -234 -235 /** -236 * Only executes the update phase of dependency-check. -237 */ -238 private void runUpdateOnly() { -239 Engine engine = null; -240 try { -241 engine = new Engine(); -242 engine.doUpdates(); -243 } catch (DatabaseException ex) { -244 LOGGER.error("Unable to connect to the dependency-check database; analysis has stopped"); -245 LOGGER.debug("", ex); -246 } finally { -247 if (engine != null) { -248 engine.cleanup(); -249 } -250 } -251 } -252 -253 /** -254 * Updates the global Settings. -255 * -256 * @param cli a reference to the CLI Parser that contains the command line arguments used to set the corresponding settings in -257 * the core engine. -258 */ -259 private void populateSettings(CliParser cli) { -260 -261 final boolean autoUpdate = cli.isAutoUpdate(); -262 final String connectionTimeout = cli.getConnectionTimeout(); -263 final String proxyServer = cli.getProxyServer(); -264 final String proxyPort = cli.getProxyPort(); -265 final String proxyUser = cli.getProxyUsername(); -266 final String proxyPass = cli.getProxyPassword(); -267 final String dataDirectory = cli.getDataDirectory(); -268 final File propertiesFile = cli.getPropertiesFile(); -269 final String suppressionFile = cli.getSuppressionFile(); -270 final String nexusUrl = cli.getNexusUrl(); -271 final String databaseDriverName = cli.getDatabaseDriverName(); -272 final String databaseDriverPath = cli.getDatabaseDriverPath(); -273 final String connectionString = cli.getConnectionString(); -274 final String databaseUser = cli.getDatabaseUser(); -275 final String databasePassword = cli.getDatabasePassword(); -276 final String additionalZipExtensions = cli.getAdditionalZipExtensions(); -277 final String pathToMono = cli.getPathToMono(); -278 final String cveMod12 = cli.getModifiedCve12Url(); -279 final String cveMod20 = cli.getModifiedCve20Url(); -280 final String cveBase12 = cli.getBaseCve12Url(); -281 final String cveBase20 = cli.getBaseCve20Url(); -282 final Integer cveValidForHours = cli.getCveValidForHours(); -283 final boolean experimentalEnabled = cli.isExperimentalEnabled(); -284 -285 if (propertiesFile != null) { +40 import org.owasp.dependencycheck.data.update.exception.UpdateException; +41 import org.owasp.dependencycheck.exception.ExceptionCollection; +42 import org.owasp.dependencycheck.exception.ReportException; +43 import org.owasp.dependencycheck.utils.InvalidSettingException; +44 import org.slf4j.impl.StaticLoggerBinder; +45 +46 /** +47 * The command line interface for the DependencyCheck application. +48 * +49 * @author Jeremy Long +50 */ +51 public class App { +52 +53 /** +54 * The logger. +55 */ +56 private static final Logger LOGGER = LoggerFactory.getLogger(App.class); +57 +58 /** +59 * The main method for the application. +60 * +61 * @param args the command line arguments +62 */ +63 public static void main(String[] args) { +64 int exitCode = 0; +65 try { +66 Settings.initialize(); +67 final App app = new App(); +68 exitCode = app.run(args); +69 LOGGER.debug("Exit code: " + exitCode); +70 } finally { +71 Settings.cleanup(true); +72 } +73 System.exit(exitCode); +74 } +75 +76 /** +77 * Main CLI entry-point into the application. +78 * +79 * @param args the command line arguments +80 * @return the exit code to return +81 */ +82 public int run(String[] args) { +83 int exitCode = 0; +84 final CliParser cli = new CliParser(); +85 +86 try { +87 cli.parse(args); +88 } catch (FileNotFoundException ex) { +89 System.err.println(ex.getMessage()); +90 cli.printHelp(); +91 return -1; +92 } catch (ParseException ex) { +93 System.err.println(ex.getMessage()); +94 cli.printHelp(); +95 return -2; +96 } +97 +98 if (cli.getVerboseLog() != null) { +99 prepareLogger(cli.getVerboseLog()); +100 } +101 +102 if (cli.isPurge()) { +103 if (cli.getConnectionString() != null) { +104 LOGGER.error("Unable to purge the database when using a non-default connection string"); +105 exitCode = -3; +106 } else { +107 try { +108 populateSettings(cli); +109 } catch (InvalidSettingException ex) { +110 LOGGER.error(ex.getMessage()); +111 LOGGER.debug("Error loading properties file", ex); +112 exitCode = -4; +113 } +114 File db; +115 try { +116 db = new File(Settings.getDataDirectory(), "dc.h2.db"); +117 if (db.exists()) { +118 if (db.delete()) { +119 LOGGER.info("Database file purged; local copy of the NVD has been removed"); +120 } else { +121 LOGGER.error("Unable to delete '{}'; please delete the file manually", db.getAbsolutePath()); +122 exitCode = -5; +123 } +124 } else { +125 LOGGER.error("Unable to purge database; the database file does not exists: {}", db.getAbsolutePath()); +126 exitCode = -6; +127 } +128 } catch (IOException ex) { +129 LOGGER.error("Unable to delete the database"); +130 exitCode = -7; +131 } +132 } +133 } else if (cli.isGetVersion()) { +134 cli.printVersionInfo(); +135 } else if (cli.isUpdateOnly()) { +136 try { +137 populateSettings(cli); +138 } catch (InvalidSettingException ex) { +139 LOGGER.error(ex.getMessage()); +140 LOGGER.debug("Error loading properties file", ex); +141 exitCode = -4; +142 } +143 try { +144 runUpdateOnly(); +145 } catch (UpdateException ex) { +146 LOGGER.error(ex.getMessage()); +147 exitCode = -8; +148 } catch (DatabaseException ex) { +149 LOGGER.error(ex.getMessage()); +150 exitCode = -9; +151 } +152 } else if (cli.isRunScan()) { +153 try { +154 populateSettings(cli); +155 } catch (InvalidSettingException ex) { +156 LOGGER.error(ex.getMessage()); +157 LOGGER.debug("Error loading properties file", ex); +158 exitCode = -4; +159 } +160 try { +161 runScan(cli.getReportDirectory(), cli.getReportFormat(), cli.getProjectName(), cli.getScanFiles(), +162 cli.getExcludeList(), cli.getSymLinkDepth()); +163 } catch (InvalidScanPathException ex) { +164 LOGGER.error("An invalid scan path was detected; unable to scan '//*' paths"); +165 exitCode = -10; +166 } catch (DatabaseException ex) { +167 LOGGER.error(ex.getMessage()); +168 exitCode = -11; +169 } catch (ReportException ex) { +170 LOGGER.error(ex.getMessage()); +171 exitCode = -12; +172 } catch (ExceptionCollection ex) { +173 if (ex.isFatal()) { +174 exitCode = -13; +175 LOGGER.error("One or more fatal errors occured"); +176 } else { +177 exitCode = -14; +178 } +179 for (Throwable e : ex.getExceptions()) { +180 LOGGER.error(e.getMessage()); +181 } +182 } +183 } else { +184 cli.printHelp(); +185 } +186 return exitCode; +187 } +188 +189 /** +190 * Scans the specified directories and writes the dependency reports to the +191 * reportDirectory. +192 * +193 * @param reportDirectory the path to the directory where the reports will +194 * be written +195 * @param outputFormat the output format of the report +196 * @param applicationName the application name for the report +197 * @param files the files/directories to scan +198 * @param excludes the patterns for files/directories to exclude +199 * @param symLinkDepth the depth that symbolic links will be followed +200 * +201 * @throws InvalidScanPathException thrown if the path to scan starts with +202 * "//" +203 * @throws ReportException thrown when the report cannot be generated +204 * @throws DatabaseException thrown when there is an error connecting to the +205 * database +206 * @throws ExceptionCollection thrown when an exception occurs during +207 * analysis; there may be multiple exceptions contained within the +208 * collection. +209 */ +210 private void runScan(String reportDirectory, String outputFormat, String applicationName, String[] files, +211 String[] excludes, int symLinkDepth) throws InvalidScanPathException, DatabaseException, ExceptionCollection, ReportException { +212 Engine engine = null; +213 try { +214 engine = new Engine(); +215 final List<String> antStylePaths = new ArrayList<String>(); +216 for (String file : files) { +217 final String antPath = ensureCanonicalPath(file); +218 antStylePaths.add(antPath); +219 } +220 +221 final Set<File> paths = new HashSet<File>(); +222 for (String file : antStylePaths) { +223 LOGGER.debug("Scanning {}", file); +224 final DirectoryScanner scanner = new DirectoryScanner(); +225 String include = file.replace('\\', '/'); +226 File baseDir; +227 +228 if (include.startsWith("//")) { +229 throw new InvalidScanPathException("Unable to scan paths specified by //"); +230 } else { +231 final int pos = getLastFileSeparator(include); +232 final String tmpBase = include.substring(0, pos); +233 final String tmpInclude = include.substring(pos + 1); +234 if (tmpInclude.indexOf('*') >= 0 || tmpInclude.indexOf('?') >= 0 +235 || (new File(include)).isFile()) { +236 baseDir = new File(tmpBase); +237 include = tmpInclude; +238 } else { +239 baseDir = new File(tmpBase, tmpInclude); +240 include = "**/*"; +241 } +242 } +243 scanner.setBasedir(baseDir); +244 final String[] includes = {include}; +245 scanner.setIncludes(includes); +246 scanner.setMaxLevelsOfSymlinks(symLinkDepth); +247 if (symLinkDepth <= 0) { +248 scanner.setFollowSymlinks(false); +249 } +250 if (excludes != null && excludes.length > 0) { +251 scanner.addExcludes(excludes); +252 } +253 scanner.scan(); +254 if (scanner.getIncludedFilesCount() > 0) { +255 for (String s : scanner.getIncludedFiles()) { +256 final File f = new File(baseDir, s); +257 LOGGER.debug("Found file {}", f.toString()); +258 paths.add(f); +259 } +260 } +261 } +262 engine.scan(paths); +263 +264 ExceptionCollection exCol = null; +265 try { +266 engine.analyzeDependencies(); +267 } catch (ExceptionCollection ex) { +268 if (ex.isFatal()) { +269 throw ex; +270 } +271 exCol = ex; +272 } +273 final List<Dependency> dependencies = engine.getDependencies(); +274 DatabaseProperties prop = null; +275 CveDB cve = null; +276 try { +277 cve = new CveDB(); +278 cve.open(); +279 prop = cve.getDatabaseProperties(); +280 } finally { +281 if (cve != null) { +282 cve.close(); +283 } +284 } +285 final ReportGenerator report = new ReportGenerator(applicationName, dependencies, engine.getAnalyzers(), prop); 286 try { -287 Settings.mergeProperties(propertiesFile); -288 } catch (FileNotFoundException ex) { -289 LOGGER.error("Unable to load properties file '{}'", propertiesFile.getPath()); -290 LOGGER.debug("", ex); -291 } catch (IOException ex) { -292 LOGGER.error("Unable to find properties file '{}'", propertiesFile.getPath()); -293 LOGGER.debug("", ex); -294 } -295 } -296 // We have to wait until we've merged the properties before attempting to set whether we use -297 // the proxy for Nexus since it could be disabled in the properties, but not explicitly stated -298 // on the command line -299 final boolean nexusUsesProxy = cli.isNexusUsesProxy(); -300 if (dataDirectory != null) { -301 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory); -302 } else if (System.getProperty("basedir") != null) { -303 final File dataDir = new File(System.getProperty("basedir"), "data"); -304 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath()); -305 } else { -306 final File jarPath = new File(App.class.getProtectionDomain().getCodeSource().getLocation().getPath()); -307 final File base = jarPath.getParentFile(); -308 final String sub = Settings.getString(Settings.KEYS.DATA_DIRECTORY); -309 final File dataDir = new File(base, sub); -310 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath()); -311 } -312 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate); -313 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_SERVER, proxyServer); -314 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PORT, proxyPort); -315 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_USERNAME, proxyUser); -316 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PASSWORD, proxyPass); -317 Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout); -318 Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile); -319 Settings.setIntIfNotNull(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, cveValidForHours); -320 -321 //File Type Analyzer Settings -322 Settings.setBoolean(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, experimentalEnabled); -323 Settings.setBoolean(Settings.KEYS.ANALYZER_JAR_ENABLED, !cli.isJarDisabled()); -324 Settings.setBoolean(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, !cli.isArchiveDisabled()); -325 Settings.setBoolean(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, !cli.isPythonDistributionDisabled()); -326 Settings.setBoolean(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, !cli.isPythonPackageDisabled()); -327 Settings.setBoolean(Settings.KEYS.ANALYZER_AUTOCONF_ENABLED, !cli.isAutoconfDisabled()); -328 Settings.setBoolean(Settings.KEYS.ANALYZER_CMAKE_ENABLED, !cli.isCmakeDisabled()); -329 Settings.setBoolean(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, !cli.isNuspecDisabled()); -330 Settings.setBoolean(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, !cli.isAssemblyDisabled()); -331 Settings.setBoolean(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_ENABLED, !cli.isBundleAuditDisabled()); -332 Settings.setBoolean(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, !cli.isOpenSSLDisabled()); -333 Settings.setBoolean(Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED, !cli.isComposerDisabled()); -334 Settings.setBoolean(Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED, !cli.isNodeJsDisabled()); -335 Settings.setBoolean(Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED, !cli.isRubyGemspecDisabled()); -336 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, !cli.isCentralDisabled()); -337 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, !cli.isNexusDisabled()); -338 -339 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH, cli.getPathToBundleAudit()); -340 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl); -341 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy); -342 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName); -343 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath); -344 Settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString); -345 Settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser); -346 Settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword); -347 Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, additionalZipExtensions); -348 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono); -349 if (cveBase12 != null && !cveBase12.isEmpty()) { -350 Settings.setString(Settings.KEYS.CVE_SCHEMA_1_2, cveBase12); -351 Settings.setString(Settings.KEYS.CVE_SCHEMA_2_0, cveBase20); -352 Settings.setString(Settings.KEYS.CVE_MODIFIED_12_URL, cveMod12); -353 Settings.setString(Settings.KEYS.CVE_MODIFIED_20_URL, cveMod20); -354 } -355 } -356 -357 /** -358 * Creates a file appender and adds it to logback. -359 * -360 * @param verboseLog the path to the verbose log file -361 */ -362 private void prepareLogger(String verboseLog) { -363 final StaticLoggerBinder loggerBinder = StaticLoggerBinder.getSingleton(); -364 final LoggerContext context = (LoggerContext) loggerBinder.getLoggerFactory(); -365 -366 final PatternLayoutEncoder encoder = new PatternLayoutEncoder(); -367 encoder.setPattern("%d %C:%L%n%-5level - %msg%n"); -368 encoder.setContext(context); -369 encoder.start(); -370 final FileAppender fa = new FileAppender(); -371 fa.setAppend(true); -372 fa.setEncoder(encoder); -373 fa.setContext(context); -374 fa.setFile(verboseLog); -375 final File f = new File(verboseLog); -376 String name = f.getName(); -377 final int i = name.lastIndexOf('.'); -378 if (i > 1) { -379 name = name.substring(0, i); -380 } -381 fa.setName(name); -382 fa.start(); -383 final ch.qos.logback.classic.Logger rootLogger = context.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME); -384 rootLogger.addAppender(fa); -385 } -386 -387 /** -388 * Takes a path and resolves it to be a canonical &amp; absolute path. The caveats are that this method will take an Ant style -389 * file selector path (../someDir/**\/*.jar) and convert it to an absolute/canonical path (at least to the left of the first * -390 * or ?). -391 * -392 * @param path the path to canonicalize -393 * @return the canonical path -394 */ -395 protected String ensureCanonicalPath(String path) { -396 String basePath = null; -397 String wildCards = null; -398 final String file = path.replace('\\', '/'); -399 if (file.contains("*") || file.contains("?")) { -400 -401 int pos = getLastFileSeparator(file); -402 if (pos < 0) { -403 return file; -404 } -405 pos += 1; -406 basePath = file.substring(0, pos); -407 wildCards = file.substring(pos); -408 } else { -409 basePath = file; -410 } +287 report.generateReports(reportDirectory, outputFormat); +288 } catch (ReportException ex) { +289 if (exCol != null) { +290 exCol.addException(ex); +291 throw exCol; +292 } else { +293 throw ex; +294 } +295 } +296 if (exCol != null && exCol.getExceptions().size()>0) { +297 throw exCol; +298 } +299 } finally { +300 if (engine != null) { +301 engine.cleanup(); +302 } +303 } +304 +305 } +306 +307 /** +308 * Only executes the update phase of dependency-check. +309 * +310 * @throws UpdateException thrown if there is an error updating +311 * @throws DatabaseException thrown if a fatal error occurred and a +312 * connection to the database could not be established +313 */ +314 private void runUpdateOnly() throws UpdateException, DatabaseException { +315 Engine engine = null; +316 try { +317 engine = new Engine(); +318 engine.doUpdates(); +319 } finally { +320 if (engine != null) { +321 engine.cleanup(); +322 } +323 } +324 } +325 +326 /** +327 * Updates the global Settings. +328 * +329 * @param cli a reference to the CLI Parser that contains the command line +330 * arguments used to set the corresponding settings in the core engine. +331 * +332 * @throws InvalidSettingException thrown when a user defined properties +333 * file is unable to be loaded. +334 */ +335 private void populateSettings(CliParser cli) throws InvalidSettingException { +336 final boolean autoUpdate = cli.isAutoUpdate(); +337 final String connectionTimeout = cli.getConnectionTimeout(); +338 final String proxyServer = cli.getProxyServer(); +339 final String proxyPort = cli.getProxyPort(); +340 final String proxyUser = cli.getProxyUsername(); +341 final String proxyPass = cli.getProxyPassword(); +342 final String dataDirectory = cli.getDataDirectory(); +343 final File propertiesFile = cli.getPropertiesFile(); +344 final String suppressionFile = cli.getSuppressionFile(); +345 final String nexusUrl = cli.getNexusUrl(); +346 final String databaseDriverName = cli.getDatabaseDriverName(); +347 final String databaseDriverPath = cli.getDatabaseDriverPath(); +348 final String connectionString = cli.getConnectionString(); +349 final String databaseUser = cli.getDatabaseUser(); +350 final String databasePassword = cli.getDatabasePassword(); +351 final String additionalZipExtensions = cli.getAdditionalZipExtensions(); +352 final String pathToMono = cli.getPathToMono(); +353 final String cveMod12 = cli.getModifiedCve12Url(); +354 final String cveMod20 = cli.getModifiedCve20Url(); +355 final String cveBase12 = cli.getBaseCve12Url(); +356 final String cveBase20 = cli.getBaseCve20Url(); +357 final Integer cveValidForHours = cli.getCveValidForHours(); +358 final boolean experimentalEnabled = cli.isExperimentalEnabled(); +359 +360 if (propertiesFile != null) { +361 try { +362 Settings.mergeProperties(propertiesFile); +363 } catch (FileNotFoundException ex) { +364 throw new InvalidSettingException("Unable to find properties file '" + propertiesFile.getPath() + "'", ex); +365 } catch (IOException ex) { +366 throw new InvalidSettingException("Error reading properties file '" + propertiesFile.getPath() + "'", ex); +367 } +368 } +369 // We have to wait until we've merged the properties before attempting to set whether we use +370 // the proxy for Nexus since it could be disabled in the properties, but not explicitly stated +371 // on the command line +372 final boolean nexusUsesProxy = cli.isNexusUsesProxy(); +373 if (dataDirectory != null) { +374 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory); +375 } else if (System.getProperty("basedir") != null) { +376 final File dataDir = new File(System.getProperty("basedir"), "data"); +377 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath()); +378 } else { +379 final File jarPath = new File(App.class.getProtectionDomain().getCodeSource().getLocation().getPath()); +380 final File base = jarPath.getParentFile(); +381 final String sub = Settings.getString(Settings.KEYS.DATA_DIRECTORY); +382 final File dataDir = new File(base, sub); +383 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath()); +384 } +385 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate); +386 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_SERVER, proxyServer); +387 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PORT, proxyPort); +388 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_USERNAME, proxyUser); +389 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PASSWORD, proxyPass); +390 Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout); +391 Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile); +392 Settings.setIntIfNotNull(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, cveValidForHours); +393 +394 //File Type Analyzer Settings +395 Settings.setBoolean(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, experimentalEnabled); +396 Settings.setBoolean(Settings.KEYS.ANALYZER_JAR_ENABLED, !cli.isJarDisabled()); +397 Settings.setBoolean(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, !cli.isArchiveDisabled()); +398 Settings.setBoolean(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, !cli.isPythonDistributionDisabled()); +399 Settings.setBoolean(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, !cli.isPythonPackageDisabled()); +400 Settings.setBoolean(Settings.KEYS.ANALYZER_AUTOCONF_ENABLED, !cli.isAutoconfDisabled()); +401 Settings.setBoolean(Settings.KEYS.ANALYZER_CMAKE_ENABLED, !cli.isCmakeDisabled()); +402 Settings.setBoolean(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, !cli.isNuspecDisabled()); +403 Settings.setBoolean(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, !cli.isAssemblyDisabled()); +404 Settings.setBoolean(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_ENABLED, !cli.isBundleAuditDisabled()); +405 Settings.setBoolean(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, !cli.isOpenSSLDisabled()); +406 Settings.setBoolean(Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED, !cli.isComposerDisabled()); +407 Settings.setBoolean(Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED, !cli.isNodeJsDisabled()); +408 Settings.setBoolean(Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED, !cli.isRubyGemspecDisabled()); +409 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, !cli.isCentralDisabled()); +410 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, !cli.isNexusDisabled()); 411 -412 File f = new File(basePath); -413 try { -414 f = f.getCanonicalFile(); -415 if (wildCards != null) { -416 f = new File(f, wildCards); -417 } -418 } catch (IOException ex) { -419 LOGGER.warn("Invalid path '{}' was provided.", path); -420 LOGGER.debug("Invalid path provided", ex); -421 } -422 return f.getAbsolutePath().replace('\\', '/'); -423 } -424 -425 /** -426 * Returns the position of the last file separator. -427 * -428 * @param file a file path -429 * @return the position of the last file separator -430 */ -431 private int getLastFileSeparator(String file) { -432 if (file.contains("*") || file.contains("?")) { -433 int p1 = file.indexOf('*'); -434 int p2 = file.indexOf('?'); -435 p1 = p1 > 0 ? p1 : file.length(); -436 p2 = p2 > 0 ? p2 : file.length(); -437 int pos = p1 < p2 ? p1 : p2; -438 pos = file.lastIndexOf('/', pos); -439 return pos; -440 } else { -441 return file.lastIndexOf('/'); -442 } -443 } -444 } +412 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH, cli.getPathToBundleAudit()); +413 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl); +414 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy); +415 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName); +416 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath); +417 Settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString); +418 Settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser); +419 Settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword); +420 Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, additionalZipExtensions); +421 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono); +422 if (cveBase12 != null && !cveBase12.isEmpty()) { +423 Settings.setString(Settings.KEYS.CVE_SCHEMA_1_2, cveBase12); +424 Settings.setString(Settings.KEYS.CVE_SCHEMA_2_0, cveBase20); +425 Settings.setString(Settings.KEYS.CVE_MODIFIED_12_URL, cveMod12); +426 Settings.setString(Settings.KEYS.CVE_MODIFIED_20_URL, cveMod20); +427 } +428 } +429 +430 /** +431 * Creates a file appender and adds it to logback. +432 * +433 * @param verboseLog the path to the verbose log file +434 */ +435 private void prepareLogger(String verboseLog) { +436 final StaticLoggerBinder loggerBinder = StaticLoggerBinder.getSingleton(); +437 final LoggerContext context = (LoggerContext) loggerBinder.getLoggerFactory(); +438 +439 final PatternLayoutEncoder encoder = new PatternLayoutEncoder(); +440 encoder.setPattern("%d %C:%L%n%-5level - %msg%n"); +441 encoder.setContext(context); +442 encoder.start(); +443 final FileAppender fa = new FileAppender(); +444 fa.setAppend(true); +445 fa.setEncoder(encoder); +446 fa.setContext(context); +447 fa.setFile(verboseLog); +448 final File f = new File(verboseLog); +449 String name = f.getName(); +450 final int i = name.lastIndexOf('.'); +451 if (i > 1) { +452 name = name.substring(0, i); +453 } +454 fa.setName(name); +455 fa.start(); +456 final ch.qos.logback.classic.Logger rootLogger = context.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME); +457 rootLogger.addAppender(fa); +458 } +459 +460 /** +461 * Takes a path and resolves it to be a canonical &amp; absolute path. The +462 * caveats are that this method will take an Ant style file selector path +463 * (../someDir/**\/*.jar) and convert it to an absolute/canonical path (at +464 * least to the left of the first * or ?). +465 * +466 * @param path the path to canonicalize +467 * @return the canonical path +468 */ +469 protected String ensureCanonicalPath(String path) { +470 String basePath; +471 String wildCards = null; +472 final String file = path.replace('\\', '/'); +473 if (file.contains("*") || file.contains("?")) { +474 +475 int pos = getLastFileSeparator(file); +476 if (pos < 0) { +477 return file; +478 } +479 pos += 1; +480 basePath = file.substring(0, pos); +481 wildCards = file.substring(pos); +482 } else { +483 basePath = file; +484 } +485 +486 File f = new File(basePath); +487 try { +488 f = f.getCanonicalFile(); +489 if (wildCards != null) { +490 f = new File(f, wildCards); +491 } +492 } catch (IOException ex) { +493 LOGGER.warn("Invalid path '{}' was provided.", path); +494 LOGGER.debug("Invalid path provided", ex); +495 } +496 return f.getAbsolutePath().replace('\\', '/'); +497 } +498 +499 /** +500 * Returns the position of the last file separator. +501 * +502 * @param file a file path +503 * @return the position of the last file separator +504 */ +505 private int getLastFileSeparator(String file) { +506 if (file.contains("*") || file.contains("?")) { +507 int p1 = file.indexOf('*'); +508 int p2 = file.indexOf('?'); +509 p1 = p1 > 0 ? p1 : file.length(); +510 p2 = p2 > 0 ? p2 : file.length(); +511 int pos = p1 < p2 ? p1 : p2; +512 pos = file.lastIndexOf('/', pos); +513 return pos; +514 } else { +515 return file.lastIndexOf('/'); +516 } +517 } +518 }
      diff --git a/xref/org/owasp/dependencycheck/Engine.html b/xref/org/owasp/dependencycheck/Engine.html index e8916237e..3f0c2ae7e 100644 --- a/xref/org/owasp/dependencycheck/Engine.html +++ b/xref/org/owasp/dependencycheck/Engine.html @@ -38,478 +38,537 @@ 30 import org.owasp.dependencycheck.data.update.exception.UpdateException; 31 import org.owasp.dependencycheck.dependency.Dependency; 32 import org.owasp.dependencycheck.exception.NoDataException; -33 import org.owasp.dependencycheck.utils.InvalidSettingException; -34 import org.owasp.dependencycheck.utils.Settings; -35 import org.slf4j.Logger; -36 import org.slf4j.LoggerFactory; -37 -38 import java.io.File; -39 import java.io.FileFilter; -40 import java.util.ArrayList; -41 import java.util.Collection; -42 import java.util.EnumMap; -43 import java.util.HashSet; -44 import java.util.Iterator; -45 import java.util.List; -46 import java.util.Map; -47 import java.util.Set; -48 -49 /** -50 * Scans files, directories, etc. for Dependencies. Analyzers are loaded and used to process the files found by the scan, if a -51 * file is encountered and an Analyzer is associated with the file type then the file is turned into a dependency. -52 * -53 * @author Jeremy Long -54 */ -55 public class Engine implements FileFilter { -56 -57 /** -58 * The list of dependencies. -59 */ -60 private List<Dependency> dependencies = new ArrayList<Dependency>(); +33 import org.owasp.dependencycheck.exception.ExceptionCollection; +34 import org.owasp.dependencycheck.exception.InitializationException; +35 import org.owasp.dependencycheck.utils.InvalidSettingException; +36 import org.owasp.dependencycheck.utils.Settings; +37 import org.slf4j.Logger; +38 import org.slf4j.LoggerFactory; +39 +40 import java.io.File; +41 import java.io.FileFilter; +42 import java.util.ArrayList; +43 import java.util.Collection; +44 import java.util.EnumMap; +45 import java.util.HashSet; +46 import java.util.Iterator; +47 import java.util.List; +48 import java.util.Map; +49 import java.util.Set; +50 +51 /** +52 * Scans files, directories, etc. for Dependencies. Analyzers are loaded and +53 * used to process the files found by the scan, if a file is encountered and an +54 * Analyzer is associated with the file type then the file is turned into a +55 * dependency. +56 * +57 * @author Jeremy Long +58 */ +59 public class Engine implements FileFilter { +60 61 /** -62 * A Map of analyzers grouped by Analysis phase. +62 * The list of dependencies. 63 */ -64 private Map<AnalysisPhase, List<Analyzer>> analyzers = new EnumMap<AnalysisPhase, List<Analyzer>>(AnalysisPhase.class); -65 -66 /** -67 * A Map of analyzers grouped by Analysis phase. -68 */ -69 private Set<FileTypeAnalyzer> fileTypeAnalyzers = new HashSet<FileTypeAnalyzer>(); -70 -71 /** -72 * The ClassLoader to use when dynamically loading Analyzer and Update services. -73 */ -74 private ClassLoader serviceClassLoader = Thread.currentThread().getContextClassLoader(); +64 private List<Dependency> dependencies = new ArrayList<Dependency>(); +65 /** +66 * A Map of analyzers grouped by Analysis phase. +67 */ +68 private final Map<AnalysisPhase, List<Analyzer>> analyzers = new EnumMap<AnalysisPhase, List<Analyzer>>(AnalysisPhase.class); +69 +70 /** +71 * A Map of analyzers grouped by Analysis phase. +72 */ +73 private final Set<FileTypeAnalyzer> fileTypeAnalyzers = new HashSet<FileTypeAnalyzer>(); +74 75 /** -76 * The Logger for use throughout the class. -77 */ -78 private static final Logger LOGGER = LoggerFactory.getLogger(Engine.class); -79 +76 * The ClassLoader to use when dynamically loading Analyzer and Update +77 * services. +78 */ +79 private ClassLoader serviceClassLoader = Thread.currentThread().getContextClassLoader(); 80 /** -81 * Creates a new Engine. -82 * -83 * @throws DatabaseException thrown if there is an error connecting to the database -84 */ -85 public Engine() throws DatabaseException { -86 initializeEngine(); -87 } -88 -89 /** -90 * Creates a new Engine. -91 * -92 * @param serviceClassLoader a reference the class loader being used -93 * @throws DatabaseException thrown if there is an error connecting to the database -94 */ -95 public Engine(ClassLoader serviceClassLoader) throws DatabaseException { -96 this.serviceClassLoader = serviceClassLoader; -97 initializeEngine(); -98 } -99 -100 /** -101 * Creates a new Engine using the specified classloader to dynamically load Analyzer and Update services. -102 * -103 * @throws DatabaseException thrown if there is an error connecting to the database -104 */ -105 protected final void initializeEngine() throws DatabaseException { -106 ConnectionFactory.initialize(); -107 loadAnalyzers(); -108 } -109 -110 /** -111 * Properly cleans up resources allocated during analysis. -112 */ -113 public void cleanup() { -114 ConnectionFactory.cleanup(); -115 } -116 -117 /** -118 * Loads the analyzers specified in the configuration file (or system properties). -119 */ -120 private void loadAnalyzers() { -121 if (!analyzers.isEmpty()) { -122 return; -123 } -124 for (AnalysisPhase phase : AnalysisPhase.values()) { -125 analyzers.put(phase, new ArrayList<Analyzer>()); -126 } -127 -128 final AnalyzerService service = new AnalyzerService(serviceClassLoader); -129 final List<Analyzer> iterator = service.getAnalyzers(); -130 for (Analyzer a : iterator) { -131 analyzers.get(a.getAnalysisPhase()).add(a); -132 if (a instanceof FileTypeAnalyzer) { -133 this.fileTypeAnalyzers.add((FileTypeAnalyzer) a); -134 } -135 } -136 } +81 * The Logger for use throughout the class. +82 */ +83 private static final Logger LOGGER = LoggerFactory.getLogger(Engine.class); +84 +85 /** +86 * Creates a new Engine. +87 * +88 * @throws DatabaseException thrown if there is an error connecting to the +89 * database +90 */ +91 public Engine() throws DatabaseException { +92 initializeEngine(); +93 } +94 +95 /** +96 * Creates a new Engine. +97 * +98 * @param serviceClassLoader a reference the class loader being used +99 * @throws DatabaseException thrown if there is an error connecting to the +100 * database +101 */ +102 public Engine(ClassLoader serviceClassLoader) throws DatabaseException { +103 this.serviceClassLoader = serviceClassLoader; +104 initializeEngine(); +105 } +106 +107 /** +108 * Creates a new Engine using the specified classloader to dynamically load +109 * Analyzer and Update services. +110 * +111 * @throws DatabaseException thrown if there is an error connecting to the +112 * database +113 */ +114 protected final void initializeEngine() throws DatabaseException { +115 ConnectionFactory.initialize(); +116 loadAnalyzers(); +117 } +118 +119 /** +120 * Properly cleans up resources allocated during analysis. +121 */ +122 public void cleanup() { +123 ConnectionFactory.cleanup(); +124 } +125 +126 /** +127 * Loads the analyzers specified in the configuration file (or system +128 * properties). +129 */ +130 private void loadAnalyzers() { +131 if (!analyzers.isEmpty()) { +132 return; +133 } +134 for (AnalysisPhase phase : AnalysisPhase.values()) { +135 analyzers.put(phase, new ArrayList<Analyzer>()); +136 } 137 -138 /** -139 * Get the List of the analyzers for a specific phase of analysis. -140 * -141 * @param phase the phase to get the configured analyzers. -142 * @return the analyzers loaded -143 */ -144 public List<Analyzer> getAnalyzers(AnalysisPhase phase) { -145 return analyzers.get(phase); +138 final AnalyzerService service = new AnalyzerService(serviceClassLoader); +139 final List<Analyzer> iterator = service.getAnalyzers(); +140 for (Analyzer a : iterator) { +141 analyzers.get(a.getAnalysisPhase()).add(a); +142 if (a instanceof FileTypeAnalyzer) { +143 this.fileTypeAnalyzers.add((FileTypeAnalyzer) a); +144 } +145 } 146 } 147 148 /** -149 * Get the dependencies identified. +149 * Get the List of the analyzers for a specific phase of analysis. 150 * -151 * @return the dependencies identified -152 */ -153 public List<Dependency> getDependencies() { -154 return dependencies; -155 } -156 -157 /** -158 * Sets the dependencies. -159 * -160 * @param dependencies the dependencies -161 */ -162 public void setDependencies(List<Dependency> dependencies) { -163 this.dependencies = dependencies; -164 } -165 -166 /** -167 * Scans an array of files or directories. If a directory is specified, it will be scanned recursively. Any dependencies -168 * identified are added to the dependency collection. +151 * @param phase the phase to get the configured analyzers. +152 * @return the analyzers loaded +153 */ +154 public List<Analyzer> getAnalyzers(AnalysisPhase phase) { +155 return analyzers.get(phase); +156 } +157 +158 /** +159 * Get the dependencies identified. +160 * +161 * @return the dependencies identified +162 */ +163 public List<Dependency> getDependencies() { +164 return dependencies; +165 } +166 +167 /** +168 * Sets the dependencies. 169 * -170 * @param paths an array of paths to files or directories to be analyzed -171 * @return the list of dependencies scanned -172 * @since v0.3.2.5 -173 */ -174 public List<Dependency> scan(String[] paths) { -175 final List<Dependency> deps = new ArrayList<Dependency>(); -176 for (String path : paths) { -177 final List<Dependency> d = scan(path); -178 if (d != null) { -179 deps.addAll(d); -180 } -181 } -182 return deps; -183 } -184 -185 /** -186 * Scans a given file or directory. If a directory is specified, it will be scanned recursively. Any dependencies identified -187 * are added to the dependency collection. -188 * -189 * @param path the path to a file or directory to be analyzed -190 * @return the list of dependencies scanned -191 */ -192 public List<Dependency> scan(String path) { -193 final File file = new File(path); -194 return scan(file); -195 } -196 -197 /** -198 * Scans an array of files or directories. If a directory is specified, it will be scanned recursively. Any dependencies -199 * identified are added to the dependency collection. +170 * @param dependencies the dependencies +171 */ +172 public void setDependencies(List<Dependency> dependencies) { +173 this.dependencies = dependencies; +174 } +175 +176 /** +177 * Scans an array of files or directories. If a directory is specified, it +178 * will be scanned recursively. Any dependencies identified are added to the +179 * dependency collection. +180 * +181 * @param paths an array of paths to files or directories to be analyzed +182 * @return the list of dependencies scanned +183 * @since v0.3.2.5 +184 */ +185 public List<Dependency> scan(String[] paths) { +186 final List<Dependency> deps = new ArrayList<Dependency>(); +187 for (String path : paths) { +188 final List<Dependency> d = scan(path); +189 if (d != null) { +190 deps.addAll(d); +191 } +192 } +193 return deps; +194 } +195 +196 /** +197 * Scans a given file or directory. If a directory is specified, it will be +198 * scanned recursively. Any dependencies identified are added to the +199 * dependency collection. 200 * -201 * @param files an array of paths to files or directories to be analyzed. -202 * @return the list of dependencies -203 * @since v0.3.2.5 -204 */ -205 public List<Dependency> scan(File[] files) { -206 final List<Dependency> deps = new ArrayList<Dependency>(); -207 for (File file : files) { -208 final List<Dependency> d = scan(file); -209 if (d != null) { -210 deps.addAll(d); -211 } -212 } -213 return deps; -214 } -215 -216 /** -217 * Scans a collection of files or directories. If a directory is specified, it will be scanned recursively. Any dependencies -218 * identified are added to the dependency collection. -219 * -220 * @param files a set of paths to files or directories to be analyzed -221 * @return the list of dependencies scanned -222 * @since v0.3.2.5 -223 */ -224 public List<Dependency> scan(Collection<File> files) { -225 final List<Dependency> deps = new ArrayList<Dependency>(); -226 for (File file : files) { -227 final List<Dependency> d = scan(file); -228 if (d != null) { -229 deps.addAll(d); -230 } -231 } -232 return deps; -233 } -234 -235 /** -236 * Scans a given file or directory. If a directory is specified, it will be scanned recursively. Any dependencies identified -237 * are added to the dependency collection. -238 * -239 * @param file the path to a file or directory to be analyzed -240 * @return the list of dependencies scanned -241 * @since v0.3.2.4 -242 */ -243 public List<Dependency> scan(File file) { -244 if (file.exists()) { -245 if (file.isDirectory()) { -246 return scanDirectory(file); -247 } else { -248 final Dependency d = scanFile(file); -249 if (d != null) { -250 final List<Dependency> deps = new ArrayList<Dependency>(); -251 deps.add(d); -252 return deps; -253 } -254 } -255 } -256 return null; -257 } -258 -259 /** -260 * Recursively scans files and directories. Any dependencies identified are added to the dependency collection. -261 * -262 * @param dir the directory to scan -263 * @return the list of Dependency objects scanned -264 */ -265 protected List<Dependency> scanDirectory(File dir) { -266 final File[] files = dir.listFiles(); -267 final List<Dependency> deps = new ArrayList<Dependency>(); -268 if (files != null) { -269 for (File f : files) { -270 if (f.isDirectory()) { -271 final List<Dependency> d = scanDirectory(f); -272 if (d != null) { -273 deps.addAll(d); -274 } -275 } else { -276 final Dependency d = scanFile(f); -277 deps.add(d); -278 } -279 } -280 } -281 return deps; -282 } -283 -284 /** -285 * Scans a specified file. If a dependency is identified it is added to the dependency collection. -286 * -287 * @param file The file to scan -288 * @return the scanned dependency -289 */ -290 protected Dependency scanFile(File file) { -291 Dependency dependency = null; -292 if (file.isFile()) { -293 if (accept(file)) { -294 dependency = new Dependency(file); -295 dependencies.add(dependency); -296 } -297 } else { -298 LOGGER.debug("Path passed to scanFile(File) is not a file: {}. Skipping the file.", file); -299 } -300 return dependency; -301 } -302 -303 /** -304 * Runs the analyzers against all of the dependencies. Since the mutable dependencies list is exposed via -305 * {@link #getDependencies()}, this method iterates over a copy of the dependencies list. Thus, the potential for -306 * {@link java.util.ConcurrentModificationException}s is avoided, and analyzers may safely add or remove entries from the -307 * dependencies list. -308 */ -309 public void analyzeDependencies() { -310 boolean autoUpdate = true; -311 try { -312 autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE); -313 } catch (InvalidSettingException ex) { -314 LOGGER.debug("Invalid setting for auto-update; using true."); -315 } -316 if (autoUpdate) { -317 doUpdates(); -318 } +201 * @param path the path to a file or directory to be analyzed +202 * @return the list of dependencies scanned +203 */ +204 public List<Dependency> scan(String path) { +205 final File file = new File(path); +206 return scan(file); +207 } +208 +209 /** +210 * Scans an array of files or directories. If a directory is specified, it +211 * will be scanned recursively. Any dependencies identified are added to the +212 * dependency collection. +213 * +214 * @param files an array of paths to files or directories to be analyzed. +215 * @return the list of dependencies +216 * @since v0.3.2.5 +217 */ +218 public List<Dependency> scan(File[] files) { +219 final List<Dependency> deps = new ArrayList<Dependency>(); +220 for (File file : files) { +221 final List<Dependency> d = scan(file); +222 if (d != null) { +223 deps.addAll(d); +224 } +225 } +226 return deps; +227 } +228 +229 /** +230 * Scans a collection of files or directories. If a directory is specified, +231 * it will be scanned recursively. Any dependencies identified are added to +232 * the dependency collection. +233 * +234 * @param files a set of paths to files or directories to be analyzed +235 * @return the list of dependencies scanned +236 * @since v0.3.2.5 +237 */ +238 public List<Dependency> scan(Collection<File> files) { +239 final List<Dependency> deps = new ArrayList<Dependency>(); +240 for (File file : files) { +241 final List<Dependency> d = scan(file); +242 if (d != null) { +243 deps.addAll(d); +244 } +245 } +246 return deps; +247 } +248 +249 /** +250 * Scans a given file or directory. If a directory is specified, it will be +251 * scanned recursively. Any dependencies identified are added to the +252 * dependency collection. +253 * +254 * @param file the path to a file or directory to be analyzed +255 * @return the list of dependencies scanned +256 * @since v0.3.2.4 +257 */ +258 public List<Dependency> scan(File file) { +259 if (file.exists()) { +260 if (file.isDirectory()) { +261 return scanDirectory(file); +262 } else { +263 final Dependency d = scanFile(file); +264 if (d != null) { +265 final List<Dependency> deps = new ArrayList<Dependency>(); +266 deps.add(d); +267 return deps; +268 } +269 } +270 } +271 return null; +272 } +273 +274 /** +275 * Recursively scans files and directories. Any dependencies identified are +276 * added to the dependency collection. +277 * +278 * @param dir the directory to scan +279 * @return the list of Dependency objects scanned +280 */ +281 protected List<Dependency> scanDirectory(File dir) { +282 final File[] files = dir.listFiles(); +283 final List<Dependency> deps = new ArrayList<Dependency>(); +284 if (files != null) { +285 for (File f : files) { +286 if (f.isDirectory()) { +287 final List<Dependency> d = scanDirectory(f); +288 if (d != null) { +289 deps.addAll(d); +290 } +291 } else { +292 final Dependency d = scanFile(f); +293 deps.add(d); +294 } +295 } +296 } +297 return deps; +298 } +299 +300 /** +301 * Scans a specified file. If a dependency is identified it is added to the +302 * dependency collection. +303 * +304 * @param file The file to scan +305 * @return the scanned dependency +306 */ +307 protected Dependency scanFile(File file) { +308 Dependency dependency = null; +309 if (file.isFile()) { +310 if (accept(file)) { +311 dependency = new Dependency(file); +312 dependencies.add(dependency); +313 } +314 } else { +315 LOGGER.debug("Path passed to scanFile(File) is not a file: {}. Skipping the file.", file); +316 } +317 return dependency; +318 } 319 -320 //need to ensure that data exists -321 try { -322 ensureDataExists(); -323 } catch (NoDataException ex) { -324 LOGGER.error("{}\n\nUnable to continue dependency-check analysis.", ex.getMessage()); -325 LOGGER.debug("", ex); -326 return; -327 } catch (DatabaseException ex) { -328 LOGGER.error("{}\n\nUnable to continue dependency-check analysis.", ex.getMessage()); -329 LOGGER.debug("", ex); -330 return; -331 -332 } -333 -334 LOGGER.debug("\n----------------------------------------------------\nBEGIN ANALYSIS\n----------------------------------------------------"); -335 LOGGER.info("Analysis Starting"); -336 final long analysisStart = System.currentTimeMillis(); -337 -338 // analysis phases -339 for (AnalysisPhase phase : AnalysisPhase.values()) { -340 final List<Analyzer> analyzerList = analyzers.get(phase); -341 -342 for (Analyzer a : analyzerList) { -343 a = initializeAnalyzer(a); -344 -345 /* need to create a copy of the collection because some of the -346 * analyzers may modify it. This prevents ConcurrentModificationExceptions. -347 * This is okay for adds/deletes because it happens per analyzer. -348 */ -349 LOGGER.debug("Begin Analyzer '{}'", a.getName()); -350 final Set<Dependency> dependencySet = new HashSet<Dependency>(dependencies); -351 for (Dependency d : dependencySet) { -352 boolean shouldAnalyze = true; -353 if (a instanceof FileTypeAnalyzer) { -354 final FileTypeAnalyzer fAnalyzer = (FileTypeAnalyzer) a; -355 shouldAnalyze = fAnalyzer.accept(d.getActualFile()); -356 } -357 if (shouldAnalyze) { -358 LOGGER.debug("Begin Analysis of '{}'", d.getActualFilePath()); -359 try { -360 a.analyze(d, this); -361 } catch (AnalysisException ex) { -362 LOGGER.warn("An error occurred while analyzing '{}'.", d.getActualFilePath()); -363 LOGGER.debug("", ex); -364 } catch (Throwable ex) { -365 //final AnalysisException ax = new AnalysisException(axMsg, ex); -366 LOGGER.warn("An unexpected error occurred during analysis of '{}'", d.getActualFilePath()); -367 LOGGER.debug("", ex); -368 } -369 } -370 } -371 } -372 } -373 for (AnalysisPhase phase : AnalysisPhase.values()) { -374 final List<Analyzer> analyzerList = analyzers.get(phase); -375 -376 for (Analyzer a : analyzerList) { -377 closeAnalyzer(a); -378 } -379 } -380 -381 LOGGER.debug("\n----------------------------------------------------\nEND ANALYSIS\n----------------------------------------------------"); -382 LOGGER.info("Analysis Complete ({} ms)", System.currentTimeMillis() - analysisStart); -383 } -384 -385 /** -386 * Initializes the given analyzer. -387 * -388 * @param analyzer the analyzer to initialize -389 * @return the initialized analyzer -390 */ -391 protected Analyzer initializeAnalyzer(Analyzer analyzer) { -392 try { -393 LOGGER.debug("Initializing {}", analyzer.getName()); -394 analyzer.initialize(); -395 } catch (Throwable ex) { -396 LOGGER.error("Exception occurred initializing {}.", analyzer.getName()); -397 LOGGER.debug("", ex); -398 try { -399 analyzer.close(); -400 } catch (Throwable ex1) { -401 LOGGER.trace("", ex1); -402 } -403 } -404 return analyzer; -405 } -406 -407 /** -408 * Closes the given analyzer. -409 * -410 * @param analyzer the analyzer to close -411 */ -412 protected void closeAnalyzer(Analyzer analyzer) { -413 LOGGER.debug("Closing Analyzer '{}'", analyzer.getName()); -414 try { -415 analyzer.close(); -416 } catch (Throwable ex) { -417 LOGGER.trace("", ex); -418 } -419 } -420 -421 /** -422 * Cycles through the cached web data sources and calls update on all of them. -423 */ -424 public void doUpdates() { -425 LOGGER.info("Checking for updates"); -426 final long updateStart = System.currentTimeMillis(); -427 final UpdateService service = new UpdateService(serviceClassLoader); -428 final Iterator<CachedWebDataSource> iterator = service.getDataSources(); -429 while (iterator.hasNext()) { -430 final CachedWebDataSource source = iterator.next(); -431 try { -432 source.update(); -433 } catch (UpdateException ex) { -434 LOGGER.warn( -435 "Unable to update Cached Web DataSource, using local data instead. Results may not include recent vulnerabilities."); -436 LOGGER.debug("Unable to update details for {}", source.getClass().getName(), ex); -437 } -438 } -439 LOGGER.info("Check for updates complete ({} ms)", System.currentTimeMillis() - updateStart); -440 } -441 -442 /** -443 * Returns a full list of all of the analyzers. This is useful for reporting which analyzers where used. -444 * -445 * @return a list of Analyzers -446 */ -447 public List<Analyzer> getAnalyzers() { -448 final List<Analyzer> ret = new ArrayList<Analyzer>(); -449 for (AnalysisPhase phase : AnalysisPhase.values()) { -450 final List<Analyzer> analyzerList = analyzers.get(phase); -451 ret.addAll(analyzerList); -452 } -453 return ret; -454 } -455 -456 /** -457 * Checks all analyzers to see if an extension is supported. -458 * -459 * @param file a file extension -460 * @return true or false depending on whether or not the file extension is supported -461 */ -462 @Override -463 public boolean accept(File file) { -464 if (file == null) { -465 return false; -466 } -467 boolean scan = false; -468 for (FileTypeAnalyzer a : this.fileTypeAnalyzers) { -469 /* note, we can't break early on this loop as the analyzers need to know if -470 they have files to work on prior to initialization */ -471 scan |= a.accept(file); -472 } -473 return scan; -474 } -475 -476 /** -477 * Returns the set of file type analyzers. -478 * -479 * @return the set of file type analyzers -480 */ -481 public Set<FileTypeAnalyzer> getFileTypeAnalyzers() { -482 return this.fileTypeAnalyzers; -483 } -484 -485 /** -486 * Checks the CPE Index to ensure documents exists. If none exist a NoDataException is thrown. -487 * -488 * @throws NoDataException thrown if no data exists in the CPE Index -489 * @throws DatabaseException thrown if there is an exception opening the database -490 */ -491 private void ensureDataExists() throws NoDataException, DatabaseException { -492 final CveDB cve = new CveDB(); -493 try { -494 cve.open(); -495 if (!cve.dataExists()) { -496 throw new NoDataException("No documents exist"); -497 } -498 } catch (DatabaseException ex) { -499 throw new NoDataException(ex.getMessage(), ex); -500 } finally { -501 cve.close(); -502 } -503 } -504 } +320 /** +321 * Runs the analyzers against all of the dependencies. Since the mutable +322 * dependencies list is exposed via {@link #getDependencies()}, this method +323 * iterates over a copy of the dependencies list. Thus, the potential for +324 * {@link java.util.ConcurrentModificationException}s is avoided, and +325 * analyzers may safely add or remove entries from the dependencies list. +326 * +327 * Every effort is made to complete analysis on the dependencies. In some +328 * cases an exception will occur with part of the analysis being performed +329 * which may not affect the entire analysis. If an exception occurs it will +330 * be included in the thrown exception collection. +331 * +332 * @throws ExceptionCollection a collections of any exceptions that occurred +333 * during analysis +334 */ +335 public void analyzeDependencies() throws ExceptionCollection { +336 final List<Throwable> exceptions = new ArrayList<Throwable>(); +337 boolean autoUpdate = true; +338 try { +339 autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE); +340 } catch (InvalidSettingException ex) { +341 LOGGER.debug("Invalid setting for auto-update; using true."); +342 exceptions.add(ex); +343 } +344 if (autoUpdate) { +345 try { +346 doUpdates(); +347 } catch (UpdateException ex) { +348 exceptions.add(ex); +349 LOGGER.warn("Unable to update Cached Web DataSource, using local " +350 + "data instead. Results may not include recent vulnerabilities."); +351 LOGGER.debug("Update Error", ex); +352 } +353 } +354 +355 //need to ensure that data exists +356 try { +357 ensureDataExists(); +358 } catch (NoDataException ex) { +359 LOGGER.error("{}\n\nUnable to continue dependency-check analysis.", ex.getMessage()); +360 LOGGER.debug("", ex); +361 exceptions.add(ex); +362 throw new ExceptionCollection("Unable to continue dependency-check analysis.", exceptions, true); +363 } catch (DatabaseException ex) { +364 LOGGER.error("{}\n\nUnable to continue dependency-check analysis.", ex.getMessage()); +365 LOGGER.debug("", ex); +366 exceptions.add(ex); +367 throw new ExceptionCollection("Unable to connect to the dependency-check database", exceptions, true); +368 } +369 +370 LOGGER.debug("\n----------------------------------------------------\nBEGIN ANALYSIS\n----------------------------------------------------"); +371 LOGGER.info("Analysis Starting"); +372 final long analysisStart = System.currentTimeMillis(); +373 +374 // analysis phases +375 for (AnalysisPhase phase : AnalysisPhase.values()) { +376 final List<Analyzer> analyzerList = analyzers.get(phase); +377 +378 for (Analyzer a : analyzerList) { +379 try { +380 a = initializeAnalyzer(a); +381 } catch (InitializationException ex) { +382 exceptions.add(ex); +383 continue; +384 } +385 +386 /* need to create a copy of the collection because some of the +387 * analyzers may modify it. This prevents ConcurrentModificationExceptions. +388 * This is okay for adds/deletes because it happens per analyzer. +389 */ +390 LOGGER.debug("Begin Analyzer '{}'", a.getName()); +391 final Set<Dependency> dependencySet = new HashSet<Dependency>(dependencies); +392 for (Dependency d : dependencySet) { +393 boolean shouldAnalyze = true; +394 if (a instanceof FileTypeAnalyzer) { +395 final FileTypeAnalyzer fAnalyzer = (FileTypeAnalyzer) a; +396 shouldAnalyze = fAnalyzer.accept(d.getActualFile()); +397 } +398 if (shouldAnalyze) { +399 LOGGER.debug("Begin Analysis of '{}'", d.getActualFilePath()); +400 try { +401 a.analyze(d, this); +402 } catch (AnalysisException ex) { +403 LOGGER.warn("An error occurred while analyzing '{}'.", d.getActualFilePath()); +404 LOGGER.debug("", ex); +405 exceptions.add(ex); +406 } catch (Throwable ex) { +407 //final AnalysisException ax = new AnalysisException(axMsg, ex); +408 LOGGER.warn("An unexpected error occurred during analysis of '{}'", d.getActualFilePath()); +409 LOGGER.debug("", ex); +410 exceptions.add(ex); +411 } +412 } +413 } +414 } +415 } +416 for (AnalysisPhase phase : AnalysisPhase.values()) { +417 final List<Analyzer> analyzerList = analyzers.get(phase); +418 +419 for (Analyzer a : analyzerList) { +420 closeAnalyzer(a); +421 } +422 } +423 +424 LOGGER.debug("\n----------------------------------------------------\nEND ANALYSIS\n----------------------------------------------------"); +425 LOGGER.info("Analysis Complete ({} ms)", System.currentTimeMillis() - analysisStart); +426 if (exceptions.size() > 0) { +427 throw new ExceptionCollection("One or more exceptions occured during dependency-check analysis", exceptions); +428 } +429 } +430 +431 /** +432 * Initializes the given analyzer. +433 * +434 * @param analyzer the analyzer to initialize +435 * @return the initialized analyzer +436 * @throws InitializationException thrown when there is a problem +437 * initializing the analyzer +438 */ +439 protected Analyzer initializeAnalyzer(Analyzer analyzer) throws InitializationException { +440 try { +441 LOGGER.debug("Initializing {}", analyzer.getName()); +442 analyzer.initialize(); +443 } catch (InitializationException ex) { +444 LOGGER.error("Exception occurred initializing {}.", analyzer.getName()); +445 LOGGER.debug("", ex); +446 try { +447 analyzer.close(); +448 } catch (Throwable ex1) { +449 LOGGER.trace("", ex1); +450 } +451 throw ex; +452 } catch (Throwable ex) { +453 LOGGER.error("Unexpected exception occurred initializing {}.", analyzer.getName()); +454 LOGGER.debug("", ex); +455 try { +456 analyzer.close(); +457 } catch (Throwable ex1) { +458 LOGGER.trace("", ex1); +459 } +460 throw new InitializationException("Unexpected Exception", ex); +461 } +462 return analyzer; +463 } +464 +465 /** +466 * Closes the given analyzer. +467 * +468 * @param analyzer the analyzer to close +469 */ +470 protected void closeAnalyzer(Analyzer analyzer) { +471 LOGGER.debug("Closing Analyzer '{}'", analyzer.getName()); +472 try { +473 analyzer.close(); +474 } catch (Throwable ex) { +475 LOGGER.trace("", ex); +476 } +477 } +478 +479 /** +480 * Cycles through the cached web data sources and calls update on all of +481 * them. +482 * +483 * @throws UpdateException thrown if the operation fails +484 */ +485 public void doUpdates() throws UpdateException { +486 LOGGER.info("Checking for updates"); +487 final long updateStart = System.currentTimeMillis(); +488 final UpdateService service = new UpdateService(serviceClassLoader); +489 final Iterator<CachedWebDataSource> iterator = service.getDataSources(); +490 while (iterator.hasNext()) { +491 final CachedWebDataSource source = iterator.next(); +492 source.update(); +493 } +494 LOGGER.info("Check for updates complete ({} ms)", System.currentTimeMillis() - updateStart); +495 } +496 +497 /** +498 * Returns a full list of all of the analyzers. This is useful for reporting +499 * which analyzers where used. +500 * +501 * @return a list of Analyzers +502 */ +503 public List<Analyzer> getAnalyzers() { +504 final List<Analyzer> ret = new ArrayList<Analyzer>(); +505 for (AnalysisPhase phase : AnalysisPhase.values()) { +506 final List<Analyzer> analyzerList = analyzers.get(phase); +507 ret.addAll(analyzerList); +508 } +509 return ret; +510 } +511 +512 /** +513 * Checks all analyzers to see if an extension is supported. +514 * +515 * @param file a file extension +516 * @return true or false depending on whether or not the file extension is +517 * supported +518 */ +519 @Override +520 public boolean accept(File file) { +521 if (file == null) { +522 return false; +523 } +524 boolean scan = false; +525 for (FileTypeAnalyzer a : this.fileTypeAnalyzers) { +526 /* note, we can't break early on this loop as the analyzers need to know if +527 they have files to work on prior to initialization */ +528 scan |= a.accept(file); +529 } +530 return scan; +531 } +532 +533 /** +534 * Returns the set of file type analyzers. +535 * +536 * @return the set of file type analyzers +537 */ +538 public Set<FileTypeAnalyzer> getFileTypeAnalyzers() { +539 return this.fileTypeAnalyzers; +540 } +541 +542 /** +543 * Checks the CPE Index to ensure documents exists. If none exist a +544 * NoDataException is thrown. +545 * +546 * @throws NoDataException thrown if no data exists in the CPE Index +547 * @throws DatabaseException thrown if there is an exception opening the +548 * database +549 */ +550 private void ensureDataExists() throws NoDataException, DatabaseException { +551 final CveDB cve = new CveDB(); +552 try { +553 cve.open(); +554 if (!cve.dataExists()) { +555 throw new NoDataException("No documents exist"); +556 } +557 } catch (DatabaseException ex) { +558 throw new NoDataException(ex.getMessage(), ex); +559 } finally { +560 cve.close(); +561 } +562 } +563 }
      diff --git a/xref/org/owasp/dependencycheck/agent/DependencyCheckScanAgent.html b/xref/org/owasp/dependencycheck/agent/DependencyCheckScanAgent.html index 1e31947e7..6f6a63245 100644 --- a/xref/org/owasp/dependencycheck/agent/DependencyCheckScanAgent.html +++ b/xref/org/owasp/dependencycheck/agent/DependencyCheckScanAgent.html @@ -35,1004 +35,1025 @@ 27 import org.owasp.dependencycheck.dependency.Dependency; 28 import org.owasp.dependencycheck.dependency.Identifier; 29 import org.owasp.dependencycheck.dependency.Vulnerability; -30 import org.owasp.dependencycheck.exception.ScanAgentException; -31 import org.owasp.dependencycheck.reporting.ReportGenerator; -32 import org.owasp.dependencycheck.utils.Settings; -33 import org.slf4j.Logger; -34 import org.slf4j.LoggerFactory; -35 -36 /** -37 * This class provides a way to easily conduct a scan solely based on existing evidence metadata rather than collecting evidence -38 * from the files themselves. This class is based on the Ant task and Maven plugin with the exception that it takes a list of -39 * dependencies that can be programmatically added from data in a spreadsheet, database or some other datasource and conduct a -40 * scan based on this pre-defined evidence. -41 * -42 * <h2>Example:</h2> -43 * <pre> -44 * List&lt;Dependency&gt; dependencies = new ArrayList&lt;Dependency&gt;(); -45 * Dependency dependency = new Dependency(new File(FileUtils.getBitBucket())); -46 * dependency.getProductEvidence().addEvidence("my-datasource", "name", "Jetty", Confidence.HIGH); -47 * dependency.getVersionEvidence().addEvidence("my-datasource", "version", "5.1.10", Confidence.HIGH); -48 * dependency.getVendorEvidence().addEvidence("my-datasource", "vendor", "mortbay", Confidence.HIGH); -49 * dependencies.add(dependency); -50 * -51 * DependencyCheckScanAgent scan = new DependencyCheckScanAgent(); -52 * scan.setDependencies(dependencies); -53 * scan.setReportFormat(ReportGenerator.Format.ALL); -54 * scan.setReportOutputDirectory(System.getProperty("user.home")); -55 * scan.execute(); -56 * </pre> -57 * -58 * @author Steve Springett -59 */ -60 @SuppressWarnings("unused") -61 public class DependencyCheckScanAgent { -62 -63 /** -64 * System specific new line character. -65 */ -66 private static final String NEW_LINE = System.getProperty("line.separator", "\n").intern(); -67 /** -68 * Logger for use throughout the class. -69 */ -70 private static final Logger LOGGER = LoggerFactory.getLogger(DependencyCheckScanAgent.class); -71 /** -72 * The application name for the report. -73 */ -74 private String applicationName = "Dependency-Check"; -75 -76 /** -77 * Get the value of applicationName. -78 * -79 * @return the value of applicationName -80 */ -81 public String getApplicationName() { -82 return applicationName; -83 } -84 -85 /** -86 * Set the value of applicationName. -87 * -88 * @param applicationName new value of applicationName -89 */ -90 public void setApplicationName(String applicationName) { -91 this.applicationName = applicationName; -92 } -93 -94 /** -95 * The pre-determined dependencies to scan -96 */ -97 private List<Dependency> dependencies; -98 -99 /** -100 * Returns a list of pre-determined dependencies. -101 * -102 * @return returns a list of dependencies -103 */ -104 public List<Dependency> getDependencies() { -105 return dependencies; -106 } -107 -108 /** -109 * Sets the list of dependencies to scan. -110 * -111 * @param dependencies new value of dependencies -112 */ -113 public void setDependencies(List<Dependency> dependencies) { -114 this.dependencies = dependencies; -115 } -116 -117 /** -118 * The location of the data directory that contains -119 */ -120 private String dataDirectory = null; -121 -122 /** -123 * Get the value of dataDirectory. -124 * -125 * @return the value of dataDirectory -126 */ -127 public String getDataDirectory() { -128 return dataDirectory; -129 } -130 -131 /** -132 * Set the value of dataDirectory. -133 * -134 * @param dataDirectory new value of dataDirectory -135 */ -136 public void setDataDirectory(String dataDirectory) { -137 this.dataDirectory = dataDirectory; -138 } -139 -140 /** -141 * Specifies the destination directory for the generated Dependency-Check report. -142 */ -143 private String reportOutputDirectory; -144 -145 /** -146 * Get the value of reportOutputDirectory. -147 * -148 * @return the value of reportOutputDirectory -149 */ -150 public String getReportOutputDirectory() { -151 return reportOutputDirectory; -152 } -153 -154 /** -155 * Set the value of reportOutputDirectory. -156 * -157 * @param reportOutputDirectory new value of reportOutputDirectory -158 */ -159 public void setReportOutputDirectory(String reportOutputDirectory) { -160 this.reportOutputDirectory = reportOutputDirectory; -161 } -162 -163 /** -164 * Specifies if the build should be failed if a CVSS score above a specified level is identified. The default is 11 which -165 * means since the CVSS scores are 0-10, by default the build will never fail and the CVSS score is set to 11. The valid range -166 * for the fail build on CVSS is 0 to 11, where anything above 10 will not cause the build to fail. -167 */ -168 private float failBuildOnCVSS = 11; -169 -170 /** -171 * Get the value of failBuildOnCVSS. -172 * -173 * @return the value of failBuildOnCVSS -174 */ -175 public float getFailBuildOnCVSS() { -176 return failBuildOnCVSS; -177 } -178 -179 /** -180 * Set the value of failBuildOnCVSS. -181 * -182 * @param failBuildOnCVSS new value of failBuildOnCVSS -183 */ -184 public void setFailBuildOnCVSS(float failBuildOnCVSS) { -185 this.failBuildOnCVSS = failBuildOnCVSS; -186 } -187 -188 /** -189 * Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not recommended that this be turned to false. Default -190 * is true. -191 */ -192 private boolean autoUpdate = true; +30 import org.owasp.dependencycheck.exception.ExceptionCollection; +31 import org.owasp.dependencycheck.exception.ScanAgentException; +32 import org.owasp.dependencycheck.reporting.ReportGenerator; +33 import org.owasp.dependencycheck.utils.Settings; +34 import org.slf4j.Logger; +35 import org.slf4j.LoggerFactory; +36 +37 /** +38 * This class provides a way to easily conduct a scan solely based on existing +39 * evidence metadata rather than collecting evidence from the files themselves. +40 * This class is based on the Ant task and Maven plugin with the exception that +41 * it takes a list of dependencies that can be programmatically added from data +42 * in a spreadsheet, database or some other datasource and conduct a scan based +43 * on this pre-defined evidence. +44 * +45 * <h2>Example:</h2> +46 * <pre> +47 * List&lt;Dependency&gt; dependencies = new ArrayList&lt;Dependency&gt;(); +48 * Dependency dependency = new Dependency(new File(FileUtils.getBitBucket())); +49 * dependency.getProductEvidence().addEvidence("my-datasource", "name", "Jetty", Confidence.HIGH); +50 * dependency.getVersionEvidence().addEvidence("my-datasource", "version", "5.1.10", Confidence.HIGH); +51 * dependency.getVendorEvidence().addEvidence("my-datasource", "vendor", "mortbay", Confidence.HIGH); +52 * dependencies.add(dependency); +53 * +54 * DependencyCheckScanAgent scan = new DependencyCheckScanAgent(); +55 * scan.setDependencies(dependencies); +56 * scan.setReportFormat(ReportGenerator.Format.ALL); +57 * scan.setReportOutputDirectory(System.getProperty("user.home")); +58 * scan.execute(); +59 * </pre> +60 * +61 * @author Steve Springett +62 */ +63 @SuppressWarnings("unused") +64 public class DependencyCheckScanAgent { +65 +66 /** +67 * System specific new line character. +68 */ +69 private static final String NEW_LINE = System.getProperty("line.separator", "\n").intern(); +70 /** +71 * Logger for use throughout the class. +72 */ +73 private static final Logger LOGGER = LoggerFactory.getLogger(DependencyCheckScanAgent.class); +74 /** +75 * The application name for the report. +76 */ +77 private String applicationName = "Dependency-Check"; +78 +79 /** +80 * Get the value of applicationName. +81 * +82 * @return the value of applicationName +83 */ +84 public String getApplicationName() { +85 return applicationName; +86 } +87 +88 /** +89 * Set the value of applicationName. +90 * +91 * @param applicationName new value of applicationName +92 */ +93 public void setApplicationName(String applicationName) { +94 this.applicationName = applicationName; +95 } +96 +97 /** +98 * The pre-determined dependencies to scan +99 */ +100 private List<Dependency> dependencies; +101 +102 /** +103 * Returns a list of pre-determined dependencies. +104 * +105 * @return returns a list of dependencies +106 */ +107 public List<Dependency> getDependencies() { +108 return dependencies; +109 } +110 +111 /** +112 * Sets the list of dependencies to scan. +113 * +114 * @param dependencies new value of dependencies +115 */ +116 public void setDependencies(List<Dependency> dependencies) { +117 this.dependencies = dependencies; +118 } +119 +120 /** +121 * The location of the data directory that contains +122 */ +123 private String dataDirectory = null; +124 +125 /** +126 * Get the value of dataDirectory. +127 * +128 * @return the value of dataDirectory +129 */ +130 public String getDataDirectory() { +131 return dataDirectory; +132 } +133 +134 /** +135 * Set the value of dataDirectory. +136 * +137 * @param dataDirectory new value of dataDirectory +138 */ +139 public void setDataDirectory(String dataDirectory) { +140 this.dataDirectory = dataDirectory; +141 } +142 +143 /** +144 * Specifies the destination directory for the generated Dependency-Check +145 * report. +146 */ +147 private String reportOutputDirectory; +148 +149 /** +150 * Get the value of reportOutputDirectory. +151 * +152 * @return the value of reportOutputDirectory +153 */ +154 public String getReportOutputDirectory() { +155 return reportOutputDirectory; +156 } +157 +158 /** +159 * Set the value of reportOutputDirectory. +160 * +161 * @param reportOutputDirectory new value of reportOutputDirectory +162 */ +163 public void setReportOutputDirectory(String reportOutputDirectory) { +164 this.reportOutputDirectory = reportOutputDirectory; +165 } +166 +167 /** +168 * Specifies if the build should be failed if a CVSS score above a specified +169 * level is identified. The default is 11 which means since the CVSS scores +170 * are 0-10, by default the build will never fail and the CVSS score is set +171 * to 11. The valid range for the fail build on CVSS is 0 to 11, where +172 * anything above 10 will not cause the build to fail. +173 */ +174 private float failBuildOnCVSS = 11; +175 +176 /** +177 * Get the value of failBuildOnCVSS. +178 * +179 * @return the value of failBuildOnCVSS +180 */ +181 public float getFailBuildOnCVSS() { +182 return failBuildOnCVSS; +183 } +184 +185 /** +186 * Set the value of failBuildOnCVSS. +187 * +188 * @param failBuildOnCVSS new value of failBuildOnCVSS +189 */ +190 public void setFailBuildOnCVSS(float failBuildOnCVSS) { +191 this.failBuildOnCVSS = failBuildOnCVSS; +192 } 193 194 /** -195 * Get the value of autoUpdate. -196 * -197 * @return the value of autoUpdate -198 */ -199 public boolean isAutoUpdate() { -200 return autoUpdate; -201 } -202 -203 /** -204 * Set the value of autoUpdate. -205 * -206 * @param autoUpdate new value of autoUpdate -207 */ -208 public void setAutoUpdate(boolean autoUpdate) { -209 this.autoUpdate = autoUpdate; -210 } -211 -212 /** -213 * flag indicating whether or not to generate a report of findings. -214 */ -215 private boolean generateReport = true; -216 -217 /** -218 * Get the value of generateReport. -219 * -220 * @return the value of generateReport -221 */ -222 public boolean isGenerateReport() { -223 return generateReport; -224 } -225 -226 /** -227 * Set the value of generateReport. -228 * -229 * @param generateReport new value of generateReport -230 */ -231 public void setGenerateReport(boolean generateReport) { -232 this.generateReport = generateReport; -233 } -234 -235 /** -236 * The report format to be generated (HTML, XML, VULN, ALL). This configuration option has no affect if using this within the -237 * Site plugin unless the externalReport is set to true. Default is HTML. -238 */ -239 private ReportGenerator.Format reportFormat = ReportGenerator.Format.HTML; +195 * Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not +196 * recommended that this be turned to false. Default is true. +197 */ +198 private boolean autoUpdate = true; +199 +200 /** +201 * Get the value of autoUpdate. +202 * +203 * @return the value of autoUpdate +204 */ +205 public boolean isAutoUpdate() { +206 return autoUpdate; +207 } +208 +209 /** +210 * Set the value of autoUpdate. +211 * +212 * @param autoUpdate new value of autoUpdate +213 */ +214 public void setAutoUpdate(boolean autoUpdate) { +215 this.autoUpdate = autoUpdate; +216 } +217 +218 /** +219 * flag indicating whether or not to generate a report of findings. +220 */ +221 private boolean generateReport = true; +222 +223 /** +224 * Get the value of generateReport. +225 * +226 * @return the value of generateReport +227 */ +228 public boolean isGenerateReport() { +229 return generateReport; +230 } +231 +232 /** +233 * Set the value of generateReport. +234 * +235 * @param generateReport new value of generateReport +236 */ +237 public void setGenerateReport(boolean generateReport) { +238 this.generateReport = generateReport; +239 } 240 241 /** -242 * Get the value of reportFormat. -243 * -244 * @return the value of reportFormat +242 * The report format to be generated (HTML, XML, VULN, ALL). This +243 * configuration option has no affect if using this within the Site plugin +244 * unless the externalReport is set to true. Default is HTML. 245 */ -246 public ReportGenerator.Format getReportFormat() { -247 return reportFormat; -248 } -249 -250 /** -251 * Set the value of reportFormat. -252 * -253 * @param reportFormat new value of reportFormat -254 */ -255 public void setReportFormat(ReportGenerator.Format reportFormat) { -256 this.reportFormat = reportFormat; -257 } -258 -259 /** -260 * The Proxy Server. +246 private ReportGenerator.Format reportFormat = ReportGenerator.Format.HTML; +247 +248 /** +249 * Get the value of reportFormat. +250 * +251 * @return the value of reportFormat +252 */ +253 public ReportGenerator.Format getReportFormat() { +254 return reportFormat; +255 } +256 +257 /** +258 * Set the value of reportFormat. +259 * +260 * @param reportFormat new value of reportFormat 261 */ -262 private String proxyServer; -263 -264 /** -265 * Get the value of proxyServer. -266 * -267 * @return the value of proxyServer +262 public void setReportFormat(ReportGenerator.Format reportFormat) { +263 this.reportFormat = reportFormat; +264 } +265 +266 /** +267 * The Proxy Server. 268 */ -269 public String getProxyServer() { -270 return proxyServer; -271 } -272 -273 /** -274 * Set the value of proxyServer. -275 * -276 * @param proxyServer new value of proxyServer -277 */ -278 public void setProxyServer(String proxyServer) { -279 this.proxyServer = proxyServer; -280 } -281 -282 /** -283 * Get the value of proxyServer. -284 * -285 * @return the value of proxyServer -286 * @deprecated use {@link org.owasp.dependencycheck.agent.DependencyCheckScanAgent#getProxyServer()} instead -287 */ -288 @Deprecated -289 public String getProxyUrl() { -290 return proxyServer; -291 } -292 -293 /** -294 * Set the value of proxyServer. -295 * -296 * @param proxyUrl new value of proxyServer -297 * @deprecated use {@link org.owasp.dependencycheck.agent.DependencyCheckScanAgent#setProxyServer(java.lang.String) -298 * } instead -299 */ -300 @Deprecated -301 public void setProxyUrl(String proxyUrl) { -302 this.proxyServer = proxyUrl; -303 } -304 -305 /** -306 * The Proxy Port. -307 */ -308 private String proxyPort; -309 -310 /** -311 * Get the value of proxyPort. -312 * -313 * @return the value of proxyPort -314 */ -315 public String getProxyPort() { -316 return proxyPort; -317 } +269 private String proxyServer; +270 +271 /** +272 * Get the value of proxyServer. +273 * +274 * @return the value of proxyServer +275 */ +276 public String getProxyServer() { +277 return proxyServer; +278 } +279 +280 /** +281 * Set the value of proxyServer. +282 * +283 * @param proxyServer new value of proxyServer +284 */ +285 public void setProxyServer(String proxyServer) { +286 this.proxyServer = proxyServer; +287 } +288 +289 /** +290 * Get the value of proxyServer. +291 * +292 * @return the value of proxyServer +293 * @deprecated use +294 * {@link org.owasp.dependencycheck.agent.DependencyCheckScanAgent#getProxyServer()} +295 * instead +296 */ +297 @Deprecated +298 public String getProxyUrl() { +299 return proxyServer; +300 } +301 +302 /** +303 * Set the value of proxyServer. +304 * +305 * @param proxyUrl new value of proxyServer +306 * @deprecated use {@link org.owasp.dependencycheck.agent.DependencyCheckScanAgent#setProxyServer(java.lang.String) +307 * } instead +308 */ +309 @Deprecated +310 public void setProxyUrl(String proxyUrl) { +311 this.proxyServer = proxyUrl; +312 } +313 +314 /** +315 * The Proxy Port. +316 */ +317 private String proxyPort; 318 319 /** -320 * Set the value of proxyPort. +320 * Get the value of proxyPort. 321 * -322 * @param proxyPort new value of proxyPort +322 * @return the value of proxyPort 323 */ -324 public void setProxyPort(String proxyPort) { -325 this.proxyPort = proxyPort; +324 public String getProxyPort() { +325 return proxyPort; 326 } 327 328 /** -329 * The Proxy username. -330 */ -331 private String proxyUsername; -332 -333 /** -334 * Get the value of proxyUsername. -335 * -336 * @return the value of proxyUsername -337 */ -338 public String getProxyUsername() { -339 return proxyUsername; -340 } +329 * Set the value of proxyPort. +330 * +331 * @param proxyPort new value of proxyPort +332 */ +333 public void setProxyPort(String proxyPort) { +334 this.proxyPort = proxyPort; +335 } +336 +337 /** +338 * The Proxy username. +339 */ +340 private String proxyUsername; 341 342 /** -343 * Set the value of proxyUsername. +343 * Get the value of proxyUsername. 344 * -345 * @param proxyUsername new value of proxyUsername +345 * @return the value of proxyUsername 346 */ -347 public void setProxyUsername(String proxyUsername) { -348 this.proxyUsername = proxyUsername; +347 public String getProxyUsername() { +348 return proxyUsername; 349 } 350 351 /** -352 * The Proxy password. -353 */ -354 private String proxyPassword; -355 -356 /** -357 * Get the value of proxyPassword. -358 * -359 * @return the value of proxyPassword -360 */ -361 public String getProxyPassword() { -362 return proxyPassword; -363 } +352 * Set the value of proxyUsername. +353 * +354 * @param proxyUsername new value of proxyUsername +355 */ +356 public void setProxyUsername(String proxyUsername) { +357 this.proxyUsername = proxyUsername; +358 } +359 +360 /** +361 * The Proxy password. +362 */ +363 private String proxyPassword; 364 365 /** -366 * Set the value of proxyPassword. +366 * Get the value of proxyPassword. 367 * -368 * @param proxyPassword new value of proxyPassword +368 * @return the value of proxyPassword 369 */ -370 public void setProxyPassword(String proxyPassword) { -371 this.proxyPassword = proxyPassword; +370 public String getProxyPassword() { +371 return proxyPassword; 372 } 373 374 /** -375 * The Connection Timeout. -376 */ -377 private String connectionTimeout; -378 -379 /** -380 * Get the value of connectionTimeout. -381 * -382 * @return the value of connectionTimeout -383 */ -384 public String getConnectionTimeout() { -385 return connectionTimeout; -386 } +375 * Set the value of proxyPassword. +376 * +377 * @param proxyPassword new value of proxyPassword +378 */ +379 public void setProxyPassword(String proxyPassword) { +380 this.proxyPassword = proxyPassword; +381 } +382 +383 /** +384 * The Connection Timeout. +385 */ +386 private String connectionTimeout; 387 388 /** -389 * Set the value of connectionTimeout. +389 * Get the value of connectionTimeout. 390 * -391 * @param connectionTimeout new value of connectionTimeout +391 * @return the value of connectionTimeout 392 */ -393 public void setConnectionTimeout(String connectionTimeout) { -394 this.connectionTimeout = connectionTimeout; +393 public String getConnectionTimeout() { +394 return connectionTimeout; 395 } 396 397 /** -398 * The file path used for verbose logging. -399 */ -400 private String logFile = null; -401 -402 /** -403 * Get the value of logFile. -404 * -405 * @return the value of logFile -406 */ -407 public String getLogFile() { -408 return logFile; -409 } +398 * Set the value of connectionTimeout. +399 * +400 * @param connectionTimeout new value of connectionTimeout +401 */ +402 public void setConnectionTimeout(String connectionTimeout) { +403 this.connectionTimeout = connectionTimeout; +404 } +405 +406 /** +407 * The file path used for verbose logging. +408 */ +409 private String logFile = null; 410 411 /** -412 * Set the value of logFile. +412 * Get the value of logFile. 413 * -414 * @param logFile new value of logFile +414 * @return the value of logFile 415 */ -416 public void setLogFile(String logFile) { -417 this.logFile = logFile; +416 public String getLogFile() { +417 return logFile; 418 } 419 420 /** -421 * The path to the suppression file. -422 */ -423 private String suppressionFile; -424 -425 /** -426 * Get the value of suppressionFile. -427 * -428 * @return the value of suppressionFile -429 */ -430 public String getSuppressionFile() { -431 return suppressionFile; -432 } +421 * Set the value of logFile. +422 * +423 * @param logFile new value of logFile +424 */ +425 public void setLogFile(String logFile) { +426 this.logFile = logFile; +427 } +428 +429 /** +430 * The path to the suppression file. +431 */ +432 private String suppressionFile; 433 434 /** -435 * Set the value of suppressionFile. +435 * Get the value of suppressionFile. 436 * -437 * @param suppressionFile new value of suppressionFile +437 * @return the value of suppressionFile 438 */ -439 public void setSuppressionFile(String suppressionFile) { -440 this.suppressionFile = suppressionFile; +439 public String getSuppressionFile() { +440 return suppressionFile; 441 } 442 443 /** -444 * flag indicating whether or not to show a summary of findings. -445 */ -446 private boolean showSummary = true; -447 -448 /** -449 * Get the value of showSummary. -450 * -451 * @return the value of showSummary -452 */ -453 public boolean isShowSummary() { -454 return showSummary; -455 } +444 * Set the value of suppressionFile. +445 * +446 * @param suppressionFile new value of suppressionFile +447 */ +448 public void setSuppressionFile(String suppressionFile) { +449 this.suppressionFile = suppressionFile; +450 } +451 +452 /** +453 * flag indicating whether or not to show a summary of findings. +454 */ +455 private boolean showSummary = true; 456 457 /** -458 * Set the value of showSummary. +458 * Get the value of showSummary. 459 * -460 * @param showSummary new value of showSummary +460 * @return the value of showSummary 461 */ -462 public void setShowSummary(boolean showSummary) { -463 this.showSummary = showSummary; +462 public boolean isShowSummary() { +463 return showSummary; 464 } 465 466 /** -467 * Whether or not the Maven Central analyzer is enabled. -468 */ -469 private boolean centralAnalyzerEnabled = true; -470 -471 /** -472 * Get the value of centralAnalyzerEnabled. -473 * -474 * @return the value of centralAnalyzerEnabled -475 */ -476 public boolean isCentralAnalyzerEnabled() { -477 return centralAnalyzerEnabled; -478 } +467 * Set the value of showSummary. +468 * +469 * @param showSummary new value of showSummary +470 */ +471 public void setShowSummary(boolean showSummary) { +472 this.showSummary = showSummary; +473 } +474 +475 /** +476 * Whether or not the Maven Central analyzer is enabled. +477 */ +478 private boolean centralAnalyzerEnabled = true; 479 480 /** -481 * Set the value of centralAnalyzerEnabled. +481 * Get the value of centralAnalyzerEnabled. 482 * -483 * @param centralAnalyzerEnabled new value of centralAnalyzerEnabled +483 * @return the value of centralAnalyzerEnabled 484 */ -485 public void setCentralAnalyzerEnabled(boolean centralAnalyzerEnabled) { -486 this.centralAnalyzerEnabled = centralAnalyzerEnabled; +485 public boolean isCentralAnalyzerEnabled() { +486 return centralAnalyzerEnabled; 487 } 488 489 /** -490 * The URL of Maven Central. -491 */ -492 private String centralUrl; -493 -494 /** -495 * Get the value of centralUrl. -496 * -497 * @return the value of centralUrl -498 */ -499 public String getCentralUrl() { -500 return centralUrl; -501 } +490 * Set the value of centralAnalyzerEnabled. +491 * +492 * @param centralAnalyzerEnabled new value of centralAnalyzerEnabled +493 */ +494 public void setCentralAnalyzerEnabled(boolean centralAnalyzerEnabled) { +495 this.centralAnalyzerEnabled = centralAnalyzerEnabled; +496 } +497 +498 /** +499 * The URL of Maven Central. +500 */ +501 private String centralUrl; 502 503 /** -504 * Set the value of centralUrl. +504 * Get the value of centralUrl. 505 * -506 * @param centralUrl new value of centralUrl +506 * @return the value of centralUrl 507 */ -508 public void setCentralUrl(String centralUrl) { -509 this.centralUrl = centralUrl; +508 public String getCentralUrl() { +509 return centralUrl; 510 } 511 512 /** -513 * Whether or not the nexus analyzer is enabled. -514 */ -515 private boolean nexusAnalyzerEnabled = true; -516 -517 /** -518 * Get the value of nexusAnalyzerEnabled. -519 * -520 * @return the value of nexusAnalyzerEnabled -521 */ -522 public boolean isNexusAnalyzerEnabled() { -523 return nexusAnalyzerEnabled; -524 } +513 * Set the value of centralUrl. +514 * +515 * @param centralUrl new value of centralUrl +516 */ +517 public void setCentralUrl(String centralUrl) { +518 this.centralUrl = centralUrl; +519 } +520 +521 /** +522 * Whether or not the nexus analyzer is enabled. +523 */ +524 private boolean nexusAnalyzerEnabled = true; 525 526 /** -527 * Set the value of nexusAnalyzerEnabled. +527 * Get the value of nexusAnalyzerEnabled. 528 * -529 * @param nexusAnalyzerEnabled new value of nexusAnalyzerEnabled +529 * @return the value of nexusAnalyzerEnabled 530 */ -531 public void setNexusAnalyzerEnabled(boolean nexusAnalyzerEnabled) { -532 this.nexusAnalyzerEnabled = nexusAnalyzerEnabled; +531 public boolean isNexusAnalyzerEnabled() { +532 return nexusAnalyzerEnabled; 533 } 534 535 /** -536 * The URL of the Nexus server. -537 */ -538 private String nexusUrl; -539 -540 /** -541 * Get the value of nexusUrl. -542 * -543 * @return the value of nexusUrl -544 */ -545 public String getNexusUrl() { -546 return nexusUrl; -547 } +536 * Set the value of nexusAnalyzerEnabled. +537 * +538 * @param nexusAnalyzerEnabled new value of nexusAnalyzerEnabled +539 */ +540 public void setNexusAnalyzerEnabled(boolean nexusAnalyzerEnabled) { +541 this.nexusAnalyzerEnabled = nexusAnalyzerEnabled; +542 } +543 +544 /** +545 * The URL of the Nexus server. +546 */ +547 private String nexusUrl; 548 549 /** -550 * Set the value of nexusUrl. +550 * Get the value of nexusUrl. 551 * -552 * @param nexusUrl new value of nexusUrl +552 * @return the value of nexusUrl 553 */ -554 public void setNexusUrl(String nexusUrl) { -555 this.nexusUrl = nexusUrl; +554 public String getNexusUrl() { +555 return nexusUrl; 556 } 557 558 /** -559 * Whether or not the defined proxy should be used when connecting to Nexus. -560 */ -561 private boolean nexusUsesProxy = true; -562 -563 /** -564 * Get the value of nexusUsesProxy. -565 * -566 * @return the value of nexusUsesProxy -567 */ -568 public boolean isNexusUsesProxy() { -569 return nexusUsesProxy; -570 } +559 * Set the value of nexusUrl. +560 * +561 * @param nexusUrl new value of nexusUrl +562 */ +563 public void setNexusUrl(String nexusUrl) { +564 this.nexusUrl = nexusUrl; +565 } +566 +567 /** +568 * Whether or not the defined proxy should be used when connecting to Nexus. +569 */ +570 private boolean nexusUsesProxy = true; 571 572 /** -573 * Set the value of nexusUsesProxy. +573 * Get the value of nexusUsesProxy. 574 * -575 * @param nexusUsesProxy new value of nexusUsesProxy +575 * @return the value of nexusUsesProxy 576 */ -577 public void setNexusUsesProxy(boolean nexusUsesProxy) { -578 this.nexusUsesProxy = nexusUsesProxy; +577 public boolean isNexusUsesProxy() { +578 return nexusUsesProxy; 579 } 580 581 /** -582 * The database driver name; such as org.h2.Driver. -583 */ -584 private String databaseDriverName; -585 -586 /** -587 * Get the value of databaseDriverName. -588 * -589 * @return the value of databaseDriverName -590 */ -591 public String getDatabaseDriverName() { -592 return databaseDriverName; -593 } +582 * Set the value of nexusUsesProxy. +583 * +584 * @param nexusUsesProxy new value of nexusUsesProxy +585 */ +586 public void setNexusUsesProxy(boolean nexusUsesProxy) { +587 this.nexusUsesProxy = nexusUsesProxy; +588 } +589 +590 /** +591 * The database driver name; such as org.h2.Driver. +592 */ +593 private String databaseDriverName; 594 595 /** -596 * Set the value of databaseDriverName. +596 * Get the value of databaseDriverName. 597 * -598 * @param databaseDriverName new value of databaseDriverName +598 * @return the value of databaseDriverName 599 */ -600 public void setDatabaseDriverName(String databaseDriverName) { -601 this.databaseDriverName = databaseDriverName; +600 public String getDatabaseDriverName() { +601 return databaseDriverName; 602 } 603 604 /** -605 * The path to the database driver JAR file if it is not on the class path. -606 */ -607 private String databaseDriverPath; -608 -609 /** -610 * Get the value of databaseDriverPath. -611 * -612 * @return the value of databaseDriverPath -613 */ -614 public String getDatabaseDriverPath() { -615 return databaseDriverPath; -616 } +605 * Set the value of databaseDriverName. +606 * +607 * @param databaseDriverName new value of databaseDriverName +608 */ +609 public void setDatabaseDriverName(String databaseDriverName) { +610 this.databaseDriverName = databaseDriverName; +611 } +612 +613 /** +614 * The path to the database driver JAR file if it is not on the class path. +615 */ +616 private String databaseDriverPath; 617 618 /** -619 * Set the value of databaseDriverPath. +619 * Get the value of databaseDriverPath. 620 * -621 * @param databaseDriverPath new value of databaseDriverPath +621 * @return the value of databaseDriverPath 622 */ -623 public void setDatabaseDriverPath(String databaseDriverPath) { -624 this.databaseDriverPath = databaseDriverPath; +623 public String getDatabaseDriverPath() { +624 return databaseDriverPath; 625 } 626 627 /** -628 * The database connection string. -629 */ -630 private String connectionString; -631 -632 /** -633 * Get the value of connectionString. -634 * -635 * @return the value of connectionString -636 */ -637 public String getConnectionString() { -638 return connectionString; -639 } +628 * Set the value of databaseDriverPath. +629 * +630 * @param databaseDriverPath new value of databaseDriverPath +631 */ +632 public void setDatabaseDriverPath(String databaseDriverPath) { +633 this.databaseDriverPath = databaseDriverPath; +634 } +635 +636 /** +637 * The database connection string. +638 */ +639 private String connectionString; 640 641 /** -642 * Set the value of connectionString. +642 * Get the value of connectionString. 643 * -644 * @param connectionString new value of connectionString +644 * @return the value of connectionString 645 */ -646 public void setConnectionString(String connectionString) { -647 this.connectionString = connectionString; +646 public String getConnectionString() { +647 return connectionString; 648 } 649 650 /** -651 * The user name for connecting to the database. -652 */ -653 private String databaseUser; -654 -655 /** -656 * Get the value of databaseUser. -657 * -658 * @return the value of databaseUser -659 */ -660 public String getDatabaseUser() { -661 return databaseUser; -662 } +651 * Set the value of connectionString. +652 * +653 * @param connectionString new value of connectionString +654 */ +655 public void setConnectionString(String connectionString) { +656 this.connectionString = connectionString; +657 } +658 +659 /** +660 * The user name for connecting to the database. +661 */ +662 private String databaseUser; 663 664 /** -665 * Set the value of databaseUser. +665 * Get the value of databaseUser. 666 * -667 * @param databaseUser new value of databaseUser +667 * @return the value of databaseUser 668 */ -669 public void setDatabaseUser(String databaseUser) { -670 this.databaseUser = databaseUser; +669 public String getDatabaseUser() { +670 return databaseUser; 671 } 672 673 /** -674 * The password to use when connecting to the database. -675 */ -676 private String databasePassword; -677 -678 /** -679 * Get the value of databasePassword. -680 * -681 * @return the value of databasePassword -682 */ -683 public String getDatabasePassword() { -684 return databasePassword; -685 } +674 * Set the value of databaseUser. +675 * +676 * @param databaseUser new value of databaseUser +677 */ +678 public void setDatabaseUser(String databaseUser) { +679 this.databaseUser = databaseUser; +680 } +681 +682 /** +683 * The password to use when connecting to the database. +684 */ +685 private String databasePassword; 686 687 /** -688 * Set the value of databasePassword. +688 * Get the value of databasePassword. 689 * -690 * @param databasePassword new value of databasePassword +690 * @return the value of databasePassword 691 */ -692 public void setDatabasePassword(String databasePassword) { -693 this.databasePassword = databasePassword; +692 public String getDatabasePassword() { +693 return databasePassword; 694 } 695 696 /** -697 * Additional ZIP File extensions to add analyze. This should be a comma-separated list of file extensions to treat like ZIP -698 * files. -699 */ -700 private String zipExtensions; -701 -702 /** -703 * Get the value of zipExtensions. -704 * -705 * @return the value of zipExtensions -706 */ -707 public String getZipExtensions() { -708 return zipExtensions; -709 } +697 * Set the value of databasePassword. +698 * +699 * @param databasePassword new value of databasePassword +700 */ +701 public void setDatabasePassword(String databasePassword) { +702 this.databasePassword = databasePassword; +703 } +704 +705 /** +706 * Additional ZIP File extensions to add analyze. This should be a +707 * comma-separated list of file extensions to treat like ZIP files. +708 */ +709 private String zipExtensions; 710 711 /** -712 * Set the value of zipExtensions. +712 * Get the value of zipExtensions. 713 * -714 * @param zipExtensions new value of zipExtensions +714 * @return the value of zipExtensions 715 */ -716 public void setZipExtensions(String zipExtensions) { -717 this.zipExtensions = zipExtensions; +716 public String getZipExtensions() { +717 return zipExtensions; 718 } 719 720 /** -721 * The url for the modified NVD CVE (1.2 schema). -722 */ -723 private String cveUrl12Modified; -724 -725 /** -726 * Get the value of cveUrl12Modified. -727 * -728 * @return the value of cveUrl12Modified -729 */ -730 public String getCveUrl12Modified() { -731 return cveUrl12Modified; -732 } +721 * Set the value of zipExtensions. +722 * +723 * @param zipExtensions new value of zipExtensions +724 */ +725 public void setZipExtensions(String zipExtensions) { +726 this.zipExtensions = zipExtensions; +727 } +728 +729 /** +730 * The url for the modified NVD CVE (1.2 schema). +731 */ +732 private String cveUrl12Modified; 733 734 /** -735 * Set the value of cveUrl12Modified. +735 * Get the value of cveUrl12Modified. 736 * -737 * @param cveUrl12Modified new value of cveUrl12Modified +737 * @return the value of cveUrl12Modified 738 */ -739 public void setCveUrl12Modified(String cveUrl12Modified) { -740 this.cveUrl12Modified = cveUrl12Modified; +739 public String getCveUrl12Modified() { +740 return cveUrl12Modified; 741 } 742 743 /** -744 * The url for the modified NVD CVE (2.0 schema). -745 */ -746 private String cveUrl20Modified; -747 -748 /** -749 * Get the value of cveUrl20Modified. -750 * -751 * @return the value of cveUrl20Modified -752 */ -753 public String getCveUrl20Modified() { -754 return cveUrl20Modified; -755 } +744 * Set the value of cveUrl12Modified. +745 * +746 * @param cveUrl12Modified new value of cveUrl12Modified +747 */ +748 public void setCveUrl12Modified(String cveUrl12Modified) { +749 this.cveUrl12Modified = cveUrl12Modified; +750 } +751 +752 /** +753 * The url for the modified NVD CVE (2.0 schema). +754 */ +755 private String cveUrl20Modified; 756 757 /** -758 * Set the value of cveUrl20Modified. +758 * Get the value of cveUrl20Modified. 759 * -760 * @param cveUrl20Modified new value of cveUrl20Modified +760 * @return the value of cveUrl20Modified 761 */ -762 public void setCveUrl20Modified(String cveUrl20Modified) { -763 this.cveUrl20Modified = cveUrl20Modified; +762 public String getCveUrl20Modified() { +763 return cveUrl20Modified; 764 } 765 766 /** -767 * Base Data Mirror URL for CVE 1.2. -768 */ -769 private String cveUrl12Base; -770 -771 /** -772 * Get the value of cveUrl12Base. -773 * -774 * @return the value of cveUrl12Base -775 */ -776 public String getCveUrl12Base() { -777 return cveUrl12Base; -778 } +767 * Set the value of cveUrl20Modified. +768 * +769 * @param cveUrl20Modified new value of cveUrl20Modified +770 */ +771 public void setCveUrl20Modified(String cveUrl20Modified) { +772 this.cveUrl20Modified = cveUrl20Modified; +773 } +774 +775 /** +776 * Base Data Mirror URL for CVE 1.2. +777 */ +778 private String cveUrl12Base; 779 780 /** -781 * Set the value of cveUrl12Base. +781 * Get the value of cveUrl12Base. 782 * -783 * @param cveUrl12Base new value of cveUrl12Base +783 * @return the value of cveUrl12Base 784 */ -785 public void setCveUrl12Base(String cveUrl12Base) { -786 this.cveUrl12Base = cveUrl12Base; +785 public String getCveUrl12Base() { +786 return cveUrl12Base; 787 } 788 789 /** -790 * Data Mirror URL for CVE 2.0. -791 */ -792 private String cveUrl20Base; -793 -794 /** -795 * Get the value of cveUrl20Base. -796 * -797 * @return the value of cveUrl20Base -798 */ -799 public String getCveUrl20Base() { -800 return cveUrl20Base; -801 } +790 * Set the value of cveUrl12Base. +791 * +792 * @param cveUrl12Base new value of cveUrl12Base +793 */ +794 public void setCveUrl12Base(String cveUrl12Base) { +795 this.cveUrl12Base = cveUrl12Base; +796 } +797 +798 /** +799 * Data Mirror URL for CVE 2.0. +800 */ +801 private String cveUrl20Base; 802 803 /** -804 * Set the value of cveUrl20Base. +804 * Get the value of cveUrl20Base. 805 * -806 * @param cveUrl20Base new value of cveUrl20Base +806 * @return the value of cveUrl20Base 807 */ -808 public void setCveUrl20Base(String cveUrl20Base) { -809 this.cveUrl20Base = cveUrl20Base; +808 public String getCveUrl20Base() { +809 return cveUrl20Base; 810 } 811 812 /** -813 * The path to Mono for .NET assembly analysis on non-windows systems. -814 */ -815 private String pathToMono; -816 -817 /** -818 * Get the value of pathToMono. -819 * -820 * @return the value of pathToMono -821 */ -822 public String getPathToMono() { -823 return pathToMono; -824 } +813 * Set the value of cveUrl20Base. +814 * +815 * @param cveUrl20Base new value of cveUrl20Base +816 */ +817 public void setCveUrl20Base(String cveUrl20Base) { +818 this.cveUrl20Base = cveUrl20Base; +819 } +820 +821 /** +822 * The path to Mono for .NET assembly analysis on non-windows systems. +823 */ +824 private String pathToMono; 825 826 /** -827 * Set the value of pathToMono. +827 * Get the value of pathToMono. 828 * -829 * @param pathToMono new value of pathToMono +829 * @return the value of pathToMono 830 */ -831 public void setPathToMono(String pathToMono) { -832 this.pathToMono = pathToMono; +831 public String getPathToMono() { +832 return pathToMono; 833 } 834 835 /** -836 * Executes the Dependency-Check on the dependent libraries. +836 * Set the value of pathToMono. 837 * -838 * @return the Engine used to scan the dependencies. -839 * @throws org.owasp.dependencycheck.data.nvdcve.DatabaseException thrown if there is an exception connecting to the database -840 */ -841 private Engine executeDependencyCheck() throws DatabaseException { -842 populateSettings(); -843 final Engine engine = new Engine(); -844 engine.setDependencies(this.dependencies); -845 engine.analyzeDependencies(); -846 return engine; -847 } -848 -849 /** -850 * Generates the reports for a given dependency-check engine. -851 * -852 * @param engine a dependency-check engine -853 * @param outDirectory the directory to write the reports to -854 */ -855 private void generateExternalReports(Engine engine, File outDirectory) { -856 DatabaseProperties prop = null; -857 CveDB cve = null; -858 try { -859 cve = new CveDB(); -860 cve.open(); -861 prop = cve.getDatabaseProperties(); -862 } catch (DatabaseException ex) { -863 LOGGER.debug("Unable to retrieve DB Properties", ex); -864 } finally { -865 if (cve != null) { -866 cve.close(); -867 } -868 } -869 final ReportGenerator r = new ReportGenerator(this.applicationName, engine.getDependencies(), engine.getAnalyzers(), prop); -870 try { -871 r.generateReports(outDirectory.getCanonicalPath(), this.reportFormat.name()); -872 } catch (IOException ex) { -873 LOGGER.error( -874 "Unexpected exception occurred during analysis; please see the verbose error log for more details."); -875 LOGGER.debug("", ex); -876 } catch (Throwable ex) { -877 LOGGER.error( -878 "Unexpected exception occurred during analysis; please see the verbose error log for more details."); -879 LOGGER.debug("", ex); -880 } -881 } -882 -883 /** -884 * Takes the properties supplied and updates the dependency-check settings. Additionally, this sets the system properties -885 * required to change the proxy server, port, and connection timeout. -886 */ -887 private void populateSettings() { -888 Settings.initialize(); -889 if (dataDirectory != null) { -890 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory); -891 } else { -892 final File jarPath = new File(DependencyCheckScanAgent.class.getProtectionDomain().getCodeSource().getLocation().getPath()); -893 final File base = jarPath.getParentFile(); -894 final String sub = Settings.getString(Settings.KEYS.DATA_DIRECTORY); -895 final File dataDir = new File(base, sub); -896 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath()); -897 } -898 -899 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate); -900 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_SERVER, proxyServer); -901 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PORT, proxyPort); -902 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_USERNAME, proxyUsername); -903 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PASSWORD, proxyPassword); -904 Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout); -905 Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile); -906 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, centralAnalyzerEnabled); -907 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_CENTRAL_URL, centralUrl); -908 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled); -909 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl); -910 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy); -911 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName); -912 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath); -913 Settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString); -914 Settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser); -915 Settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword); -916 Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions); -917 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_12_URL, cveUrl12Modified); -918 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_20_URL, cveUrl20Modified); -919 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_1_2, cveUrl12Base); -920 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_2_0, cveUrl20Base); -921 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono); -922 } -923 -924 /** -925 * Executes the dependency-check and generates the report. -926 * -927 * @return a reference to the engine used to perform the scan. -928 * @throws org.owasp.dependencycheck.exception.ScanAgentException thrown if there is an exception executing the scan. -929 */ -930 public Engine execute() throws ScanAgentException { -931 Engine engine = null; -932 try { -933 engine = executeDependencyCheck(); -934 if (this.generateReport) { -935 generateExternalReports(engine, new File(this.reportOutputDirectory)); -936 } -937 if (this.showSummary) { -938 showSummary(engine.getDependencies()); -939 } -940 if (this.failBuildOnCVSS <= 10) { -941 checkForFailure(engine.getDependencies()); -942 } -943 } catch (DatabaseException ex) { -944 LOGGER.error( -945 "Unable to connect to the dependency-check database; analysis has stopped"); -946 LOGGER.debug("", ex); -947 } finally { -948 Settings.cleanup(true); -949 if (engine != null) { -950 engine.cleanup(); -951 } -952 } -953 return engine; -954 } -955 -956 /** -957 * Checks to see if a vulnerability has been identified with a CVSS score that is above the threshold set in the -958 * configuration. -959 * -960 * @param dependencies the list of dependency objects -961 * @throws org.owasp.dependencycheck.exception.ScanAgentException thrown if there is an exception executing the scan. -962 */ -963 private void checkForFailure(List<Dependency> dependencies) throws ScanAgentException { -964 final StringBuilder ids = new StringBuilder(); -965 for (Dependency d : dependencies) { -966 boolean addName = true; -967 for (Vulnerability v : d.getVulnerabilities()) { -968 if (v.getCvssScore() >= failBuildOnCVSS) { -969 if (addName) { -970 addName = false; -971 ids.append(NEW_LINE).append(d.getFileName()).append(": "); -972 ids.append(v.getName()); -973 } else { -974 ids.append(", ").append(v.getName()); -975 } -976 } -977 } -978 } -979 if (ids.length() > 0) { -980 final String msg = String.format("%n%nDependency-Check Failure:%n" -981 + "One or more dependencies were identified with vulnerabilities that have a CVSS score greater then '%.1f': %s%n" -982 + "See the dependency-check report for more details.%n%n", failBuildOnCVSS, ids.toString()); -983 -984 throw new ScanAgentException(msg); -985 } -986 } -987 -988 /** -989 * Generates a warning message listing a summary of dependencies and their associated CPE and CVE entries. -990 * -991 * @param dependencies a list of dependency objects -992 */ -993 private void showSummary(List<Dependency> dependencies) { -994 final StringBuilder summary = new StringBuilder(); -995 for (Dependency d : dependencies) { -996 boolean firstEntry = true; -997 final StringBuilder ids = new StringBuilder(); -998 for (Vulnerability v : d.getVulnerabilities()) { -999 if (firstEntry) { -1000 firstEntry = false; -1001 } else { -1002 ids.append(", "); -1003 } -1004 ids.append(v.getName()); -1005 } -1006 if (ids.length() > 0) { -1007 summary.append(d.getFileName()).append(" ("); -1008 firstEntry = true; -1009 for (Identifier id : d.getIdentifiers()) { -1010 if (firstEntry) { -1011 firstEntry = false; -1012 } else { -1013 summary.append(", "); -1014 } -1015 summary.append(id.getValue()); -1016 } -1017 summary.append(") : ").append(ids).append(NEW_LINE); -1018 } -1019 } -1020 if (summary.length() > 0) { -1021 LOGGER.warn("\n\nOne or more dependencies were identified with known vulnerabilities:\n\n{}\n\n" -1022 + "See the dependency-check report for more details.\n\n", -1023 summary.toString()); -1024 } -1025 } -1026 -1027 } +838 * @param pathToMono new value of pathToMono +839 */ +840 public void setPathToMono(String pathToMono) { +841 this.pathToMono = pathToMono; +842 } +843 +844 /** +845 * Executes the Dependency-Check on the dependent libraries. +846 * +847 * @return the Engine used to scan the dependencies. +848 * @throws ExceptionCollection a collection of one or more exceptions that +849 * occurred during analysis. +850 */ +851 private Engine executeDependencyCheck() throws ExceptionCollection { +852 populateSettings(); +853 final Engine engine; +854 try { +855 engine = new Engine(); +856 } catch (DatabaseException ex) { +857 throw new ExceptionCollection(ex, true); +858 } +859 engine.setDependencies(this.dependencies); +860 engine.analyzeDependencies(); +861 return engine; +862 } +863 +864 /** +865 * Generates the reports for a given dependency-check engine. +866 * +867 * @param engine a dependency-check engine +868 * @param outDirectory the directory to write the reports to +869 */ +870 private void generateExternalReports(Engine engine, File outDirectory) { +871 DatabaseProperties prop = null; +872 CveDB cve = null; +873 try { +874 cve = new CveDB(); +875 cve.open(); +876 prop = cve.getDatabaseProperties(); +877 } catch (DatabaseException ex) { +878 LOGGER.debug("Unable to retrieve DB Properties", ex); +879 } finally { +880 if (cve != null) { +881 cve.close(); +882 } +883 } +884 final ReportGenerator r = new ReportGenerator(this.applicationName, engine.getDependencies(), engine.getAnalyzers(), prop); +885 try { +886 r.generateReports(outDirectory.getCanonicalPath(), this.reportFormat.name()); +887 } catch (IOException ex) { +888 LOGGER.error( +889 "Unexpected exception occurred during analysis; please see the verbose error log for more details."); +890 LOGGER.debug("", ex); +891 } catch (Throwable ex) { +892 LOGGER.error( +893 "Unexpected exception occurred during analysis; please see the verbose error log for more details."); +894 LOGGER.debug("", ex); +895 } +896 } +897 +898 /** +899 * Takes the properties supplied and updates the dependency-check settings. +900 * Additionally, this sets the system properties required to change the +901 * proxy server, port, and connection timeout. +902 */ +903 private void populateSettings() { +904 Settings.initialize(); +905 if (dataDirectory != null) { +906 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory); +907 } else { +908 final File jarPath = new File(DependencyCheckScanAgent.class.getProtectionDomain().getCodeSource().getLocation().getPath()); +909 final File base = jarPath.getParentFile(); +910 final String sub = Settings.getString(Settings.KEYS.DATA_DIRECTORY); +911 final File dataDir = new File(base, sub); +912 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath()); +913 } +914 +915 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate); +916 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_SERVER, proxyServer); +917 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PORT, proxyPort); +918 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_USERNAME, proxyUsername); +919 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PASSWORD, proxyPassword); +920 Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout); +921 Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile); +922 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, centralAnalyzerEnabled); +923 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_CENTRAL_URL, centralUrl); +924 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled); +925 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl); +926 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy); +927 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName); +928 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath); +929 Settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString); +930 Settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser); +931 Settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword); +932 Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions); +933 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_12_URL, cveUrl12Modified); +934 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_20_URL, cveUrl20Modified); +935 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_1_2, cveUrl12Base); +936 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_2_0, cveUrl20Base); +937 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono); +938 } +939 +940 /** +941 * Executes the dependency-check and generates the report. +942 * +943 * @return a reference to the engine used to perform the scan. +944 * @throws org.owasp.dependencycheck.exception.ScanAgentException thrown if +945 * there is an exception executing the scan. +946 */ +947 public Engine execute() throws ScanAgentException { +948 Engine engine = null; +949 try { +950 engine = executeDependencyCheck(); +951 if (this.generateReport) { +952 generateExternalReports(engine, new File(this.reportOutputDirectory)); +953 } +954 if (this.showSummary) { +955 showSummary(engine.getDependencies()); +956 } +957 if (this.failBuildOnCVSS <= 10) { +958 checkForFailure(engine.getDependencies()); +959 } +960 } catch (ExceptionCollection ex) { +961 if (ex.isFatal()) { +962 LOGGER.error("A fatal exception occurred during analysis; analysis has stopped. Please see the debug log for more details."); +963 LOGGER.debug("", ex); +964 } +965 throw new ScanAgentException("One or more exceptions occurred during analysis; please see the debug log for more details.", ex); +966 } finally { +967 Settings.cleanup(true); +968 if (engine != null) { +969 engine.cleanup(); +970 } +971 } +972 return engine; +973 } +974 +975 /** +976 * Checks to see if a vulnerability has been identified with a CVSS score +977 * that is above the threshold set in the configuration. +978 * +979 * @param dependencies the list of dependency objects +980 * @throws org.owasp.dependencycheck.exception.ScanAgentException thrown if +981 * there is an exception executing the scan. +982 */ +983 private void checkForFailure(List<Dependency> dependencies) throws ScanAgentException { +984 final StringBuilder ids = new StringBuilder(); +985 for (Dependency d : dependencies) { +986 boolean addName = true; +987 for (Vulnerability v : d.getVulnerabilities()) { +988 if (v.getCvssScore() >= failBuildOnCVSS) { +989 if (addName) { +990 addName = false; +991 ids.append(NEW_LINE).append(d.getFileName()).append(": "); +992 ids.append(v.getName()); +993 } else { +994 ids.append(", ").append(v.getName()); +995 } +996 } +997 } +998 } +999 if (ids.length() > 0) { +1000 final String msg = String.format("%n%nDependency-Check Failure:%n" +1001 + "One or more dependencies were identified with vulnerabilities that have a CVSS score greater then '%.1f': %s%n" +1002 + "See the dependency-check report for more details.%n%n", failBuildOnCVSS, ids.toString()); +1003 +1004 throw new ScanAgentException(msg); +1005 } +1006 } +1007 +1008 /** +1009 * Generates a warning message listing a summary of dependencies and their +1010 * associated CPE and CVE entries. +1011 * +1012 * @param dependencies a list of dependency objects +1013 */ +1014 private void showSummary(List<Dependency> dependencies) { +1015 final StringBuilder summary = new StringBuilder(); +1016 for (Dependency d : dependencies) { +1017 boolean firstEntry = true; +1018 final StringBuilder ids = new StringBuilder(); +1019 for (Vulnerability v : d.getVulnerabilities()) { +1020 if (firstEntry) { +1021 firstEntry = false; +1022 } else { +1023 ids.append(", "); +1024 } +1025 ids.append(v.getName()); +1026 } +1027 if (ids.length() > 0) { +1028 summary.append(d.getFileName()).append(" ("); +1029 firstEntry = true; +1030 for (Identifier id : d.getIdentifiers()) { +1031 if (firstEntry) { +1032 firstEntry = false; +1033 } else { +1034 summary.append(", "); +1035 } +1036 summary.append(id.getValue()); +1037 } +1038 summary.append(") : ").append(ids).append(NEW_LINE); +1039 } +1040 } +1041 if (summary.length() > 0) { +1042 LOGGER.warn("\n\nOne or more dependencies were identified with known vulnerabilities:\n\n{}\n\n" +1043 + "See the dependency-check report for more details.\n\n", +1044 summary.toString()); +1045 } +1046 } +1047 +1048 }
      diff --git a/xref/org/owasp/dependencycheck/agent/package-frame.html b/xref/org/owasp/dependencycheck/agent/package-frame.html index 038470e7a..50f477099 100644 --- a/xref/org/owasp/dependencycheck/agent/package-frame.html +++ b/xref/org/owasp/dependencycheck/agent/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.agent + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.agent diff --git a/xref/org/owasp/dependencycheck/agent/package-summary.html b/xref/org/owasp/dependencycheck/agent/package-summary.html index 682059143..66f186594 100644 --- a/xref/org/owasp/dependencycheck/agent/package-summary.html +++ b/xref/org/owasp/dependencycheck/agent/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.agent + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.agent diff --git a/xref/org/owasp/dependencycheck/analyzer/AbstractAnalyzer.html b/xref/org/owasp/dependencycheck/analyzer/AbstractAnalyzer.html index 076b5f721..a7a1237ad 100644 --- a/xref/org/owasp/dependencycheck/analyzer/AbstractAnalyzer.html +++ b/xref/org/owasp/dependencycheck/analyzer/AbstractAnalyzer.html @@ -25,32 +25,36 @@ 17 */ 18 package org.owasp.dependencycheck.analyzer; 19 -20 /** -21 * -22 * @author Jeremy Long -23 */ -24 public abstract class AbstractAnalyzer implements Analyzer { -25 -26 /** -27 * The initialize method does nothing for this Analyzer. -28 * -29 * @throws Exception thrown if there is an exception -30 */ -31 @Override -32 public void initialize() throws Exception { -33 //do nothing -34 } -35 -36 /** -37 * The close method does nothing for this Analyzer. -38 * -39 * @throws Exception thrown if there is an exception -40 */ -41 @Override -42 public void close() throws Exception { -43 //do nothing -44 } -45 } +20 import org.owasp.dependencycheck.exception.InitializationException; +21 +22 /** +23 * Base class for analyzers to avoid code duplication of initialize and close +24 * as most analyzers do not need these methods. +25 * +26 * @author Jeremy Long +27 */ +28 public abstract class AbstractAnalyzer implements Analyzer { +29 +30 /** +31 * The initialize method does nothing for this Analyzer. +32 * +33 * @throws InitializationException thrown if there is an exception +34 */ +35 @Override +36 public void initialize() throws InitializationException { +37 //do nothing +38 } +39 +40 /** +41 * The close method does nothing for this Analyzer. +42 * +43 * @throws Exception thrown if there is an exception +44 */ +45 @Override +46 public void close() throws Exception { +47 //do nothing +48 } +49 }
      diff --git a/xref/org/owasp/dependencycheck/analyzer/AbstractFileTypeAnalyzer.html b/xref/org/owasp/dependencycheck/analyzer/AbstractFileTypeAnalyzer.html index 2c2eaceef..46135995f 100644 --- a/xref/org/owasp/dependencycheck/analyzer/AbstractFileTypeAnalyzer.html +++ b/xref/org/owasp/dependencycheck/analyzer/AbstractFileTypeAnalyzer.html @@ -38,195 +38,206 @@ 30 import java.util.Collections; 31 import java.util.HashSet; 32 import java.util.Set; -33 -34 /** -35 * The base FileTypeAnalyzer that all analyzers that have specific file types they analyze should extend. -36 * -37 * @author Jeremy Long -38 */ -39 public abstract class AbstractFileTypeAnalyzer extends AbstractAnalyzer implements FileTypeAnalyzer { -40 -41 //<editor-fold defaultstate="collapsed" desc="Constructor"> -42 /** -43 * Base constructor that all children must call. This checks the configuration to determine if the analyzer is enabled. -44 */ -45 public AbstractFileTypeAnalyzer() { -46 reset(); -47 } -48 //</editor-fold> -49 -50 //<editor-fold defaultstate="collapsed" desc="Field definitions"> -51 /** -52 * The logger. -53 */ -54 private static final Logger LOGGER = LoggerFactory.getLogger(AbstractFileTypeAnalyzer.class); -55 /** -56 * Whether the file type analyzer detected any files it needs to analyze. -57 */ -58 private boolean filesMatched = false; -59 -60 /** -61 * Get the value of filesMatched. A flag indicating whether the scan included any file types this analyzer supports. -62 * -63 * @return the value of filesMatched -64 */ -65 protected boolean isFilesMatched() { -66 return filesMatched; -67 } -68 -69 /** -70 * Set the value of filesMatched. A flag indicating whether the scan included any file types this analyzer supports. -71 * -72 * @param filesMatched new value of filesMatched -73 */ -74 protected void setFilesMatched(boolean filesMatched) { -75 this.filesMatched = filesMatched; -76 } -77 -78 /** -79 * A flag indicating whether or not the analyzer is enabled. -80 */ -81 private boolean enabled = true; +33 import org.owasp.dependencycheck.exception.InitializationException; +34 +35 /** +36 * The base FileTypeAnalyzer that all analyzers that have specific file types +37 * they analyze should extend. +38 * +39 * @author Jeremy Long +40 */ +41 public abstract class AbstractFileTypeAnalyzer extends AbstractAnalyzer implements FileTypeAnalyzer { +42 +43 //<editor-fold defaultstate="collapsed" desc="Constructor"> +44 /** +45 * Base constructor that all children must call. This checks the +46 * configuration to determine if the analyzer is enabled. +47 */ +48 public AbstractFileTypeAnalyzer() { +49 reset(); +50 } +51 //</editor-fold> +52 +53 //<editor-fold defaultstate="collapsed" desc="Field definitions"> +54 /** +55 * The logger. +56 */ +57 private static final Logger LOGGER = LoggerFactory.getLogger(AbstractFileTypeAnalyzer.class); +58 /** +59 * Whether the file type analyzer detected any files it needs to analyze. +60 */ +61 private boolean filesMatched = false; +62 +63 /** +64 * Get the value of filesMatched. A flag indicating whether the scan +65 * included any file types this analyzer supports. +66 * +67 * @return the value of filesMatched +68 */ +69 protected boolean isFilesMatched() { +70 return filesMatched; +71 } +72 +73 /** +74 * Set the value of filesMatched. A flag indicating whether the scan +75 * included any file types this analyzer supports. +76 * +77 * @param filesMatched new value of filesMatched +78 */ +79 protected void setFilesMatched(boolean filesMatched) { +80 this.filesMatched = filesMatched; +81 } 82 83 /** -84 * Get the value of enabled. -85 * -86 * @return the value of enabled -87 */ -88 public boolean isEnabled() { -89 return enabled; -90 } -91 -92 /** -93 * Set the value of enabled. -94 * -95 * @param enabled new value of enabled -96 */ -97 public void setEnabled(boolean enabled) { -98 this.enabled = enabled; -99 } -100 //</editor-fold> -101 -102 //<editor-fold defaultstate="collapsed" desc="Abstract methods children must implement"> -103 /** -104 * <p> -105 * Returns the {@link java.io.FileFilter} used to determine which files are to be analyzed. An example would be an analyzer -106 * that inspected Java jar files. Implementors may use {@link org.owasp.dependencycheck.utils.FileFilterBuilder}.</p> -107 * <p> -108 * If the analyzer returns null it will not cause additional files to be analyzed, but will be executed against every file -109 * loaded.</p> -110 * -111 * @return the file filter used to determine which files are to be analyzed -112 */ -113 protected abstract FileFilter getFileFilter(); -114 -115 /** -116 * Initializes the file type analyzer. +84 * A flag indicating whether or not the analyzer is enabled. +85 */ +86 private boolean enabled = true; +87 +88 /** +89 * Get the value of enabled. +90 * +91 * @return the value of enabled +92 */ +93 public boolean isEnabled() { +94 return enabled; +95 } +96 +97 /** +98 * Set the value of enabled. +99 * +100 * @param enabled new value of enabled +101 */ +102 public void setEnabled(boolean enabled) { +103 this.enabled = enabled; +104 } +105 //</editor-fold> +106 +107 //<editor-fold defaultstate="collapsed" desc="Abstract methods children must implement"> +108 /** +109 * <p> +110 * Returns the {@link java.io.FileFilter} used to determine which files are +111 * to be analyzed. An example would be an analyzer that inspected Java jar +112 * files. Implementors may use +113 * {@link org.owasp.dependencycheck.utils.FileFilterBuilder}.</p> +114 * <p> +115 * If the analyzer returns null it will not cause additional files to be +116 * analyzed, but will be executed against every file loaded.</p> 117 * -118 * @throws Exception thrown if there is an exception during initialization +118 * @return the file filter used to determine which files are to be analyzed 119 */ -120 protected abstract void initializeFileTypeAnalyzer() throws Exception; +120 protected abstract FileFilter getFileFilter(); 121 122 /** -123 * Analyzes a given dependency. If the dependency is an archive, such as a WAR or EAR, the contents are extracted, scanned, -124 * and added to the list of dependencies within the engine. -125 * -126 * @param dependency the dependency to analyze -127 * @param engine the engine scanning -128 * @throws AnalysisException thrown if there is an analysis exception -129 */ -130 protected abstract void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException; -131 -132 /** -133 * <p> -134 * Returns the setting key to determine if the analyzer is enabled.</p> -135 * -136 * @return the key for the analyzer's enabled property -137 */ -138 protected abstract String getAnalyzerEnabledSettingKey(); -139 -140 //</editor-fold> -141 //<editor-fold defaultstate="collapsed" desc="Final implementations for the Analyzer interface"> -142 /** -143 * Initializes the analyzer. +123 * Initializes the file type analyzer. +124 * +125 * @throws InitializationException thrown if there is an exception during +126 * initialization +127 */ +128 protected abstract void initializeFileTypeAnalyzer() throws InitializationException; +129 +130 /** +131 * Analyzes a given dependency. If the dependency is an archive, such as a +132 * WAR or EAR, the contents are extracted, scanned, and added to the list of +133 * dependencies within the engine. +134 * +135 * @param dependency the dependency to analyze +136 * @param engine the engine scanning +137 * @throws AnalysisException thrown if there is an analysis exception +138 */ +139 protected abstract void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException; +140 +141 /** +142 * <p> +143 * Returns the setting key to determine if the analyzer is enabled.</p> 144 * -145 * @throws Exception thrown if there is an exception during initialization +145 * @return the key for the analyzer's enabled property 146 */ -147 @Override -148 public final void initialize() throws Exception { -149 if (filesMatched) { -150 initializeFileTypeAnalyzer(); -151 } else { -152 enabled = false; -153 } -154 } -155 -156 /** -157 * Resets the enabled flag on the analyzer. -158 */ -159 @Override -160 public final void reset() { -161 final String key = getAnalyzerEnabledSettingKey(); -162 try { -163 enabled = Settings.getBoolean(key, true); -164 } catch (InvalidSettingException ex) { -165 LOGGER.warn("Invalid setting for property '{}'", key); -166 LOGGER.debug("", ex); -167 LOGGER.warn("{} has been disabled", getName()); -168 } -169 } -170 -171 /** -172 * Analyzes a given dependency. If the dependency is an archive, such as a WAR or EAR, the contents are extracted, scanned, -173 * and added to the list of dependencies within the engine. -174 * -175 * @param dependency the dependency to analyze -176 * @param engine the engine scanning -177 * @throws AnalysisException thrown if there is an analysis exception -178 */ -179 @Override -180 public final void analyze(Dependency dependency, Engine engine) throws AnalysisException { -181 if (enabled) { -182 analyzeFileType(dependency, engine); -183 } -184 } -185 -186 @Override -187 public boolean accept(File pathname) { -188 final FileFilter filter = getFileFilter(); -189 boolean accepted = false; -190 if (null == filter) { -191 LOGGER.error("The '{}' analyzer is misconfigured and does not have a file filter; it will be disabled", getName()); -192 } else if (enabled) { -193 accepted = filter.accept(pathname); -194 if (accepted) { -195 filesMatched = true; -196 } -197 } -198 return accepted; -199 } -200 -201 //</editor-fold> -202 //<editor-fold defaultstate="collapsed" desc="Static utility methods"> -203 /** -204 * <p> -205 * Utility method to help in the creation of the extensions set. This constructs a new Set that can be used in a final static -206 * declaration.</p> -207 * <p> -208 * This implementation was copied from -209 * http://stackoverflow.com/questions/2041778/initialize-java-hashset-values-by-construction</p>; -210 * -211 * @param strings a list of strings to add to the set. -212 * @return a Set of strings. -213 */ -214 protected static Set<String> newHashSet(String... strings) { -215 final Set<String> set = new HashSet<String>(strings.length); -216 Collections.addAll(set, strings); -217 return set; -218 } -219 -220 //</editor-fold> -221 } +147 protected abstract String getAnalyzerEnabledSettingKey(); +148 +149 //</editor-fold> +150 //<editor-fold defaultstate="collapsed" desc="Final implementations for the Analyzer interface"> +151 /** +152 * Initializes the analyzer. +153 * +154 * @throws InitializationException thrown if there is an exception during +155 * initialization +156 */ +157 @Override +158 public final void initialize() throws InitializationException { +159 if (filesMatched) { +160 initializeFileTypeAnalyzer(); +161 } else { +162 enabled = false; +163 } +164 } +165 +166 /** +167 * Resets the enabled flag on the analyzer. +168 */ +169 @Override +170 public final void reset() { +171 final String key = getAnalyzerEnabledSettingKey(); +172 try { +173 enabled = Settings.getBoolean(key, true); +174 } catch (InvalidSettingException ex) { +175 LOGGER.warn("Invalid setting for property '{}'", key); +176 LOGGER.debug("", ex); +177 LOGGER.warn("{} has been disabled", getName()); +178 } +179 } +180 +181 /** +182 * Analyzes a given dependency. If the dependency is an archive, such as a +183 * WAR or EAR, the contents are extracted, scanned, and added to the list of +184 * dependencies within the engine. +185 * +186 * @param dependency the dependency to analyze +187 * @param engine the engine scanning +188 * @throws AnalysisException thrown if there is an analysis exception +189 */ +190 @Override +191 public final void analyze(Dependency dependency, Engine engine) throws AnalysisException { +192 if (enabled) { +193 analyzeFileType(dependency, engine); +194 } +195 } +196 +197 @Override +198 public boolean accept(File pathname) { +199 final FileFilter filter = getFileFilter(); +200 boolean accepted = false; +201 if (null == filter) { +202 LOGGER.error("The '{}' analyzer is misconfigured and does not have a file filter; it will be disabled", getName()); +203 } else if (enabled) { +204 accepted = filter.accept(pathname); +205 if (accepted) { +206 filesMatched = true; +207 } +208 } +209 return accepted; +210 } +211 +212 //</editor-fold> +213 //<editor-fold defaultstate="collapsed" desc="Static utility methods"> +214 /** +215 * <p> +216 * Utility method to help in the creation of the extensions set. This +217 * constructs a new Set that can be used in a final static declaration.</p> +218 * <p> +219 * This implementation was copied from +220 * http://stackoverflow.com/questions/2041778/initialize-java-hashset-values-by-construction</p>; +221 * +222 * @param strings a list of strings to add to the set. +223 * @return a Set of strings. +224 */ +225 protected static Set<String> newHashSet(String... strings) { +226 final Set<String> set = new HashSet<String>(strings.length); +227 Collections.addAll(set, strings); +228 return set; +229 } +230 +231 //</editor-fold> +232 }
      diff --git a/xref/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzer.html b/xref/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzer.html index 974fddd8b..0e9f20d3b 100644 --- a/xref/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzer.html +++ b/xref/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzer.html @@ -33,163 +33,161 @@ 25 import java.util.List; 26 import java.util.Set; 27 import java.util.regex.Pattern; -28 import org.owasp.dependencycheck.suppression.SuppressionParseException; -29 import org.owasp.dependencycheck.suppression.SuppressionParser; -30 import org.owasp.dependencycheck.suppression.SuppressionRule; -31 import org.owasp.dependencycheck.utils.DownloadFailedException; -32 import org.owasp.dependencycheck.utils.Downloader; -33 import org.owasp.dependencycheck.utils.FileUtils; -34 import org.owasp.dependencycheck.utils.Settings; -35 import org.slf4j.Logger; -36 import org.slf4j.LoggerFactory; -37 import org.xml.sax.SAXException; -38 -39 /** -40 * Abstract base suppression analyzer that contains methods for parsing the -41 * suppression xml file. -42 * -43 * @author Jeremy Long -44 */ -45 public abstract class AbstractSuppressionAnalyzer extends AbstractAnalyzer { -46 -47 /** -48 * The Logger for use throughout the class -49 */ -50 private static final Logger LOGGER = LoggerFactory.getLogger(AbstractSuppressionAnalyzer.class); -51 -52 //<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer"> -53 /** -54 * Returns a list of file EXTENSIONS supported by this analyzer. -55 * -56 * @return a list of file EXTENSIONS supported by this analyzer. -57 */ -58 public Set<String> getSupportedExtensions() { -59 return null; -60 } -61 -62 //</editor-fold> -63 /** -64 * The initialize method loads the suppression XML file. -65 * -66 * @throws Exception thrown if there is an exception -67 */ -68 @Override -69 public void initialize() throws Exception { -70 super.initialize(); -71 loadSuppressionData(); -72 } -73 -74 /** -75 * The list of suppression rules -76 */ -77 private List<SuppressionRule> rules; +28 import org.owasp.dependencycheck.exception.InitializationException; +29 import org.owasp.dependencycheck.xml.suppression.SuppressionParseException; +30 import org.owasp.dependencycheck.xml.suppression.SuppressionParser; +31 import org.owasp.dependencycheck.xml.suppression.SuppressionRule; +32 import org.owasp.dependencycheck.utils.DownloadFailedException; +33 import org.owasp.dependencycheck.utils.Downloader; +34 import org.owasp.dependencycheck.utils.FileUtils; +35 import org.owasp.dependencycheck.utils.Settings; +36 import org.slf4j.Logger; +37 import org.slf4j.LoggerFactory; +38 import org.xml.sax.SAXException; +39 +40 /** +41 * Abstract base suppression analyzer that contains methods for parsing the +42 * suppression xml file. +43 * +44 * @author Jeremy Long +45 */ +46 public abstract class AbstractSuppressionAnalyzer extends AbstractAnalyzer { +47 +48 /** +49 * The Logger for use throughout the class +50 */ +51 private static final Logger LOGGER = LoggerFactory.getLogger(AbstractSuppressionAnalyzer.class); +52 +53 //<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer"> +54 /** +55 * Returns a list of file EXTENSIONS supported by this analyzer. +56 * +57 * @return a list of file EXTENSIONS supported by this analyzer. +58 */ +59 public Set<String> getSupportedExtensions() { +60 return null; +61 } +62 +63 //</editor-fold> +64 /** +65 * The initialize method loads the suppression XML file. +66 * +67 * @throws InitializationException thrown if there is an exception +68 */ +69 @Override +70 public void initialize() throws InitializationException { +71 super.initialize(); +72 try { +73 loadSuppressionData(); +74 } catch (SuppressionParseException ex) { +75 throw new InitializationException("Error initializing the suppression analyzer", ex); +76 } +77 } 78 79 /** -80 * Get the value of rules. -81 * -82 * @return the value of rules -83 */ -84 public List<SuppressionRule> getRules() { -85 return rules; -86 } -87 -88 /** -89 * Set the value of rules. -90 * -91 * @param rules new value of rules -92 */ -93 public void setRules(List<SuppressionRule> rules) { -94 this.rules = rules; -95 } -96 -97 /** -98 * Loads the suppression rules file. -99 * -100 * @throws SuppressionParseException thrown if the XML cannot be parsed. -101 */ -102 private void loadSuppressionData() throws SuppressionParseException { -103 final SuppressionParser parser = new SuppressionParser(); -104 File file = null; -105 try { -106 rules = parser.parseSuppressionRules(this.getClass().getClassLoader().getResourceAsStream("dependencycheck-base-suppression.xml")); -107 } catch (SuppressionParseException ex) { -108 LOGGER.error("Unable to parse the base suppression data file"); -109 LOGGER.debug("Unable to parse the base suppression data file", ex); -110 } catch (SAXException ex) { -111 LOGGER.error("Unable to parse the base suppression data file"); -112 LOGGER.debug("Unable to parse the base suppression data file", ex); -113 } -114 final String suppressionFilePath = Settings.getString(Settings.KEYS.SUPPRESSION_FILE); -115 if (suppressionFilePath == null) { -116 return; -117 } -118 boolean deleteTempFile = false; -119 try { -120 final Pattern uriRx = Pattern.compile("^(https?|file)\\:.*", Pattern.CASE_INSENSITIVE); -121 if (uriRx.matcher(suppressionFilePath).matches()) { -122 deleteTempFile = true; -123 file = FileUtils.getTempFile("suppression", "xml"); -124 final URL url = new URL(suppressionFilePath); -125 try { -126 Downloader.fetchFile(url, file, false); -127 } catch (DownloadFailedException ex) { -128 Downloader.fetchFile(url, file, true); -129 } -130 } else { -131 file = new File(suppressionFilePath); -132 if (!file.exists()) { -133 final InputStream suppressionsFromClasspath = this.getClass().getClassLoader().getResourceAsStream(suppressionFilePath); -134 if (suppressionsFromClasspath != null) { -135 deleteTempFile = true; -136 file = FileUtils.getTempFile("suppression", "xml"); -137 try { -138 org.apache.commons.io.FileUtils.copyInputStreamToFile(suppressionsFromClasspath, file); -139 } catch (IOException ex) { -140 throwSuppressionParseException("Unable to locate suppressions file in classpath", ex); -141 } -142 } -143 } -144 } -145 +80 * The list of suppression rules +81 */ +82 private List<SuppressionRule> rules; +83 +84 /** +85 * Get the value of rules. +86 * +87 * @return the value of rules +88 */ +89 public List<SuppressionRule> getRules() { +90 return rules; +91 } +92 +93 /** +94 * Set the value of rules. +95 * +96 * @param rules new value of rules +97 */ +98 public void setRules(List<SuppressionRule> rules) { +99 this.rules = rules; +100 } +101 +102 /** +103 * Loads the suppression rules file. +104 * +105 * @throws SuppressionParseException thrown if the XML cannot be parsed. +106 */ +107 private void loadSuppressionData() throws SuppressionParseException { +108 final SuppressionParser parser = new SuppressionParser(); +109 File file = null; +110 try { +111 rules = parser.parseSuppressionRules(this.getClass().getClassLoader().getResourceAsStream("dependencycheck-base-suppression.xml")); +112 } catch (SAXException ex) { +113 throw new SuppressionParseException("Unable to parse the base suppression data file", ex); +114 } +115 final String suppressionFilePath = Settings.getString(Settings.KEYS.SUPPRESSION_FILE); +116 if (suppressionFilePath == null) { +117 return; +118 } +119 boolean deleteTempFile = false; +120 try { +121 final Pattern uriRx = Pattern.compile("^(https?|file)\\:.*", Pattern.CASE_INSENSITIVE); +122 if (uriRx.matcher(suppressionFilePath).matches()) { +123 deleteTempFile = true; +124 file = FileUtils.getTempFile("suppression", "xml"); +125 final URL url = new URL(suppressionFilePath); +126 try { +127 Downloader.fetchFile(url, file, false); +128 } catch (DownloadFailedException ex) { +129 Downloader.fetchFile(url, file, true); +130 } +131 } else { +132 file = new File(suppressionFilePath); +133 if (!file.exists()) { +134 final InputStream suppressionsFromClasspath = this.getClass().getClassLoader().getResourceAsStream(suppressionFilePath); +135 if (suppressionsFromClasspath != null) { +136 deleteTempFile = true; +137 file = FileUtils.getTempFile("suppression", "xml"); +138 try { +139 org.apache.commons.io.FileUtils.copyInputStreamToFile(suppressionsFromClasspath, file); +140 } catch (IOException ex) { +141 throwSuppressionParseException("Unable to locate suppressions file in classpath", ex); +142 } +143 } +144 } +145 } 146 if (file != null) { 147 try { -148 //rules = parser.parseSuppressionRules(file); -149 rules.addAll(parser.parseSuppressionRules(file)); -150 LOGGER.debug("{} suppression rules were loaded.", rules.size()); -151 } catch (SuppressionParseException ex) { -152 LOGGER.warn("Unable to parse suppression xml file '{}'", file.getPath()); -153 LOGGER.warn(ex.getMessage()); -154 LOGGER.debug("", ex); -155 throw ex; -156 } -157 } -158 } catch (DownloadFailedException ex) { -159 throwSuppressionParseException("Unable to fetch the configured suppression file", ex); -160 } catch (MalformedURLException ex) { -161 throwSuppressionParseException("Configured suppression file has an invalid URL", ex); -162 } catch (IOException ex) { -163 throwSuppressionParseException("Unable to create temp file for suppressions", ex); -164 } finally { -165 if (deleteTempFile && file != null) { -166 FileUtils.delete(file); -167 } -168 } -169 } -170 -171 /** -172 * Utility method to throw parse exceptions. -173 * -174 * @param message the exception message -175 * @param exception the cause of the exception -176 * @throws SuppressionParseException throws the generated -177 * SuppressionParseException -178 */ -179 private void throwSuppressionParseException(String message, Exception exception) throws SuppressionParseException { -180 LOGGER.warn(message); -181 LOGGER.debug("", exception); -182 throw new SuppressionParseException(message, exception); -183 } -184 } +148 rules.addAll(parser.parseSuppressionRules(file)); +149 LOGGER.debug("{} suppression rules were loaded.", rules.size()); +150 } catch (SuppressionParseException ex) { +151 LOGGER.warn("Unable to parse suppression xml file '{}'", file.getPath()); +152 LOGGER.warn(ex.getMessage()); +153 throw ex; +154 } +155 } +156 } catch (DownloadFailedException ex) { +157 throwSuppressionParseException("Unable to fetch the configured suppression file", ex); +158 } catch (MalformedURLException ex) { +159 throwSuppressionParseException("Configured suppression file has an invalid URL", ex); +160 } catch (IOException ex) { +161 throwSuppressionParseException("Unable to create temp file for suppressions", ex); +162 } finally { +163 if (deleteTempFile && file != null) { +164 FileUtils.delete(file); +165 } +166 } +167 } +168 +169 /** +170 * Utility method to throw parse exceptions. +171 * +172 * @param message the exception message +173 * @param exception the cause of the exception +174 * @throws SuppressionParseException throws the generated +175 * SuppressionParseException +176 */ +177 private void throwSuppressionParseException(String message, Exception exception) throws SuppressionParseException { +178 LOGGER.warn(message); +179 LOGGER.debug("", exception); +180 throw new SuppressionParseException(message, exception); +181 } +182 }
      diff --git a/xref/org/owasp/dependencycheck/analyzer/Analyzer.html b/xref/org/owasp/dependencycheck/analyzer/Analyzer.html index 5d083a6e3..b363ffba7 100644 --- a/xref/org/owasp/dependencycheck/analyzer/Analyzer.html +++ b/xref/org/owasp/dependencycheck/analyzer/Analyzer.html @@ -28,55 +28,62 @@ 20 import org.owasp.dependencycheck.Engine; 21 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; 22 import org.owasp.dependencycheck.dependency.Dependency; -23 -24 /** -25 * An interface that defines an Analyzer that is used to identify Dependencies. An analyzer will collect information -26 * about the dependency in the form of Evidence. -27 * -28 * @author Jeremy Long -29 */ -30 public interface Analyzer { -31 -32 /** -33 * Analyzes the given dependency. The analysis could be anything from identifying an Identifier for the dependency, -34 * to finding vulnerabilities, etc. Additionally, if the analyzer collects enough information to add a description -35 * or license information for the dependency it should be added. -36 * -37 * @param dependency a dependency to analyze. -38 * @param engine the engine that is scanning the dependencies - this is useful if we need to check other -39 * dependencies -40 * @throws AnalysisException is thrown if there is an error analyzing the dependency file -41 */ -42 void analyze(Dependency dependency, Engine engine) throws AnalysisException; -43 -44 /** -45 * Returns the name of the analyzer. -46 * -47 * @return the name of the analyzer. -48 */ -49 String getName(); -50 -51 /** -52 * Returns the phase that the analyzer is intended to run in. -53 * -54 * @return the phase that the analyzer is intended to run in. -55 */ -56 AnalysisPhase getAnalysisPhase(); -57 -58 /** -59 * The initialize method is called (once) prior to the analyze method being called on all of the dependencies. -60 * -61 * @throws Exception is thrown if an exception occurs initializing the analyzer. -62 */ -63 void initialize() throws Exception; -64 -65 /** -66 * The close method is called after all of the dependencies have been analyzed. -67 * -68 * @throws Exception is thrown if an exception occurs closing the analyzer. -69 */ -70 void close() throws Exception; -71 } +23 import org.owasp.dependencycheck.exception.InitializationException; +24 +25 /** +26 * An interface that defines an Analyzer that is used to identify Dependencies. +27 * An analyzer will collect information about the dependency in the form of +28 * Evidence. +29 * +30 * @author Jeremy Long +31 */ +32 public interface Analyzer { +33 +34 /** +35 * Analyzes the given dependency. The analysis could be anything from +36 * identifying an Identifier for the dependency, to finding vulnerabilities, +37 * etc. Additionally, if the analyzer collects enough information to add a +38 * description or license information for the dependency it should be added. +39 * +40 * @param dependency a dependency to analyze. +41 * @param engine the engine that is scanning the dependencies - this is +42 * useful if we need to check other dependencies +43 * @throws AnalysisException is thrown if there is an error analyzing the +44 * dependency file +45 */ +46 void analyze(Dependency dependency, Engine engine) throws AnalysisException; +47 +48 /** +49 * Returns the name of the analyzer. +50 * +51 * @return the name of the analyzer. +52 */ +53 String getName(); +54 +55 /** +56 * Returns the phase that the analyzer is intended to run in. +57 * +58 * @return the phase that the analyzer is intended to run in. +59 */ +60 AnalysisPhase getAnalysisPhase(); +61 +62 /** +63 * The initialize method is called (once) prior to the analyze method being +64 * called on all of the dependencies. +65 * +66 * @throws InitializationException is thrown if an exception occurs +67 * initializing the analyzer. +68 */ +69 void initialize() throws InitializationException; +70 +71 /** +72 * The close method is called after all of the dependencies have been +73 * analyzed. +74 * +75 * @throws Exception is thrown if an exception occurs closing the analyzer. +76 */ +77 void close() throws Exception; +78 }
      diff --git a/xref/org/owasp/dependencycheck/analyzer/ArchiveAnalyzer.html b/xref/org/owasp/dependencycheck/analyzer/ArchiveAnalyzer.html index 4bfdf4f7f..357c4dac7 100644 --- a/xref/org/owasp/dependencycheck/analyzer/ArchiveAnalyzer.html +++ b/xref/org/owasp/dependencycheck/analyzer/ArchiveAnalyzer.html @@ -57,467 +57,538 @@ 49 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; 50 import org.owasp.dependencycheck.analyzer.exception.ArchiveExtractionException; 51 import org.owasp.dependencycheck.dependency.Dependency; -52 import org.owasp.dependencycheck.utils.FileFilterBuilder; -53 import org.owasp.dependencycheck.utils.FileUtils; -54 import org.owasp.dependencycheck.utils.Settings; -55 -56 import org.slf4j.Logger; -57 import org.slf4j.LoggerFactory; -58 -59 /** -60 * <p> -61 * An analyzer that extracts files from archives and ensures any supported files contained within the archive are added to the -62 * dependency list.</p> -63 * -64 * @author Jeremy Long -65 */ -66 public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer { -67 -68 /** -69 * The logger. -70 */ -71 private static final Logger LOGGER = LoggerFactory.getLogger(ArchiveAnalyzer.class); -72 /** -73 * The count of directories created during analysis. This is used for creating temporary directories. -74 */ -75 private static int dirCount = 0; -76 /** -77 * The parent directory for the individual directories per archive. -78 */ -79 private File tempFileLocation = null; -80 /** -81 * The max scan depth that the analyzer will recursively extract nested archives. -82 */ -83 private static final int MAX_SCAN_DEPTH = Settings.getInt("archive.scan.depth", 3); -84 /** -85 * Tracks the current scan/extraction depth for nested archives. -86 */ -87 private int scanDepth = 0; -88 -89 //<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer"> -90 /** -91 * The name of the analyzer. -92 */ -93 private static final String ANALYZER_NAME = "Archive Analyzer"; -94 /** -95 * The phase that this analyzer is intended to run in. -96 */ -97 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INITIAL; -98 /** -99 * The set of things we can handle with Zip methods -100 */ -101 private static final Set<String> ZIPPABLES = newHashSet("zip", "ear", "war", "jar", "sar", "apk", "nupkg"); -102 /** -103 * The set of file extensions supported by this analyzer. Note for developers, any additions to this list will need to be -104 * explicitly handled in {@link #extractFiles(File, File, Engine)}. -105 */ -106 private static final Set<String> EXTENSIONS = newHashSet("tar", "gz", "tgz", "bz2", "tbz2"); -107 -108 /** -109 * Detects files with extensions to remove from the engine's collection of dependencies. -110 */ -111 private static final FileFilter REMOVE_FROM_ANALYSIS = FileFilterBuilder.newInstance().addExtensions("zip", "tar", "gz", "tgz", "bz2", "tbz2") -112 .build(); -113 -114 static { -115 final String additionalZipExt = Settings.getString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS); -116 if (additionalZipExt != null) { -117 final String[] ext = additionalZipExt.split("\\s*,\\s*"); -118 Collections.addAll(ZIPPABLES, ext); -119 } -120 EXTENSIONS.addAll(ZIPPABLES); -121 } -122 -123 /** -124 * The file filter used to filter supported files. -125 */ -126 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(EXTENSIONS).build(); +52 import org.owasp.dependencycheck.exception.InitializationException; +53 import org.owasp.dependencycheck.utils.FileFilterBuilder; +54 import org.owasp.dependencycheck.utils.FileUtils; +55 import org.owasp.dependencycheck.utils.Settings; +56 +57 import org.slf4j.Logger; +58 import org.slf4j.LoggerFactory; +59 +60 /** +61 * <p> +62 * An analyzer that extracts files from archives and ensures any supported files +63 * contained within the archive are added to the dependency list.</p> +64 * +65 * @author Jeremy Long +66 */ +67 public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer { +68 +69 /** +70 * The logger. +71 */ +72 private static final Logger LOGGER = LoggerFactory.getLogger(ArchiveAnalyzer.class); +73 /** +74 * The count of directories created during analysis. This is used for +75 * creating temporary directories. +76 */ +77 private static int dirCount = 0; +78 /** +79 * The parent directory for the individual directories per archive. +80 */ +81 private File tempFileLocation = null; +82 /** +83 * The max scan depth that the analyzer will recursively extract nested +84 * archives. +85 */ +86 private static final int MAX_SCAN_DEPTH = Settings.getInt("archive.scan.depth", 3); +87 /** +88 * Tracks the current scan/extraction depth for nested archives. +89 */ +90 private int scanDepth = 0; +91 +92 //<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer"> +93 /** +94 * The name of the analyzer. +95 */ +96 private static final String ANALYZER_NAME = "Archive Analyzer"; +97 /** +98 * The phase that this analyzer is intended to run in. +99 */ +100 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INITIAL; +101 /** +102 * The set of things we can handle with Zip methods +103 */ +104 private static final Set<String> ZIPPABLES = newHashSet("zip", "ear", "war", "jar", "sar", "apk", "nupkg"); +105 /** +106 * The set of file extensions supported by this analyzer. Note for +107 * developers, any additions to this list will need to be explicitly handled +108 * in {@link #extractFiles(File, File, Engine)}. +109 */ +110 private static final Set<String> EXTENSIONS = newHashSet("tar", "gz", "tgz", "bz2", "tbz2"); +111 +112 /** +113 * Detects files with extensions to remove from the engine's collection of +114 * dependencies. +115 */ +116 private static final FileFilter REMOVE_FROM_ANALYSIS = FileFilterBuilder.newInstance().addExtensions("zip", "tar", "gz", "tgz", "bz2", "tbz2") +117 .build(); +118 +119 static { +120 final String additionalZipExt = Settings.getString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS); +121 if (additionalZipExt != null) { +122 final String[] ext = additionalZipExt.split("\\s*,\\s*"); +123 Collections.addAll(ZIPPABLES, ext); +124 } +125 EXTENSIONS.addAll(ZIPPABLES); +126 } 127 -128 @Override -129 protected FileFilter getFileFilter() { -130 return FILTER; -131 } +128 /** +129 * The file filter used to filter supported files. +130 */ +131 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(EXTENSIONS).build(); 132 -133 /** -134 * Detects files with .zip extension. -135 */ -136 private static final FileFilter ZIP_FILTER = FileFilterBuilder.newInstance().addExtensions("zip").build(); +133 @Override +134 protected FileFilter getFileFilter() { +135 return FILTER; +136 } 137 138 /** -139 * Returns the name of the analyzer. -140 * -141 * @return the name of the analyzer. -142 */ -143 @Override -144 public String getName() { -145 return ANALYZER_NAME; -146 } -147 -148 /** -149 * Returns the phase that the analyzer is intended to run in. -150 * -151 * @return the phase that the analyzer is intended to run in. -152 */ -153 @Override -154 public AnalysisPhase getAnalysisPhase() { -155 return ANALYSIS_PHASE; -156 } -157 //</editor-fold> -158 -159 /** -160 * Returns the key used in the properties file to reference the analyzer's enabled property. -161 * -162 * @return the analyzer's enabled property setting key -163 */ -164 @Override -165 protected String getAnalyzerEnabledSettingKey() { -166 return Settings.KEYS.ANALYZER_ARCHIVE_ENABLED; -167 } -168 -169 /** -170 * The initialize method does nothing for this Analyzer. -171 * -172 * @throws Exception is thrown if there is an exception deleting or creating temporary files -173 */ -174 @Override -175 public void initializeFileTypeAnalyzer() throws Exception { -176 final File baseDir = Settings.getTempDirectory(); -177 tempFileLocation = File.createTempFile("check", "tmp", baseDir); -178 if (!tempFileLocation.delete()) { -179 final String msg = String.format("Unable to delete temporary file '%s'.", tempFileLocation.getAbsolutePath()); -180 throw new AnalysisException(msg); -181 } -182 if (!tempFileLocation.mkdirs()) { -183 final String msg = String.format("Unable to create directory '%s'.", tempFileLocation.getAbsolutePath()); -184 throw new AnalysisException(msg); -185 } -186 } -187 -188 /** -189 * The close method deletes any temporary files and directories created during analysis. -190 * -191 * @throws Exception thrown if there is an exception deleting temporary files -192 */ -193 @Override -194 public void close() throws Exception { -195 if (tempFileLocation != null && tempFileLocation.exists()) { -196 LOGGER.debug("Attempting to delete temporary files"); -197 final boolean success = FileUtils.delete(tempFileLocation); -198 if (!success && tempFileLocation.exists()) { -199 final String[] l = tempFileLocation.list(); -200 if (l != null && l.length > 0) { -201 LOGGER.warn("Failed to delete some temporary files, see the log for more details"); -202 } -203 } -204 } -205 } -206 -207 /** -208 * Analyzes a given dependency. If the dependency is an archive, such as a WAR or EAR, the contents are extracted, scanned, -209 * and added to the list of dependencies within the engine. -210 * -211 * @param dependency the dependency to analyze -212 * @param engine the engine scanning -213 * @throws AnalysisException thrown if there is an analysis exception -214 */ -215 @Override -216 public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { -217 final File f = new File(dependency.getActualFilePath()); -218 final File tmpDir = getNextTempDirectory(); -219 extractFiles(f, tmpDir, engine); -220 -221 //make a copy -222 final Set<Dependency> dependencySet = findMoreDependencies(engine, tmpDir); -223 if (!dependencySet.isEmpty()) { -224 for (Dependency d : dependencySet) { -225 //fix the dependency's display name and path -226 final String displayPath = String.format("%s%s", -227 dependency.getFilePath(), -228 d.getActualFilePath().substring(tmpDir.getAbsolutePath().length())); -229 final String displayName = String.format("%s: %s", -230 dependency.getFileName(), -231 d.getFileName()); -232 d.setFilePath(displayPath); -233 d.setFileName(displayName); -234 -235 //TODO - can we get more evidence from the parent? EAR contains module name, etc. -236 //analyze the dependency (i.e. extract files) if it is a supported type. -237 if (this.accept(d.getActualFile()) && scanDepth < MAX_SCAN_DEPTH) { -238 scanDepth += 1; -239 analyze(d, engine); -240 scanDepth -= 1; -241 } -242 } -243 } -244 if (REMOVE_FROM_ANALYSIS.accept(dependency.getActualFile())) { -245 addDisguisedJarsToDependencies(dependency, engine); -246 engine.getDependencies().remove(dependency); -247 } -248 Collections.sort(engine.getDependencies()); -249 } -250 -251 /** -252 * If a zip file was identified as a possible JAR, this method will add the zip to the list of dependencies. -253 * -254 * @param dependency the zip file -255 * @param engine the engine -256 * @throws AnalysisException thrown if there is an issue -257 */ -258 private void addDisguisedJarsToDependencies(Dependency dependency, Engine engine) throws AnalysisException { -259 if (ZIP_FILTER.accept(dependency.getActualFile()) && isZipFileActuallyJarFile(dependency)) { -260 final File tdir = getNextTempDirectory(); -261 final String fileName = dependency.getFileName(); -262 -263 LOGGER.info("The zip file '{}' appears to be a JAR file, making a copy and analyzing it as a JAR.", fileName); -264 -265 final File tmpLoc = new File(tdir, fileName.substring(0, fileName.length() - 3) + "jar"); -266 try { -267 org.apache.commons.io.FileUtils.copyFile(tdir, tmpLoc); -268 final Set<Dependency> dependencySet = findMoreDependencies(engine, tmpLoc); -269 if (!dependencySet.isEmpty()) { -270 if (dependencySet.size() != 1) { -271 LOGGER.info("Deep copy of ZIP to JAR file resulted in more than one dependency?"); -272 } -273 for (Dependency d : dependencySet) { -274 //fix the dependency's display name and path -275 d.setFilePath(dependency.getFilePath()); -276 d.setDisplayFileName(dependency.getFileName()); -277 } -278 } -279 } catch (IOException ex) { -280 LOGGER.debug("Unable to perform deep copy on '{}'", dependency.getActualFile().getPath(), ex); -281 } -282 } -283 } -284 /** -285 * An empty dependency set. -286 */ -287 private static final Set<Dependency> EMPTY_DEPENDENCY_SET = Collections.emptySet(); -288 -289 /** -290 * Scan the given file/folder, and return any new dependencies found. -291 * -292 * @param engine used to scan -293 * @param file target of scanning -294 * @return any dependencies that weren't known to the engine before -295 */ -296 private static Set<Dependency> findMoreDependencies(Engine engine, File file) { -297 final List<Dependency> before = new ArrayList<Dependency>(engine.getDependencies()); -298 engine.scan(file); -299 final List<Dependency> after = engine.getDependencies(); -300 final boolean sizeChanged = before.size() != after.size(); -301 final Set<Dependency> newDependencies; -302 if (sizeChanged) { -303 //get the new dependencies -304 newDependencies = new HashSet<Dependency>(after); -305 newDependencies.removeAll(before); -306 } else { -307 newDependencies = EMPTY_DEPENDENCY_SET; -308 } -309 return newDependencies; -310 } -311 -312 /** -313 * Retrieves the next temporary directory to extract an archive too. -314 * -315 * @return a directory -316 * @throws AnalysisException thrown if unable to create temporary directory -317 */ -318 private File getNextTempDirectory() throws AnalysisException { -319 dirCount += 1; -320 final File directory = new File(tempFileLocation, String.valueOf(dirCount)); -321 //getting an exception for some directories not being able to be created; might be because the directory already exists? -322 if (directory.exists()) { -323 return getNextTempDirectory(); -324 } -325 if (!directory.mkdirs()) { -326 final String msg = String.format("Unable to create temp directory '%s'.", directory.getAbsolutePath()); -327 throw new AnalysisException(msg); -328 } -329 return directory; -330 } -331 -332 /** -333 * Extracts the contents of an archive into the specified directory. -334 * -335 * @param archive an archive file such as a WAR or EAR -336 * @param destination a directory to extract the contents to -337 * @param engine the scanning engine -338 * @throws AnalysisException thrown if the archive is not found -339 */ -340 private void extractFiles(File archive, File destination, Engine engine) throws AnalysisException { -341 if (archive != null && destination != null) { -342 FileInputStream fis; -343 try { -344 fis = new FileInputStream(archive); -345 } catch (FileNotFoundException ex) { -346 LOGGER.debug("", ex); -347 throw new AnalysisException("Archive file was not found.", ex); -348 } -349 final String archiveExt = FileUtils.getFileExtension(archive.getName()).toLowerCase(); -350 try { -351 if (ZIPPABLES.contains(archiveExt)) { -352 extractArchive(new ZipArchiveInputStream(new BufferedInputStream(fis)), destination, engine); -353 } else if ("tar".equals(archiveExt)) { -354 extractArchive(new TarArchiveInputStream(new BufferedInputStream(fis)), destination, engine); -355 } else if ("gz".equals(archiveExt) || "tgz".equals(archiveExt)) { -356 final String uncompressedName = GzipUtils.getUncompressedFilename(archive.getName()); -357 final File f = new File(destination, uncompressedName); -358 if (engine.accept(f)) { -359 decompressFile(new GzipCompressorInputStream(new BufferedInputStream(fis)), f); -360 } -361 } else if ("bz2".equals(archiveExt) || "tbz2".equals(archiveExt)) { -362 final String uncompressedName = BZip2Utils.getUncompressedFilename(archive.getName()); -363 final File f = new File(destination, uncompressedName); -364 if (engine.accept(f)) { -365 decompressFile(new BZip2CompressorInputStream(new BufferedInputStream(fis)), f); -366 } -367 } -368 } catch (ArchiveExtractionException ex) { -369 LOGGER.warn("Exception extracting archive '{}'.", archive.getName()); -370 LOGGER.debug("", ex); -371 } catch (IOException ex) { -372 LOGGER.warn("Exception reading archive '{}'.", archive.getName()); -373 LOGGER.debug("", ex); -374 } finally { -375 close(fis); -376 } -377 } -378 } -379 -380 /** -381 * Extracts files from an archive. -382 * -383 * @param input the archive to extract files from -384 * @param destination the location to write the files too -385 * @param engine the dependency-check engine -386 * @throws ArchiveExtractionException thrown if there is an exception extracting files from the archive -387 */ -388 private void extractArchive(ArchiveInputStream input, File destination, Engine engine) throws ArchiveExtractionException { -389 ArchiveEntry entry; -390 try { -391 while ((entry = input.getNextEntry()) != null) { -392 final File file = new File(destination, entry.getName()); -393 if (entry.isDirectory()) { -394 if (!file.exists() && !file.mkdirs()) { -395 final String msg = String.format("Unable to create directory '%s'.", file.getAbsolutePath()); -396 throw new AnalysisException(msg); -397 } -398 } else if (engine.accept(file)) { -399 extractAcceptedFile(input, file); -400 } -401 } -402 } catch (Throwable ex) { -403 throw new ArchiveExtractionException(ex); -404 } finally { -405 close(input); -406 } -407 } -408 -409 /** -410 * Extracts a file from an archive. -411 * -412 * @param input the archives input stream -413 * @param file the file to extract -414 * @throws AnalysisException thrown if there is an error -415 */ -416 private static void extractAcceptedFile(ArchiveInputStream input, File file) throws AnalysisException { -417 LOGGER.debug("Extracting '{}'", file.getPath()); -418 FileOutputStream fos = null; -419 try { -420 final File parent = file.getParentFile(); -421 if (!parent.isDirectory() && !parent.mkdirs()) { -422 final String msg = String.format("Unable to build directory '%s'.", parent.getAbsolutePath()); -423 throw new AnalysisException(msg); -424 } -425 fos = new FileOutputStream(file); -426 IOUtils.copy(input, fos); -427 } catch (FileNotFoundException ex) { -428 LOGGER.debug("", ex); -429 final String msg = String.format("Unable to find file '%s'.", file.getName()); -430 throw new AnalysisException(msg, ex); -431 } catch (IOException ex) { -432 LOGGER.debug("", ex); -433 final String msg = String.format("IO Exception while parsing file '%s'.", file.getName()); -434 throw new AnalysisException(msg, ex); -435 } finally { -436 close(fos); -437 } -438 } -439 -440 /** -441 * Decompresses a file. -442 * -443 * @param inputStream the compressed file -444 * @param outputFile the location to write the decompressed file -445 * @throws ArchiveExtractionException thrown if there is an exception decompressing the file -446 */ -447 private void decompressFile(CompressorInputStream inputStream, File outputFile) throws ArchiveExtractionException { -448 LOGGER.debug("Decompressing '{}'", outputFile.getPath()); -449 FileOutputStream out = null; -450 try { -451 out = new FileOutputStream(outputFile); -452 IOUtils.copy(inputStream, out); -453 } catch (FileNotFoundException ex) { -454 LOGGER.debug("", ex); -455 throw new ArchiveExtractionException(ex); -456 } catch (IOException ex) { -457 LOGGER.debug("", ex); -458 throw new ArchiveExtractionException(ex); -459 } finally { -460 close(out); -461 } -462 } -463 -464 /** -465 * Close the given {@link Closeable} instance, ignoring nulls, and logging any thrown {@link IOException}. -466 * -467 * @param closeable to be closed -468 */ -469 private static void close(Closeable closeable) { -470 if (null != closeable) { -471 try { -472 closeable.close(); -473 } catch (IOException ex) { -474 LOGGER.trace("", ex); -475 } -476 } -477 } -478 -479 /** -480 * Attempts to determine if a zip file is actually a JAR file. -481 * -482 * @param dependency the dependency to check -483 * @return true if the dependency appears to be a JAR file; otherwise false +139 * Detects files with .zip extension. +140 */ +141 private static final FileFilter ZIP_FILTER = FileFilterBuilder.newInstance().addExtensions("zip").build(); +142 +143 /** +144 * Returns the name of the analyzer. +145 * +146 * @return the name of the analyzer. +147 */ +148 @Override +149 public String getName() { +150 return ANALYZER_NAME; +151 } +152 +153 /** +154 * Returns the phase that the analyzer is intended to run in. +155 * +156 * @return the phase that the analyzer is intended to run in. +157 */ +158 @Override +159 public AnalysisPhase getAnalysisPhase() { +160 return ANALYSIS_PHASE; +161 } +162 //</editor-fold> +163 +164 /** +165 * Returns the key used in the properties file to reference the analyzer's +166 * enabled property. +167 * +168 * @return the analyzer's enabled property setting key +169 */ +170 @Override +171 protected String getAnalyzerEnabledSettingKey() { +172 return Settings.KEYS.ANALYZER_ARCHIVE_ENABLED; +173 } +174 +175 /** +176 * The initialize method does nothing for this Analyzer. +177 * +178 * @throws InitializationException is thrown if there is an exception +179 * deleting or creating temporary files +180 */ +181 @Override +182 public void initializeFileTypeAnalyzer() throws InitializationException { +183 try { +184 final File baseDir = Settings.getTempDirectory(); +185 tempFileLocation = File.createTempFile("check", "tmp", baseDir); +186 if (!tempFileLocation.delete()) { +187 setEnabled(false); +188 final String msg = String.format("Unable to delete temporary file '%s'.", tempFileLocation.getAbsolutePath()); +189 throw new InitializationException(msg); +190 } +191 if (!tempFileLocation.mkdirs()) { +192 setEnabled(false); +193 final String msg = String.format("Unable to create directory '%s'.", tempFileLocation.getAbsolutePath()); +194 throw new InitializationException(msg); +195 } +196 } catch (IOException ex) { +197 setEnabled(false); +198 throw new InitializationException("Unable to create a temporary file", ex); +199 } +200 } +201 +202 /** +203 * The close method deletes any temporary files and directories created +204 * during analysis. +205 * +206 * @throws Exception thrown if there is an exception deleting temporary +207 * files +208 */ +209 @Override +210 public void close() throws Exception { +211 if (tempFileLocation != null && tempFileLocation.exists()) { +212 LOGGER.debug("Attempting to delete temporary files"); +213 final boolean success = FileUtils.delete(tempFileLocation); +214 if (!success && tempFileLocation.exists()) { +215 final String[] l = tempFileLocation.list(); +216 if (l != null && l.length > 0) { +217 LOGGER.warn("Failed to delete some temporary files, see the log for more details"); +218 } +219 } +220 } +221 } +222 +223 /** +224 * Analyzes a given dependency. If the dependency is an archive, such as a +225 * WAR or EAR, the contents are extracted, scanned, and added to the list of +226 * dependencies within the engine. +227 * +228 * @param dependency the dependency to analyze +229 * @param engine the engine scanning +230 * @throws AnalysisException thrown if there is an analysis exception +231 */ +232 @Override +233 public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { +234 final File f = new File(dependency.getActualFilePath()); +235 final File tmpDir = getNextTempDirectory(); +236 extractFiles(f, tmpDir, engine); +237 +238 //make a copy +239 final Set<Dependency> dependencySet = findMoreDependencies(engine, tmpDir); +240 if (!dependencySet.isEmpty()) { +241 for (Dependency d : dependencySet) { +242 //fix the dependency's display name and path +243 final String displayPath = String.format("%s%s", +244 dependency.getFilePath(), +245 d.getActualFilePath().substring(tmpDir.getAbsolutePath().length())); +246 final String displayName = String.format("%s: %s", +247 dependency.getFileName(), +248 d.getFileName()); +249 d.setFilePath(displayPath); +250 d.setFileName(displayName); +251 +252 //TODO - can we get more evidence from the parent? EAR contains module name, etc. +253 //analyze the dependency (i.e. extract files) if it is a supported type. +254 if (this.accept(d.getActualFile()) && scanDepth < MAX_SCAN_DEPTH) { +255 scanDepth += 1; +256 analyze(d, engine); +257 scanDepth -= 1; +258 } +259 } +260 } +261 if (REMOVE_FROM_ANALYSIS.accept(dependency.getActualFile())) { +262 addDisguisedJarsToDependencies(dependency, engine); +263 engine.getDependencies().remove(dependency); +264 } +265 Collections.sort(engine.getDependencies()); +266 } +267 +268 /** +269 * If a zip file was identified as a possible JAR, this method will add the +270 * zip to the list of dependencies. +271 * +272 * @param dependency the zip file +273 * @param engine the engine +274 * @throws AnalysisException thrown if there is an issue +275 */ +276 private void addDisguisedJarsToDependencies(Dependency dependency, Engine engine) throws AnalysisException { +277 if (ZIP_FILTER.accept(dependency.getActualFile()) && isZipFileActuallyJarFile(dependency)) { +278 final File tdir = getNextTempDirectory(); +279 final String fileName = dependency.getFileName(); +280 +281 LOGGER.info("The zip file '{}' appears to be a JAR file, making a copy and analyzing it as a JAR.", fileName); +282 +283 final File tmpLoc = new File(tdir, fileName.substring(0, fileName.length() - 3) + "jar"); +284 try { +285 org.apache.commons.io.FileUtils.copyFile(tdir, tmpLoc); +286 final Set<Dependency> dependencySet = findMoreDependencies(engine, tmpLoc); +287 if (!dependencySet.isEmpty()) { +288 if (dependencySet.size() != 1) { +289 LOGGER.info("Deep copy of ZIP to JAR file resulted in more than one dependency?"); +290 } +291 for (Dependency d : dependencySet) { +292 //fix the dependency's display name and path +293 d.setFilePath(dependency.getFilePath()); +294 d.setDisplayFileName(dependency.getFileName()); +295 } +296 } +297 } catch (IOException ex) { +298 LOGGER.debug("Unable to perform deep copy on '{}'", dependency.getActualFile().getPath(), ex); +299 } +300 } +301 } +302 /** +303 * An empty dependency set. +304 */ +305 private static final Set<Dependency> EMPTY_DEPENDENCY_SET = Collections.emptySet(); +306 +307 /** +308 * Scan the given file/folder, and return any new dependencies found. +309 * +310 * @param engine used to scan +311 * @param file target of scanning +312 * @return any dependencies that weren't known to the engine before +313 */ +314 private static Set<Dependency> findMoreDependencies(Engine engine, File file) { +315 final List<Dependency> before = new ArrayList<Dependency>(engine.getDependencies()); +316 engine.scan(file); +317 final List<Dependency> after = engine.getDependencies(); +318 final boolean sizeChanged = before.size() != after.size(); +319 final Set<Dependency> newDependencies; +320 if (sizeChanged) { +321 //get the new dependencies +322 newDependencies = new HashSet<Dependency>(after); +323 newDependencies.removeAll(before); +324 } else { +325 newDependencies = EMPTY_DEPENDENCY_SET; +326 } +327 return newDependencies; +328 } +329 +330 /** +331 * Retrieves the next temporary directory to extract an archive too. +332 * +333 * @return a directory +334 * @throws AnalysisException thrown if unable to create temporary directory +335 */ +336 private File getNextTempDirectory() throws AnalysisException { +337 dirCount += 1; +338 final File directory = new File(tempFileLocation, String.valueOf(dirCount)); +339 //getting an exception for some directories not being able to be created; might be because the directory already exists? +340 if (directory.exists()) { +341 return getNextTempDirectory(); +342 } +343 if (!directory.mkdirs()) { +344 final String msg = String.format("Unable to create temp directory '%s'.", directory.getAbsolutePath()); +345 throw new AnalysisException(msg); +346 } +347 return directory; +348 } +349 +350 /** +351 * Extracts the contents of an archive into the specified directory. +352 * +353 * @param archive an archive file such as a WAR or EAR +354 * @param destination a directory to extract the contents to +355 * @param engine the scanning engine +356 * @throws AnalysisException thrown if the archive is not found +357 */ +358 private void extractFiles(File archive, File destination, Engine engine) throws AnalysisException { +359 if (archive != null && destination != null) { +360 FileInputStream fis; +361 try { +362 fis = new FileInputStream(archive); +363 } catch (FileNotFoundException ex) { +364 LOGGER.debug("", ex); +365 throw new AnalysisException("Archive file was not found.", ex); +366 } +367 final String archiveExt = FileUtils.getFileExtension(archive.getName()).toLowerCase(); +368 try { +369 if (ZIPPABLES.contains(archiveExt)) { +370 final BufferedInputStream in = new BufferedInputStream(fis); +371 ensureReadableJar(archiveExt, in); +372 extractArchive(new ZipArchiveInputStream(in), destination, engine); +373 } else if ("tar".equals(archiveExt)) { +374 extractArchive(new TarArchiveInputStream(new BufferedInputStream(fis)), destination, engine); +375 } else if ("gz".equals(archiveExt) || "tgz".equals(archiveExt)) { +376 final String uncompressedName = GzipUtils.getUncompressedFilename(archive.getName()); +377 final File f = new File(destination, uncompressedName); +378 if (engine.accept(f)) { +379 decompressFile(new GzipCompressorInputStream(new BufferedInputStream(fis)), f); +380 } +381 } else if ("bz2".equals(archiveExt) || "tbz2".equals(archiveExt)) { +382 final String uncompressedName = BZip2Utils.getUncompressedFilename(archive.getName()); +383 final File f = new File(destination, uncompressedName); +384 if (engine.accept(f)) { +385 decompressFile(new BZip2CompressorInputStream(new BufferedInputStream(fis)), f); +386 } +387 } +388 } catch (ArchiveExtractionException ex) { +389 LOGGER.warn("Exception extracting archive '{}'.", archive.getName()); +390 LOGGER.debug("", ex); +391 } catch (IOException ex) { +392 LOGGER.warn("Exception reading archive '{}'.", archive.getName()); +393 LOGGER.debug("", ex); +394 } finally { +395 close(fis); +396 } +397 } +398 } +399 +400 /** +401 * Checks if the file being scanned is a JAR that begins with '#!/bin' which +402 * indicates it is a fully executable jar. If a fully executable JAR is +403 * identified the input stream will be advanced to the start of the actual +404 * JAR file ( skipping the script). +405 * +406 * @see +407 * <a href="http://docs.spring.io/spring-boot/docs/1.3.0.BUILD-SNAPSHOT/reference/htmlsingle/#deployment-install">Installing +408 * Spring Boot Applications</a> +409 * @param archiveExt the file extension +410 * @param in the input stream +411 * @throws IOException thrown if there is an error reading the stream +412 */ +413 private void ensureReadableJar(final String archiveExt, BufferedInputStream in) throws IOException { +414 if ("jar".equals(archiveExt) && in.markSupported()) { +415 in.mark(7); +416 final byte[] b = new byte[7]; +417 in.read(b); +418 if (b[0] == '#' +419 && b[1] == '!' +420 && b[2] == '/' +421 && b[3] == 'b' +422 && b[4] == 'i' +423 && b[5] == 'n' +424 && b[6] == '/') { +425 boolean stillLooking = true; +426 int chr, nxtChr; +427 while (stillLooking && (chr = in.read()) != -1) { +428 if (chr == '\n' || chr == '\r') { +429 in.mark(4); +430 if ((chr = in.read()) != -1) { +431 if (chr == 'P' && (chr = in.read()) != -1) { +432 if (chr == 'K' && (chr = in.read()) != -1) { +433 if ((chr == 3 || chr == 5 || chr == 7) && (nxtChr = in.read()) != -1) { +434 if (nxtChr == chr + 1) { +435 stillLooking = false; +436 in.reset(); +437 } +438 } +439 } +440 } +441 } +442 } +443 } +444 } +445 } +446 } +447 +448 /** +449 * Extracts files from an archive. +450 * +451 * @param input the archive to extract files from +452 * @param destination the location to write the files too +453 * @param engine the dependency-check engine +454 * @throws ArchiveExtractionException thrown if there is an exception +455 * extracting files from the archive +456 */ +457 private void extractArchive(ArchiveInputStream input, File destination, Engine engine) throws ArchiveExtractionException { +458 ArchiveEntry entry; +459 try { +460 while ((entry = input.getNextEntry()) != null) { +461 final File file = new File(destination, entry.getName()); +462 if (entry.isDirectory()) { +463 if (!file.exists() && !file.mkdirs()) { +464 final String msg = String.format("Unable to create directory '%s'.", file.getAbsolutePath()); +465 throw new AnalysisException(msg); +466 } +467 } else if (engine.accept(file)) { +468 extractAcceptedFile(input, file); +469 } +470 } +471 } catch (Throwable ex) { +472 throw new ArchiveExtractionException(ex); +473 } finally { +474 close(input); +475 } +476 } +477 +478 /** +479 * Extracts a file from an archive. +480 * +481 * @param input the archives input stream +482 * @param file the file to extract +483 * @throws AnalysisException thrown if there is an error 484 */ -485 private boolean isZipFileActuallyJarFile(Dependency dependency) { -486 boolean isJar = false; -487 ZipFile zip = null; +485 private static void extractAcceptedFile(ArchiveInputStream input, File file) throws AnalysisException { +486 LOGGER.debug("Extracting '{}'", file.getPath()); +487 FileOutputStream fos = null; 488 try { -489 zip = new ZipFile(dependency.getActualFilePath()); -490 if (zip.getEntry("META-INF/MANIFEST.MF") != null -491 || zip.getEntry("META-INF/maven") != null) { -492 final Enumeration<ZipArchiveEntry> entries = zip.getEntries(); -493 while (entries.hasMoreElements()) { -494 final ZipArchiveEntry entry = entries.nextElement(); -495 if (!entry.isDirectory()) { -496 final String name = entry.getName().toLowerCase(); -497 if (name.endsWith(".class")) { -498 isJar = true; -499 break; -500 } -501 } -502 } -503 } -504 } catch (IOException ex) { -505 LOGGER.debug("Unable to unzip zip file '{}'", dependency.getFilePath(), ex); -506 } finally { -507 ZipFile.closeQuietly(zip); -508 } -509 -510 return isJar; -511 } -512 } +489 final File parent = file.getParentFile(); +490 if (!parent.isDirectory() && !parent.mkdirs()) { +491 final String msg = String.format("Unable to build directory '%s'.", parent.getAbsolutePath()); +492 throw new AnalysisException(msg); +493 } +494 fos = new FileOutputStream(file); +495 IOUtils.copy(input, fos); +496 } catch (FileNotFoundException ex) { +497 LOGGER.debug("", ex); +498 final String msg = String.format("Unable to find file '%s'.", file.getName()); +499 throw new AnalysisException(msg, ex); +500 } catch (IOException ex) { +501 LOGGER.debug("", ex); +502 final String msg = String.format("IO Exception while parsing file '%s'.", file.getName()); +503 throw new AnalysisException(msg, ex); +504 } finally { +505 close(fos); +506 } +507 } +508 +509 /** +510 * Decompresses a file. +511 * +512 * @param inputStream the compressed file +513 * @param outputFile the location to write the decompressed file +514 * @throws ArchiveExtractionException thrown if there is an exception +515 * decompressing the file +516 */ +517 private void decompressFile(CompressorInputStream inputStream, File outputFile) throws ArchiveExtractionException { +518 LOGGER.debug("Decompressing '{}'", outputFile.getPath()); +519 FileOutputStream out = null; +520 try { +521 out = new FileOutputStream(outputFile); +522 IOUtils.copy(inputStream, out); +523 } catch (FileNotFoundException ex) { +524 LOGGER.debug("", ex); +525 throw new ArchiveExtractionException(ex); +526 } catch (IOException ex) { +527 LOGGER.debug("", ex); +528 throw new ArchiveExtractionException(ex); +529 } finally { +530 close(out); +531 } +532 } +533 +534 /** +535 * Close the given {@link Closeable} instance, ignoring nulls, and logging +536 * any thrown {@link IOException}. +537 * +538 * @param closeable to be closed +539 */ +540 private static void close(Closeable closeable) { +541 if (null != closeable) { +542 try { +543 closeable.close(); +544 } catch (IOException ex) { +545 LOGGER.trace("", ex); +546 } +547 } +548 } +549 +550 /** +551 * Attempts to determine if a zip file is actually a JAR file. +552 * +553 * @param dependency the dependency to check +554 * @return true if the dependency appears to be a JAR file; otherwise false +555 */ +556 private boolean isZipFileActuallyJarFile(Dependency dependency) { +557 boolean isJar = false; +558 ZipFile zip = null; +559 try { +560 zip = new ZipFile(dependency.getActualFilePath()); +561 if (zip.getEntry("META-INF/MANIFEST.MF") != null +562 || zip.getEntry("META-INF/maven") != null) { +563 final Enumeration<ZipArchiveEntry> entries = zip.getEntries(); +564 while (entries.hasMoreElements()) { +565 final ZipArchiveEntry entry = entries.nextElement(); +566 if (!entry.isDirectory()) { +567 final String name = entry.getName().toLowerCase(); +568 if (name.endsWith(".class")) { +569 isJar = true; +570 break; +571 } +572 } +573 } +574 } +575 } catch (IOException ex) { +576 LOGGER.debug("Unable to unzip zip file '{}'", dependency.getFilePath(), ex); +577 } finally { +578 ZipFile.closeQuietly(zip); +579 } +580 +581 return isJar; +582 } +583 }
      diff --git a/xref/org/owasp/dependencycheck/analyzer/AssemblyAnalyzer.html b/xref/org/owasp/dependencycheck/analyzer/AssemblyAnalyzer.html index 0c7ce37cf..12b21ab99 100644 --- a/xref/org/owasp/dependencycheck/analyzer/AssemblyAnalyzer.html +++ b/xref/org/owasp/dependencycheck/analyzer/AssemblyAnalyzer.html @@ -51,268 +51,284 @@ 43 import javax.xml.xpath.XPathFactory; 44 import java.util.ArrayList; 45 import java.util.List; -46 -47 /** -48 * Analyzer for getting company, product, and version information from a .NET assembly. -49 * -50 * @author colezlaw -51 * -52 */ -53 public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer { -54 -55 /** -56 * The analyzer name -57 */ -58 private static final String ANALYZER_NAME = "Assembly Analyzer"; -59 /** -60 * The analysis phase -61 */ -62 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; -63 /** -64 * The list of supported extensions -65 */ -66 private static final String[] SUPPORTED_EXTENSIONS = {"dll", "exe"}; -67 /** -68 * The temp value for GrokAssembly.exe -69 */ -70 private File grokAssemblyExe = null; -71 /** -72 * The DocumentBuilder for parsing the XML -73 */ -74 private DocumentBuilder builder; -75 /** -76 * Logger -77 */ -78 private static final Logger LOGGER = LoggerFactory.getLogger(AssemblyAnalyzer.class); -79 -80 /** -81 * Builds the beginnings of a List for ProcessBuilder -82 * -83 * @return the list of arguments to begin populating the ProcessBuilder -84 */ -85 private List<String> buildArgumentList() { -86 // Use file.separator as a wild guess as to whether this is Windows -87 final List<String> args = new ArrayList<String>(); -88 if (!"\\".equals(System.getProperty("file.separator"))) { -89 if (Settings.getString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH) != null) { -90 args.add(Settings.getString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH)); -91 } else { -92 args.add("mono"); -93 } -94 } -95 args.add(grokAssemblyExe.getPath()); -96 -97 return args; -98 } +46 import javax.xml.parsers.ParserConfigurationException; +47 import org.owasp.dependencycheck.exception.InitializationException; +48 +49 /** +50 * Analyzer for getting company, product, and version information from a .NET +51 * assembly. +52 * +53 * @author colezlaw +54 * +55 */ +56 public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer { +57 +58 /** +59 * The analyzer name +60 */ +61 private static final String ANALYZER_NAME = "Assembly Analyzer"; +62 /** +63 * The analysis phase +64 */ +65 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; +66 /** +67 * The list of supported extensions +68 */ +69 private static final String[] SUPPORTED_EXTENSIONS = {"dll", "exe"}; +70 /** +71 * The temp value for GrokAssembly.exe +72 */ +73 private File grokAssemblyExe = null; +74 /** +75 * The DocumentBuilder for parsing the XML +76 */ +77 private DocumentBuilder builder; +78 /** +79 * Logger +80 */ +81 private static final Logger LOGGER = LoggerFactory.getLogger(AssemblyAnalyzer.class); +82 +83 /** +84 * Builds the beginnings of a List for ProcessBuilder +85 * +86 * @return the list of arguments to begin populating the ProcessBuilder +87 */ +88 private List<String> buildArgumentList() { +89 // Use file.separator as a wild guess as to whether this is Windows +90 final List<String> args = new ArrayList<String>(); +91 if (!"\\".equals(System.getProperty("file.separator"))) { +92 if (Settings.getString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH) != null) { +93 args.add(Settings.getString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH)); +94 } else { +95 args.add("mono"); +96 } +97 } +98 args.add(grokAssemblyExe.getPath()); 99 -100 /** -101 * Performs the analysis on a single Dependency. -102 * -103 * @param dependency the dependency to analyze -104 * @param engine the engine to perform the analysis under -105 * @throws AnalysisException if anything goes sideways -106 */ -107 @Override -108 public void analyzeFileType(Dependency dependency, Engine engine) -109 throws AnalysisException { -110 if (grokAssemblyExe == null) { -111 LOGGER.warn("GrokAssembly didn't get deployed"); -112 return; -113 } -114 -115 final List<String> args = buildArgumentList(); -116 args.add(dependency.getActualFilePath()); -117 final ProcessBuilder pb = new ProcessBuilder(args); -118 Document doc = null; -119 try { -120 final Process proc = pb.start(); -121 -122 doc = builder.parse(proc.getInputStream()); -123 -124 // Try evacuating the error stream -125 final String errorStream = IOUtils.toString(proc.getErrorStream(), "UTF-8"); -126 if (null != errorStream && !errorStream.isEmpty()) { -127 LOGGER.warn("Error from GrokAssembly: {}", errorStream); -128 } -129 -130 int rc = 0; -131 try { -132 rc = proc.waitFor(); -133 } catch (InterruptedException ie) { -134 return; -135 } -136 if (rc == 3) { -137 LOGGER.debug("{} is not a .NET assembly or executable and as such cannot be analyzed by dependency-check", -138 dependency.getActualFilePath()); -139 return; -140 } else if (rc != 0) { -141 LOGGER.warn("Return code {} from GrokAssembly", rc); -142 } -143 -144 final XPath xpath = XPathFactory.newInstance().newXPath(); -145 -146 // First, see if there was an error -147 final String error = xpath.evaluate("/assembly/error", doc); -148 if (error != null && !error.isEmpty()) { -149 throw new AnalysisException(error); -150 } -151 -152 final String version = xpath.evaluate("/assembly/version", doc); -153 if (version != null) { -154 dependency.getVersionEvidence().addEvidence(new Evidence("grokassembly", "version", -155 version, Confidence.HIGHEST)); -156 } -157 -158 final String vendor = xpath.evaluate("/assembly/company", doc); -159 if (vendor != null) { -160 dependency.getVendorEvidence().addEvidence(new Evidence("grokassembly", "vendor", -161 vendor, Confidence.HIGH)); -162 } -163 -164 final String product = xpath.evaluate("/assembly/product", doc); -165 if (product != null) { -166 dependency.getProductEvidence().addEvidence(new Evidence("grokassembly", "product", -167 product, Confidence.HIGH)); -168 } -169 -170 } catch (IOException ioe) { -171 throw new AnalysisException(ioe); -172 } catch (SAXException saxe) { -173 throw new AnalysisException("Couldn't parse GrokAssembly result", saxe); -174 } catch (XPathExpressionException xpe) { -175 // This shouldn't happen -176 throw new AnalysisException(xpe); -177 } -178 } -179 -180 /** -181 * Initialize the analyzer. In this case, extract GrokAssembly.exe to a temporary location. -182 * -183 * @throws Exception if anything goes wrong -184 */ -185 @Override -186 public void initializeFileTypeAnalyzer() throws Exception { -187 final File tempFile = File.createTempFile("GKA", ".exe", Settings.getTempDirectory()); -188 FileOutputStream fos = null; -189 InputStream is = null; -190 try { -191 fos = new FileOutputStream(tempFile); -192 is = AssemblyAnalyzer.class.getClassLoader().getResourceAsStream("GrokAssembly.exe"); -193 IOUtils.copy(is, fos); -194 -195 grokAssemblyExe = tempFile; -196 // Set the temp file to get deleted when we're done -197 grokAssemblyExe.deleteOnExit(); -198 LOGGER.debug("Extracted GrokAssembly.exe to {}", grokAssemblyExe.getPath()); -199 } catch (IOException ioe) { -200 this.setEnabled(false); -201 LOGGER.warn("Could not extract GrokAssembly.exe: {}", ioe.getMessage()); -202 throw new AnalysisException("Could not extract GrokAssembly.exe", ioe); -203 } finally { -204 if (fos != null) { -205 try { -206 fos.close(); -207 } catch (Throwable e) { -208 LOGGER.debug("Error closing output stream"); -209 } -210 } -211 if (is != null) { -212 try { -213 is.close(); -214 } catch (Throwable e) { -215 LOGGER.debug("Error closing input stream"); -216 } -217 } -218 } -219 -220 // Now, need to see if GrokAssembly actually runs from this location. -221 final List<String> args = buildArgumentList(); -222 try { -223 final ProcessBuilder pb = new ProcessBuilder(args); -224 final Process p = pb.start(); -225 // Try evacuating the error stream -226 IOUtils.copy(p.getErrorStream(), NullOutputStream.NULL_OUTPUT_STREAM); -227 -228 final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(p.getInputStream()); -229 final XPath xpath = XPathFactory.newInstance().newXPath(); -230 final String error = xpath.evaluate("/assembly/error", doc); -231 if (p.waitFor() != 1 || error == null || error.isEmpty()) { -232 LOGGER.warn("An error occurred with the .NET AssemblyAnalyzer, please see the log for more details."); -233 LOGGER.debug("GrokAssembly.exe is not working properly"); -234 grokAssemblyExe = null; -235 this.setEnabled(false); -236 throw new AnalysisException("Could not execute .NET AssemblyAnalyzer"); -237 } -238 } catch (AnalysisException e) { -239 throw e; -240 } catch (Throwable e) { -241 LOGGER.warn("An error occurred with the .NET AssemblyAnalyzer;\n" -242 + "this can be ignored unless you are scanning .NET DLLs. Please see the log for more details."); -243 LOGGER.debug("Could not execute GrokAssembly {}", e.getMessage()); -244 this.setEnabled(false); -245 throw new AnalysisException("An error occurred with the .NET AssemblyAnalyzer", e); -246 } -247 builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); -248 } -249 -250 /** -251 * Removes resources used from the local file system. -252 * -253 * @throws Exception thrown if there is a problem closing the analyzer -254 */ -255 @Override -256 public void close() throws Exception { -257 super.close(); -258 try { -259 if (grokAssemblyExe != null && !grokAssemblyExe.delete()) { -260 grokAssemblyExe.deleteOnExit(); -261 } -262 } catch (SecurityException se) { -263 LOGGER.debug("Can't delete temporary GrokAssembly.exe"); -264 } -265 } -266 -267 /** -268 * The File Filter used to filter supported extensions. +100 return args; +101 } +102 +103 /** +104 * Performs the analysis on a single Dependency. +105 * +106 * @param dependency the dependency to analyze +107 * @param engine the engine to perform the analysis under +108 * @throws AnalysisException if anything goes sideways +109 */ +110 @Override +111 public void analyzeFileType(Dependency dependency, Engine engine) +112 throws AnalysisException { +113 if (grokAssemblyExe == null) { +114 LOGGER.warn("GrokAssembly didn't get deployed"); +115 return; +116 } +117 +118 final List<String> args = buildArgumentList(); +119 args.add(dependency.getActualFilePath()); +120 final ProcessBuilder pb = new ProcessBuilder(args); +121 Document doc = null; +122 try { +123 final Process proc = pb.start(); +124 +125 doc = builder.parse(proc.getInputStream()); +126 +127 // Try evacuating the error stream +128 final String errorStream = IOUtils.toString(proc.getErrorStream(), "UTF-8"); +129 if (null != errorStream && !errorStream.isEmpty()) { +130 LOGGER.warn("Error from GrokAssembly: {}", errorStream); +131 } +132 +133 int rc = 0; +134 try { +135 rc = proc.waitFor(); +136 } catch (InterruptedException ie) { +137 return; +138 } +139 if (rc == 3) { +140 LOGGER.debug("{} is not a .NET assembly or executable and as such cannot be analyzed by dependency-check", +141 dependency.getActualFilePath()); +142 return; +143 } else if (rc != 0) { +144 LOGGER.warn("Return code {} from GrokAssembly", rc); +145 } +146 +147 final XPath xpath = XPathFactory.newInstance().newXPath(); +148 +149 // First, see if there was an error +150 final String error = xpath.evaluate("/assembly/error", doc); +151 if (error != null && !error.isEmpty()) { +152 throw new AnalysisException(error); +153 } +154 +155 final String version = xpath.evaluate("/assembly/version", doc); +156 if (version != null) { +157 dependency.getVersionEvidence().addEvidence(new Evidence("grokassembly", "version", +158 version, Confidence.HIGHEST)); +159 } +160 +161 final String vendor = xpath.evaluate("/assembly/company", doc); +162 if (vendor != null) { +163 dependency.getVendorEvidence().addEvidence(new Evidence("grokassembly", "vendor", +164 vendor, Confidence.HIGH)); +165 } +166 +167 final String product = xpath.evaluate("/assembly/product", doc); +168 if (product != null) { +169 dependency.getProductEvidence().addEvidence(new Evidence("grokassembly", "product", +170 product, Confidence.HIGH)); +171 } +172 +173 } catch (IOException ioe) { +174 throw new AnalysisException(ioe); +175 } catch (SAXException saxe) { +176 throw new AnalysisException("Couldn't parse GrokAssembly result", saxe); +177 } catch (XPathExpressionException xpe) { +178 // This shouldn't happen +179 throw new AnalysisException(xpe); +180 } +181 } +182 +183 /** +184 * Initialize the analyzer. In this case, extract GrokAssembly.exe to a +185 * temporary location. +186 * +187 * @throws InitializationException thrown if anything goes wrong +188 */ +189 @Override +190 public void initializeFileTypeAnalyzer() throws InitializationException { +191 final File tempFile; +192 try { +193 tempFile = File.createTempFile("GKA", ".exe", Settings.getTempDirectory()); +194 } catch (IOException ex) { +195 setEnabled(false); +196 throw new InitializationException("Unable to create temporary file for the assembly analyzerr", ex); +197 } +198 FileOutputStream fos = null; +199 InputStream is = null; +200 try { +201 fos = new FileOutputStream(tempFile); +202 is = AssemblyAnalyzer.class.getClassLoader().getResourceAsStream("GrokAssembly.exe"); +203 IOUtils.copy(is, fos); +204 +205 grokAssemblyExe = tempFile; +206 // Set the temp file to get deleted when we're done +207 grokAssemblyExe.deleteOnExit(); +208 LOGGER.debug("Extracted GrokAssembly.exe to {}", grokAssemblyExe.getPath()); +209 } catch (IOException ioe) { +210 this.setEnabled(false); +211 LOGGER.warn("Could not extract GrokAssembly.exe: {}", ioe.getMessage()); +212 throw new InitializationException("Could not extract GrokAssembly.exe", ioe); +213 } finally { +214 if (fos != null) { +215 try { +216 fos.close(); +217 } catch (Throwable e) { +218 LOGGER.debug("Error closing output stream"); +219 } +220 } +221 if (is != null) { +222 try { +223 is.close(); +224 } catch (Throwable e) { +225 LOGGER.debug("Error closing input stream"); +226 } +227 } +228 } +229 +230 // Now, need to see if GrokAssembly actually runs from this location. +231 final List<String> args = buildArgumentList(); +232 try { +233 final ProcessBuilder pb = new ProcessBuilder(args); +234 final Process p = pb.start(); +235 // Try evacuating the error stream +236 IOUtils.copy(p.getErrorStream(), NullOutputStream.NULL_OUTPUT_STREAM); +237 +238 final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(p.getInputStream()); +239 final XPath xpath = XPathFactory.newInstance().newXPath(); +240 final String error = xpath.evaluate("/assembly/error", doc); +241 if (p.waitFor() != 1 || error == null || error.isEmpty()) { +242 LOGGER.warn("An error occurred with the .NET AssemblyAnalyzer, please see the log for more details."); +243 LOGGER.debug("GrokAssembly.exe is not working properly"); +244 grokAssemblyExe = null; +245 setEnabled(false); +246 throw new InitializationException("Could not execute .NET AssemblyAnalyzer"); +247 } +248 } catch (InitializationException e) { +249 throw e; +250 } catch (Throwable e) { +251 LOGGER.warn("An error occurred with the .NET AssemblyAnalyzer;\n" +252 + "this can be ignored unless you are scanning .NET DLLs. Please see the log for more details."); +253 LOGGER.debug("Could not execute GrokAssembly {}", e.getMessage()); +254 setEnabled(false); +255 throw new InitializationException("An error occurred with the .NET AssemblyAnalyzer", e); +256 } +257 try { +258 builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); +259 } catch (ParserConfigurationException ex) { +260 setEnabled(false); +261 throw new InitializationException("Error initializing the assembly analyzer", ex); +262 } +263 } +264 +265 /** +266 * Removes resources used from the local file system. +267 * +268 * @throws Exception thrown if there is a problem closing the analyzer 269 */ -270 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions( -271 SUPPORTED_EXTENSIONS).build(); -272 -273 @Override -274 protected FileFilter getFileFilter() { -275 return FILTER; -276 } -277 -278 /** -279 * Gets this analyzer's name. -280 * -281 * @return the analyzer name -282 */ -283 @Override -284 public String getName() { -285 return ANALYZER_NAME; -286 } +270 @Override +271 public void close() throws Exception { +272 super.close(); +273 try { +274 if (grokAssemblyExe != null && !grokAssemblyExe.delete()) { +275 grokAssemblyExe.deleteOnExit(); +276 } +277 } catch (SecurityException se) { +278 LOGGER.debug("Can't delete temporary GrokAssembly.exe"); +279 } +280 } +281 +282 /** +283 * The File Filter used to filter supported extensions. +284 */ +285 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions( +286 SUPPORTED_EXTENSIONS).build(); 287 -288 /** -289 * Returns the phase this analyzer runs under. -290 * -291 * @return the phase this runs under -292 */ -293 @Override -294 public AnalysisPhase getAnalysisPhase() { -295 return ANALYSIS_PHASE; -296 } -297 -298 /** -299 * Returns the key used in the properties file to reference the analyzer's enabled property. -300 * -301 * @return the analyzer's enabled property setting key -302 */ -303 @Override -304 protected String getAnalyzerEnabledSettingKey() { -305 return Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED; -306 } -307 } +288 @Override +289 protected FileFilter getFileFilter() { +290 return FILTER; +291 } +292 +293 /** +294 * Gets this analyzer's name. +295 * +296 * @return the analyzer name +297 */ +298 @Override +299 public String getName() { +300 return ANALYZER_NAME; +301 } +302 +303 /** +304 * Returns the phase this analyzer runs under. +305 * +306 * @return the phase this runs under +307 */ +308 @Override +309 public AnalysisPhase getAnalysisPhase() { +310 return ANALYSIS_PHASE; +311 } +312 +313 /** +314 * Returns the key used in the properties file to reference the analyzer's +315 * enabled property. +316 * +317 * @return the analyzer's enabled property setting key +318 */ +319 @Override +320 protected String getAnalyzerEnabledSettingKey() { +321 return Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED; +322 } +323 }
      diff --git a/xref/org/owasp/dependencycheck/analyzer/AutoconfAnalyzer.html b/xref/org/owasp/dependencycheck/analyzer/AutoconfAnalyzer.html index 7561a4627..3ca94822e 100644 --- a/xref/org/owasp/dependencycheck/analyzer/AutoconfAnalyzer.html +++ b/xref/org/owasp/dependencycheck/analyzer/AutoconfAnalyzer.html @@ -43,248 +43,253 @@ 35 import java.util.List; 36 import java.util.regex.Matcher; 37 import java.util.regex.Pattern; -38 -39 /** -40 * Used to analyze Autoconf input files named configure.ac or configure.in. Files simply named "configure" are also analyzed, -41 * assuming they are generated by Autoconf, and contain certain special package descriptor variables. -42 * -43 * @author Dale Visser -44 * @see <a href="https://www.gnu.org/software/autoconf/">Autoconf - GNU Project - Free Software Foundation (FSF)</a> -45 */ -46 @Experimental -47 public class AutoconfAnalyzer extends AbstractFileTypeAnalyzer { -48 -49 /** -50 * Autoconf output filename. -51 */ -52 private static final String CONFIGURE = "configure"; -53 -54 /** -55 * Autoconf input filename. -56 */ -57 private static final String CONFIGURE_IN = "configure.in"; -58 -59 /** -60 * Autoconf input filename. -61 */ -62 private static final String CONFIGURE_AC = "configure.ac"; -63 -64 /** -65 * The name of the analyzer. -66 */ -67 private static final String ANALYZER_NAME = "Autoconf Analyzer"; -68 -69 /** -70 * The phase that this analyzer is intended to run in. -71 */ -72 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; -73 -74 /** -75 * The set of file extensions supported by this analyzer. -76 */ -77 private static final String[] EXTENSIONS = {"ac", "in"}; -78 -79 /** -80 * Matches AC_INIT variables in the output configure script. -81 */ -82 private static final Pattern PACKAGE_VAR = Pattern.compile( -83 "PACKAGE_(.+?)='(.*?)'", Pattern.DOTALL | Pattern.CASE_INSENSITIVE); -84 -85 /** -86 * Matches AC_INIT statement in configure.ac file. -87 */ -88 private static final Pattern AC_INIT_PATTERN; -89 -90 static { -91 // each instance of param or sep_param has a capture group -92 final String param = "\\[{0,2}(.+?)\\]{0,2}"; -93 final String sepParam = "\\s*,\\s*" + param; -94 // Group 1: Package -95 // Group 2: Version -96 // Group 3: optional -97 // Group 4: Bug report address (if it exists) -98 // Group 5: optional -99 // Group 6: Tarname (if it exists) -100 // Group 7: optional -101 // Group 8: URL (if it exists) -102 AC_INIT_PATTERN = Pattern.compile(String.format( -103 "AC_INIT\\(%s%s(%s)?(%s)?(%s)?\\s*\\)", param, sepParam, -104 sepParam, sepParam, sepParam), Pattern.DOTALL -105 | Pattern.CASE_INSENSITIVE); -106 } -107 -108 /** -109 * The file filter used to determine which files this analyzer supports. -110 */ -111 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addFilenames(CONFIGURE).addExtensions( -112 EXTENSIONS).build(); -113 -114 /** -115 * Returns the FileFilter -116 * -117 * @return the FileFilter -118 */ -119 @Override -120 protected FileFilter getFileFilter() { -121 return FILTER; -122 } -123 -124 /** -125 * Returns the name of the analyzer. -126 * -127 * @return the name of the analyzer. -128 */ -129 @Override -130 public String getName() { -131 return ANALYZER_NAME; -132 } -133 -134 /** -135 * Returns the phase that the analyzer is intended to run in. -136 * -137 * @return the phase that the analyzer is intended to run in. -138 */ -139 @Override -140 public AnalysisPhase getAnalysisPhase() { -141 return ANALYSIS_PHASE; -142 } -143 -144 /** -145 * Returns the key used in the properties file to reference the analyzer's enabled property. -146 * -147 * @return the analyzer's enabled property setting key -148 */ -149 @Override -150 protected String getAnalyzerEnabledSettingKey() { -151 return Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED; -152 } -153 -154 @Override -155 protected void analyzeFileType(Dependency dependency, Engine engine) -156 throws AnalysisException { -157 final File actualFile = dependency.getActualFile(); -158 final String name = actualFile.getName(); -159 if (name.startsWith(CONFIGURE)) { -160 final File parent = actualFile.getParentFile(); -161 final String parentName = parent.getName(); -162 dependency.setDisplayFileName(parentName + "/" + name); -163 final boolean isOutputScript = CONFIGURE.equals(name); -164 if (isOutputScript || CONFIGURE_AC.equals(name) -165 || CONFIGURE_IN.equals(name)) { -166 final String contents = getFileContents(actualFile); -167 if (!contents.isEmpty()) { -168 if (isOutputScript) { -169 extractConfigureScriptEvidence(dependency, name, -170 contents); -171 } else { -172 gatherEvidence(dependency, name, contents); -173 } -174 } -175 } -176 } else { -177 // copy, alter and set in case some other thread is iterating over -178 final List<Dependency> dependencies = new ArrayList<Dependency>( -179 engine.getDependencies()); -180 dependencies.remove(dependency); -181 engine.setDependencies(dependencies); -182 } -183 } -184 -185 /** -186 * Extracts evidence from the configuration. -187 * -188 * @param dependency the dependency being analyzed -189 * @param name the name of the source of evidence -190 * @param contents the contents to analyze for evidence -191 */ -192 private void extractConfigureScriptEvidence(Dependency dependency, -193 final String name, final String contents) { -194 final Matcher matcher = PACKAGE_VAR.matcher(contents); -195 while (matcher.find()) { -196 final String variable = matcher.group(1); -197 final String value = matcher.group(2); -198 if (!value.isEmpty()) { -199 if (variable.endsWith("NAME")) { -200 dependency.getProductEvidence().addEvidence(name, variable, -201 value, Confidence.HIGHEST); -202 } else if ("VERSION".equals(variable)) { -203 dependency.getVersionEvidence().addEvidence(name, variable, -204 value, Confidence.HIGHEST); -205 } else if ("BUGREPORT".equals(variable)) { -206 dependency.getVendorEvidence().addEvidence(name, variable, -207 value, Confidence.HIGH); -208 } else if ("URL".equals(variable)) { -209 dependency.getVendorEvidence().addEvidence(name, variable, -210 value, Confidence.HIGH); -211 } -212 } -213 } -214 } -215 -216 /** -217 * Retrieves the contents of a given file. -218 * -219 * @param actualFile the file to read -220 * @return the contents of the file -221 * @throws AnalysisException thrown if there is an IO Exception -222 */ -223 private String getFileContents(final File actualFile) -224 throws AnalysisException { -225 try { -226 return FileUtils.readFileToString(actualFile, Charset.defaultCharset()).trim(); -227 } catch (IOException e) { -228 throw new AnalysisException( -229 "Problem occurred while reading dependency file.", e); -230 } -231 } -232 -233 /** -234 * Gathers evidence from a given file -235 * -236 * @param dependency the dependency to add evidence to -237 * @param name the source of the evidence -238 * @param contents the evidence to analyze -239 */ -240 private void gatherEvidence(Dependency dependency, final String name, -241 String contents) { -242 final Matcher matcher = AC_INIT_PATTERN.matcher(contents); -243 if (matcher.find()) { -244 final EvidenceCollection productEvidence = dependency -245 .getProductEvidence(); -246 productEvidence.addEvidence(name, "Package", matcher.group(1), -247 Confidence.HIGHEST); -248 dependency.getVersionEvidence().addEvidence(name, -249 "Package Version", matcher.group(2), Confidence.HIGHEST); -250 final EvidenceCollection vendorEvidence = dependency -251 .getVendorEvidence(); -252 if (null != matcher.group(3)) { -253 vendorEvidence.addEvidence(name, "Bug report address", -254 matcher.group(4), Confidence.HIGH); -255 } -256 if (null != matcher.group(5)) { -257 productEvidence.addEvidence(name, "Tarname", matcher.group(6), -258 Confidence.HIGH); +38 import org.owasp.dependencycheck.exception.InitializationException; +39 +40 /** +41 * Used to analyze Autoconf input files named configure.ac or configure.in. +42 * Files simply named "configure" are also analyzed, assuming they are generated +43 * by Autoconf, and contain certain special package descriptor variables. +44 * +45 * @author Dale Visser +46 * @see <a href="https://www.gnu.org/software/autoconf/">Autoconf - GNU Project +47 * - Free Software Foundation (FSF)</a> +48 */ +49 @Experimental +50 public class AutoconfAnalyzer extends AbstractFileTypeAnalyzer { +51 +52 /** +53 * Autoconf output filename. +54 */ +55 private static final String CONFIGURE = "configure"; +56 +57 /** +58 * Autoconf input filename. +59 */ +60 private static final String CONFIGURE_IN = "configure.in"; +61 +62 /** +63 * Autoconf input filename. +64 */ +65 private static final String CONFIGURE_AC = "configure.ac"; +66 +67 /** +68 * The name of the analyzer. +69 */ +70 private static final String ANALYZER_NAME = "Autoconf Analyzer"; +71 +72 /** +73 * The phase that this analyzer is intended to run in. +74 */ +75 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; +76 +77 /** +78 * The set of file extensions supported by this analyzer. +79 */ +80 private static final String[] EXTENSIONS = {"ac", "in"}; +81 +82 /** +83 * Matches AC_INIT variables in the output configure script. +84 */ +85 private static final Pattern PACKAGE_VAR = Pattern.compile( +86 "PACKAGE_(.+?)='(.*?)'", Pattern.DOTALL | Pattern.CASE_INSENSITIVE); +87 +88 /** +89 * Matches AC_INIT statement in configure.ac file. +90 */ +91 private static final Pattern AC_INIT_PATTERN; +92 +93 static { +94 // each instance of param or sep_param has a capture group +95 final String param = "\\[{0,2}(.+?)\\]{0,2}"; +96 final String sepParam = "\\s*,\\s*" + param; +97 // Group 1: Package +98 // Group 2: Version +99 // Group 3: optional +100 // Group 4: Bug report address (if it exists) +101 // Group 5: optional +102 // Group 6: Tarname (if it exists) +103 // Group 7: optional +104 // Group 8: URL (if it exists) +105 AC_INIT_PATTERN = Pattern.compile(String.format( +106 "AC_INIT\\(%s%s(%s)?(%s)?(%s)?\\s*\\)", param, sepParam, +107 sepParam, sepParam, sepParam), Pattern.DOTALL +108 | Pattern.CASE_INSENSITIVE); +109 } +110 +111 /** +112 * The file filter used to determine which files this analyzer supports. +113 */ +114 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addFilenames(CONFIGURE).addExtensions( +115 EXTENSIONS).build(); +116 +117 /** +118 * Returns the FileFilter +119 * +120 * @return the FileFilter +121 */ +122 @Override +123 protected FileFilter getFileFilter() { +124 return FILTER; +125 } +126 +127 /** +128 * Returns the name of the analyzer. +129 * +130 * @return the name of the analyzer. +131 */ +132 @Override +133 public String getName() { +134 return ANALYZER_NAME; +135 } +136 +137 /** +138 * Returns the phase that the analyzer is intended to run in. +139 * +140 * @return the phase that the analyzer is intended to run in. +141 */ +142 @Override +143 public AnalysisPhase getAnalysisPhase() { +144 return ANALYSIS_PHASE; +145 } +146 +147 /** +148 * Returns the key used in the properties file to reference the analyzer's +149 * enabled property. +150 * +151 * @return the analyzer's enabled property setting key +152 */ +153 @Override +154 protected String getAnalyzerEnabledSettingKey() { +155 return Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED; +156 } +157 +158 @Override +159 protected void analyzeFileType(Dependency dependency, Engine engine) +160 throws AnalysisException { +161 final File actualFile = dependency.getActualFile(); +162 final String name = actualFile.getName(); +163 if (name.startsWith(CONFIGURE)) { +164 final File parent = actualFile.getParentFile(); +165 final String parentName = parent.getName(); +166 dependency.setDisplayFileName(parentName + "/" + name); +167 final boolean isOutputScript = CONFIGURE.equals(name); +168 if (isOutputScript || CONFIGURE_AC.equals(name) +169 || CONFIGURE_IN.equals(name)) { +170 final String contents = getFileContents(actualFile); +171 if (!contents.isEmpty()) { +172 if (isOutputScript) { +173 extractConfigureScriptEvidence(dependency, name, +174 contents); +175 } else { +176 gatherEvidence(dependency, name, contents); +177 } +178 } +179 } +180 } else { +181 // copy, alter and set in case some other thread is iterating over +182 final List<Dependency> dependencies = new ArrayList<Dependency>( +183 engine.getDependencies()); +184 dependencies.remove(dependency); +185 engine.setDependencies(dependencies); +186 } +187 } +188 +189 /** +190 * Extracts evidence from the configuration. +191 * +192 * @param dependency the dependency being analyzed +193 * @param name the name of the source of evidence +194 * @param contents the contents to analyze for evidence +195 */ +196 private void extractConfigureScriptEvidence(Dependency dependency, +197 final String name, final String contents) { +198 final Matcher matcher = PACKAGE_VAR.matcher(contents); +199 while (matcher.find()) { +200 final String variable = matcher.group(1); +201 final String value = matcher.group(2); +202 if (!value.isEmpty()) { +203 if (variable.endsWith("NAME")) { +204 dependency.getProductEvidence().addEvidence(name, variable, +205 value, Confidence.HIGHEST); +206 } else if ("VERSION".equals(variable)) { +207 dependency.getVersionEvidence().addEvidence(name, variable, +208 value, Confidence.HIGHEST); +209 } else if ("BUGREPORT".equals(variable)) { +210 dependency.getVendorEvidence().addEvidence(name, variable, +211 value, Confidence.HIGH); +212 } else if ("URL".equals(variable)) { +213 dependency.getVendorEvidence().addEvidence(name, variable, +214 value, Confidence.HIGH); +215 } +216 } +217 } +218 } +219 +220 /** +221 * Retrieves the contents of a given file. +222 * +223 * @param actualFile the file to read +224 * @return the contents of the file +225 * @throws AnalysisException thrown if there is an IO Exception +226 */ +227 private String getFileContents(final File actualFile) +228 throws AnalysisException { +229 try { +230 return FileUtils.readFileToString(actualFile, Charset.defaultCharset()).trim(); +231 } catch (IOException e) { +232 throw new AnalysisException( +233 "Problem occurred while reading dependency file.", e); +234 } +235 } +236 +237 /** +238 * Gathers evidence from a given file +239 * +240 * @param dependency the dependency to add evidence to +241 * @param name the source of the evidence +242 * @param contents the evidence to analyze +243 */ +244 private void gatherEvidence(Dependency dependency, final String name, +245 String contents) { +246 final Matcher matcher = AC_INIT_PATTERN.matcher(contents); +247 if (matcher.find()) { +248 final EvidenceCollection productEvidence = dependency +249 .getProductEvidence(); +250 productEvidence.addEvidence(name, "Package", matcher.group(1), +251 Confidence.HIGHEST); +252 dependency.getVersionEvidence().addEvidence(name, +253 "Package Version", matcher.group(2), Confidence.HIGHEST); +254 final EvidenceCollection vendorEvidence = dependency +255 .getVendorEvidence(); +256 if (null != matcher.group(3)) { +257 vendorEvidence.addEvidence(name, "Bug report address", +258 matcher.group(4), Confidence.HIGH); 259 } -260 if (null != matcher.group(7)) { -261 final String url = matcher.group(8); -262 if (UrlStringUtils.isUrl(url)) { -263 vendorEvidence.addEvidence(name, "URL", url, -264 Confidence.HIGH); -265 } -266 } -267 } -268 } -269 -270 /** -271 * Initializes the file type analyzer. -272 * -273 * @throws Exception thrown if there is an exception during initialization -274 */ -275 @Override -276 protected void initializeFileTypeAnalyzer() throws Exception { -277 // No initialization needed. -278 } -279 } +260 if (null != matcher.group(5)) { +261 productEvidence.addEvidence(name, "Tarname", matcher.group(6), +262 Confidence.HIGH); +263 } +264 if (null != matcher.group(7)) { +265 final String url = matcher.group(8); +266 if (UrlStringUtils.isUrl(url)) { +267 vendorEvidence.addEvidence(name, "URL", url, +268 Confidence.HIGH); +269 } +270 } +271 } +272 } +273 +274 /** +275 * Initializes the file type analyzer. +276 * +277 * @throws InitializationException thrown if there is an exception during +278 * initialization +279 */ +280 @Override +281 protected void initializeFileTypeAnalyzer() throws InitializationException { +282 // No initialization needed. +283 } +284 }
      diff --git a/xref/org/owasp/dependencycheck/analyzer/CMakeAnalyzer.html b/xref/org/owasp/dependencycheck/analyzer/CMakeAnalyzer.html index f5f3f1e81..f090a3223 100644 --- a/xref/org/owasp/dependencycheck/analyzer/CMakeAnalyzer.html +++ b/xref/org/owasp/dependencycheck/analyzer/CMakeAnalyzer.html @@ -46,205 +46,211 @@ 38 import java.security.NoSuchAlgorithmException; 39 import java.util.regex.Matcher; 40 import java.util.regex.Pattern; -41 -42 /** -43 * <p> -44 * Used to analyze CMake build files, and collect information that can be used to determine the associated CPE.</p> -45 * <p> -46 * Note: This analyzer catches straightforward invocations of the project command, plus some other observed patterns of version -47 * inclusion in real CMake projects. Many projects make use of older versions of CMake and/or use custom "homebrew" ways to insert -48 * version information. Hopefully as the newer CMake call pattern grows in usage, this analyzer allow more CPEs to be -49 * identified.</p> -50 * -51 * @author Dale Visser -52 */ -53 @Experimental -54 public class CMakeAnalyzer extends AbstractFileTypeAnalyzer { -55 -56 /** -57 * The logger. -58 */ -59 private static final Logger LOGGER = LoggerFactory.getLogger(CMakeAnalyzer.class); -60 -61 /** -62 * Used when compiling file scanning regex patterns. -63 */ -64 private static final int REGEX_OPTIONS = Pattern.DOTALL -65 | Pattern.CASE_INSENSITIVE | Pattern.MULTILINE; -66 -67 /** -68 * Regex to extract the product information. -69 */ -70 private static final Pattern PROJECT = Pattern.compile( -71 "^ *project *\\([ \\n]*(\\w+)[ \\n]*.*?\\)", REGEX_OPTIONS); -72 -73 /** -74 * Regex to extract product and version information. -75 * -76 * Group 1: Product -77 * -78 * Group 2: Version -79 */ -80 private static final Pattern SET_VERSION = Pattern -81 .compile( -82 "^ *set\\s*\\(\\s*(\\w+)_version\\s+\"?(\\d+(?:\\.\\d+)+)[\\s\"]?\\)", -83 REGEX_OPTIONS); -84 -85 /** -86 * Detects files that can be analyzed. -87 */ -88 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(".cmake") -89 .addFilenames("CMakeLists.txt").build(); -90 -91 /** -92 * A reference to SHA1 message digest. -93 */ -94 private static MessageDigest sha1 = null; -95 -96 static { -97 try { -98 sha1 = MessageDigest.getInstance("SHA1"); -99 } catch (NoSuchAlgorithmException e) { -100 LOGGER.error(e.getMessage()); -101 } -102 } -103 -104 /** -105 * Returns the name of the CMake analyzer. -106 * -107 * @return the name of the analyzer -108 * -109 */ -110 @Override -111 public String getName() { -112 return "CMake Analyzer"; -113 } -114 -115 /** -116 * Tell that we are used for information collection. -117 * -118 * @return INFORMATION_COLLECTION -119 */ -120 @Override -121 public AnalysisPhase getAnalysisPhase() { -122 return AnalysisPhase.INFORMATION_COLLECTION; -123 } -124 -125 /** -126 * Returns the set of supported file extensions. -127 * -128 * @return the set of supported file extensions -129 */ -130 @Override -131 protected FileFilter getFileFilter() { -132 return FILTER; -133 } -134 -135 /** -136 * No-op initializer implementation. -137 * -138 * @throws Exception never thrown -139 */ -140 @Override -141 protected void initializeFileTypeAnalyzer() throws Exception { -142 // Nothing to do here. -143 } -144 -145 /** -146 * Analyzes python packages and adds evidence to the dependency. -147 * -148 * @param dependency the dependency being analyzed -149 * @param engine the engine being used to perform the scan -150 * @throws AnalysisException thrown if there is an unrecoverable error analyzing the dependency -151 */ -152 @Override -153 protected void analyzeFileType(Dependency dependency, Engine engine) -154 throws AnalysisException { -155 final File file = dependency.getActualFile(); -156 final String parentName = file.getParentFile().getName(); -157 final String name = file.getName(); -158 dependency.setDisplayFileName(String.format("%s%c%s", parentName, File.separatorChar, name)); -159 String contents; -160 try { -161 contents = FileUtils.readFileToString(file, Charset.defaultCharset()).trim(); -162 } catch (IOException e) { -163 throw new AnalysisException( -164 "Problem occurred while reading dependency file.", e); -165 } -166 -167 if (StringUtils.isNotBlank(contents)) { -168 final Matcher m = PROJECT.matcher(contents); -169 int count = 0; -170 while (m.find()) { -171 count++; -172 LOGGER.debug(String.format( -173 "Found project command match with %d groups: %s", -174 m.groupCount(), m.group(0))); -175 final String group = m.group(1); -176 LOGGER.debug("Group 1: " + group); -177 dependency.getProductEvidence().addEvidence(name, "Project", -178 group, Confidence.HIGH); -179 } -180 LOGGER.debug("Found {} matches.", count); -181 analyzeSetVersionCommand(dependency, engine, contents); -182 } -183 } -184 -185 /** -186 * Extracts the version information from the contents. If more then one version is found additional dependencies are added to -187 * the dependency list. -188 * -189 * @param dependency the dependency being analyzed -190 * @param engine the dependency-check engine -191 * @param contents the version information -192 */ -193 private void analyzeSetVersionCommand(Dependency dependency, Engine engine, String contents) { -194 Dependency currentDep = dependency; -195 -196 final Matcher m = SET_VERSION.matcher(contents); -197 int count = 0; -198 while (m.find()) { -199 count++; -200 LOGGER.debug("Found project command match with {} groups: {}", -201 m.groupCount(), m.group(0)); -202 String product = m.group(1); -203 final String version = m.group(2); -204 LOGGER.debug("Group 1: " + product); -205 LOGGER.debug("Group 2: " + version); -206 final String aliasPrefix = "ALIASOF_"; -207 if (product.startsWith(aliasPrefix)) { -208 product = product.replaceFirst(aliasPrefix, ""); -209 } -210 if (count > 1) { -211 //TODO - refactor so we do not assign to the parameter (checkstyle) -212 currentDep = new Dependency(dependency.getActualFile()); -213 currentDep.setDisplayFileName(String.format("%s:%s", dependency.getDisplayFileName(), product)); -214 final String filePath = String.format("%s:%s", dependency.getFilePath(), product); -215 currentDep.setFilePath(filePath); -216 -217 byte[] path; -218 try { -219 path = filePath.getBytes("UTF-8"); -220 } catch (UnsupportedEncodingException ex) { -221 path = filePath.getBytes(); -222 } -223 currentDep.setSha1sum(Checksum.getHex(sha1.digest(path))); -224 engine.getDependencies().add(currentDep); -225 } -226 final String source = currentDep.getDisplayFileName(); -227 currentDep.getProductEvidence().addEvidence(source, "Product", -228 product, Confidence.MEDIUM); -229 currentDep.getVersionEvidence().addEvidence(source, "Version", -230 version, Confidence.MEDIUM); -231 } -232 LOGGER.debug(String.format("Found %d matches.", count)); -233 } -234 -235 @Override -236 protected String getAnalyzerEnabledSettingKey() { -237 return Settings.KEYS.ANALYZER_CMAKE_ENABLED; -238 } -239 } +41 import org.owasp.dependencycheck.exception.InitializationException; +42 +43 /** +44 * <p> +45 * Used to analyze CMake build files, and collect information that can be used +46 * to determine the associated CPE.</p> +47 * <p> +48 * Note: This analyzer catches straightforward invocations of the project +49 * command, plus some other observed patterns of version inclusion in real CMake +50 * projects. Many projects make use of older versions of CMake and/or use custom +51 * "homebrew" ways to insert version information. Hopefully as the newer CMake +52 * call pattern grows in usage, this analyzer allow more CPEs to be +53 * identified.</p> +54 * +55 * @author Dale Visser +56 */ +57 @Experimental +58 public class CMakeAnalyzer extends AbstractFileTypeAnalyzer { +59 +60 /** +61 * The logger. +62 */ +63 private static final Logger LOGGER = LoggerFactory.getLogger(CMakeAnalyzer.class); +64 +65 /** +66 * Used when compiling file scanning regex patterns. +67 */ +68 private static final int REGEX_OPTIONS = Pattern.DOTALL +69 | Pattern.CASE_INSENSITIVE | Pattern.MULTILINE; +70 +71 /** +72 * Regex to extract the product information. +73 */ +74 private static final Pattern PROJECT = Pattern.compile( +75 "^ *project *\\([ \\n]*(\\w+)[ \\n]*.*?\\)", REGEX_OPTIONS); +76 +77 /** +78 * Regex to extract product and version information. +79 * +80 * Group 1: Product +81 * +82 * Group 2: Version +83 */ +84 private static final Pattern SET_VERSION = Pattern +85 .compile( +86 "^ *set\\s*\\(\\s*(\\w+)_version\\s+\"?(\\d+(?:\\.\\d+)+)[\\s\"]?\\)", +87 REGEX_OPTIONS); +88 +89 /** +90 * Detects files that can be analyzed. +91 */ +92 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(".cmake") +93 .addFilenames("CMakeLists.txt").build(); +94 +95 /** +96 * A reference to SHA1 message digest. +97 */ +98 private static MessageDigest sha1 = null; +99 +100 static { +101 try { +102 sha1 = MessageDigest.getInstance("SHA1"); +103 } catch (NoSuchAlgorithmException e) { +104 LOGGER.error(e.getMessage()); +105 } +106 } +107 +108 /** +109 * Returns the name of the CMake analyzer. +110 * +111 * @return the name of the analyzer +112 * +113 */ +114 @Override +115 public String getName() { +116 return "CMake Analyzer"; +117 } +118 +119 /** +120 * Tell that we are used for information collection. +121 * +122 * @return INFORMATION_COLLECTION +123 */ +124 @Override +125 public AnalysisPhase getAnalysisPhase() { +126 return AnalysisPhase.INFORMATION_COLLECTION; +127 } +128 +129 /** +130 * Returns the set of supported file extensions. +131 * +132 * @return the set of supported file extensions +133 */ +134 @Override +135 protected FileFilter getFileFilter() { +136 return FILTER; +137 } +138 +139 /** +140 * No-op initializer implementation. +141 * +142 * @throws InitializationException never thrown +143 */ +144 @Override +145 protected void initializeFileTypeAnalyzer() throws InitializationException { +146 // Nothing to do here. +147 } +148 +149 /** +150 * Analyzes python packages and adds evidence to the dependency. +151 * +152 * @param dependency the dependency being analyzed +153 * @param engine the engine being used to perform the scan +154 * @throws AnalysisException thrown if there is an unrecoverable error +155 * analyzing the dependency +156 */ +157 @Override +158 protected void analyzeFileType(Dependency dependency, Engine engine) +159 throws AnalysisException { +160 final File file = dependency.getActualFile(); +161 final String parentName = file.getParentFile().getName(); +162 final String name = file.getName(); +163 dependency.setDisplayFileName(String.format("%s%c%s", parentName, File.separatorChar, name)); +164 String contents; +165 try { +166 contents = FileUtils.readFileToString(file, Charset.defaultCharset()).trim(); +167 } catch (IOException e) { +168 throw new AnalysisException( +169 "Problem occurred while reading dependency file.", e); +170 } +171 +172 if (StringUtils.isNotBlank(contents)) { +173 final Matcher m = PROJECT.matcher(contents); +174 int count = 0; +175 while (m.find()) { +176 count++; +177 LOGGER.debug(String.format( +178 "Found project command match with %d groups: %s", +179 m.groupCount(), m.group(0))); +180 final String group = m.group(1); +181 LOGGER.debug("Group 1: " + group); +182 dependency.getProductEvidence().addEvidence(name, "Project", +183 group, Confidence.HIGH); +184 } +185 LOGGER.debug("Found {} matches.", count); +186 analyzeSetVersionCommand(dependency, engine, contents); +187 } +188 } +189 +190 /** +191 * Extracts the version information from the contents. If more then one +192 * version is found additional dependencies are added to the dependency +193 * list. +194 * +195 * @param dependency the dependency being analyzed +196 * @param engine the dependency-check engine +197 * @param contents the version information +198 */ +199 private void analyzeSetVersionCommand(Dependency dependency, Engine engine, String contents) { +200 Dependency currentDep = dependency; +201 +202 final Matcher m = SET_VERSION.matcher(contents); +203 int count = 0; +204 while (m.find()) { +205 count++; +206 LOGGER.debug("Found project command match with {} groups: {}", +207 m.groupCount(), m.group(0)); +208 String product = m.group(1); +209 final String version = m.group(2); +210 LOGGER.debug("Group 1: " + product); +211 LOGGER.debug("Group 2: " + version); +212 final String aliasPrefix = "ALIASOF_"; +213 if (product.startsWith(aliasPrefix)) { +214 product = product.replaceFirst(aliasPrefix, ""); +215 } +216 if (count > 1) { +217 //TODO - refactor so we do not assign to the parameter (checkstyle) +218 currentDep = new Dependency(dependency.getActualFile()); +219 currentDep.setDisplayFileName(String.format("%s:%s", dependency.getDisplayFileName(), product)); +220 final String filePath = String.format("%s:%s", dependency.getFilePath(), product); +221 currentDep.setFilePath(filePath); +222 +223 byte[] path; +224 try { +225 path = filePath.getBytes("UTF-8"); +226 } catch (UnsupportedEncodingException ex) { +227 path = filePath.getBytes(); +228 } +229 currentDep.setSha1sum(Checksum.getHex(sha1.digest(path))); +230 engine.getDependencies().add(currentDep); +231 } +232 final String source = currentDep.getDisplayFileName(); +233 currentDep.getProductEvidence().addEvidence(source, "Product", +234 product, Confidence.MEDIUM); +235 currentDep.getVersionEvidence().addEvidence(source, "Version", +236 version, Confidence.MEDIUM); +237 } +238 LOGGER.debug(String.format("Found %d matches.", count)); +239 } +240 +241 @Override +242 protected String getAnalyzerEnabledSettingKey() { +243 return Settings.KEYS.ANALYZER_CMAKE_ENABLED; +244 } +245 }
      diff --git a/xref/org/owasp/dependencycheck/analyzer/CPEAnalyzer.html b/xref/org/owasp/dependencycheck/analyzer/CPEAnalyzer.html index c20446fa5..dada8235f 100644 --- a/xref/org/owasp/dependencycheck/analyzer/CPEAnalyzer.html +++ b/xref/org/owasp/dependencycheck/analyzer/CPEAnalyzer.html @@ -53,762 +53,773 @@ 45 import org.owasp.dependencycheck.dependency.EvidenceCollection; 46 import org.owasp.dependencycheck.dependency.Identifier; 47 import org.owasp.dependencycheck.dependency.VulnerableSoftware; -48 import org.owasp.dependencycheck.utils.DependencyVersion; -49 import org.owasp.dependencycheck.utils.DependencyVersionUtil; -50 import org.slf4j.Logger; -51 import org.slf4j.LoggerFactory; -52 -53 /** -54 * CPEAnalyzer is a utility class that takes a project dependency and attempts -55 * to discern if there is an associated CPE. It uses the evidence contained -56 * within the dependency to search the Lucene index. -57 * -58 * @author Jeremy Long -59 */ -60 public class CPEAnalyzer implements Analyzer { -61 -62 /** -63 * The Logger. -64 */ -65 private static final Logger LOGGER = LoggerFactory.getLogger(CPEAnalyzer.class); -66 /** -67 * The maximum number of query results to return. -68 */ -69 static final int MAX_QUERY_RESULTS = 25; -70 /** -71 * The weighting boost to give terms when constructing the Lucene query. -72 */ -73 static final String WEIGHTING_BOOST = "^5"; -74 /** -75 * A string representation of a regular expression defining characters -76 * utilized within the CPE Names. -77 */ -78 static final String CLEANSE_CHARACTER_RX = "[^A-Za-z0-9 ._-]"; -79 /** -80 * A string representation of a regular expression used to remove all but -81 * alpha characters. -82 */ -83 static final String CLEANSE_NONALPHA_RX = "[^A-Za-z]*"; -84 /** -85 * The additional size to add to a new StringBuilder to account for extra -86 * data that will be written into the string. -87 */ -88 static final int STRING_BUILDER_BUFFER = 20; -89 /** -90 * The CPE in memory index. -91 */ -92 private CpeMemoryIndex cpe; -93 /** -94 * The CVE Database. -95 */ -96 private CveDB cve; -97 -98 /** -99 * The URL to perform a search of the NVD CVE data at NIST. -100 */ -101 public static final String NVD_SEARCH_URL = "https://web.nvd.nist.gov/view/vuln/search-results?adv_search=true&cves=on&cpe_version=%s"; -102 -103 /** -104 * Returns the name of this analyzer. -105 * -106 * @return the name of this analyzer. -107 */ -108 @Override -109 public String getName() { -110 return "CPE Analyzer"; -111 } -112 -113 /** -114 * Returns the analysis phase that this analyzer should run in. -115 * -116 * @return the analysis phase that this analyzer should run in. -117 */ -118 @Override -119 public AnalysisPhase getAnalysisPhase() { -120 return AnalysisPhase.IDENTIFIER_ANALYSIS; -121 } -122 -123 /** -124 * Creates the CPE Lucene Index. -125 * -126 * @throws Exception is thrown if there is an issue opening the index. -127 */ -128 @Override -129 public void initialize() throws Exception { -130 this.open(); -131 } -132 -133 /** -134 * Opens the data source. -135 * -136 * @throws IOException when the Lucene directory to be queried does not -137 * exist or is corrupt. -138 * @throws DatabaseException when the database throws an exception. This -139 * usually occurs when the database is in use by another process. -140 */ -141 public void open() throws IOException, DatabaseException { -142 if (!isOpen()) { -143 cve = new CveDB(); -144 cve.open(); -145 cpe = CpeMemoryIndex.getInstance(); -146 try { -147 LOGGER.info("Creating the CPE Index"); -148 final long creationStart = System.currentTimeMillis(); -149 cpe.open(cve); -150 LOGGER.info("CPE Index Created ({} ms)", System.currentTimeMillis() - creationStart); -151 } catch (IndexException ex) { -152 LOGGER.debug("IndexException", ex); -153 throw new DatabaseException(ex); -154 } -155 } -156 } -157 -158 /** -159 * Closes the data sources. -160 */ -161 @Override -162 public void close() { -163 if (cpe != null) { -164 cpe.close(); -165 cpe = null; -166 } -167 if (cve != null) { -168 cve.close(); -169 cve = null; -170 } -171 } -172 -173 public boolean isOpen() { -174 return cpe != null && cpe.isOpen(); -175 } -176 -177 /** -178 * Searches the data store of CPE entries, trying to identify the CPE for -179 * the given dependency based on the evidence contained within. The -180 * dependency passed in is updated with any identified CPE values. -181 * -182 * @param dependency the dependency to search for CPE entries on. -183 * @throws CorruptIndexException is thrown when the Lucene index is corrupt. -184 * @throws IOException is thrown when an IOException occurs. -185 * @throws ParseException is thrown when the Lucene query cannot be parsed. -186 */ -187 protected void determineCPE(Dependency dependency) throws CorruptIndexException, IOException, ParseException { -188 //TODO test dojo-war against this. we shold get dojo-toolkit:dojo-toolkit AND dojo-toolkit:toolkit -189 String vendors = ""; -190 String products = ""; -191 for (Confidence confidence : Confidence.values()) { -192 if (dependency.getVendorEvidence().contains(confidence)) { -193 vendors = addEvidenceWithoutDuplicateTerms(vendors, dependency.getVendorEvidence(), confidence); -194 LOGGER.debug("vendor search: {}", vendors); -195 } -196 if (dependency.getProductEvidence().contains(confidence)) { -197 products = addEvidenceWithoutDuplicateTerms(products, dependency.getProductEvidence(), confidence); -198 LOGGER.debug("product search: {}", products); -199 } -200 if (!vendors.isEmpty() && !products.isEmpty()) { -201 final List<IndexEntry> entries = searchCPE(vendors, products, dependency.getVendorEvidence().getWeighting(), -202 dependency.getProductEvidence().getWeighting()); -203 if (entries == null) { -204 continue; -205 } -206 boolean identifierAdded = false; -207 for (IndexEntry e : entries) { -208 LOGGER.debug("Verifying entry: {}", e); -209 if (verifyEntry(e, dependency)) { -210 final String vendor = e.getVendor(); -211 final String product = e.getProduct(); -212 LOGGER.debug("identified vendor/product: {}/{}", vendor, product); -213 identifierAdded |= determineIdentifiers(dependency, vendor, product, confidence); -214 } +48 import org.owasp.dependencycheck.exception.InitializationException; +49 import org.owasp.dependencycheck.utils.DependencyVersion; +50 import org.owasp.dependencycheck.utils.DependencyVersionUtil; +51 import org.slf4j.Logger; +52 import org.slf4j.LoggerFactory; +53 +54 /** +55 * CPEAnalyzer is a utility class that takes a project dependency and attempts +56 * to discern if there is an associated CPE. It uses the evidence contained +57 * within the dependency to search the Lucene index. +58 * +59 * @author Jeremy Long +60 */ +61 public class CPEAnalyzer implements Analyzer { +62 +63 /** +64 * The Logger. +65 */ +66 private static final Logger LOGGER = LoggerFactory.getLogger(CPEAnalyzer.class); +67 /** +68 * The maximum number of query results to return. +69 */ +70 static final int MAX_QUERY_RESULTS = 25; +71 /** +72 * The weighting boost to give terms when constructing the Lucene query. +73 */ +74 static final String WEIGHTING_BOOST = "^5"; +75 /** +76 * A string representation of a regular expression defining characters +77 * utilized within the CPE Names. +78 */ +79 static final String CLEANSE_CHARACTER_RX = "[^A-Za-z0-9 ._-]"; +80 /** +81 * A string representation of a regular expression used to remove all but +82 * alpha characters. +83 */ +84 static final String CLEANSE_NONALPHA_RX = "[^A-Za-z]*"; +85 /** +86 * The additional size to add to a new StringBuilder to account for extra +87 * data that will be written into the string. +88 */ +89 static final int STRING_BUILDER_BUFFER = 20; +90 /** +91 * The CPE in memory index. +92 */ +93 private CpeMemoryIndex cpe; +94 /** +95 * The CVE Database. +96 */ +97 private CveDB cve; +98 +99 /** +100 * The URL to perform a search of the NVD CVE data at NIST. +101 */ +102 public static final String NVD_SEARCH_URL = "https://web.nvd.nist.gov/view/vuln/search-results?adv_search=true&cves=on&cpe_version=%s"; +103 +104 /** +105 * Returns the name of this analyzer. +106 * +107 * @return the name of this analyzer. +108 */ +109 @Override +110 public String getName() { +111 return "CPE Analyzer"; +112 } +113 +114 /** +115 * Returns the analysis phase that this analyzer should run in. +116 * +117 * @return the analysis phase that this analyzer should run in. +118 */ +119 @Override +120 public AnalysisPhase getAnalysisPhase() { +121 return AnalysisPhase.IDENTIFIER_ANALYSIS; +122 } +123 +124 /** +125 * Creates the CPE Lucene Index. +126 * +127 * @throws InitializationException is thrown if there is an issue opening +128 * the index. +129 */ +130 @Override +131 public void initialize() throws InitializationException { +132 try { +133 this.open(); +134 } catch (IOException ex) { +135 LOGGER.debug("Exception initializing the Lucene Index", ex); +136 throw new InitializationException("An exception occurred initializing the Lucene Index", ex); +137 } catch (DatabaseException ex) { +138 LOGGER.debug("Exception accessing the database", ex); +139 throw new InitializationException("An exception occurred accessing the database", ex); +140 } +141 } +142 +143 /** +144 * Opens the data source. +145 * +146 * @throws IOException when the Lucene directory to be queried does not +147 * exist or is corrupt. +148 * @throws DatabaseException when the database throws an exception. This +149 * usually occurs when the database is in use by another process. +150 */ +151 public void open() throws IOException, DatabaseException { +152 if (!isOpen()) { +153 cve = new CveDB(); +154 cve.open(); +155 cpe = CpeMemoryIndex.getInstance(); +156 try { +157 LOGGER.info("Creating the CPE Index"); +158 final long creationStart = System.currentTimeMillis(); +159 cpe.open(cve); +160 LOGGER.info("CPE Index Created ({} ms)", System.currentTimeMillis() - creationStart); +161 } catch (IndexException ex) { +162 LOGGER.debug("IndexException", ex); +163 throw new DatabaseException(ex); +164 } +165 } +166 } +167 +168 /** +169 * Closes the data sources. +170 */ +171 @Override +172 public void close() { +173 if (cpe != null) { +174 cpe.close(); +175 cpe = null; +176 } +177 if (cve != null) { +178 cve.close(); +179 cve = null; +180 } +181 } +182 +183 public boolean isOpen() { +184 return cpe != null && cpe.isOpen(); +185 } +186 +187 /** +188 * Searches the data store of CPE entries, trying to identify the CPE for +189 * the given dependency based on the evidence contained within. The +190 * dependency passed in is updated with any identified CPE values. +191 * +192 * @param dependency the dependency to search for CPE entries on. +193 * @throws CorruptIndexException is thrown when the Lucene index is corrupt. +194 * @throws IOException is thrown when an IOException occurs. +195 * @throws ParseException is thrown when the Lucene query cannot be parsed. +196 */ +197 protected void determineCPE(Dependency dependency) throws CorruptIndexException, IOException, ParseException { +198 //TODO test dojo-war against this. we shold get dojo-toolkit:dojo-toolkit AND dojo-toolkit:toolkit +199 String vendors = ""; +200 String products = ""; +201 for (Confidence confidence : Confidence.values()) { +202 if (dependency.getVendorEvidence().contains(confidence)) { +203 vendors = addEvidenceWithoutDuplicateTerms(vendors, dependency.getVendorEvidence(), confidence); +204 LOGGER.debug("vendor search: {}", vendors); +205 } +206 if (dependency.getProductEvidence().contains(confidence)) { +207 products = addEvidenceWithoutDuplicateTerms(products, dependency.getProductEvidence(), confidence); +208 LOGGER.debug("product search: {}", products); +209 } +210 if (!vendors.isEmpty() && !products.isEmpty()) { +211 final List<IndexEntry> entries = searchCPE(vendors, products, dependency.getVendorEvidence().getWeighting(), +212 dependency.getProductEvidence().getWeighting()); +213 if (entries == null) { +214 continue; 215 } -216 if (identifierAdded) { -217 break; -218 } -219 } -220 } -221 } -222 -223 /** -224 * Returns the text created by concatenating the text and the values from -225 * the EvidenceCollection (filtered for a specific confidence). This -226 * attempts to prevent duplicate terms from being added.<br/<br/> Note, if -227 * the evidence is longer then 200 characters it will be truncated. -228 * -229 * @param text the base text. -230 * @param ec an EvidenceCollection -231 * @param confidenceFilter a Confidence level to filter the evidence by. -232 * @return the new evidence text -233 */ -234 private String addEvidenceWithoutDuplicateTerms(final String text, final EvidenceCollection ec, Confidence confidenceFilter) { -235 final String txt = (text == null) ? "" : text; -236 final StringBuilder sb = new StringBuilder(txt.length() + (20 * ec.size())); -237 sb.append(' ').append(txt).append(' '); -238 for (Evidence e : ec.iterator(confidenceFilter)) { -239 String value = e.getValue(); -240 -241 //hack to get around the fact that lucene does a really good job of recognizing domains and not -242 // splitting them. TODO - put together a better lucene analyzer specific to the domain. -243 if (value.startsWith("http://")) { -244 value = value.substring(7).replaceAll("\\.", " "); -245 } -246 if (value.startsWith("https://")) { -247 value = value.substring(8).replaceAll("\\.", " "); -248 } -249 if (sb.indexOf(" " + value + " ") < 0) { -250 sb.append(value).append(' '); -251 } -252 } -253 return sb.toString().trim(); -254 } -255 -256 /** -257 * <p> -258 * Searches the Lucene CPE index to identify possible CPE entries associated -259 * with the supplied vendor, product, and version.</p> -260 * -261 * <p> -262 * If either the vendorWeightings or productWeightings lists have been -263 * populated this data is used to add weighting factors to the search.</p> -264 * -265 * @param vendor the text used to search the vendor field -266 * @param product the text used to search the product field -267 * @param vendorWeightings a list of strings to use to add weighting factors -268 * to the vendor field -269 * @param productWeightings Adds a list of strings that will be used to add -270 * weighting factors to the product search -271 * @return a list of possible CPE values -272 */ -273 protected List<IndexEntry> searchCPE(String vendor, String product, -274 Set<String> vendorWeightings, Set<String> productWeightings) { -275 -276 final List<IndexEntry> ret = new ArrayList<IndexEntry>(MAX_QUERY_RESULTS); -277 -278 final String searchString = buildSearch(vendor, product, vendorWeightings, productWeightings); -279 if (searchString == null) { -280 return ret; -281 } -282 try { -283 final TopDocs docs = cpe.search(searchString, MAX_QUERY_RESULTS); -284 for (ScoreDoc d : docs.scoreDocs) { -285 if (d.score >= 0.08) { -286 final Document doc = cpe.getDocument(d.doc); -287 final IndexEntry entry = new IndexEntry(); -288 entry.setVendor(doc.get(Fields.VENDOR)); -289 entry.setProduct(doc.get(Fields.PRODUCT)); -290 entry.setSearchScore(d.score); -291 if (!ret.contains(entry)) { -292 ret.add(entry); -293 } -294 } -295 } -296 return ret; -297 } catch (ParseException ex) { -298 LOGGER.warn("An error occurred querying the CPE data. See the log for more details."); -299 LOGGER.info("Unable to parse: {}", searchString, ex); -300 } catch (IOException ex) { -301 LOGGER.warn("An error occurred reading CPE data. See the log for more details."); -302 LOGGER.info("IO Error with search string: {}", searchString, ex); -303 } -304 return null; -305 } -306 -307 /** -308 * <p> -309 * Builds a Lucene search string by properly escaping data and constructing -310 * a valid search query.</p> -311 * -312 * <p> -313 * If either the possibleVendor or possibleProducts lists have been -314 * populated this data is used to add weighting factors to the search string -315 * generated.</p> -316 * -317 * @param vendor text to search the vendor field -318 * @param product text to search the product field -319 * @param vendorWeighting a list of strings to apply to the vendor to boost -320 * the terms weight -321 * @param productWeightings a list of strings to apply to the product to -322 * boost the terms weight -323 * @return the Lucene query -324 */ -325 protected String buildSearch(String vendor, String product, -326 Set<String> vendorWeighting, Set<String> productWeightings) { -327 final String v = vendor; //.replaceAll("[^\\w\\d]", " "); -328 final String p = product; //.replaceAll("[^\\w\\d]", " "); -329 final StringBuilder sb = new StringBuilder(v.length() + p.length() -330 + Fields.PRODUCT.length() + Fields.VENDOR.length() + STRING_BUILDER_BUFFER); -331 -332 if (!appendWeightedSearch(sb, Fields.PRODUCT, p, productWeightings)) { -333 return null; -334 } -335 sb.append(" AND "); -336 if (!appendWeightedSearch(sb, Fields.VENDOR, v, vendorWeighting)) { -337 return null; -338 } -339 return sb.toString(); -340 } +216 boolean identifierAdded = false; +217 for (IndexEntry e : entries) { +218 LOGGER.debug("Verifying entry: {}", e); +219 if (verifyEntry(e, dependency)) { +220 final String vendor = e.getVendor(); +221 final String product = e.getProduct(); +222 LOGGER.debug("identified vendor/product: {}/{}", vendor, product); +223 identifierAdded |= determineIdentifiers(dependency, vendor, product, confidence); +224 } +225 } +226 if (identifierAdded) { +227 break; +228 } +229 } +230 } +231 } +232 +233 /** +234 * Returns the text created by concatenating the text and the values from +235 * the EvidenceCollection (filtered for a specific confidence). This +236 * attempts to prevent duplicate terms from being added.<br/<br/> Note, if +237 * the evidence is longer then 200 characters it will be truncated. +238 * +239 * @param text the base text. +240 * @param ec an EvidenceCollection +241 * @param confidenceFilter a Confidence level to filter the evidence by. +242 * @return the new evidence text +243 */ +244 private String addEvidenceWithoutDuplicateTerms(final String text, final EvidenceCollection ec, Confidence confidenceFilter) { +245 final String txt = (text == null) ? "" : text; +246 final StringBuilder sb = new StringBuilder(txt.length() + (20 * ec.size())); +247 sb.append(' ').append(txt).append(' '); +248 for (Evidence e : ec.iterator(confidenceFilter)) { +249 String value = e.getValue(); +250 +251 //hack to get around the fact that lucene does a really good job of recognizing domains and not +252 // splitting them. TODO - put together a better lucene analyzer specific to the domain. +253 if (value.startsWith("http://")) { +254 value = value.substring(7).replaceAll("\\.", " "); +255 } +256 if (value.startsWith("https://")) { +257 value = value.substring(8).replaceAll("\\.", " "); +258 } +259 if (sb.indexOf(" " + value + " ") < 0) { +260 sb.append(value).append(' '); +261 } +262 } +263 return sb.toString().trim(); +264 } +265 +266 /** +267 * <p> +268 * Searches the Lucene CPE index to identify possible CPE entries associated +269 * with the supplied vendor, product, and version.</p> +270 * +271 * <p> +272 * If either the vendorWeightings or productWeightings lists have been +273 * populated this data is used to add weighting factors to the search.</p> +274 * +275 * @param vendor the text used to search the vendor field +276 * @param product the text used to search the product field +277 * @param vendorWeightings a list of strings to use to add weighting factors +278 * to the vendor field +279 * @param productWeightings Adds a list of strings that will be used to add +280 * weighting factors to the product search +281 * @return a list of possible CPE values +282 */ +283 protected List<IndexEntry> searchCPE(String vendor, String product, +284 Set<String> vendorWeightings, Set<String> productWeightings) { +285 +286 final List<IndexEntry> ret = new ArrayList<IndexEntry>(MAX_QUERY_RESULTS); +287 +288 final String searchString = buildSearch(vendor, product, vendorWeightings, productWeightings); +289 if (searchString == null) { +290 return ret; +291 } +292 try { +293 final TopDocs docs = cpe.search(searchString, MAX_QUERY_RESULTS); +294 for (ScoreDoc d : docs.scoreDocs) { +295 if (d.score >= 0.08) { +296 final Document doc = cpe.getDocument(d.doc); +297 final IndexEntry entry = new IndexEntry(); +298 entry.setVendor(doc.get(Fields.VENDOR)); +299 entry.setProduct(doc.get(Fields.PRODUCT)); +300 entry.setSearchScore(d.score); +301 if (!ret.contains(entry)) { +302 ret.add(entry); +303 } +304 } +305 } +306 return ret; +307 } catch (ParseException ex) { +308 LOGGER.warn("An error occurred querying the CPE data. See the log for more details."); +309 LOGGER.info("Unable to parse: {}", searchString, ex); +310 } catch (IOException ex) { +311 LOGGER.warn("An error occurred reading CPE data. See the log for more details."); +312 LOGGER.info("IO Error with search string: {}", searchString, ex); +313 } +314 return null; +315 } +316 +317 /** +318 * <p> +319 * Builds a Lucene search string by properly escaping data and constructing +320 * a valid search query.</p> +321 * +322 * <p> +323 * If either the possibleVendor or possibleProducts lists have been +324 * populated this data is used to add weighting factors to the search string +325 * generated.</p> +326 * +327 * @param vendor text to search the vendor field +328 * @param product text to search the product field +329 * @param vendorWeighting a list of strings to apply to the vendor to boost +330 * the terms weight +331 * @param productWeightings a list of strings to apply to the product to +332 * boost the terms weight +333 * @return the Lucene query +334 */ +335 protected String buildSearch(String vendor, String product, +336 Set<String> vendorWeighting, Set<String> productWeightings) { +337 final String v = vendor; //.replaceAll("[^\\w\\d]", " "); +338 final String p = product; //.replaceAll("[^\\w\\d]", " "); +339 final StringBuilder sb = new StringBuilder(v.length() + p.length() +340 + Fields.PRODUCT.length() + Fields.VENDOR.length() + STRING_BUILDER_BUFFER); 341 -342 /** -343 * This method constructs a Lucene query for a given field. The searchText -344 * is split into separate words and if the word is within the list of -345 * weighted words then an additional weighting is applied to the term as it -346 * is appended into the query. -347 * -348 * @param sb a StringBuilder that the query text will be appended to. -349 * @param field the field within the Lucene index that the query is -350 * searching. -351 * @param searchText text used to construct the query. -352 * @param weightedText a list of terms that will be considered higher -353 * importance when searching. -354 * @return if the append was successful. -355 */ -356 private boolean appendWeightedSearch(StringBuilder sb, String field, String searchText, Set<String> weightedText) { -357 sb.append(' ').append(field).append(":( "); -358 -359 final String cleanText = cleanseText(searchText); -360 -361 if (cleanText.isEmpty()) { -362 return false; -363 } -364 -365 if (weightedText == null || weightedText.isEmpty()) { -366 LuceneUtils.appendEscapedLuceneQuery(sb, cleanText); -367 } else { -368 final StringTokenizer tokens = new StringTokenizer(cleanText); -369 while (tokens.hasMoreElements()) { -370 final String word = tokens.nextToken(); -371 StringBuilder temp = null; -372 for (String weighted : weightedText) { -373 final String weightedStr = cleanseText(weighted); -374 if (equalsIgnoreCaseAndNonAlpha(word, weightedStr)) { -375 temp = new StringBuilder(word.length() + 2); -376 LuceneUtils.appendEscapedLuceneQuery(temp, word); -377 temp.append(WEIGHTING_BOOST); -378 if (!word.equalsIgnoreCase(weightedStr)) { -379 temp.append(' '); -380 LuceneUtils.appendEscapedLuceneQuery(temp, weightedStr); -381 temp.append(WEIGHTING_BOOST); -382 } -383 break; -384 } -385 } -386 sb.append(' '); -387 if (temp == null) { -388 LuceneUtils.appendEscapedLuceneQuery(sb, word); -389 } else { -390 sb.append(temp); -391 } -392 } -393 } -394 sb.append(" ) "); -395 return true; -396 } -397 -398 /** -399 * Removes characters from the input text that are not used within the CPE -400 * index. -401 * -402 * @param text is the text to remove the characters from. -403 * @return the text having removed some characters. -404 */ -405 private String cleanseText(String text) { -406 return text.replaceAll(CLEANSE_CHARACTER_RX, " "); -407 } -408 -409 /** -410 * Compares two strings after lower casing them and removing the non-alpha -411 * characters. -412 * -413 * @param l string one to compare. -414 * @param r string two to compare. -415 * @return whether or not the two strings are similar. -416 */ -417 private boolean equalsIgnoreCaseAndNonAlpha(String l, String r) { -418 if (l == null || r == null) { -419 return false; -420 } -421 -422 final String left = l.replaceAll(CLEANSE_NONALPHA_RX, ""); -423 final String right = r.replaceAll(CLEANSE_NONALPHA_RX, ""); -424 return left.equalsIgnoreCase(right); -425 } -426 -427 /** -428 * Ensures that the CPE Identified matches the dependency. This validates -429 * that the product, vendor, and version information for the CPE are -430 * contained within the dependencies evidence. -431 * -432 * @param entry a CPE entry. -433 * @param dependency the dependency that the CPE entries could be for. -434 * @return whether or not the entry is valid. -435 */ -436 private boolean verifyEntry(final IndexEntry entry, final Dependency dependency) { -437 boolean isValid = false; -438 -439 //TODO - does this nullify some of the fuzzy matching that happens in the lucene search? -440 // for instance CPE some-component and in the evidence we have SomeComponent. -441 if (collectionContainsString(dependency.getProductEvidence(), entry.getProduct()) -442 && collectionContainsString(dependency.getVendorEvidence(), entry.getVendor())) { -443 //&& collectionContainsVersion(dependency.getVersionEvidence(), entry.getVersion()) -444 isValid = true; -445 } -446 return isValid; -447 } +342 if (!appendWeightedSearch(sb, Fields.PRODUCT, p, productWeightings)) { +343 return null; +344 } +345 sb.append(" AND "); +346 if (!appendWeightedSearch(sb, Fields.VENDOR, v, vendorWeighting)) { +347 return null; +348 } +349 return sb.toString(); +350 } +351 +352 /** +353 * This method constructs a Lucene query for a given field. The searchText +354 * is split into separate words and if the word is within the list of +355 * weighted words then an additional weighting is applied to the term as it +356 * is appended into the query. +357 * +358 * @param sb a StringBuilder that the query text will be appended to. +359 * @param field the field within the Lucene index that the query is +360 * searching. +361 * @param searchText text used to construct the query. +362 * @param weightedText a list of terms that will be considered higher +363 * importance when searching. +364 * @return if the append was successful. +365 */ +366 private boolean appendWeightedSearch(StringBuilder sb, String field, String searchText, Set<String> weightedText) { +367 sb.append(' ').append(field).append(":( "); +368 +369 final String cleanText = cleanseText(searchText); +370 +371 if (cleanText.isEmpty()) { +372 return false; +373 } +374 +375 if (weightedText == null || weightedText.isEmpty()) { +376 LuceneUtils.appendEscapedLuceneQuery(sb, cleanText); +377 } else { +378 final StringTokenizer tokens = new StringTokenizer(cleanText); +379 while (tokens.hasMoreElements()) { +380 final String word = tokens.nextToken(); +381 StringBuilder temp = null; +382 for (String weighted : weightedText) { +383 final String weightedStr = cleanseText(weighted); +384 if (equalsIgnoreCaseAndNonAlpha(word, weightedStr)) { +385 temp = new StringBuilder(word.length() + 2); +386 LuceneUtils.appendEscapedLuceneQuery(temp, word); +387 temp.append(WEIGHTING_BOOST); +388 if (!word.equalsIgnoreCase(weightedStr)) { +389 temp.append(' '); +390 LuceneUtils.appendEscapedLuceneQuery(temp, weightedStr); +391 temp.append(WEIGHTING_BOOST); +392 } +393 break; +394 } +395 } +396 sb.append(' '); +397 if (temp == null) { +398 LuceneUtils.appendEscapedLuceneQuery(sb, word); +399 } else { +400 sb.append(temp); +401 } +402 } +403 } +404 sb.append(" ) "); +405 return true; +406 } +407 +408 /** +409 * Removes characters from the input text that are not used within the CPE +410 * index. +411 * +412 * @param text is the text to remove the characters from. +413 * @return the text having removed some characters. +414 */ +415 private String cleanseText(String text) { +416 return text.replaceAll(CLEANSE_CHARACTER_RX, " "); +417 } +418 +419 /** +420 * Compares two strings after lower casing them and removing the non-alpha +421 * characters. +422 * +423 * @param l string one to compare. +424 * @param r string two to compare. +425 * @return whether or not the two strings are similar. +426 */ +427 private boolean equalsIgnoreCaseAndNonAlpha(String l, String r) { +428 if (l == null || r == null) { +429 return false; +430 } +431 +432 final String left = l.replaceAll(CLEANSE_NONALPHA_RX, ""); +433 final String right = r.replaceAll(CLEANSE_NONALPHA_RX, ""); +434 return left.equalsIgnoreCase(right); +435 } +436 +437 /** +438 * Ensures that the CPE Identified matches the dependency. This validates +439 * that the product, vendor, and version information for the CPE are +440 * contained within the dependencies evidence. +441 * +442 * @param entry a CPE entry. +443 * @param dependency the dependency that the CPE entries could be for. +444 * @return whether or not the entry is valid. +445 */ +446 private boolean verifyEntry(final IndexEntry entry, final Dependency dependency) { +447 boolean isValid = false; 448 -449 /** -450 * Used to determine if the EvidenceCollection contains a specific string. -451 * -452 * @param ec an EvidenceCollection -453 * @param text the text to search for -454 * @return whether or not the EvidenceCollection contains the string -455 */ -456 private boolean collectionContainsString(EvidenceCollection ec, String text) { -457 //TODO - likely need to change the split... not sure if this will work for CPE with special chars -458 if (text == null) { -459 return false; -460 } -461 final String[] words = text.split("[\\s_-]"); -462 final List<String> list = new ArrayList<String>(); -463 String tempWord = null; -464 for (String word : words) { -465 /* -466 single letter words should be concatenated with the next word. -467 so { "m", "core", "sample" } -> { "mcore", "sample" } -468 */ -469 if (tempWord != null) { -470 list.add(tempWord + word); -471 tempWord = null; -472 } else if (word.length() <= 2) { -473 tempWord = word; -474 } else { -475 list.add(word); -476 } -477 } -478 if (tempWord != null) { -479 if (!list.isEmpty()) { -480 final String tmp = list.get(list.size() - 1) + tempWord; -481 list.add(tmp); -482 } else { -483 list.add(tempWord); -484 } -485 } -486 if (list.isEmpty()) { -487 return false; -488 } -489 boolean contains = true; -490 for (String word : list) { -491 contains &= ec.containsUsedString(word); -492 } -493 return contains; -494 } -495 -496 /** -497 * Analyzes a dependency and attempts to determine if there are any CPE -498 * identifiers for this dependency. -499 * -500 * @param dependency The Dependency to analyze. -501 * @param engine The analysis engine -502 * @throws AnalysisException is thrown if there is an issue analyzing the -503 * dependency. -504 */ -505 @Override -506 public synchronized void analyze(Dependency dependency, Engine engine) throws AnalysisException { -507 try { -508 determineCPE(dependency); -509 } catch (CorruptIndexException ex) { -510 throw new AnalysisException("CPE Index is corrupt.", ex); -511 } catch (IOException ex) { -512 throw new AnalysisException("Failure opening the CPE Index.", ex); -513 } catch (ParseException ex) { -514 throw new AnalysisException("Unable to parse the generated Lucene query for this dependency.", ex); -515 } -516 } -517 -518 /** -519 * Retrieves a list of CPE values from the CveDB based on the vendor and -520 * product passed in. The list is then validated to find only CPEs that are -521 * valid for the given dependency. It is possible that the CPE identified is -522 * a best effort "guess" based on the vendor, product, and version -523 * information. -524 * -525 * @param dependency the Dependency being analyzed -526 * @param vendor the vendor for the CPE being analyzed -527 * @param product the product for the CPE being analyzed -528 * @param currentConfidence the current confidence being used during -529 * analysis -530 * @return <code>true</code> if an identifier was added to the dependency; -531 * otherwise <code>false</code> -532 * @throws UnsupportedEncodingException is thrown if UTF-8 is not supported -533 */ -534 protected boolean determineIdentifiers(Dependency dependency, String vendor, String product, -535 Confidence currentConfidence) throws UnsupportedEncodingException { -536 final Set<VulnerableSoftware> cpes = cve.getCPEs(vendor, product); -537 DependencyVersion bestGuess = new DependencyVersion("-"); -538 Confidence bestGuessConf = null; -539 boolean hasBroadMatch = false; -540 final List<IdentifierMatch> collected = new ArrayList<IdentifierMatch>(); -541 -542 //TODO the following algorithm incorrectly identifies things as a lower version -543 // if there lower confidence evidence when the current (highest) version number -544 // is newer then anything in the NVD. -545 for (Confidence conf : Confidence.values()) { -546 for (Evidence evidence : dependency.getVersionEvidence().iterator(conf)) { -547 final DependencyVersion evVer = DependencyVersionUtil.parseVersion(evidence.getValue()); -548 if (evVer == null) { -549 continue; -550 } -551 for (VulnerableSoftware vs : cpes) { -552 DependencyVersion dbVer; -553 if (vs.getUpdate() != null && !vs.getUpdate().isEmpty()) { -554 dbVer = DependencyVersionUtil.parseVersion(vs.getVersion() + '.' + vs.getUpdate()); -555 } else { -556 dbVer = DependencyVersionUtil.parseVersion(vs.getVersion()); -557 } -558 if (dbVer == null) { //special case, no version specified - everything is vulnerable -559 hasBroadMatch = true; -560 final String url = String.format(NVD_SEARCH_URL, URLEncoder.encode(vs.getName(), "UTF-8")); -561 final IdentifierMatch match = new IdentifierMatch("cpe", vs.getName(), url, IdentifierConfidence.BROAD_MATCH, conf); -562 collected.add(match); -563 } else if (evVer.equals(dbVer)) { //yeah! exact match -564 final String url = String.format(NVD_SEARCH_URL, URLEncoder.encode(vs.getName(), "UTF-8")); -565 final IdentifierMatch match = new IdentifierMatch("cpe", vs.getName(), url, IdentifierConfidence.EXACT_MATCH, conf); -566 collected.add(match); -567 } else //TODO the following isn't quite right is it? need to think about this guessing game a bit more. -568 if (evVer.getVersionParts().size() <= dbVer.getVersionParts().size() -569 && evVer.matchesAtLeastThreeLevels(dbVer)) { -570 if (bestGuessConf == null || bestGuessConf.compareTo(conf) > 0) { -571 if (bestGuess.getVersionParts().size() < dbVer.getVersionParts().size()) { -572 bestGuess = dbVer; -573 bestGuessConf = conf; -574 } -575 } -576 } -577 } -578 if (bestGuessConf == null || bestGuessConf.compareTo(conf) > 0) { -579 if (bestGuess.getVersionParts().size() < evVer.getVersionParts().size()) { -580 bestGuess = evVer; -581 bestGuessConf = conf; -582 } -583 } -584 } -585 } -586 final String cpeName = String.format("cpe:/a:%s:%s:%s", vendor, product, bestGuess.toString()); -587 String url = null; -588 if (hasBroadMatch) { //if we have a broad match we can add the URL to the best guess. -589 final String cpeUrlName = String.format("cpe:/a:%s:%s", vendor, product); -590 url = String.format(NVD_SEARCH_URL, URLEncoder.encode(cpeUrlName, "UTF-8")); -591 } -592 if (bestGuessConf == null) { -593 bestGuessConf = Confidence.LOW; -594 } -595 final IdentifierMatch match = new IdentifierMatch("cpe", cpeName, url, IdentifierConfidence.BEST_GUESS, bestGuessConf); -596 collected.add(match); -597 -598 Collections.sort(collected); -599 final IdentifierConfidence bestIdentifierQuality = collected.get(0).getConfidence(); -600 final Confidence bestEvidenceQuality = collected.get(0).getEvidenceConfidence(); -601 boolean identifierAdded = false; -602 for (IdentifierMatch m : collected) { -603 if (bestIdentifierQuality.equals(m.getConfidence()) -604 && bestEvidenceQuality.equals(m.getEvidenceConfidence())) { -605 final Identifier i = m.getIdentifier(); -606 if (bestIdentifierQuality == IdentifierConfidence.BEST_GUESS) { -607 i.setConfidence(Confidence.LOW); -608 } else { -609 i.setConfidence(bestEvidenceQuality); -610 } -611 dependency.addIdentifier(i); -612 identifierAdded = true; -613 } -614 } -615 return identifierAdded; -616 } -617 -618 /** -619 * The confidence whether the identifier is an exact match, or a best guess. -620 */ -621 private enum IdentifierConfidence { -622 -623 /** -624 * An exact match for the CPE. -625 */ -626 EXACT_MATCH, -627 /** -628 * A best guess for the CPE. -629 */ -630 BEST_GUESS, -631 /** -632 * The entire vendor/product group must be added (without a guess at -633 * version) because there is a CVE with a VS that only specifies -634 * vendor/product. -635 */ -636 BROAD_MATCH -637 } -638 -639 /** -640 * A simple object to hold an identifier and carry information about the -641 * confidence in the identifier. -642 */ -643 private static class IdentifierMatch implements Comparable<IdentifierMatch> { -644 -645 /** -646 * Constructs an IdentifierMatch. -647 * -648 * @param type the type of identifier (such as CPE) -649 * @param value the value of the identifier -650 * @param url the URL of the identifier -651 * @param identifierConfidence the confidence in the identifier: best -652 * guess or exact match -653 * @param evidenceConfidence the confidence of the evidence used to find -654 * the identifier -655 */ -656 IdentifierMatch(String type, String value, String url, IdentifierConfidence identifierConfidence, Confidence evidenceConfidence) { -657 this.identifier = new Identifier(type, value, url); -658 this.confidence = identifierConfidence; -659 this.evidenceConfidence = evidenceConfidence; -660 } -661 //<editor-fold defaultstate="collapsed" desc="Property implementations: evidenceConfidence, confidence, identifier"> -662 /** -663 * The confidence in the evidence used to identify this match. -664 */ -665 private Confidence evidenceConfidence; -666 -667 /** -668 * Get the value of evidenceConfidence -669 * -670 * @return the value of evidenceConfidence -671 */ -672 public Confidence getEvidenceConfidence() { -673 return evidenceConfidence; -674 } -675 -676 /** -677 * Set the value of evidenceConfidence -678 * -679 * @param evidenceConfidence new value of evidenceConfidence -680 */ -681 public void setEvidenceConfidence(Confidence evidenceConfidence) { -682 this.evidenceConfidence = evidenceConfidence; -683 } -684 /** -685 * The confidence whether this is an exact match, or a best guess. -686 */ -687 private IdentifierConfidence confidence; -688 -689 /** -690 * Get the value of confidence. -691 * -692 * @return the value of confidence -693 */ -694 public IdentifierConfidence getConfidence() { -695 return confidence; -696 } -697 -698 /** -699 * Set the value of confidence. -700 * -701 * @param confidence new value of confidence -702 */ -703 public void setConfidence(IdentifierConfidence confidence) { -704 this.confidence = confidence; -705 } -706 /** -707 * The CPE identifier. -708 */ -709 private Identifier identifier; -710 -711 /** -712 * Get the value of identifier. -713 * -714 * @return the value of identifier -715 */ -716 public Identifier getIdentifier() { -717 return identifier; -718 } -719 -720 /** -721 * Set the value of identifier. -722 * -723 * @param identifier new value of identifier -724 */ -725 public void setIdentifier(Identifier identifier) { -726 this.identifier = identifier; -727 } -728 //</editor-fold> -729 //<editor-fold defaultstate="collapsed" desc="Standard implementations of toString, hashCode, and equals"> +449 //TODO - does this nullify some of the fuzzy matching that happens in the lucene search? +450 // for instance CPE some-component and in the evidence we have SomeComponent. +451 if (collectionContainsString(dependency.getProductEvidence(), entry.getProduct()) +452 && collectionContainsString(dependency.getVendorEvidence(), entry.getVendor())) { +453 //&& collectionContainsVersion(dependency.getVersionEvidence(), entry.getVersion()) +454 isValid = true; +455 } +456 return isValid; +457 } +458 +459 /** +460 * Used to determine if the EvidenceCollection contains a specific string. +461 * +462 * @param ec an EvidenceCollection +463 * @param text the text to search for +464 * @return whether or not the EvidenceCollection contains the string +465 */ +466 private boolean collectionContainsString(EvidenceCollection ec, String text) { +467 //TODO - likely need to change the split... not sure if this will work for CPE with special chars +468 if (text == null) { +469 return false; +470 } +471 final String[] words = text.split("[\\s_-]"); +472 final List<String> list = new ArrayList<String>(); +473 String tempWord = null; +474 for (String word : words) { +475 /* +476 single letter words should be concatenated with the next word. +477 so { "m", "core", "sample" } -> { "mcore", "sample" } +478 */ +479 if (tempWord != null) { +480 list.add(tempWord + word); +481 tempWord = null; +482 } else if (word.length() <= 2) { +483 tempWord = word; +484 } else { +485 list.add(word); +486 } +487 } +488 if (tempWord != null) { +489 if (!list.isEmpty()) { +490 final String tmp = list.get(list.size() - 1) + tempWord; +491 list.add(tmp); +492 } else { +493 list.add(tempWord); +494 } +495 } +496 if (list.isEmpty()) { +497 return false; +498 } +499 boolean contains = true; +500 for (String word : list) { +501 contains &= ec.containsUsedString(word); +502 } +503 return contains; +504 } +505 +506 /** +507 * Analyzes a dependency and attempts to determine if there are any CPE +508 * identifiers for this dependency. +509 * +510 * @param dependency The Dependency to analyze. +511 * @param engine The analysis engine +512 * @throws AnalysisException is thrown if there is an issue analyzing the +513 * dependency. +514 */ +515 @Override +516 public synchronized void analyze(Dependency dependency, Engine engine) throws AnalysisException { +517 try { +518 determineCPE(dependency); +519 } catch (CorruptIndexException ex) { +520 throw new AnalysisException("CPE Index is corrupt.", ex); +521 } catch (IOException ex) { +522 throw new AnalysisException("Failure opening the CPE Index.", ex); +523 } catch (ParseException ex) { +524 throw new AnalysisException("Unable to parse the generated Lucene query for this dependency.", ex); +525 } +526 } +527 +528 /** +529 * Retrieves a list of CPE values from the CveDB based on the vendor and +530 * product passed in. The list is then validated to find only CPEs that are +531 * valid for the given dependency. It is possible that the CPE identified is +532 * a best effort "guess" based on the vendor, product, and version +533 * information. +534 * +535 * @param dependency the Dependency being analyzed +536 * @param vendor the vendor for the CPE being analyzed +537 * @param product the product for the CPE being analyzed +538 * @param currentConfidence the current confidence being used during +539 * analysis +540 * @return <code>true</code> if an identifier was added to the dependency; +541 * otherwise <code>false</code> +542 * @throws UnsupportedEncodingException is thrown if UTF-8 is not supported +543 */ +544 protected boolean determineIdentifiers(Dependency dependency, String vendor, String product, +545 Confidence currentConfidence) throws UnsupportedEncodingException { +546 final Set<VulnerableSoftware> cpes = cve.getCPEs(vendor, product); +547 DependencyVersion bestGuess = new DependencyVersion("-"); +548 Confidence bestGuessConf = null; +549 boolean hasBroadMatch = false; +550 final List<IdentifierMatch> collected = new ArrayList<IdentifierMatch>(); +551 +552 //TODO the following algorithm incorrectly identifies things as a lower version +553 // if there lower confidence evidence when the current (highest) version number +554 // is newer then anything in the NVD. +555 for (Confidence conf : Confidence.values()) { +556 for (Evidence evidence : dependency.getVersionEvidence().iterator(conf)) { +557 final DependencyVersion evVer = DependencyVersionUtil.parseVersion(evidence.getValue()); +558 if (evVer == null) { +559 continue; +560 } +561 for (VulnerableSoftware vs : cpes) { +562 DependencyVersion dbVer; +563 if (vs.getUpdate() != null && !vs.getUpdate().isEmpty()) { +564 dbVer = DependencyVersionUtil.parseVersion(vs.getVersion() + '.' + vs.getUpdate()); +565 } else { +566 dbVer = DependencyVersionUtil.parseVersion(vs.getVersion()); +567 } +568 if (dbVer == null) { //special case, no version specified - everything is vulnerable +569 hasBroadMatch = true; +570 final String url = String.format(NVD_SEARCH_URL, URLEncoder.encode(vs.getName(), "UTF-8")); +571 final IdentifierMatch match = new IdentifierMatch("cpe", vs.getName(), url, IdentifierConfidence.BROAD_MATCH, conf); +572 collected.add(match); +573 } else if (evVer.equals(dbVer)) { //yeah! exact match +574 final String url = String.format(NVD_SEARCH_URL, URLEncoder.encode(vs.getName(), "UTF-8")); +575 final IdentifierMatch match = new IdentifierMatch("cpe", vs.getName(), url, IdentifierConfidence.EXACT_MATCH, conf); +576 collected.add(match); +577 +578 //TODO the following isn't quite right is it? need to think about this guessing game a bit more. +579 } else if (evVer.getVersionParts().size() <= dbVer.getVersionParts().size() +580 && evVer.matchesAtLeastThreeLevels(dbVer)) { +581 if (bestGuessConf == null || bestGuessConf.compareTo(conf) > 0) { +582 if (bestGuess.getVersionParts().size() < dbVer.getVersionParts().size()) { +583 bestGuess = dbVer; +584 bestGuessConf = conf; +585 } +586 } +587 } +588 } +589 if (bestGuessConf == null || bestGuessConf.compareTo(conf) > 0) { +590 if (bestGuess.getVersionParts().size() < evVer.getVersionParts().size()) { +591 bestGuess = evVer; +592 bestGuessConf = conf; +593 } +594 } +595 } +596 } +597 final String cpeName = String.format("cpe:/a:%s:%s:%s", vendor, product, bestGuess.toString()); +598 String url = null; +599 if (hasBroadMatch) { //if we have a broad match we can add the URL to the best guess. +600 final String cpeUrlName = String.format("cpe:/a:%s:%s", vendor, product); +601 url = String.format(NVD_SEARCH_URL, URLEncoder.encode(cpeUrlName, "UTF-8")); +602 } +603 if (bestGuessConf == null) { +604 bestGuessConf = Confidence.LOW; +605 } +606 final IdentifierMatch match = new IdentifierMatch("cpe", cpeName, url, IdentifierConfidence.BEST_GUESS, bestGuessConf); +607 collected.add(match); +608 +609 Collections.sort(collected); +610 final IdentifierConfidence bestIdentifierQuality = collected.get(0).getConfidence(); +611 final Confidence bestEvidenceQuality = collected.get(0).getEvidenceConfidence(); +612 boolean identifierAdded = false; +613 for (IdentifierMatch m : collected) { +614 if (bestIdentifierQuality.equals(m.getConfidence()) +615 && bestEvidenceQuality.equals(m.getEvidenceConfidence())) { +616 final Identifier i = m.getIdentifier(); +617 if (bestIdentifierQuality == IdentifierConfidence.BEST_GUESS) { +618 i.setConfidence(Confidence.LOW); +619 } else { +620 i.setConfidence(bestEvidenceQuality); +621 } +622 dependency.addIdentifier(i); +623 identifierAdded = true; +624 } +625 } +626 return identifierAdded; +627 } +628 +629 /** +630 * The confidence whether the identifier is an exact match, or a best guess. +631 */ +632 private enum IdentifierConfidence { +633 +634 /** +635 * An exact match for the CPE. +636 */ +637 EXACT_MATCH, +638 /** +639 * A best guess for the CPE. +640 */ +641 BEST_GUESS, +642 /** +643 * The entire vendor/product group must be added (without a guess at +644 * version) because there is a CVE with a VS that only specifies +645 * vendor/product. +646 */ +647 BROAD_MATCH +648 } +649 +650 /** +651 * A simple object to hold an identifier and carry information about the +652 * confidence in the identifier. +653 */ +654 private static class IdentifierMatch implements Comparable<IdentifierMatch> { +655 +656 /** +657 * Constructs an IdentifierMatch. +658 * +659 * @param type the type of identifier (such as CPE) +660 * @param value the value of the identifier +661 * @param url the URL of the identifier +662 * @param identifierConfidence the confidence in the identifier: best +663 * guess or exact match +664 * @param evidenceConfidence the confidence of the evidence used to find +665 * the identifier +666 */ +667 IdentifierMatch(String type, String value, String url, IdentifierConfidence identifierConfidence, Confidence evidenceConfidence) { +668 this.identifier = new Identifier(type, value, url); +669 this.confidence = identifierConfidence; +670 this.evidenceConfidence = evidenceConfidence; +671 } +672 //<editor-fold defaultstate="collapsed" desc="Property implementations: evidenceConfidence, confidence, identifier"> +673 /** +674 * The confidence in the evidence used to identify this match. +675 */ +676 private Confidence evidenceConfidence; +677 +678 /** +679 * Get the value of evidenceConfidence +680 * +681 * @return the value of evidenceConfidence +682 */ +683 public Confidence getEvidenceConfidence() { +684 return evidenceConfidence; +685 } +686 +687 /** +688 * Set the value of evidenceConfidence +689 * +690 * @param evidenceConfidence new value of evidenceConfidence +691 */ +692 public void setEvidenceConfidence(Confidence evidenceConfidence) { +693 this.evidenceConfidence = evidenceConfidence; +694 } +695 /** +696 * The confidence whether this is an exact match, or a best guess. +697 */ +698 private IdentifierConfidence confidence; +699 +700 /** +701 * Get the value of confidence. +702 * +703 * @return the value of confidence +704 */ +705 public IdentifierConfidence getConfidence() { +706 return confidence; +707 } +708 +709 /** +710 * Set the value of confidence. +711 * +712 * @param confidence new value of confidence +713 */ +714 public void setConfidence(IdentifierConfidence confidence) { +715 this.confidence = confidence; +716 } +717 /** +718 * The CPE identifier. +719 */ +720 private Identifier identifier; +721 +722 /** +723 * Get the value of identifier. +724 * +725 * @return the value of identifier +726 */ +727 public Identifier getIdentifier() { +728 return identifier; +729 } 730 731 /** -732 * Standard toString() implementation. +732 * Set the value of identifier. 733 * -734 * @return the string representation of the object +734 * @param identifier new value of identifier 735 */ -736 @Override -737 public String toString() { -738 return "IdentifierMatch{" + "evidenceConfidence=" + evidenceConfidence -739 + ", confidence=" + confidence + ", identifier=" + identifier + '}'; -740 } +736 public void setIdentifier(Identifier identifier) { +737 this.identifier = identifier; +738 } +739 //</editor-fold> +740 //<editor-fold defaultstate="collapsed" desc="Standard implementations of toString, hashCode, and equals"> 741 742 /** -743 * Standard hashCode() implementation. +743 * Standard toString() implementation. 744 * -745 * @return the hashCode +745 * @return the string representation of the object 746 */ 747 @Override -748 public int hashCode() { -749 int hash = 5; -750 hash = 97 * hash + (this.evidenceConfidence != null ? this.evidenceConfidence.hashCode() : 0); -751 hash = 97 * hash + (this.confidence != null ? this.confidence.hashCode() : 0); -752 hash = 97 * hash + (this.identifier != null ? this.identifier.hashCode() : 0); -753 return hash; -754 } -755 -756 /** -757 * Standard equals implementation. -758 * -759 * @param obj the object to compare -760 * @return true if the objects are equal, otherwise false -761 */ -762 @Override -763 public boolean equals(Object obj) { -764 if (obj == null) { -765 return false; -766 } -767 if (getClass() != obj.getClass()) { -768 return false; -769 } -770 final IdentifierMatch other = (IdentifierMatch) obj; -771 if (this.evidenceConfidence != other.evidenceConfidence) { -772 return false; -773 } -774 if (this.confidence != other.confidence) { -775 return false; -776 } -777 if (this.identifier != other.identifier && (this.identifier == null || !this.identifier.equals(other.identifier))) { -778 return false; -779 } -780 return true; -781 } -782 //</editor-fold> -783 -784 /** -785 * Standard implementation of compareTo that compares identifier -786 * confidence, evidence confidence, and then the identifier. -787 * -788 * @param o the IdentifierMatch to compare to -789 * @return the natural ordering of IdentifierMatch -790 */ -791 @Override -792 public int compareTo(IdentifierMatch o) { -793 int conf = this.confidence.compareTo(o.confidence); -794 if (conf == 0) { -795 conf = this.evidenceConfidence.compareTo(o.evidenceConfidence); -796 if (conf == 0) { -797 conf = identifier.compareTo(o.identifier); -798 } -799 } -800 return conf; -801 } -802 } -803 } +748 public String toString() { +749 return "IdentifierMatch{" + "evidenceConfidence=" + evidenceConfidence +750 + ", confidence=" + confidence + ", identifier=" + identifier + '}'; +751 } +752 +753 /** +754 * Standard hashCode() implementation. +755 * +756 * @return the hashCode +757 */ +758 @Override +759 public int hashCode() { +760 int hash = 5; +761 hash = 97 * hash + (this.evidenceConfidence != null ? this.evidenceConfidence.hashCode() : 0); +762 hash = 97 * hash + (this.confidence != null ? this.confidence.hashCode() : 0); +763 hash = 97 * hash + (this.identifier != null ? this.identifier.hashCode() : 0); +764 return hash; +765 } +766 +767 /** +768 * Standard equals implementation. +769 * +770 * @param obj the object to compare +771 * @return true if the objects are equal, otherwise false +772 */ +773 @Override +774 public boolean equals(Object obj) { +775 if (obj == null) { +776 return false; +777 } +778 if (getClass() != obj.getClass()) { +779 return false; +780 } +781 final IdentifierMatch other = (IdentifierMatch) obj; +782 if (this.evidenceConfidence != other.evidenceConfidence) { +783 return false; +784 } +785 if (this.confidence != other.confidence) { +786 return false; +787 } +788 if (this.identifier != other.identifier && (this.identifier == null || !this.identifier.equals(other.identifier))) { +789 return false; +790 } +791 return true; +792 } +793 //</editor-fold> +794 +795 /** +796 * Standard implementation of compareTo that compares identifier +797 * confidence, evidence confidence, and then the identifier. +798 * +799 * @param o the IdentifierMatch to compare to +800 * @return the natural ordering of IdentifierMatch +801 */ +802 @Override +803 public int compareTo(IdentifierMatch o) { +804 int conf = this.confidence.compareTo(o.confidence); +805 if (conf == 0) { +806 conf = this.evidenceConfidence.compareTo(o.evidenceConfidence); +807 if (conf == 0) { +808 conf = identifier.compareTo(o.identifier); +809 } +810 } +811 return conf; +812 } +813 } +814 }
      diff --git a/xref/org/owasp/dependencycheck/analyzer/CentralAnalyzer.html b/xref/org/owasp/dependencycheck/analyzer/CentralAnalyzer.html index 39a71f5b4..3fc3de35e 100644 --- a/xref/org/owasp/dependencycheck/analyzer/CentralAnalyzer.html +++ b/xref/org/owasp/dependencycheck/analyzer/CentralAnalyzer.html @@ -41,209 +41,219 @@ 33 import java.io.FileFilter; 34 import java.io.FileNotFoundException; 35 import java.io.IOException; -36 import java.net.URL; -37 import java.util.List; -38 import org.owasp.dependencycheck.utils.DownloadFailedException; -39 import org.owasp.dependencycheck.utils.Downloader; -40 import org.owasp.dependencycheck.utils.FileFilterBuilder; -41 import org.owasp.dependencycheck.utils.InvalidSettingException; -42 import org.owasp.dependencycheck.utils.Settings; -43 -44 /** -45 * Analyzer which will attempt to locate a dependency, and the GAV information, by querying Central for the dependency's SHA-1 -46 * digest. -47 * -48 * @author colezlaw -49 */ -50 public class CentralAnalyzer extends AbstractFileTypeAnalyzer { -51 -52 /** -53 * The logger. -54 */ -55 private static final Logger LOGGER = LoggerFactory.getLogger(CentralAnalyzer.class); -56 -57 /** -58 * The name of the analyzer. -59 */ -60 private static final String ANALYZER_NAME = "Central Analyzer"; -61 -62 /** -63 * The phase in which this analyzer runs. -64 */ -65 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; -66 -67 /** -68 * The types of files on which this will work. -69 */ -70 private static final String SUPPORTED_EXTENSIONS = "jar"; -71 -72 /** -73 * The analyzer should be disabled if there are errors, so this is a flag to determine if such an error has occurred. -74 */ -75 private boolean errorFlag = false; -76 -77 /** -78 * The searcher itself. -79 */ -80 private CentralSearch searcher; -81 /** -82 * Field indicating if the analyzer is enabled. -83 */ -84 private final boolean enabled = checkEnabled(); -85 -86 /** -87 * Determine whether to enable this analyzer or not. -88 * -89 * @return whether the analyzer should be enabled -90 */ -91 @Override -92 public boolean isEnabled() { -93 return enabled; -94 } -95 -96 /** -97 * Determines if this analyzer is enabled. -98 * -99 * @return <code>true</code> if the analyzer is enabled; otherwise <code>false</code> -100 */ -101 private boolean checkEnabled() { -102 boolean retval = false; -103 -104 try { -105 if (Settings.getBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED)) { -106 if (!Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED) -107 || NexusAnalyzer.DEFAULT_URL.equals(Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL))) { -108 LOGGER.debug("Enabling the Central analyzer"); -109 retval = true; -110 } else { -111 LOGGER.info("Nexus analyzer is enabled, disabling the Central Analyzer"); -112 } -113 } else { -114 LOGGER.info("Central analyzer disabled"); -115 } -116 } catch (InvalidSettingException ise) { -117 LOGGER.warn("Invalid setting. Disabling the Central analyzer"); -118 } -119 return retval; -120 } -121 -122 /** -123 * Initializes the analyzer once before any analysis is performed. -124 * -125 * @throws Exception if there's an error during initialization -126 */ -127 @Override -128 public void initializeFileTypeAnalyzer() throws Exception { -129 LOGGER.debug("Initializing Central analyzer"); -130 LOGGER.debug("Central analyzer enabled: {}", isEnabled()); -131 if (isEnabled()) { -132 final String searchUrl = Settings.getString(Settings.KEYS.ANALYZER_CENTRAL_URL); -133 LOGGER.debug("Central Analyzer URL: {}", searchUrl); -134 searcher = new CentralSearch(new URL(searchUrl)); -135 } -136 } -137 -138 /** -139 * Returns the analyzer's name. -140 * -141 * @return the name of the analyzer -142 */ -143 @Override -144 public String getName() { -145 return ANALYZER_NAME; -146 } -147 -148 /** -149 * Returns the key used in the properties file to to reference the analyzer's enabled property. -150 * -151 * @return the analyzer's enabled property setting key. -152 */ -153 @Override -154 protected String getAnalyzerEnabledSettingKey() { -155 return Settings.KEYS.ANALYZER_CENTRAL_ENABLED; -156 } -157 -158 /** -159 * Returns the analysis phase under which the analyzer runs. +36 import java.net.MalformedURLException; +37 import java.net.URL; +38 import java.util.List; +39 import org.owasp.dependencycheck.exception.InitializationException; +40 import org.owasp.dependencycheck.utils.DownloadFailedException; +41 import org.owasp.dependencycheck.utils.Downloader; +42 import org.owasp.dependencycheck.utils.FileFilterBuilder; +43 import org.owasp.dependencycheck.utils.InvalidSettingException; +44 import org.owasp.dependencycheck.utils.Settings; +45 +46 /** +47 * Analyzer which will attempt to locate a dependency, and the GAV information, +48 * by querying Central for the dependency's SHA-1 digest. +49 * +50 * @author colezlaw +51 */ +52 public class CentralAnalyzer extends AbstractFileTypeAnalyzer { +53 +54 /** +55 * The logger. +56 */ +57 private static final Logger LOGGER = LoggerFactory.getLogger(CentralAnalyzer.class); +58 +59 /** +60 * The name of the analyzer. +61 */ +62 private static final String ANALYZER_NAME = "Central Analyzer"; +63 +64 /** +65 * The phase in which this analyzer runs. +66 */ +67 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; +68 +69 /** +70 * The types of files on which this will work. +71 */ +72 private static final String SUPPORTED_EXTENSIONS = "jar"; +73 +74 /** +75 * The analyzer should be disabled if there are errors, so this is a flag to +76 * determine if such an error has occurred. +77 */ +78 private boolean errorFlag = false; +79 +80 /** +81 * The searcher itself. +82 */ +83 private CentralSearch searcher; +84 /** +85 * Field indicating if the analyzer is enabled. +86 */ +87 private final boolean enabled = checkEnabled(); +88 +89 /** +90 * Determine whether to enable this analyzer or not. +91 * +92 * @return whether the analyzer should be enabled +93 */ +94 @Override +95 public boolean isEnabled() { +96 return enabled; +97 } +98 +99 /** +100 * Determines if this analyzer is enabled. +101 * +102 * @return <code>true</code> if the analyzer is enabled; otherwise +103 * <code>false</code> +104 */ +105 private boolean checkEnabled() { +106 boolean retval = false; +107 +108 try { +109 if (Settings.getBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED)) { +110 if (!Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED) +111 || NexusAnalyzer.DEFAULT_URL.equals(Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL))) { +112 LOGGER.debug("Enabling the Central analyzer"); +113 retval = true; +114 } else { +115 LOGGER.info("Nexus analyzer is enabled, disabling the Central Analyzer"); +116 } +117 } else { +118 LOGGER.info("Central analyzer disabled"); +119 } +120 } catch (InvalidSettingException ise) { +121 LOGGER.warn("Invalid setting. Disabling the Central analyzer"); +122 } +123 return retval; +124 } +125 +126 /** +127 * Initializes the analyzer once before any analysis is performed. +128 * +129 * @throws InitializationException if there's an error during initialization +130 */ +131 @Override +132 public void initializeFileTypeAnalyzer() throws InitializationException { +133 LOGGER.debug("Initializing Central analyzer"); +134 LOGGER.debug("Central analyzer enabled: {}", isEnabled()); +135 if (isEnabled()) { +136 final String searchUrl = Settings.getString(Settings.KEYS.ANALYZER_CENTRAL_URL); +137 LOGGER.debug("Central Analyzer URL: {}", searchUrl); +138 try { +139 searcher = new CentralSearch(new URL(searchUrl)); +140 } catch (MalformedURLException ex) { +141 setEnabled(false); +142 throw new InitializationException("The configured URL to Maven Central is malformed: " + searchUrl, ex); +143 } +144 } +145 } +146 +147 /** +148 * Returns the analyzer's name. +149 * +150 * @return the name of the analyzer +151 */ +152 @Override +153 public String getName() { +154 return ANALYZER_NAME; +155 } +156 +157 /** +158 * Returns the key used in the properties file to to reference the +159 * analyzer's enabled property. 160 * -161 * @return the phase under which the analyzer runs +161 * @return the analyzer's enabled property setting key. 162 */ 163 @Override -164 public AnalysisPhase getAnalysisPhase() { -165 return ANALYSIS_PHASE; +164 protected String getAnalyzerEnabledSettingKey() { +165 return Settings.KEYS.ANALYZER_CENTRAL_ENABLED; 166 } 167 168 /** -169 * The file filter used to determine which files this analyzer supports. -170 */ -171 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(SUPPORTED_EXTENSIONS).build(); -172 +169 * Returns the analysis phase under which the analyzer runs. +170 * +171 * @return the phase under which the analyzer runs +172 */ 173 @Override -174 protected FileFilter getFileFilter() { -175 return FILTER; +174 public AnalysisPhase getAnalysisPhase() { +175 return ANALYSIS_PHASE; 176 } 177 178 /** -179 * Performs the analysis. -180 * -181 * @param dependency the dependency to analyze -182 * @param engine the engine -183 * @throws AnalysisException when there's an exception during analysis -184 */ -185 @Override -186 public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { -187 if (errorFlag || !isEnabled()) { -188 return; -189 } -190 -191 try { -192 final List<MavenArtifact> mas = searcher.searchSha1(dependency.getSha1sum()); -193 final Confidence confidence = mas.size() > 1 ? Confidence.HIGH : Confidence.HIGHEST; -194 for (MavenArtifact ma : mas) { -195 LOGGER.debug("Central analyzer found artifact ({}) for dependency ({})", ma, dependency.getFileName()); -196 dependency.addAsEvidence("central", ma, confidence); -197 boolean pomAnalyzed = false; -198 for (Evidence e : dependency.getVendorEvidence()) { -199 if ("pom".equals(e.getSource())) { -200 pomAnalyzed = true; -201 break; -202 } -203 } -204 if (!pomAnalyzed && ma.getPomUrl() != null) { -205 File pomFile = null; -206 try { -207 final File baseDir = Settings.getTempDirectory(); -208 pomFile = File.createTempFile("pom", ".xml", baseDir); -209 if (!pomFile.delete()) { -210 LOGGER.warn("Unable to fetch pom.xml for {} from Central; " -211 + "this could result in undetected CPE/CVEs.", dependency.getFileName()); -212 LOGGER.debug("Unable to delete temp file"); -213 } -214 LOGGER.debug("Downloading {}", ma.getPomUrl()); -215 Downloader.fetchFile(new URL(ma.getPomUrl()), pomFile); -216 PomUtils.analyzePOM(dependency, pomFile); -217 -218 } catch (DownloadFailedException ex) { -219 LOGGER.warn("Unable to download pom.xml for {} from Central; " -220 + "this could result in undetected CPE/CVEs.", dependency.getFileName()); -221 } finally { -222 if (pomFile != null && !FileUtils.deleteQuietly(pomFile)) { -223 pomFile.deleteOnExit(); -224 } -225 } -226 } +179 * The file filter used to determine which files this analyzer supports. +180 */ +181 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(SUPPORTED_EXTENSIONS).build(); +182 +183 @Override +184 protected FileFilter getFileFilter() { +185 return FILTER; +186 } +187 +188 /** +189 * Performs the analysis. +190 * +191 * @param dependency the dependency to analyze +192 * @param engine the engine +193 * @throws AnalysisException when there's an exception during analysis +194 */ +195 @Override +196 public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { +197 if (errorFlag || !isEnabled()) { +198 return; +199 } +200 +201 try { +202 final List<MavenArtifact> mas = searcher.searchSha1(dependency.getSha1sum()); +203 final Confidence confidence = mas.size() > 1 ? Confidence.HIGH : Confidence.HIGHEST; +204 for (MavenArtifact ma : mas) { +205 LOGGER.debug("Central analyzer found artifact ({}) for dependency ({})", ma, dependency.getFileName()); +206 dependency.addAsEvidence("central", ma, confidence); +207 boolean pomAnalyzed = false; +208 for (Evidence e : dependency.getVendorEvidence()) { +209 if ("pom".equals(e.getSource())) { +210 pomAnalyzed = true; +211 break; +212 } +213 } +214 if (!pomAnalyzed && ma.getPomUrl() != null) { +215 File pomFile = null; +216 try { +217 final File baseDir = Settings.getTempDirectory(); +218 pomFile = File.createTempFile("pom", ".xml", baseDir); +219 if (!pomFile.delete()) { +220 LOGGER.warn("Unable to fetch pom.xml for {} from Central; " +221 + "this could result in undetected CPE/CVEs.", dependency.getFileName()); +222 LOGGER.debug("Unable to delete temp file"); +223 } +224 LOGGER.debug("Downloading {}", ma.getPomUrl()); +225 Downloader.fetchFile(new URL(ma.getPomUrl()), pomFile); +226 PomUtils.analyzePOM(dependency, pomFile); 227 -228 } -229 } catch (IllegalArgumentException iae) { -230 LOGGER.info("invalid sha1-hash on {}", dependency.getFileName()); -231 } catch (FileNotFoundException fnfe) { -232 LOGGER.debug("Artifact not found in repository: '{}", dependency.getFileName()); -233 } catch (IOException ioe) { -234 LOGGER.debug("Could not connect to Central search", ioe); -235 errorFlag = true; -236 } -237 } -238 } +228 } catch (DownloadFailedException ex) { +229 LOGGER.warn("Unable to download pom.xml for {} from Central; " +230 + "this could result in undetected CPE/CVEs.", dependency.getFileName()); +231 } finally { +232 if (pomFile != null && !FileUtils.deleteQuietly(pomFile)) { +233 pomFile.deleteOnExit(); +234 } +235 } +236 } +237 +238 } +239 } catch (IllegalArgumentException iae) { +240 LOGGER.info("invalid sha1-hash on {}", dependency.getFileName()); +241 } catch (FileNotFoundException fnfe) { +242 LOGGER.debug("Artifact not found in repository: '{}", dependency.getFileName()); +243 } catch (IOException ioe) { +244 LOGGER.debug("Could not connect to Central search", ioe); +245 errorFlag = true; +246 } +247 } +248 }
      diff --git a/xref/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzer.html b/xref/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzer.html index 81b4a7155..4fd93c80a 100644 --- a/xref/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzer.html +++ b/xref/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzer.html @@ -43,132 +43,141 @@ 35 import java.io.FileNotFoundException; 36 import java.nio.charset.Charset; 37 import java.security.MessageDigest; -38 -39 /** -40 * Used to analyze a composer.lock file for a composer PHP app. -41 * -42 * @author colezlaw -43 */ -44 @Experimental -45 public class ComposerLockAnalyzer extends AbstractFileTypeAnalyzer { -46 -47 /** -48 * The logger. -49 */ -50 private static final Logger LOGGER = LoggerFactory.getLogger(ComposerLockAnalyzer.class); -51 -52 /** -53 * The analyzer name. -54 */ -55 private static final String ANALYZER_NAME = "Composer.lock analyzer"; -56 -57 /** -58 * composer.json. -59 */ -60 private static final String COMPOSER_LOCK = "composer.lock"; -61 -62 /** -63 * The FileFilter. -64 */ -65 private static final FileFilter FILE_FILTER = FileFilterBuilder.newInstance().addFilenames(COMPOSER_LOCK).build(); -66 -67 /** -68 * Returns the FileFilter. -69 * -70 * @return the FileFilter -71 */ -72 @Override -73 protected FileFilter getFileFilter() { -74 return FILE_FILTER; -75 } -76 -77 /** -78 * Initializes the analyzer. -79 * -80 * @throws Exception thrown if an exception occurs getting an instance of SHA1 -81 */ -82 @Override -83 protected void initializeFileTypeAnalyzer() throws Exception { -84 sha1 = MessageDigest.getInstance("SHA1"); -85 } -86 -87 /** -88 * The MessageDigest for calculating a new digest for the new dependencies added. -89 */ -90 private MessageDigest sha1 = null; -91 -92 /** -93 * Entry point for the analyzer. -94 * -95 * @param dependency the dependency to analyze -96 * @param engine the engine scanning -97 * @throws AnalysisException if there's a failure during analysis +38 import java.security.NoSuchAlgorithmException; +39 import org.owasp.dependencycheck.exception.InitializationException; +40 +41 /** +42 * Used to analyze a composer.lock file for a composer PHP app. +43 * +44 * @author colezlaw +45 */ +46 @Experimental +47 public class ComposerLockAnalyzer extends AbstractFileTypeAnalyzer { +48 +49 /** +50 * The logger. +51 */ +52 private static final Logger LOGGER = LoggerFactory.getLogger(ComposerLockAnalyzer.class); +53 +54 /** +55 * The analyzer name. +56 */ +57 private static final String ANALYZER_NAME = "Composer.lock analyzer"; +58 +59 /** +60 * composer.json. +61 */ +62 private static final String COMPOSER_LOCK = "composer.lock"; +63 +64 /** +65 * The FileFilter. +66 */ +67 private static final FileFilter FILE_FILTER = FileFilterBuilder.newInstance().addFilenames(COMPOSER_LOCK).build(); +68 +69 /** +70 * Returns the FileFilter. +71 * +72 * @return the FileFilter +73 */ +74 @Override +75 protected FileFilter getFileFilter() { +76 return FILE_FILTER; +77 } +78 +79 /** +80 * Initializes the analyzer. +81 * +82 * @throws InitializationException thrown if an exception occurs getting an +83 * instance of SHA1 +84 */ +85 @Override +86 protected void initializeFileTypeAnalyzer() throws InitializationException { +87 try { +88 sha1 = MessageDigest.getInstance("SHA1"); +89 } catch (NoSuchAlgorithmException ex) { +90 setEnabled(false); +91 throw new InitializationException("Unable to create SHA1 MmessageDigest", ex); +92 } +93 } +94 +95 /** +96 * The MessageDigest for calculating a new digest for the new dependencies +97 * added. 98 */ -99 @Override -100 protected void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { -101 FileInputStream fis = null; -102 try { -103 fis = new FileInputStream(dependency.getActualFile()); -104 final ComposerLockParser clp = new ComposerLockParser(fis); -105 LOGGER.info("Checking composer.lock file {}", dependency.getActualFilePath()); -106 clp.process(); -107 for (ComposerDependency dep : clp.getDependencies()) { -108 final Dependency d = new Dependency(dependency.getActualFile()); -109 d.setDisplayFileName(String.format("%s:%s/%s", dependency.getDisplayFileName(), dep.getGroup(), dep.getProject())); -110 final String filePath = String.format("%s:%s/%s", dependency.getFilePath(), dep.getGroup(), dep.getProject()); -111 d.setFilePath(filePath); -112 d.setSha1sum(Checksum.getHex(sha1.digest(filePath.getBytes(Charset.defaultCharset())))); -113 d.getVendorEvidence().addEvidence(COMPOSER_LOCK, "vendor", dep.getGroup(), Confidence.HIGHEST); -114 d.getProductEvidence().addEvidence(COMPOSER_LOCK, "product", dep.getProject(), Confidence.HIGHEST); -115 d.getVersionEvidence().addEvidence(COMPOSER_LOCK, "version", dep.getVersion(), Confidence.HIGHEST); -116 LOGGER.info("Adding dependency {}", d); -117 engine.getDependencies().add(d); -118 } -119 } catch (FileNotFoundException fnfe) { -120 LOGGER.warn("Error opening dependency {}", dependency.getActualFilePath()); -121 } catch (ComposerException ce) { -122 LOGGER.warn("Error parsing composer.json {}", dependency.getActualFilePath(), ce); -123 } finally { -124 if (fis != null) { -125 try { -126 fis.close(); -127 } catch (Exception e) { -128 LOGGER.debug("Unable to close file", e); -129 } -130 } -131 } -132 } -133 -134 /** -135 * Gets the key to determine whether the analyzer is enabled. -136 * -137 * @return the key specifying whether the analyzer is enabled -138 */ -139 @Override -140 protected String getAnalyzerEnabledSettingKey() { -141 return Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED; -142 } -143 -144 /** -145 * Returns the analyzer's name. -146 * -147 * @return the analyzer's name -148 */ -149 @Override -150 public String getName() { -151 return ANALYZER_NAME; -152 } -153 -154 /** -155 * Returns the phase this analyzer should run under. -156 * -157 * @return the analysis phase -158 */ -159 @Override -160 public AnalysisPhase getAnalysisPhase() { -161 return AnalysisPhase.INFORMATION_COLLECTION; -162 } -163 } +99 private MessageDigest sha1 = null; +100 +101 /** +102 * Entry point for the analyzer. +103 * +104 * @param dependency the dependency to analyze +105 * @param engine the engine scanning +106 * @throws AnalysisException if there's a failure during analysis +107 */ +108 @Override +109 protected void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { +110 FileInputStream fis = null; +111 try { +112 fis = new FileInputStream(dependency.getActualFile()); +113 final ComposerLockParser clp = new ComposerLockParser(fis); +114 LOGGER.info("Checking composer.lock file {}", dependency.getActualFilePath()); +115 clp.process(); +116 for (ComposerDependency dep : clp.getDependencies()) { +117 final Dependency d = new Dependency(dependency.getActualFile()); +118 d.setDisplayFileName(String.format("%s:%s/%s", dependency.getDisplayFileName(), dep.getGroup(), dep.getProject())); +119 final String filePath = String.format("%s:%s/%s", dependency.getFilePath(), dep.getGroup(), dep.getProject()); +120 d.setFilePath(filePath); +121 d.setSha1sum(Checksum.getHex(sha1.digest(filePath.getBytes(Charset.defaultCharset())))); +122 d.getVendorEvidence().addEvidence(COMPOSER_LOCK, "vendor", dep.getGroup(), Confidence.HIGHEST); +123 d.getProductEvidence().addEvidence(COMPOSER_LOCK, "product", dep.getProject(), Confidence.HIGHEST); +124 d.getVersionEvidence().addEvidence(COMPOSER_LOCK, "version", dep.getVersion(), Confidence.HIGHEST); +125 LOGGER.info("Adding dependency {}", d); +126 engine.getDependencies().add(d); +127 } +128 } catch (FileNotFoundException fnfe) { +129 LOGGER.warn("Error opening dependency {}", dependency.getActualFilePath()); +130 } catch (ComposerException ce) { +131 LOGGER.warn("Error parsing composer.json {}", dependency.getActualFilePath(), ce); +132 } finally { +133 if (fis != null) { +134 try { +135 fis.close(); +136 } catch (Exception e) { +137 LOGGER.debug("Unable to close file", e); +138 } +139 } +140 } +141 } +142 +143 /** +144 * Gets the key to determine whether the analyzer is enabled. +145 * +146 * @return the key specifying whether the analyzer is enabled +147 */ +148 @Override +149 protected String getAnalyzerEnabledSettingKey() { +150 return Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED; +151 } +152 +153 /** +154 * Returns the analyzer's name. +155 * +156 * @return the analyzer's name +157 */ +158 @Override +159 public String getName() { +160 return ANALYZER_NAME; +161 } +162 +163 /** +164 * Returns the phase this analyzer should run under. +165 * +166 * @return the analysis phase +167 */ +168 @Override +169 public AnalysisPhase getAnalysisPhase() { +170 return AnalysisPhase.INFORMATION_COLLECTION; +171 } +172 }
      diff --git a/xref/org/owasp/dependencycheck/analyzer/CpeSuppressionAnalyzer.html b/xref/org/owasp/dependencycheck/analyzer/CpeSuppressionAnalyzer.html index 91803c5fc..69344012e 100644 --- a/xref/org/owasp/dependencycheck/analyzer/CpeSuppressionAnalyzer.html +++ b/xref/org/owasp/dependencycheck/analyzer/CpeSuppressionAnalyzer.html @@ -28,7 +28,7 @@ 20 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; 21 import org.owasp.dependencycheck.Engine; 22 import org.owasp.dependencycheck.dependency.Dependency; -23 import org.owasp.dependencycheck.suppression.SuppressionRule; +23 import org.owasp.dependencycheck.xml.suppression.SuppressionRule; 24 25 /** 26 * The suppression analyzer processes an externally defined XML document that complies with the suppressions.xsd schema. diff --git a/xref/org/owasp/dependencycheck/analyzer/HintAnalyzer.html b/xref/org/owasp/dependencycheck/analyzer/HintAnalyzer.html index 6b5626c04..3cd496f97 100644 --- a/xref/org/owasp/dependencycheck/analyzer/HintAnalyzer.html +++ b/xref/org/owasp/dependencycheck/analyzer/HintAnalyzer.html @@ -25,163 +25,340 @@ 17 */ 18 package org.owasp.dependencycheck.analyzer; 19 -20 import java.util.ArrayList; -21 import java.util.Iterator; -22 import java.util.List; -23 import java.util.Set; -24 import org.owasp.dependencycheck.Engine; -25 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; -26 import org.owasp.dependencycheck.dependency.Confidence; -27 import org.owasp.dependencycheck.dependency.Dependency; -28 import org.owasp.dependencycheck.dependency.Evidence; -29 -30 /** -31 * -32 * @author Jeremy Long -33 */ -34 public class HintAnalyzer extends AbstractAnalyzer implements Analyzer { -35 -36 //<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer"> -37 /** -38 * The name of the analyzer. -39 */ -40 private static final String ANALYZER_NAME = "Hint Analyzer"; -41 /** -42 * The phase that this analyzer is intended to run in. -43 */ -44 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_IDENTIFIER_ANALYSIS; -45 -46 /** -47 * Returns the name of the analyzer. -48 * -49 * @return the name of the analyzer. -50 */ -51 @Override -52 public String getName() { -53 return ANALYZER_NAME; -54 } +20 import java.io.File; +21 import java.io.IOException; +22 import java.io.InputStream; +23 import java.net.MalformedURLException; +24 import java.net.URL; +25 import java.util.ArrayList; +26 import java.util.Iterator; +27 import java.util.List; +28 import java.util.regex.Pattern; +29 import org.owasp.dependencycheck.Engine; +30 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; +31 import org.owasp.dependencycheck.dependency.Dependency; +32 import org.owasp.dependencycheck.dependency.Evidence; +33 import org.owasp.dependencycheck.exception.InitializationException; +34 import org.owasp.dependencycheck.xml.suppression.PropertyType; +35 import org.owasp.dependencycheck.utils.DownloadFailedException; +36 import org.owasp.dependencycheck.utils.Downloader; +37 import org.owasp.dependencycheck.utils.FileUtils; +38 import org.owasp.dependencycheck.utils.Settings; +39 import org.owasp.dependencycheck.xml.hints.VendorDuplicatingHintRule; +40 import org.owasp.dependencycheck.xml.hints.HintParseException; +41 import org.owasp.dependencycheck.xml.hints.HintParser; +42 import org.owasp.dependencycheck.xml.hints.HintRule; +43 import org.owasp.dependencycheck.xml.hints.Hints; +44 import org.slf4j.Logger; +45 import org.slf4j.LoggerFactory; +46 import org.xml.sax.SAXException; +47 +48 /** +49 * This analyzer adds evidence to dependencies to enhance the accuracy of +50 * library identification. +51 * +52 * @author Jeremy Long +53 */ +54 public class HintAnalyzer extends AbstractAnalyzer implements Analyzer { 55 -56 /** -57 * Returns the phase that the analyzer is intended to run in. -58 * -59 * @return the phase that the analyzer is intended to run in. -60 */ -61 @Override -62 public AnalysisPhase getAnalysisPhase() { -63 return ANALYSIS_PHASE; -64 } -65 //</editor-fold> -66 -67 /** -68 * The HintAnalyzer uses knowledge about a dependency to add additional information to help in identification of identifiers -69 * or vulnerabilities. -70 * -71 * @param dependency The dependency being analyzed -72 * @param engine The scanning engine -73 * @throws AnalysisException is thrown if there is an exception analyzing the dependency. -74 */ -75 @Override -76 public void analyze(Dependency dependency, Engine engine) throws AnalysisException { -77 final Evidence springTest1 = new Evidence("Manifest", -78 "Implementation-Title", -79 "Spring Framework", -80 Confidence.HIGH); -81 -82 final Evidence springTest2 = new Evidence("Manifest", -83 "Implementation-Title", -84 "org.springframework.core", -85 Confidence.HIGH); -86 -87 final Evidence springTest3 = new Evidence("Manifest", -88 "Implementation-Title", -89 "spring-core", -90 Confidence.HIGH); -91 -92 final Evidence springTest4 = new Evidence("jar", -93 "package name", -94 "springframework", -95 Confidence.LOW); -96 -97 final Evidence springSecurityTest1 = new Evidence("Manifest", -98 "Bundle-Name", -99 "Spring Security Core", -100 Confidence.MEDIUM); -101 -102 final Evidence springSecurityTest2 = new Evidence("pom", -103 "artifactid", -104 "spring-security-core", -105 Confidence.HIGH); -106 -107 final Evidence symfony = new Evidence("composer.lock", -108 "vendor", -109 "symfony", -110 Confidence.HIGHEST); -111 -112 final Evidence zendframeworkVendor = new Evidence("composer.lock", -113 "vendor", -114 "zendframework", -115 Confidence.HIGHEST); -116 -117 final Evidence zendframeworkProduct = new Evidence("composer.lock", -118 "product", -119 "zendframework", -120 Confidence.HIGHEST); -121 -122 //springsource/vware problem -123 final Set<Evidence> product = dependency.getProductEvidence().getEvidence(); -124 final Set<Evidence> vendor = dependency.getVendorEvidence().getEvidence(); -125 -126 if (product.contains(springTest1) || product.contains(springTest2) || product.contains(springTest3) -127 || (dependency.getFileName().contains("spring") && product.contains(springTest4))) { -128 dependency.getProductEvidence().addEvidence("hint analyzer", "product", "springsource spring framework", Confidence.HIGH); -129 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "SpringSource", Confidence.HIGH); -130 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "vmware", Confidence.HIGH); -131 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "pivotal", Confidence.HIGH); -132 } -133 -134 if (vendor.contains(springTest4)) { -135 dependency.getProductEvidence().addEvidence("hint analyzer", "product", "springsource_spring_framework", Confidence.HIGH); -136 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "vmware", Confidence.HIGH); -137 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "pivotal", Confidence.HIGH); -138 } -139 -140 if (product.contains(springSecurityTest1) || product.contains(springSecurityTest2)) { -141 dependency.getProductEvidence().addEvidence("hint analyzer", "product", "springsource_spring_security", Confidence.HIGH); -142 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "SpringSource", Confidence.HIGH); -143 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "vmware", Confidence.HIGH); -144 } -145 -146 if (vendor.contains(symfony)) { -147 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "sensiolabs", Confidence.HIGHEST); -148 } -149 -150 if (vendor.contains(zendframeworkVendor)) { -151 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "zend", Confidence.HIGHEST); -152 } -153 -154 if (product.contains(zendframeworkProduct)) { -155 dependency.getProductEvidence().addEvidence("hint analyzer", "vendor", "zend_framework", Confidence.HIGHEST); -156 } -157 -158 //sun/oracle problem -159 final Iterator<Evidence> itr = dependency.getVendorEvidence().iterator(); -160 final List<Evidence> newEntries = new ArrayList<Evidence>(); -161 while (itr.hasNext()) { -162 final Evidence e = itr.next(); -163 if ("sun".equalsIgnoreCase(e.getValue(false))) { -164 final Evidence newEvidence = new Evidence(e.getSource() + " (hint)", e.getName(), "oracle", e.getConfidence()); -165 newEntries.add(newEvidence); -166 } else if ("oracle".equalsIgnoreCase(e.getValue(false))) { -167 final Evidence newEvidence = new Evidence(e.getSource() + " (hint)", e.getName(), "sun", e.getConfidence()); -168 newEntries.add(newEvidence); +56 //<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer"> +57 /** +58 * The name of the analyzer. +59 */ +60 private static final String ANALYZER_NAME = "Hint Analyzer"; +61 /** +62 * The phase that this analyzer is intended to run in. +63 */ +64 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_IDENTIFIER_ANALYSIS; +65 +66 /** +67 * Returns the name of the analyzer. +68 * +69 * @return the name of the analyzer. +70 */ +71 @Override +72 public String getName() { +73 return ANALYZER_NAME; +74 } +75 +76 /** +77 * Returns the phase that the analyzer is intended to run in. +78 * +79 * @return the phase that the analyzer is intended to run in. +80 */ +81 @Override +82 public AnalysisPhase getAnalysisPhase() { +83 return ANALYSIS_PHASE; +84 } +85 +86 /** +87 * The initialize method does nothing for this Analyzer. +88 * +89 * @throws InitializationException thrown if there is an exception +90 */ +91 @Override +92 public void initialize() throws InitializationException { +93 try { +94 super.initialize(); +95 loadHintRules(); +96 } catch (HintParseException ex) { +97 LOGGER.debug("Unable to parse hint file", ex); +98 throw new InitializationException("Unable to parse the hint file", ex); +99 } +100 } +101 //</editor-fold> +102 +103 /** +104 * The Logger for use throughout the class +105 */ +106 private static final Logger LOGGER = LoggerFactory.getLogger(HintAnalyzer.class); +107 /** +108 * The name of the hint rule file +109 */ +110 private static final String HINT_RULE_FILE_NAME = "dependencycheck-base-hint.xml"; +111 /** +112 * The collection of hints. +113 */ +114 private Hints hints; +115 +116 /** +117 * The HintAnalyzer uses knowledge about a dependency to add additional +118 * information to help in identification of identifiers or vulnerabilities. +119 * +120 * @param dependency The dependency being analyzed +121 * @param engine The scanning engine +122 * @throws AnalysisException is thrown if there is an exception analyzing +123 * the dependency. +124 */ +125 @Override +126 public void analyze(Dependency dependency, Engine engine) throws AnalysisException { +127 for (HintRule hint : hints.getHintRules()) { +128 boolean shouldAdd = false; +129 for (Evidence given : hint.getGivenVendor()) { +130 if (dependency.getVendorEvidence().getEvidence().contains(given)) { +131 shouldAdd = true; +132 break; +133 } +134 } +135 if (!shouldAdd) { +136 for (Evidence given : hint.getGivenProduct()) { +137 if (dependency.getProductEvidence().getEvidence().contains(given)) { +138 shouldAdd = true; +139 break; +140 } +141 } +142 } +143 if (!shouldAdd) { +144 for (PropertyType pt : hint.getFilenames()) { +145 if (pt.matches(dependency.getFileName())) { +146 shouldAdd = true; +147 } +148 } +149 } +150 if (shouldAdd) { +151 for (Evidence e : hint.getAddVendor()) { +152 dependency.getVendorEvidence().addEvidence(e); +153 } +154 for (Evidence e : hint.getAddProduct()) { +155 dependency.getProductEvidence().addEvidence(e); +156 } +157 } +158 } +159 +160 final Iterator<Evidence> itr = dependency.getVendorEvidence().iterator(); +161 final List<Evidence> newEntries = new ArrayList<Evidence>(); +162 while (itr.hasNext()) { +163 final Evidence e = itr.next(); +164 for (VendorDuplicatingHintRule dhr : hints.getVendorDuplicatingHintRules()) { +165 if (dhr.getValue().equalsIgnoreCase(e.getValue(false))) { +166 newEntries.add(new Evidence(e.getSource() + " (hint)", +167 e.getName(), dhr.getDuplicate(), e.getConfidence())); +168 } 169 } 170 } 171 for (Evidence e : newEntries) { 172 dependency.getVendorEvidence().addEvidence(e); 173 } 174 -175 } -176 } +175 //<editor-fold defaultstate="collapsed" desc="Old implementation"> +176 /* +177 final Evidence springTest1 = new Evidence("Manifest", +178 "Implementation-Title", +179 "Spring Framework", +180 Confidence.HIGH); +181 +182 final Evidence springTest2 = new Evidence("Manifest", +183 "Implementation-Title", +184 "org.springframework.core", +185 Confidence.HIGH); +186 +187 final Evidence springTest3 = new Evidence("Manifest", +188 "Implementation-Title", +189 "spring-core", +190 Confidence.HIGH); +191 +192 final Evidence springTest4 = new Evidence("jar", +193 "package name", +194 "springframework", +195 Confidence.LOW); +196 +197 final Evidence springSecurityTest1 = new Evidence("Manifest", +198 "Bundle-Name", +199 "Spring Security Core", +200 Confidence.MEDIUM); +201 +202 final Evidence springSecurityTest2 = new Evidence("pom", +203 "artifactid", +204 "spring-security-core", +205 Confidence.HIGH); +206 +207 final Evidence symfony = new Evidence("composer.lock", +208 "vendor", +209 "symfony", +210 Confidence.HIGHEST); +211 +212 final Evidence zendframeworkVendor = new Evidence("composer.lock", +213 "vendor", +214 "zendframework", +215 Confidence.HIGHEST); +216 +217 final Evidence zendframeworkProduct = new Evidence("composer.lock", +218 "product", +219 "zendframework", +220 Confidence.HIGHEST); +221 +222 //springsource/vware problem +223 final Set<Evidence> product = dependency.getProductEvidence().getEvidence(); +224 final Set<Evidence> vendor = dependency.getVendorEvidence().getEvidence(); +225 +226 if (product.contains(springTest1) || product.contains(springTest2) || product.contains(springTest3) +227 || (dependency.getFileName().contains("spring") && product.contains(springTest4))) { +228 dependency.getProductEvidence().addEvidence("hint analyzer", "product", "springsource spring framework", Confidence.HIGH); +229 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "SpringSource", Confidence.HIGH); +230 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "vmware", Confidence.HIGH); +231 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "pivotal", Confidence.HIGH); +232 } +233 +234 if (vendor.contains(springTest4)) { +235 dependency.getProductEvidence().addEvidence("hint analyzer", "product", "springsource_spring_framework", Confidence.HIGH); +236 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "vmware", Confidence.HIGH); +237 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "pivotal", Confidence.HIGH); +238 } +239 +240 if (product.contains(springSecurityTest1) || product.contains(springSecurityTest2)) { +241 dependency.getProductEvidence().addEvidence("hint analyzer", "product", "springsource_spring_security", Confidence.HIGH); +242 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "SpringSource", Confidence.HIGH); +243 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "vmware", Confidence.HIGH); +244 } +245 +246 if (vendor.contains(symfony)) { +247 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "sensiolabs", Confidence.HIGHEST); +248 } +249 +250 if (vendor.contains(zendframeworkVendor)) { +251 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "zend", Confidence.HIGHEST); +252 } +253 +254 if (product.contains(zendframeworkProduct)) { +255 dependency.getProductEvidence().addEvidence("hint analyzer", "vendor", "zend_framework", Confidence.HIGHEST); +256 } +257 +258 //sun/oracle problem +259 final Iterator<Evidence> itr = dependency.getVendorEvidence().iterator(); +260 final List<Evidence> newEntries = new ArrayList<Evidence>(); +261 while (itr.hasNext()) { +262 final Evidence e = itr.next(); +263 if ("sun".equalsIgnoreCase(e.getValue(false))) { +264 final Evidence newEvidence = new Evidence(e.getSource() + " (hint)", e.getName(), "oracle", e.getConfidence()); +265 newEntries.add(newEvidence); +266 } else if ("oracle".equalsIgnoreCase(e.getValue(false))) { +267 final Evidence newEvidence = new Evidence(e.getSource() + " (hint)", e.getName(), "sun", e.getConfidence()); +268 newEntries.add(newEvidence); +269 } +270 } +271 for (Evidence e : newEntries) { +272 dependency.getVendorEvidence().addEvidence(e); +273 } +274 */ +275 //</editor-fold> +276 } +277 +278 /** +279 * Loads the hint rules file. +280 * +281 * @throws HintParseException thrown if the XML cannot be parsed. +282 */ +283 private void loadHintRules() throws HintParseException { +284 final HintParser parser = new HintParser(); +285 File file = null; +286 try { +287 hints = parser.parseHints(this.getClass().getClassLoader().getResourceAsStream(HINT_RULE_FILE_NAME)); +288 } catch (HintParseException ex) { +289 LOGGER.error("Unable to parse the base hint data file"); +290 LOGGER.debug("Unable to parse the base hint data file", ex); +291 } catch (SAXException ex) { +292 LOGGER.error("Unable to parse the base hint data file"); +293 LOGGER.debug("Unable to parse the base hint data file", ex); +294 } +295 final String filePath = Settings.getString(Settings.KEYS.HINTS_FILE); +296 if (filePath == null) { +297 return; +298 } +299 boolean deleteTempFile = false; +300 try { +301 final Pattern uriRx = Pattern.compile("^(https?|file)\\:.*", Pattern.CASE_INSENSITIVE); +302 if (uriRx.matcher(filePath).matches()) { +303 deleteTempFile = true; +304 file = FileUtils.getTempFile("hint", "xml"); +305 final URL url = new URL(filePath); +306 try { +307 Downloader.fetchFile(url, file, false); +308 } catch (DownloadFailedException ex) { +309 Downloader.fetchFile(url, file, true); +310 } +311 } else { +312 file = new File(filePath); +313 if (!file.exists()) { +314 final InputStream fromClasspath = this.getClass().getClassLoader().getResourceAsStream(filePath); +315 if (fromClasspath != null) { +316 deleteTempFile = true; +317 file = FileUtils.getTempFile("hint", "xml"); +318 try { +319 org.apache.commons.io.FileUtils.copyInputStreamToFile(fromClasspath, file); +320 } catch (IOException ex) { +321 throw new HintParseException("Unable to locate suppressions file in classpath", ex); +322 } +323 } +324 } +325 } +326 +327 if (file != null) { +328 try { +329 final Hints newHints = parser.parseHints(file); +330 hints.getHintRules().addAll(newHints.getHintRules()); +331 hints.getVendorDuplicatingHintRules().addAll(newHints.getVendorDuplicatingHintRules()); +332 LOGGER.debug("{} hint rules were loaded.", hints.getHintRules().size()); +333 LOGGER.debug("{} duplicating hint rules were loaded.", hints.getVendorDuplicatingHintRules().size()); +334 } catch (HintParseException ex) { +335 LOGGER.warn("Unable to parse hint rule xml file '{}'", file.getPath()); +336 LOGGER.warn(ex.getMessage()); +337 LOGGER.debug("", ex); +338 throw ex; +339 } +340 } +341 } catch (DownloadFailedException ex) { +342 throw new HintParseException("Unable to fetch the configured hint file", ex); +343 } catch (MalformedURLException ex) { +344 throw new HintParseException("Configured hint file has an invalid URL", ex); +345 } catch (IOException ex) { +346 throw new HintParseException("Unable to create temp file for hints", ex); +347 } finally { +348 if (deleteTempFile && file != null) { +349 FileUtils.delete(file); +350 } +351 } +352 } +353 }
      diff --git a/xref/org/owasp/dependencycheck/analyzer/JarAnalyzer.html b/xref/org/owasp/dependencycheck/analyzer/JarAnalyzer.html index 973da820f..197720596 100644 --- a/xref/org/owasp/dependencycheck/analyzer/JarAnalyzer.html +++ b/xref/org/owasp/dependencycheck/analyzer/JarAnalyzer.html @@ -57,1184 +57,1188 @@ 49 import org.owasp.dependencycheck.dependency.Confidence; 50 import org.owasp.dependencycheck.dependency.Dependency; 51 import org.owasp.dependencycheck.dependency.EvidenceCollection; -52 import org.owasp.dependencycheck.utils.FileFilterBuilder; -53 import org.owasp.dependencycheck.xml.pom.License; -54 import org.owasp.dependencycheck.xml.pom.PomUtils; -55 import org.owasp.dependencycheck.xml.pom.Model; -56 import org.owasp.dependencycheck.utils.FileUtils; -57 import org.owasp.dependencycheck.utils.Settings; -58 import org.slf4j.Logger; -59 import org.slf4j.LoggerFactory; -60 -61 /** -62 * Used to load a JAR file and collect information that can be used to determine -63 * the associated CPE. -64 * -65 * @author Jeremy Long -66 */ -67 public class JarAnalyzer extends AbstractFileTypeAnalyzer { -68 -69 //<editor-fold defaultstate="collapsed" desc="Constants and Member Variables"> -70 /** -71 * The logger. -72 */ -73 private static final Logger LOGGER = LoggerFactory.getLogger(JarAnalyzer.class); -74 /** -75 * The count of directories created during analysis. This is used for -76 * creating temporary directories. -77 */ -78 private static int dirCount = 0; -79 /** -80 * The system independent newline character. -81 */ -82 private static final String NEWLINE = System.getProperty("line.separator"); -83 /** -84 * A list of values in the manifest to ignore as they only result in false -85 * positives. -86 */ -87 private static final Set<String> IGNORE_VALUES = newHashSet( -88 "Sun Java System Application Server"); -89 /** -90 * A list of elements in the manifest to ignore. -91 */ -92 private static final Set<String> IGNORE_KEYS = newHashSet( -93 "built-by", -94 "created-by", -95 "builtby", -96 "createdby", -97 "build-jdk", -98 "buildjdk", -99 "ant-version", -100 "antversion", -101 "dynamicimportpackage", -102 "dynamicimport-package", -103 "dynamic-importpackage", -104 "dynamic-import-package", -105 "import-package", -106 "ignore-package", -107 "export-package", -108 "importpackage", -109 "ignorepackage", -110 "exportpackage", -111 "sealed", -112 "manifest-version", -113 "archiver-version", -114 "manifestversion", -115 "archiverversion", -116 "classpath", -117 "class-path", -118 "tool", -119 "bundle-manifestversion", -120 "bundlemanifestversion", -121 "bundle-vendor", -122 "include-resource", -123 "embed-dependency", -124 "ipojo-components", -125 "ipojo-extension", -126 "eclipse-sourcereferences"); -127 /** -128 * Deprecated Jar manifest attribute, that is, nonetheless, useful for -129 * analysis. -130 */ -131 @SuppressWarnings("deprecation") -132 private static final String IMPLEMENTATION_VENDOR_ID = Attributes.Name.IMPLEMENTATION_VENDOR_ID -133 .toString(); -134 /** -135 * item in some manifest, should be considered medium confidence. -136 */ -137 private static final String BUNDLE_VERSION = "Bundle-Version"; //: 2.1.2 -138 /** -139 * item in some manifest, should be considered medium confidence. -140 */ -141 private static final String BUNDLE_DESCRIPTION = "Bundle-Description"; //: Apache Struts 2 -142 /** -143 * item in some manifest, should be considered medium confidence. -144 */ -145 private static final String BUNDLE_NAME = "Bundle-Name"; //: Struts 2 Core -146 /** -147 * A pattern to detect HTML within text. -148 */ -149 private static final Pattern HTML_DETECTION_PATTERN = Pattern.compile("\\<[a-z]+.*/?\\>", Pattern.CASE_INSENSITIVE); -150 -151 //</editor-fold> -152 /** -153 * Constructs a new JarAnalyzer. -154 */ -155 public JarAnalyzer() { -156 } -157 -158 //<editor-fold defaultstate="collapsed" desc="All standard implmentation details of Analyzer"> -159 /** -160 * The name of the analyzer. -161 */ -162 private static final String ANALYZER_NAME = "Jar Analyzer"; -163 /** -164 * The phase that this analyzer is intended to run in. -165 */ -166 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; -167 /** -168 * The set of file extensions supported by this analyzer. -169 */ -170 private static final String[] EXTENSIONS = {"jar", "war"}; -171 -172 /** -173 * The file filter used to determine which files this analyzer supports. -174 */ -175 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(EXTENSIONS).build(); -176 -177 /** -178 * Returns the FileFilter. -179 * -180 * @return the FileFilter -181 */ -182 @Override -183 protected FileFilter getFileFilter() { -184 return FILTER; -185 } -186 -187 /** -188 * Returns the name of the analyzer. -189 * -190 * @return the name of the analyzer. -191 */ -192 @Override -193 public String getName() { -194 return ANALYZER_NAME; -195 } -196 -197 /** -198 * Returns the phase that the analyzer is intended to run in. -199 * -200 * @return the phase that the analyzer is intended to run in. -201 */ -202 @Override -203 public AnalysisPhase getAnalysisPhase() { -204 return ANALYSIS_PHASE; -205 } -206 //</editor-fold> -207 -208 /** -209 * Returns the key used in the properties file to reference the analyzer's -210 * enabled property. -211 * -212 * @return the analyzer's enabled property setting key -213 */ -214 @Override -215 protected String getAnalyzerEnabledSettingKey() { -216 return Settings.KEYS.ANALYZER_JAR_ENABLED; -217 } -218 -219 /** -220 * Loads a specified JAR file and collects information from the manifest and -221 * checksums to identify the correct CPE information. -222 * -223 * @param dependency the dependency to analyze. -224 * @param engine the engine that is scanning the dependencies -225 * @throws AnalysisException is thrown if there is an error reading the JAR -226 * file. -227 */ -228 @Override -229 public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { -230 try { -231 final List<ClassNameInformation> classNames = collectClassNames(dependency); -232 final String fileName = dependency.getFileName().toLowerCase(); -233 if (classNames.isEmpty() -234 && (fileName.endsWith("-sources.jar") -235 || fileName.endsWith("-javadoc.jar") -236 || fileName.endsWith("-src.jar") -237 || fileName.endsWith("-doc.jar"))) { -238 engine.getDependencies().remove(dependency); -239 } -240 final boolean hasManifest = parseManifest(dependency, classNames); -241 final boolean hasPOM = analyzePOM(dependency, classNames, engine); -242 final boolean addPackagesAsEvidence = !(hasManifest && hasPOM); -243 analyzePackageNames(classNames, dependency, addPackagesAsEvidence); -244 } catch (IOException ex) { -245 throw new AnalysisException("Exception occurred reading the JAR file.", ex); -246 } -247 } -248 -249 /** -250 * Attempts to find a pom.xml within the JAR file. If found it extracts -251 * information and adds it to the evidence. This will attempt to interpolate -252 * the strings contained within the pom.properties if one exists. -253 * -254 * @param dependency the dependency being analyzed -255 * @param classes a collection of class name information -256 * @param engine the analysis engine, used to add additional dependencies -257 * @throws AnalysisException is thrown if there is an exception parsing the -258 * pom -259 * @return whether or not evidence was added to the dependency -260 */ -261 protected boolean analyzePOM(Dependency dependency, List<ClassNameInformation> classes, Engine engine) throws AnalysisException { -262 boolean foundSomething = false; -263 final JarFile jar; -264 try { -265 jar = new JarFile(dependency.getActualFilePath()); -266 } catch (IOException ex) { -267 LOGGER.warn("Unable to read JarFile '{}'.", dependency.getActualFilePath()); -268 LOGGER.trace("", ex); -269 return false; -270 } -271 List<String> pomEntries; -272 try { -273 pomEntries = retrievePomListing(jar); -274 } catch (IOException ex) { -275 LOGGER.warn("Unable to read Jar file entries in '{}'.", dependency.getActualFilePath()); -276 LOGGER.trace("", ex); -277 return false; -278 } -279 File externalPom = null; -280 if (pomEntries.isEmpty()) { -281 final String pomPath = FilenameUtils.removeExtension(dependency.getActualFilePath()) + ".pom"; -282 externalPom = new File(pomPath); -283 if (externalPom.isFile()) { -284 pomEntries.add(pomPath); -285 } else { -286 return false; -287 } -288 } -289 for (String path : pomEntries) { -290 LOGGER.debug("Reading pom entry: {}", path); -291 Properties pomProperties = null; -292 try { -293 if (externalPom == null) { -294 pomProperties = retrievePomProperties(path, jar); -295 } -296 } catch (IOException ex) { -297 LOGGER.trace("ignore this, failed reading a non-existent pom.properties", ex); -298 } -299 Model pom = null; -300 try { -301 if (pomEntries.size() > 1) { -302 //extract POM to its own directory and add it as its own dependency -303 final Dependency newDependency = new Dependency(); -304 pom = extractPom(path, jar, newDependency); -305 -306 final String displayPath = String.format("%s%s%s", -307 dependency.getFilePath(), -308 File.separator, -309 path); -310 final String displayName = String.format("%s%s%s", -311 dependency.getFileName(), -312 File.separator, -313 path); -314 -315 newDependency.setFileName(displayName); -316 newDependency.setFilePath(displayPath); -317 pom.processProperties(pomProperties); -318 setPomEvidence(newDependency, pom, null); -319 engine.getDependencies().add(newDependency); -320 Collections.sort(engine.getDependencies()); -321 } else { -322 if (externalPom == null) { -323 pom = PomUtils.readPom(path, jar); -324 } else { -325 pom = PomUtils.readPom(externalPom); -326 } -327 pom.processProperties(pomProperties); -328 foundSomething |= setPomEvidence(dependency, pom, classes); -329 } -330 } catch (AnalysisException ex) { -331 LOGGER.warn("An error occurred while analyzing '{}'.", dependency.getActualFilePath()); -332 LOGGER.trace("", ex); -333 } -334 } -335 return foundSomething; -336 } -337 -338 /** -339 * Given a path to a pom.xml within a JarFile, this method attempts to load -340 * a sibling pom.properties if one exists. -341 * -342 * @param path the path to the pom.xml within the JarFile -343 * @param jar the JarFile to load the pom.properties from -344 * @return a Properties object or null if no pom.properties was found -345 * @throws IOException thrown if there is an exception reading the -346 * pom.properties -347 */ -348 private Properties retrievePomProperties(String path, final JarFile jar) throws IOException { -349 Properties pomProperties = null; -350 final String propPath = path.substring(0, path.length() - 7) + "pom.properies"; -351 final ZipEntry propEntry = jar.getEntry(propPath); -352 if (propEntry != null) { -353 Reader reader = null; -354 try { -355 reader = new InputStreamReader(jar.getInputStream(propEntry), "UTF-8"); -356 pomProperties = new Properties(); -357 pomProperties.load(reader); -358 LOGGER.debug("Read pom.properties: {}", propPath); -359 } finally { -360 if (reader != null) { -361 try { -362 reader.close(); -363 } catch (IOException ex) { -364 LOGGER.trace("close error", ex); -365 } -366 } -367 } -368 } -369 return pomProperties; -370 } -371 -372 /** -373 * Searches a JarFile for pom.xml entries and returns a listing of these -374 * entries. -375 * -376 * @param jar the JarFile to search -377 * @return a list of pom.xml entries -378 * @throws IOException thrown if there is an exception reading a JarEntry -379 */ -380 private List<String> retrievePomListing(final JarFile jar) throws IOException { -381 final List<String> pomEntries = new ArrayList<String>(); -382 final Enumeration<JarEntry> entries = jar.entries(); -383 while (entries.hasMoreElements()) { -384 final JarEntry entry = entries.nextElement(); -385 final String entryName = (new File(entry.getName())).getName().toLowerCase(); -386 if (!entry.isDirectory() && "pom.xml".equals(entryName)) { -387 LOGGER.trace("POM Entry found: {}", entry.getName()); -388 pomEntries.add(entry.getName()); -389 } -390 } -391 return pomEntries; -392 } -393 -394 /** -395 * Retrieves the specified POM from a jar file and converts it to a Model. -396 * -397 * @param path the path to the pom.xml file within the jar file -398 * @param jar the jar file to extract the pom from -399 * @param dependency the dependency being analyzed -400 * @return returns the POM object -401 * @throws AnalysisException is thrown if there is an exception extracting -402 * or parsing the POM {@link org.owasp.dependencycheck.xml.pom.Model} object -403 */ -404 private Model extractPom(String path, JarFile jar, Dependency dependency) throws AnalysisException { -405 InputStream input = null; -406 FileOutputStream fos = null; -407 final File tmpDir = getNextTempDirectory(); -408 final File file = new File(tmpDir, "pom.xml"); -409 try { -410 final ZipEntry entry = jar.getEntry(path); -411 input = jar.getInputStream(entry); -412 fos = new FileOutputStream(file); -413 IOUtils.copy(input, fos); -414 dependency.setActualFilePath(file.getAbsolutePath()); -415 } catch (IOException ex) { -416 LOGGER.warn("An error occurred reading '{}' from '{}'.", path, dependency.getFilePath()); -417 LOGGER.error("", ex); -418 } finally { -419 closeStream(fos); -420 closeStream(input); -421 } -422 return PomUtils.readPom(file); -423 } -424 -425 /** -426 * Silently closes an input stream ignoring errors. -427 * -428 * @param stream an input stream to close -429 */ -430 private void closeStream(InputStream stream) { -431 if (stream != null) { -432 try { -433 stream.close(); -434 } catch (IOException ex) { -435 LOGGER.trace("", ex); -436 } -437 } -438 } -439 -440 /** -441 * Silently closes an output stream ignoring errors. -442 * -443 * @param stream an output stream to close -444 */ -445 private void closeStream(OutputStream stream) { -446 if (stream != null) { -447 try { -448 stream.close(); -449 } catch (IOException ex) { -450 LOGGER.trace("", ex); -451 } -452 } -453 } -454 -455 /** -456 * Sets evidence from the pom on the supplied dependency. -457 * -458 * @param dependency the dependency to set data on -459 * @param pom the information from the pom -460 * @param classes a collection of ClassNameInformation - containing data -461 * about the fully qualified class names within the JAR file being analyzed -462 * @return true if there was evidence within the pom that we could use; -463 * otherwise false -464 */ -465 public static boolean setPomEvidence(Dependency dependency, Model pom, List<ClassNameInformation> classes) { -466 boolean foundSomething = false; -467 boolean addAsIdentifier = true; -468 if (pom == null) { -469 return foundSomething; -470 } -471 String groupid = pom.getGroupId(); -472 String parentGroupId = pom.getParentGroupId(); -473 String artifactid = pom.getArtifactId(); -474 String parentArtifactId = pom.getParentArtifactId(); -475 String version = pom.getVersion(); -476 String parentVersion = pom.getParentVersion(); -477 -478 if ("org.sonatype.oss".equals(parentGroupId) && "oss-parent".equals(parentArtifactId)) { -479 parentGroupId = null; -480 parentArtifactId = null; -481 parentVersion = null; -482 } -483 -484 if ((groupid == null || groupid.isEmpty()) && parentGroupId != null && !parentGroupId.isEmpty()) { -485 groupid = parentGroupId; -486 } -487 -488 final String originalGroupID = groupid; -489 if (groupid.startsWith("org.") || groupid.startsWith("com.")) { -490 groupid = groupid.substring(4); -491 } -492 -493 if ((artifactid == null || artifactid.isEmpty()) && parentArtifactId != null && !parentArtifactId.isEmpty()) { -494 artifactid = parentArtifactId; -495 } -496 -497 final String originalArtifactID = artifactid; -498 if (artifactid.startsWith("org.") || artifactid.startsWith("com.")) { -499 artifactid = artifactid.substring(4); -500 } -501 -502 if ((version == null || version.isEmpty()) && parentVersion != null && !parentVersion.isEmpty()) { -503 version = parentVersion; -504 } -505 -506 if (groupid != null && !groupid.isEmpty()) { -507 foundSomething = true; -508 dependency.getVendorEvidence().addEvidence("pom", "groupid", groupid, Confidence.HIGHEST); -509 dependency.getProductEvidence().addEvidence("pom", "groupid", groupid, Confidence.LOW); -510 addMatchingValues(classes, groupid, dependency.getVendorEvidence()); -511 addMatchingValues(classes, groupid, dependency.getProductEvidence()); -512 if (parentGroupId != null && !parentGroupId.isEmpty() && !parentGroupId.equals(groupid)) { -513 dependency.getVendorEvidence().addEvidence("pom", "parent-groupid", parentGroupId, Confidence.MEDIUM); -514 dependency.getProductEvidence().addEvidence("pom", "parent-groupid", parentGroupId, Confidence.LOW); -515 addMatchingValues(classes, parentGroupId, dependency.getVendorEvidence()); -516 addMatchingValues(classes, parentGroupId, dependency.getProductEvidence()); -517 } -518 } else { -519 addAsIdentifier = false; -520 } -521 -522 if (artifactid != null && !artifactid.isEmpty()) { -523 foundSomething = true; -524 dependency.getProductEvidence().addEvidence("pom", "artifactid", artifactid, Confidence.HIGHEST); -525 dependency.getVendorEvidence().addEvidence("pom", "artifactid", artifactid, Confidence.LOW); -526 addMatchingValues(classes, artifactid, dependency.getVendorEvidence()); -527 addMatchingValues(classes, artifactid, dependency.getProductEvidence()); -528 if (parentArtifactId != null && !parentArtifactId.isEmpty() && !parentArtifactId.equals(artifactid)) { -529 dependency.getProductEvidence().addEvidence("pom", "parent-artifactid", parentArtifactId, Confidence.MEDIUM); -530 dependency.getVendorEvidence().addEvidence("pom", "parent-artifactid", parentArtifactId, Confidence.LOW); -531 addMatchingValues(classes, parentArtifactId, dependency.getVendorEvidence()); -532 addMatchingValues(classes, parentArtifactId, dependency.getProductEvidence()); -533 } -534 } else { -535 addAsIdentifier = false; -536 } -537 -538 if (version != null && !version.isEmpty()) { -539 foundSomething = true; -540 dependency.getVersionEvidence().addEvidence("pom", "version", version, Confidence.HIGHEST); -541 if (parentVersion != null && !parentVersion.isEmpty() && !parentVersion.equals(version)) { -542 dependency.getVersionEvidence().addEvidence("pom", "parent-version", version, Confidence.LOW); -543 } -544 } else { -545 addAsIdentifier = false; -546 } -547 -548 if (addAsIdentifier) { -549 dependency.addIdentifier("maven", String.format("%s:%s:%s", originalGroupID, originalArtifactID, version), null, Confidence.HIGH); -550 } -551 -552 // org name -553 final String org = pom.getOrganization(); -554 if (org != null && !org.isEmpty()) { -555 dependency.getVendorEvidence().addEvidence("pom", "organization name", org, Confidence.HIGH); -556 dependency.getProductEvidence().addEvidence("pom", "organization name", org, Confidence.LOW); -557 addMatchingValues(classes, org, dependency.getVendorEvidence()); -558 addMatchingValues(classes, org, dependency.getProductEvidence()); -559 } -560 //pom name -561 final String pomName = pom.getName(); -562 if (pomName -563 != null && !pomName.isEmpty()) { -564 foundSomething = true; -565 dependency.getProductEvidence().addEvidence("pom", "name", pomName, Confidence.HIGH); -566 dependency.getVendorEvidence().addEvidence("pom", "name", pomName, Confidence.HIGH); -567 addMatchingValues(classes, pomName, dependency.getVendorEvidence()); -568 addMatchingValues(classes, pomName, dependency.getProductEvidence()); -569 } -570 -571 //Description -572 final String description = pom.getDescription(); -573 if (description != null && !description.isEmpty() && !description.startsWith("POM was created by")) { -574 foundSomething = true; -575 final String trimmedDescription = addDescription(dependency, description, "pom", "description"); -576 addMatchingValues(classes, trimmedDescription, dependency.getVendorEvidence()); -577 addMatchingValues(classes, trimmedDescription, dependency.getProductEvidence()); -578 } -579 -580 final String projectURL = pom.getProjectURL(); -581 if (projectURL != null && !projectURL.trim().isEmpty()) { -582 dependency.getVendorEvidence().addEvidence("pom", "url", projectURL, Confidence.HIGHEST); -583 } -584 -585 extractLicense(pom, dependency); -586 return foundSomething; -587 } -588 -589 /** -590 * Analyzes the path information of the classes contained within the -591 * JarAnalyzer to try and determine possible vendor or product names. If any -592 * are found they are stored in the packageVendor and packageProduct -593 * hashSets. -594 * -595 * @param classNames a list of class names -596 * @param dependency a dependency to analyze -597 * @param addPackagesAsEvidence a flag indicating whether or not package -598 * names should be added as evidence. -599 */ -600 protected void analyzePackageNames(List<ClassNameInformation> classNames, -601 Dependency dependency, boolean addPackagesAsEvidence) { -602 final Map<String, Integer> vendorIdentifiers = new HashMap<String, Integer>(); -603 final Map<String, Integer> productIdentifiers = new HashMap<String, Integer>(); -604 analyzeFullyQualifiedClassNames(classNames, vendorIdentifiers, productIdentifiers); -605 -606 final int classCount = classNames.size(); -607 final EvidenceCollection vendor = dependency.getVendorEvidence(); -608 final EvidenceCollection product = dependency.getProductEvidence(); -609 -610 for (Map.Entry<String, Integer> entry : vendorIdentifiers.entrySet()) { -611 final float ratio = entry.getValue() / (float) classCount; -612 if (ratio > 0.5) { -613 //TODO remove weighting -614 vendor.addWeighting(entry.getKey()); -615 if (addPackagesAsEvidence && entry.getKey().length() > 1) { -616 vendor.addEvidence("jar", "package name", entry.getKey(), Confidence.LOW); -617 } -618 } -619 } -620 for (Map.Entry<String, Integer> entry : productIdentifiers.entrySet()) { -621 final float ratio = entry.getValue() / (float) classCount; -622 if (ratio > 0.5) { -623 product.addWeighting(entry.getKey()); -624 if (addPackagesAsEvidence && entry.getKey().length() > 1) { -625 product.addEvidence("jar", "package name", entry.getKey(), Confidence.LOW); -626 } -627 } -628 } -629 } -630 -631 /** -632 * <p> -633 * Reads the manifest from the JAR file and collects the entries. Some -634 * vendorKey entries are:</p> -635 * <ul><li>Implementation Title</li> -636 * <li>Implementation Version</li> <li>Implementation Vendor</li> -637 * <li>Implementation VendorId</li> <li>Bundle Name</li> <li>Bundle -638 * Version</li> <li>Bundle Vendor</li> <li>Bundle Description</li> <li>Main -639 * Class</li> </ul> -640 * However, all but a handful of specific entries are read in. -641 * -642 * @param dependency A reference to the dependency -643 * @param classInformation a collection of class information -644 * @return whether evidence was identified parsing the manifest -645 * @throws IOException if there is an issue reading the JAR file -646 */ -647 protected boolean parseManifest(Dependency dependency, -648 List<ClassNameInformation> classInformation) -649 throws IOException { -650 boolean foundSomething = false; -651 JarFile jar = null; -652 try { -653 jar = new JarFile(dependency.getActualFilePath()); -654 final Manifest manifest = jar.getManifest(); -655 if (manifest == null) { -656 if (!dependency.getFileName().toLowerCase().endsWith("-sources.jar") -657 && !dependency.getFileName().toLowerCase().endsWith("-javadoc.jar") -658 && !dependency.getFileName().toLowerCase().endsWith("-src.jar") -659 && !dependency.getFileName().toLowerCase().endsWith("-doc.jar")) { -660 LOGGER.debug("Jar file '{}' does not contain a manifest.", -661 dependency.getFileName()); -662 } -663 return false; -664 } -665 final EvidenceCollection vendorEvidence = dependency.getVendorEvidence(); -666 final EvidenceCollection productEvidence = dependency.getProductEvidence(); -667 final EvidenceCollection versionEvidence = dependency.getVersionEvidence(); -668 -669 String source = "Manifest"; -670 String specificationVersion = null; -671 boolean hasImplementationVersion = false; -672 Attributes atts = manifest.getMainAttributes(); -673 for (Entry<Object, Object> entry : atts.entrySet()) { -674 String key = entry.getKey().toString(); -675 String value = atts.getValue(key); -676 if (HTML_DETECTION_PATTERN.matcher(value).find()) { -677 value = Jsoup.parse(value).text(); -678 } -679 if (IGNORE_VALUES.contains(value)) { -680 continue; -681 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_TITLE.toString())) { -682 foundSomething = true; -683 productEvidence.addEvidence(source, key, value, Confidence.HIGH); -684 addMatchingValues(classInformation, value, productEvidence); -685 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VERSION.toString())) { -686 hasImplementationVersion = true; -687 foundSomething = true; -688 versionEvidence.addEvidence(source, key, value, Confidence.HIGH); -689 } else if ("specification-version".equalsIgnoreCase(key)) { -690 specificationVersion = key; -691 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VENDOR.toString())) { -692 foundSomething = true; -693 vendorEvidence.addEvidence(source, key, value, Confidence.HIGH); -694 addMatchingValues(classInformation, value, vendorEvidence); -695 } else if (key.equalsIgnoreCase(IMPLEMENTATION_VENDOR_ID)) { -696 foundSomething = true; -697 vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -698 addMatchingValues(classInformation, value, vendorEvidence); -699 } else if (key.equalsIgnoreCase(BUNDLE_DESCRIPTION)) { -700 foundSomething = true; -701 addDescription(dependency, value, "manifest", key); -702 addMatchingValues(classInformation, value, productEvidence); -703 } else if (key.equalsIgnoreCase(BUNDLE_NAME)) { -704 foundSomething = true; -705 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -706 addMatchingValues(classInformation, value, productEvidence); -707 // //the following caused false positives. -708 // } else if (key.equalsIgnoreCase(BUNDLE_VENDOR)) { -709 // foundSomething = true; -710 // vendorEvidence.addEvidence(source, key, value, Confidence.HIGH); -711 // addMatchingValues(classInformation, value, vendorEvidence); -712 } else if (key.equalsIgnoreCase(BUNDLE_VERSION)) { -713 foundSomething = true; -714 versionEvidence.addEvidence(source, key, value, Confidence.HIGH); -715 } else if (key.equalsIgnoreCase(Attributes.Name.MAIN_CLASS.toString())) { -716 continue; -717 //skipping main class as if this has important information to add -718 // it will be added during class name analysis... if other fields -719 // have the information from the class name then they will get added... -720 } else { -721 key = key.toLowerCase(); -722 if (!IGNORE_KEYS.contains(key) -723 && !key.endsWith("jdk") -724 && !key.contains("lastmodified") -725 && !key.endsWith("package") -726 && !key.endsWith("classpath") -727 && !key.endsWith("class-path") -728 && !key.endsWith("-scm") //todo change this to a regex? -729 && !key.startsWith("scm-") -730 && !value.trim().startsWith("scm:") -731 && !isImportPackage(key, value) -732 && !isPackage(key, value)) { -733 foundSomething = true; -734 if (key.contains("version")) { -735 if (!key.contains("specification")) { -736 versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -737 } -738 } else if ("build-id".equals(key)) { -739 int pos = value.indexOf('('); -740 if (pos >= 0) { -741 value = value.substring(0, pos - 1); -742 } -743 pos = value.indexOf('['); -744 if (pos >= 0) { -745 value = value.substring(0, pos - 1); -746 } -747 versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -748 } else if (key.contains("title")) { -749 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -750 addMatchingValues(classInformation, value, productEvidence); -751 } else if (key.contains("vendor")) { -752 if (key.contains("specification")) { -753 vendorEvidence.addEvidence(source, key, value, Confidence.LOW); -754 } else { -755 vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -756 addMatchingValues(classInformation, value, vendorEvidence); -757 } -758 } else if (key.contains("name")) { -759 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -760 vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -761 addMatchingValues(classInformation, value, vendorEvidence); -762 addMatchingValues(classInformation, value, productEvidence); -763 } else if (key.contains("license")) { -764 addLicense(dependency, value); -765 } else if (key.contains("description")) { -766 addDescription(dependency, value, "manifest", key); -767 } else { -768 productEvidence.addEvidence(source, key, value, Confidence.LOW); -769 vendorEvidence.addEvidence(source, key, value, Confidence.LOW); -770 addMatchingValues(classInformation, value, vendorEvidence); -771 addMatchingValues(classInformation, value, productEvidence); -772 if (value.matches(".*\\d.*")) { -773 final StringTokenizer tokenizer = new StringTokenizer(value, " "); -774 while (tokenizer.hasMoreElements()) { -775 final String s = tokenizer.nextToken(); -776 if (s.matches("^[0-9.]+$")) { -777 versionEvidence.addEvidence(source, key, s, Confidence.LOW); -778 } -779 } -780 } -781 } -782 } -783 } -784 } -785 -786 for (Map.Entry<String, Attributes> item : manifest.getEntries().entrySet()) { -787 final String name = item.getKey(); -788 source = "manifest: " + name; -789 atts = item.getValue(); -790 for (Entry<Object, Object> entry : atts.entrySet()) { -791 final String key = entry.getKey().toString(); -792 final String value = atts.getValue(key); -793 if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_TITLE.toString())) { -794 foundSomething = true; -795 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -796 addMatchingValues(classInformation, value, productEvidence); -797 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VERSION.toString())) { +52 import org.owasp.dependencycheck.exception.InitializationException; +53 import org.owasp.dependencycheck.utils.FileFilterBuilder; +54 import org.owasp.dependencycheck.xml.pom.License; +55 import org.owasp.dependencycheck.xml.pom.PomUtils; +56 import org.owasp.dependencycheck.xml.pom.Model; +57 import org.owasp.dependencycheck.utils.FileUtils; +58 import org.owasp.dependencycheck.utils.Settings; +59 import org.slf4j.Logger; +60 import org.slf4j.LoggerFactory; +61 +62 /** +63 * Used to load a JAR file and collect information that can be used to determine +64 * the associated CPE. +65 * +66 * @author Jeremy Long +67 */ +68 public class JarAnalyzer extends AbstractFileTypeAnalyzer { +69 +70 //<editor-fold defaultstate="collapsed" desc="Constants and Member Variables"> +71 /** +72 * The logger. +73 */ +74 private static final Logger LOGGER = LoggerFactory.getLogger(JarAnalyzer.class); +75 /** +76 * The count of directories created during analysis. This is used for +77 * creating temporary directories. +78 */ +79 private static int dirCount = 0; +80 /** +81 * The system independent newline character. +82 */ +83 private static final String NEWLINE = System.getProperty("line.separator"); +84 /** +85 * A list of values in the manifest to ignore as they only result in false +86 * positives. +87 */ +88 private static final Set<String> IGNORE_VALUES = newHashSet( +89 "Sun Java System Application Server"); +90 /** +91 * A list of elements in the manifest to ignore. +92 */ +93 private static final Set<String> IGNORE_KEYS = newHashSet( +94 "built-by", +95 "created-by", +96 "builtby", +97 "createdby", +98 "build-jdk", +99 "buildjdk", +100 "ant-version", +101 "antversion", +102 "dynamicimportpackage", +103 "dynamicimport-package", +104 "dynamic-importpackage", +105 "dynamic-import-package", +106 "import-package", +107 "ignore-package", +108 "export-package", +109 "importpackage", +110 "ignorepackage", +111 "exportpackage", +112 "sealed", +113 "manifest-version", +114 "archiver-version", +115 "manifestversion", +116 "archiverversion", +117 "classpath", +118 "class-path", +119 "tool", +120 "bundle-manifestversion", +121 "bundlemanifestversion", +122 "bundle-vendor", +123 "include-resource", +124 "embed-dependency", +125 "ipojo-components", +126 "ipojo-extension", +127 "eclipse-sourcereferences"); +128 /** +129 * Deprecated Jar manifest attribute, that is, nonetheless, useful for +130 * analysis. +131 */ +132 @SuppressWarnings("deprecation") +133 private static final String IMPLEMENTATION_VENDOR_ID = Attributes.Name.IMPLEMENTATION_VENDOR_ID +134 .toString(); +135 /** +136 * item in some manifest, should be considered medium confidence. +137 */ +138 private static final String BUNDLE_VERSION = "Bundle-Version"; //: 2.1.2 +139 /** +140 * item in some manifest, should be considered medium confidence. +141 */ +142 private static final String BUNDLE_DESCRIPTION = "Bundle-Description"; //: Apache Struts 2 +143 /** +144 * item in some manifest, should be considered medium confidence. +145 */ +146 private static final String BUNDLE_NAME = "Bundle-Name"; //: Struts 2 Core +147 /** +148 * A pattern to detect HTML within text. +149 */ +150 private static final Pattern HTML_DETECTION_PATTERN = Pattern.compile("\\<[a-z]+.*/?\\>", Pattern.CASE_INSENSITIVE); +151 +152 //</editor-fold> +153 /** +154 * Constructs a new JarAnalyzer. +155 */ +156 public JarAnalyzer() { +157 } +158 +159 //<editor-fold defaultstate="collapsed" desc="All standard implmentation details of Analyzer"> +160 /** +161 * The name of the analyzer. +162 */ +163 private static final String ANALYZER_NAME = "Jar Analyzer"; +164 /** +165 * The phase that this analyzer is intended to run in. +166 */ +167 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; +168 /** +169 * The set of file extensions supported by this analyzer. +170 */ +171 private static final String[] EXTENSIONS = {"jar", "war"}; +172 +173 /** +174 * The file filter used to determine which files this analyzer supports. +175 */ +176 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(EXTENSIONS).build(); +177 +178 /** +179 * Returns the FileFilter. +180 * +181 * @return the FileFilter +182 */ +183 @Override +184 protected FileFilter getFileFilter() { +185 return FILTER; +186 } +187 +188 /** +189 * Returns the name of the analyzer. +190 * +191 * @return the name of the analyzer. +192 */ +193 @Override +194 public String getName() { +195 return ANALYZER_NAME; +196 } +197 +198 /** +199 * Returns the phase that the analyzer is intended to run in. +200 * +201 * @return the phase that the analyzer is intended to run in. +202 */ +203 @Override +204 public AnalysisPhase getAnalysisPhase() { +205 return ANALYSIS_PHASE; +206 } +207 //</editor-fold> +208 +209 /** +210 * Returns the key used in the properties file to reference the analyzer's +211 * enabled property. +212 * +213 * @return the analyzer's enabled property setting key +214 */ +215 @Override +216 protected String getAnalyzerEnabledSettingKey() { +217 return Settings.KEYS.ANALYZER_JAR_ENABLED; +218 } +219 +220 /** +221 * Loads a specified JAR file and collects information from the manifest and +222 * checksums to identify the correct CPE information. +223 * +224 * @param dependency the dependency to analyze. +225 * @param engine the engine that is scanning the dependencies +226 * @throws AnalysisException is thrown if there is an error reading the JAR +227 * file. +228 */ +229 @Override +230 public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { +231 try { +232 final List<ClassNameInformation> classNames = collectClassNames(dependency); +233 final String fileName = dependency.getFileName().toLowerCase(); +234 if (classNames.isEmpty() +235 && (fileName.endsWith("-sources.jar") +236 || fileName.endsWith("-javadoc.jar") +237 || fileName.endsWith("-src.jar") +238 || fileName.endsWith("-doc.jar"))) { +239 engine.getDependencies().remove(dependency); +240 } +241 final boolean hasManifest = parseManifest(dependency, classNames); +242 final boolean hasPOM = analyzePOM(dependency, classNames, engine); +243 final boolean addPackagesAsEvidence = !(hasManifest && hasPOM); +244 analyzePackageNames(classNames, dependency, addPackagesAsEvidence); +245 } catch (IOException ex) { +246 throw new AnalysisException("Exception occurred reading the JAR file.", ex); +247 } +248 } +249 +250 /** +251 * Attempts to find a pom.xml within the JAR file. If found it extracts +252 * information and adds it to the evidence. This will attempt to interpolate +253 * the strings contained within the pom.properties if one exists. +254 * +255 * @param dependency the dependency being analyzed +256 * @param classes a collection of class name information +257 * @param engine the analysis engine, used to add additional dependencies +258 * @throws AnalysisException is thrown if there is an exception parsing the +259 * pom +260 * @return whether or not evidence was added to the dependency +261 */ +262 protected boolean analyzePOM(Dependency dependency, List<ClassNameInformation> classes, Engine engine) throws AnalysisException { +263 boolean foundSomething = false; +264 final JarFile jar; +265 try { +266 jar = new JarFile(dependency.getActualFilePath()); +267 } catch (IOException ex) { +268 LOGGER.warn("Unable to read JarFile '{}'.", dependency.getActualFilePath()); +269 LOGGER.trace("", ex); +270 return false; +271 } +272 List<String> pomEntries; +273 try { +274 pomEntries = retrievePomListing(jar); +275 } catch (IOException ex) { +276 LOGGER.warn("Unable to read Jar file entries in '{}'.", dependency.getActualFilePath()); +277 LOGGER.trace("", ex); +278 return false; +279 } +280 File externalPom = null; +281 if (pomEntries.isEmpty()) { +282 final String pomPath = FilenameUtils.removeExtension(dependency.getActualFilePath()) + ".pom"; +283 externalPom = new File(pomPath); +284 if (externalPom.isFile()) { +285 pomEntries.add(pomPath); +286 } else { +287 return false; +288 } +289 } +290 for (String path : pomEntries) { +291 LOGGER.debug("Reading pom entry: {}", path); +292 Properties pomProperties = null; +293 try { +294 if (externalPom == null) { +295 pomProperties = retrievePomProperties(path, jar); +296 } +297 } catch (IOException ex) { +298 LOGGER.trace("ignore this, failed reading a non-existent pom.properties", ex); +299 } +300 Model pom = null; +301 try { +302 if (pomEntries.size() > 1) { +303 //extract POM to its own directory and add it as its own dependency +304 final Dependency newDependency = new Dependency(); +305 pom = extractPom(path, jar, newDependency); +306 +307 final String displayPath = String.format("%s%s%s", +308 dependency.getFilePath(), +309 File.separator, +310 path); +311 final String displayName = String.format("%s%s%s", +312 dependency.getFileName(), +313 File.separator, +314 path); +315 +316 newDependency.setFileName(displayName); +317 newDependency.setFilePath(displayPath); +318 pom.processProperties(pomProperties); +319 setPomEvidence(newDependency, pom, null); +320 engine.getDependencies().add(newDependency); +321 Collections.sort(engine.getDependencies()); +322 } else { +323 if (externalPom == null) { +324 pom = PomUtils.readPom(path, jar); +325 } else { +326 pom = PomUtils.readPom(externalPom); +327 } +328 pom.processProperties(pomProperties); +329 foundSomething |= setPomEvidence(dependency, pom, classes); +330 } +331 } catch (AnalysisException ex) { +332 LOGGER.warn("An error occurred while analyzing '{}'.", dependency.getActualFilePath()); +333 LOGGER.trace("", ex); +334 } +335 } +336 return foundSomething; +337 } +338 +339 /** +340 * Given a path to a pom.xml within a JarFile, this method attempts to load +341 * a sibling pom.properties if one exists. +342 * +343 * @param path the path to the pom.xml within the JarFile +344 * @param jar the JarFile to load the pom.properties from +345 * @return a Properties object or null if no pom.properties was found +346 * @throws IOException thrown if there is an exception reading the +347 * pom.properties +348 */ +349 private Properties retrievePomProperties(String path, final JarFile jar) throws IOException { +350 Properties pomProperties = null; +351 final String propPath = path.substring(0, path.length() - 7) + "pom.properies"; +352 final ZipEntry propEntry = jar.getEntry(propPath); +353 if (propEntry != null) { +354 Reader reader = null; +355 try { +356 reader = new InputStreamReader(jar.getInputStream(propEntry), "UTF-8"); +357 pomProperties = new Properties(); +358 pomProperties.load(reader); +359 LOGGER.debug("Read pom.properties: {}", propPath); +360 } finally { +361 if (reader != null) { +362 try { +363 reader.close(); +364 } catch (IOException ex) { +365 LOGGER.trace("close error", ex); +366 } +367 } +368 } +369 } +370 return pomProperties; +371 } +372 +373 /** +374 * Searches a JarFile for pom.xml entries and returns a listing of these +375 * entries. +376 * +377 * @param jar the JarFile to search +378 * @return a list of pom.xml entries +379 * @throws IOException thrown if there is an exception reading a JarEntry +380 */ +381 private List<String> retrievePomListing(final JarFile jar) throws IOException { +382 final List<String> pomEntries = new ArrayList<String>(); +383 final Enumeration<JarEntry> entries = jar.entries(); +384 while (entries.hasMoreElements()) { +385 final JarEntry entry = entries.nextElement(); +386 final String entryName = (new File(entry.getName())).getName().toLowerCase(); +387 if (!entry.isDirectory() && "pom.xml".equals(entryName)) { +388 LOGGER.trace("POM Entry found: {}", entry.getName()); +389 pomEntries.add(entry.getName()); +390 } +391 } +392 return pomEntries; +393 } +394 +395 /** +396 * Retrieves the specified POM from a jar file and converts it to a Model. +397 * +398 * @param path the path to the pom.xml file within the jar file +399 * @param jar the jar file to extract the pom from +400 * @param dependency the dependency being analyzed +401 * @return returns the POM object +402 * @throws AnalysisException is thrown if there is an exception extracting +403 * or parsing the POM {@link org.owasp.dependencycheck.xml.pom.Model} object +404 */ +405 private Model extractPom(String path, JarFile jar, Dependency dependency) throws AnalysisException { +406 InputStream input = null; +407 FileOutputStream fos = null; +408 final File tmpDir = getNextTempDirectory(); +409 final File file = new File(tmpDir, "pom.xml"); +410 try { +411 final ZipEntry entry = jar.getEntry(path); +412 input = jar.getInputStream(entry); +413 fos = new FileOutputStream(file); +414 IOUtils.copy(input, fos); +415 dependency.setActualFilePath(file.getAbsolutePath()); +416 } catch (IOException ex) { +417 LOGGER.warn("An error occurred reading '{}' from '{}'.", path, dependency.getFilePath()); +418 LOGGER.error("", ex); +419 } finally { +420 closeStream(fos); +421 closeStream(input); +422 } +423 return PomUtils.readPom(file); +424 } +425 +426 /** +427 * Silently closes an input stream ignoring errors. +428 * +429 * @param stream an input stream to close +430 */ +431 private void closeStream(InputStream stream) { +432 if (stream != null) { +433 try { +434 stream.close(); +435 } catch (IOException ex) { +436 LOGGER.trace("", ex); +437 } +438 } +439 } +440 +441 /** +442 * Silently closes an output stream ignoring errors. +443 * +444 * @param stream an output stream to close +445 */ +446 private void closeStream(OutputStream stream) { +447 if (stream != null) { +448 try { +449 stream.close(); +450 } catch (IOException ex) { +451 LOGGER.trace("", ex); +452 } +453 } +454 } +455 +456 /** +457 * Sets evidence from the pom on the supplied dependency. +458 * +459 * @param dependency the dependency to set data on +460 * @param pom the information from the pom +461 * @param classes a collection of ClassNameInformation - containing data +462 * about the fully qualified class names within the JAR file being analyzed +463 * @return true if there was evidence within the pom that we could use; +464 * otherwise false +465 */ +466 public static boolean setPomEvidence(Dependency dependency, Model pom, List<ClassNameInformation> classes) { +467 boolean foundSomething = false; +468 boolean addAsIdentifier = true; +469 if (pom == null) { +470 return foundSomething; +471 } +472 String groupid = pom.getGroupId(); +473 String parentGroupId = pom.getParentGroupId(); +474 String artifactid = pom.getArtifactId(); +475 String parentArtifactId = pom.getParentArtifactId(); +476 String version = pom.getVersion(); +477 String parentVersion = pom.getParentVersion(); +478 +479 if ("org.sonatype.oss".equals(parentGroupId) && "oss-parent".equals(parentArtifactId)) { +480 parentGroupId = null; +481 parentArtifactId = null; +482 parentVersion = null; +483 } +484 +485 if ((groupid == null || groupid.isEmpty()) && parentGroupId != null && !parentGroupId.isEmpty()) { +486 groupid = parentGroupId; +487 } +488 +489 final String originalGroupID = groupid; +490 if (groupid.startsWith("org.") || groupid.startsWith("com.")) { +491 groupid = groupid.substring(4); +492 } +493 +494 if ((artifactid == null || artifactid.isEmpty()) && parentArtifactId != null && !parentArtifactId.isEmpty()) { +495 artifactid = parentArtifactId; +496 } +497 +498 final String originalArtifactID = artifactid; +499 if (artifactid.startsWith("org.") || artifactid.startsWith("com.")) { +500 artifactid = artifactid.substring(4); +501 } +502 +503 if ((version == null || version.isEmpty()) && parentVersion != null && !parentVersion.isEmpty()) { +504 version = parentVersion; +505 } +506 +507 if (groupid != null && !groupid.isEmpty()) { +508 foundSomething = true; +509 dependency.getVendorEvidence().addEvidence("pom", "groupid", groupid, Confidence.HIGHEST); +510 dependency.getProductEvidence().addEvidence("pom", "groupid", groupid, Confidence.LOW); +511 addMatchingValues(classes, groupid, dependency.getVendorEvidence()); +512 addMatchingValues(classes, groupid, dependency.getProductEvidence()); +513 if (parentGroupId != null && !parentGroupId.isEmpty() && !parentGroupId.equals(groupid)) { +514 dependency.getVendorEvidence().addEvidence("pom", "parent-groupid", parentGroupId, Confidence.MEDIUM); +515 dependency.getProductEvidence().addEvidence("pom", "parent-groupid", parentGroupId, Confidence.LOW); +516 addMatchingValues(classes, parentGroupId, dependency.getVendorEvidence()); +517 addMatchingValues(classes, parentGroupId, dependency.getProductEvidence()); +518 } +519 } else { +520 addAsIdentifier = false; +521 } +522 +523 if (artifactid != null && !artifactid.isEmpty()) { +524 foundSomething = true; +525 dependency.getProductEvidence().addEvidence("pom", "artifactid", artifactid, Confidence.HIGHEST); +526 dependency.getVendorEvidence().addEvidence("pom", "artifactid", artifactid, Confidence.LOW); +527 addMatchingValues(classes, artifactid, dependency.getVendorEvidence()); +528 addMatchingValues(classes, artifactid, dependency.getProductEvidence()); +529 if (parentArtifactId != null && !parentArtifactId.isEmpty() && !parentArtifactId.equals(artifactid)) { +530 dependency.getProductEvidence().addEvidence("pom", "parent-artifactid", parentArtifactId, Confidence.MEDIUM); +531 dependency.getVendorEvidence().addEvidence("pom", "parent-artifactid", parentArtifactId, Confidence.LOW); +532 addMatchingValues(classes, parentArtifactId, dependency.getVendorEvidence()); +533 addMatchingValues(classes, parentArtifactId, dependency.getProductEvidence()); +534 } +535 } else { +536 addAsIdentifier = false; +537 } +538 +539 if (version != null && !version.isEmpty()) { +540 foundSomething = true; +541 dependency.getVersionEvidence().addEvidence("pom", "version", version, Confidence.HIGHEST); +542 if (parentVersion != null && !parentVersion.isEmpty() && !parentVersion.equals(version)) { +543 dependency.getVersionEvidence().addEvidence("pom", "parent-version", version, Confidence.LOW); +544 } +545 } else { +546 addAsIdentifier = false; +547 } +548 +549 if (addAsIdentifier) { +550 dependency.addIdentifier("maven", String.format("%s:%s:%s", originalGroupID, originalArtifactID, version), null, Confidence.HIGH); +551 } +552 +553 // org name +554 final String org = pom.getOrganization(); +555 if (org != null && !org.isEmpty()) { +556 dependency.getVendorEvidence().addEvidence("pom", "organization name", org, Confidence.HIGH); +557 dependency.getProductEvidence().addEvidence("pom", "organization name", org, Confidence.LOW); +558 addMatchingValues(classes, org, dependency.getVendorEvidence()); +559 addMatchingValues(classes, org, dependency.getProductEvidence()); +560 } +561 //pom name +562 final String pomName = pom.getName(); +563 if (pomName +564 != null && !pomName.isEmpty()) { +565 foundSomething = true; +566 dependency.getProductEvidence().addEvidence("pom", "name", pomName, Confidence.HIGH); +567 dependency.getVendorEvidence().addEvidence("pom", "name", pomName, Confidence.HIGH); +568 addMatchingValues(classes, pomName, dependency.getVendorEvidence()); +569 addMatchingValues(classes, pomName, dependency.getProductEvidence()); +570 } +571 +572 //Description +573 final String description = pom.getDescription(); +574 if (description != null && !description.isEmpty() && !description.startsWith("POM was created by")) { +575 foundSomething = true; +576 final String trimmedDescription = addDescription(dependency, description, "pom", "description"); +577 addMatchingValues(classes, trimmedDescription, dependency.getVendorEvidence()); +578 addMatchingValues(classes, trimmedDescription, dependency.getProductEvidence()); +579 } +580 +581 final String projectURL = pom.getProjectURL(); +582 if (projectURL != null && !projectURL.trim().isEmpty()) { +583 dependency.getVendorEvidence().addEvidence("pom", "url", projectURL, Confidence.HIGHEST); +584 } +585 +586 extractLicense(pom, dependency); +587 return foundSomething; +588 } +589 +590 /** +591 * Analyzes the path information of the classes contained within the +592 * JarAnalyzer to try and determine possible vendor or product names. If any +593 * are found they are stored in the packageVendor and packageProduct +594 * hashSets. +595 * +596 * @param classNames a list of class names +597 * @param dependency a dependency to analyze +598 * @param addPackagesAsEvidence a flag indicating whether or not package +599 * names should be added as evidence. +600 */ +601 protected void analyzePackageNames(List<ClassNameInformation> classNames, +602 Dependency dependency, boolean addPackagesAsEvidence) { +603 final Map<String, Integer> vendorIdentifiers = new HashMap<String, Integer>(); +604 final Map<String, Integer> productIdentifiers = new HashMap<String, Integer>(); +605 analyzeFullyQualifiedClassNames(classNames, vendorIdentifiers, productIdentifiers); +606 +607 final int classCount = classNames.size(); +608 final EvidenceCollection vendor = dependency.getVendorEvidence(); +609 final EvidenceCollection product = dependency.getProductEvidence(); +610 +611 for (Map.Entry<String, Integer> entry : vendorIdentifiers.entrySet()) { +612 final float ratio = entry.getValue() / (float) classCount; +613 if (ratio > 0.5) { +614 //TODO remove weighting +615 vendor.addWeighting(entry.getKey()); +616 if (addPackagesAsEvidence && entry.getKey().length() > 1) { +617 vendor.addEvidence("jar", "package name", entry.getKey(), Confidence.LOW); +618 } +619 } +620 } +621 for (Map.Entry<String, Integer> entry : productIdentifiers.entrySet()) { +622 final float ratio = entry.getValue() / (float) classCount; +623 if (ratio > 0.5) { +624 product.addWeighting(entry.getKey()); +625 if (addPackagesAsEvidence && entry.getKey().length() > 1) { +626 product.addEvidence("jar", "package name", entry.getKey(), Confidence.LOW); +627 } +628 } +629 } +630 } +631 +632 /** +633 * <p> +634 * Reads the manifest from the JAR file and collects the entries. Some +635 * vendorKey entries are:</p> +636 * <ul><li>Implementation Title</li> +637 * <li>Implementation Version</li> <li>Implementation Vendor</li> +638 * <li>Implementation VendorId</li> <li>Bundle Name</li> <li>Bundle +639 * Version</li> <li>Bundle Vendor</li> <li>Bundle Description</li> <li>Main +640 * Class</li> </ul> +641 * However, all but a handful of specific entries are read in. +642 * +643 * @param dependency A reference to the dependency +644 * @param classInformation a collection of class information +645 * @return whether evidence was identified parsing the manifest +646 * @throws IOException if there is an issue reading the JAR file +647 */ +648 protected boolean parseManifest(Dependency dependency, List<ClassNameInformation> classInformation) throws IOException { +649 boolean foundSomething = false; +650 JarFile jar = null; +651 try { +652 jar = new JarFile(dependency.getActualFilePath()); +653 final Manifest manifest = jar.getManifest(); +654 if (manifest == null) { +655 if (!dependency.getFileName().toLowerCase().endsWith("-sources.jar") +656 && !dependency.getFileName().toLowerCase().endsWith("-javadoc.jar") +657 && !dependency.getFileName().toLowerCase().endsWith("-src.jar") +658 && !dependency.getFileName().toLowerCase().endsWith("-doc.jar")) { +659 LOGGER.debug("Jar file '{}' does not contain a manifest.", +660 dependency.getFileName()); +661 } +662 return false; +663 } +664 final EvidenceCollection vendorEvidence = dependency.getVendorEvidence(); +665 final EvidenceCollection productEvidence = dependency.getProductEvidence(); +666 final EvidenceCollection versionEvidence = dependency.getVersionEvidence(); +667 String source = "Manifest"; +668 String specificationVersion = null; +669 boolean hasImplementationVersion = false; +670 Attributes atts = manifest.getMainAttributes(); +671 for (Entry<Object, Object> entry : atts.entrySet()) { +672 String key = entry.getKey().toString(); +673 String value = atts.getValue(key); +674 if (HTML_DETECTION_PATTERN.matcher(value).find()) { +675 value = Jsoup.parse(value).text(); +676 } +677 if (IGNORE_VALUES.contains(value)) { +678 continue; +679 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_TITLE.toString())) { +680 foundSomething = true; +681 productEvidence.addEvidence(source, key, value, Confidence.HIGH); +682 addMatchingValues(classInformation, value, productEvidence); +683 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VERSION.toString())) { +684 hasImplementationVersion = true; +685 foundSomething = true; +686 versionEvidence.addEvidence(source, key, value, Confidence.HIGH); +687 } else if ("specification-version".equalsIgnoreCase(key)) { +688 specificationVersion = key; +689 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VENDOR.toString())) { +690 foundSomething = true; +691 vendorEvidence.addEvidence(source, key, value, Confidence.HIGH); +692 addMatchingValues(classInformation, value, vendorEvidence); +693 } else if (key.equalsIgnoreCase(IMPLEMENTATION_VENDOR_ID)) { +694 foundSomething = true; +695 vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +696 addMatchingValues(classInformation, value, vendorEvidence); +697 } else if (key.equalsIgnoreCase(BUNDLE_DESCRIPTION)) { +698 foundSomething = true; +699 addDescription(dependency, value, "manifest", key); +700 addMatchingValues(classInformation, value, productEvidence); +701 } else if (key.equalsIgnoreCase(BUNDLE_NAME)) { +702 foundSomething = true; +703 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +704 addMatchingValues(classInformation, value, productEvidence); +705 // //the following caused false positives. +706 // } else if (key.equalsIgnoreCase(BUNDLE_VENDOR)) { +707 // foundSomething = true; +708 // vendorEvidence.addEvidence(source, key, value, Confidence.HIGH); +709 // addMatchingValues(classInformation, value, vendorEvidence); +710 } else if (key.equalsIgnoreCase(BUNDLE_VERSION)) { +711 foundSomething = true; +712 versionEvidence.addEvidence(source, key, value, Confidence.HIGH); +713 } else if (key.equalsIgnoreCase(Attributes.Name.MAIN_CLASS.toString())) { +714 continue; +715 //skipping main class as if this has important information to add +716 // it will be added during class name analysis... if other fields +717 // have the information from the class name then they will get added... +718 } else { +719 key = key.toLowerCase(); +720 if (!IGNORE_KEYS.contains(key) +721 && !key.endsWith("jdk") +722 && !key.contains("lastmodified") +723 && !key.endsWith("package") +724 && !key.endsWith("classpath") +725 && !key.endsWith("class-path") +726 && !key.endsWith("-scm") //todo change this to a regex? +727 && !key.startsWith("scm-") +728 && !value.trim().startsWith("scm:") +729 && !isImportPackage(key, value) +730 && !isPackage(key, value)) { +731 foundSomething = true; +732 if (key.contains("version")) { +733 if (!key.contains("specification")) { +734 versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +735 } +736 } else if ("build-id".equals(key)) { +737 int pos = value.indexOf('('); +738 if (pos >= 0) { +739 value = value.substring(0, pos - 1); +740 } +741 pos = value.indexOf('['); +742 if (pos >= 0) { +743 value = value.substring(0, pos - 1); +744 } +745 versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +746 } else if (key.contains("title")) { +747 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +748 addMatchingValues(classInformation, value, productEvidence); +749 } else if (key.contains("vendor")) { +750 if (key.contains("specification")) { +751 vendorEvidence.addEvidence(source, key, value, Confidence.LOW); +752 } else { +753 vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +754 addMatchingValues(classInformation, value, vendorEvidence); +755 } +756 } else if (key.contains("name")) { +757 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +758 vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +759 addMatchingValues(classInformation, value, vendorEvidence); +760 addMatchingValues(classInformation, value, productEvidence); +761 } else if (key.contains("license")) { +762 addLicense(dependency, value); +763 } else if (key.contains("description")) { +764 addDescription(dependency, value, "manifest", key); +765 } else { +766 productEvidence.addEvidence(source, key, value, Confidence.LOW); +767 vendorEvidence.addEvidence(source, key, value, Confidence.LOW); +768 addMatchingValues(classInformation, value, vendorEvidence); +769 addMatchingValues(classInformation, value, productEvidence); +770 if (value.matches(".*\\d.*")) { +771 final StringTokenizer tokenizer = new StringTokenizer(value, " "); +772 while (tokenizer.hasMoreElements()) { +773 final String s = tokenizer.nextToken(); +774 if (s.matches("^[0-9.]+$")) { +775 versionEvidence.addEvidence(source, key, s, Confidence.LOW); +776 } +777 } +778 } +779 } +780 } +781 } +782 } +783 for (Map.Entry<String, Attributes> item : manifest.getEntries().entrySet()) { +784 final String name = item.getKey(); +785 source = "manifest: " + name; +786 atts = item.getValue(); +787 for (Entry<Object, Object> entry : atts.entrySet()) { +788 final String key = entry.getKey().toString(); +789 final String value = atts.getValue(key); +790 if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_TITLE.toString())) { +791 foundSomething = true; +792 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +793 addMatchingValues(classInformation, value, productEvidence); +794 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VERSION.toString())) { +795 foundSomething = true; +796 versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +797 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VENDOR.toString())) { 798 foundSomething = true; -799 versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -800 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VENDOR.toString())) { -801 foundSomething = true; -802 vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -803 addMatchingValues(classInformation, value, vendorEvidence); -804 } else if (key.equalsIgnoreCase(Attributes.Name.SPECIFICATION_TITLE.toString())) { -805 foundSomething = true; -806 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -807 addMatchingValues(classInformation, value, productEvidence); -808 } -809 } -810 } -811 if (specificationVersion != null && !hasImplementationVersion) { -812 foundSomething = true; -813 versionEvidence.addEvidence(source, "specification-version", specificationVersion, Confidence.HIGH); -814 } -815 } finally { -816 if (jar != null) { -817 jar.close(); -818 } -819 } -820 return foundSomething; -821 } -822 -823 /** -824 * Adds a description to the given dependency. If the description contains -825 * one of the following strings beyond 100 characters, then the description -826 * used will be trimmed to that position: -827 * <ul><li>"such as"</li><li>"like "</li><li>"will use "</li><li>"* uses -828 * "</li></ul> -829 * -830 * @param dependency a dependency -831 * @param description the description -832 * @param source the source of the evidence -833 * @param key the "name" of the evidence -834 * @return if the description is trimmed, the trimmed version is returned; -835 * otherwise the original description is returned -836 */ -837 public static String addDescription(Dependency dependency, String description, String source, String key) { -838 if (dependency.getDescription() == null) { -839 dependency.setDescription(description); -840 } -841 String desc; -842 if (HTML_DETECTION_PATTERN.matcher(description).find()) { -843 desc = Jsoup.parse(description).text(); -844 } else { -845 desc = description; -846 } -847 dependency.setDescription(desc); -848 if (desc.length() > 100) { -849 desc = desc.replaceAll("\\s\\s+", " "); -850 final int posSuchAs = desc.toLowerCase().indexOf("such as ", 100); -851 final int posLike = desc.toLowerCase().indexOf("like ", 100); -852 final int posWillUse = desc.toLowerCase().indexOf("will use ", 100); -853 final int posUses = desc.toLowerCase().indexOf(" uses ", 100); -854 int pos = -1; -855 pos = Math.max(pos, posSuchAs); -856 if (pos >= 0 && posLike >= 0) { -857 pos = Math.min(pos, posLike); -858 } else { -859 pos = Math.max(pos, posLike); -860 } -861 if (pos >= 0 && posWillUse >= 0) { -862 pos = Math.min(pos, posWillUse); -863 } else { -864 pos = Math.max(pos, posWillUse); -865 } -866 if (pos >= 0 && posUses >= 0) { -867 pos = Math.min(pos, posUses); -868 } else { -869 pos = Math.max(pos, posUses); -870 } -871 -872 if (pos > 0) { -873 desc = desc.substring(0, pos) + "..."; -874 } -875 dependency.getProductEvidence().addEvidence(source, key, desc, Confidence.LOW); -876 dependency.getVendorEvidence().addEvidence(source, key, desc, Confidence.LOW); -877 } else { -878 dependency.getProductEvidence().addEvidence(source, key, desc, Confidence.MEDIUM); -879 dependency.getVendorEvidence().addEvidence(source, key, desc, Confidence.MEDIUM); -880 } -881 return desc; -882 } -883 -884 /** -885 * Adds a license to the given dependency. -886 * -887 * @param d a dependency -888 * @param license the license -889 */ -890 private void addLicense(Dependency d, String license) { -891 if (d.getLicense() == null) { -892 d.setLicense(license); -893 } else if (!d.getLicense().contains(license)) { -894 d.setLicense(d.getLicense() + NEWLINE + license); -895 } -896 } -897 -898 /** -899 * The parent directory for the individual directories per archive. -900 */ -901 private File tempFileLocation = null; -902 -903 /** -904 * Initializes the JarAnalyzer. -905 * -906 * @throws Exception is thrown if there is an exception creating a temporary -907 * directory -908 */ -909 @Override -910 public void initializeFileTypeAnalyzer() throws Exception { -911 final File baseDir = Settings.getTempDirectory(); -912 tempFileLocation = File.createTempFile("check", "tmp", baseDir); -913 if (!tempFileLocation.delete()) { -914 final String msg = String.format("Unable to delete temporary file '%s'.", tempFileLocation.getAbsolutePath()); -915 throw new AnalysisException(msg); -916 } -917 if (!tempFileLocation.mkdirs()) { -918 final String msg = String.format("Unable to create directory '%s'.", tempFileLocation.getAbsolutePath()); -919 throw new AnalysisException(msg); -920 } -921 } -922 -923 /** -924 * Deletes any files extracted from the JAR during analysis. -925 */ -926 @Override -927 public void close() { -928 if (tempFileLocation != null && tempFileLocation.exists()) { -929 LOGGER.debug("Attempting to delete temporary files"); -930 final boolean success = FileUtils.delete(tempFileLocation); -931 if (!success) { -932 LOGGER.warn("Failed to delete some temporary files, see the log for more details"); -933 } -934 } -935 } -936 -937 /** -938 * Determines if the key value pair from the manifest is for an "import" -939 * type entry for package names. -940 * -941 * @param key the key from the manifest -942 * @param value the value from the manifest -943 * @return true or false depending on if it is believed the entry is an -944 * "import" entry -945 */ -946 private boolean isImportPackage(String key, String value) { -947 final Pattern packageRx = Pattern.compile("^([a-zA-Z0-9_#\\$\\*\\.]+\\s*[,;]\\s*)+([a-zA-Z0-9_#\\$\\*\\.]+\\s*)?$"); -948 final boolean matches = packageRx.matcher(value).matches(); -949 return matches && (key.contains("import") || key.contains("include") || value.length() > 10); -950 } -951 -952 /** -953 * Cycles through an enumeration of JarEntries, contained within the -954 * dependency, and returns a list of the class names. This does not include -955 * core Java package names (i.e. java.* or javax.*). -956 * -957 * @param dependency the dependency being analyzed -958 * @return an list of fully qualified class names -959 */ -960 private List<ClassNameInformation> collectClassNames(Dependency dependency) { -961 final List<ClassNameInformation> classNames = new ArrayList<ClassNameInformation>(); -962 JarFile jar = null; -963 try { -964 jar = new JarFile(dependency.getActualFilePath()); -965 final Enumeration<JarEntry> entries = jar.entries(); -966 while (entries.hasMoreElements()) { -967 final JarEntry entry = entries.nextElement(); -968 final String name = entry.getName().toLowerCase(); -969 //no longer stripping "|com\\.sun" - there are some com.sun jar files with CVEs. -970 if (name.endsWith(".class") && !name.matches("^javax?\\..*$")) { -971 final ClassNameInformation className = new ClassNameInformation(name.substring(0, name.length() - 6)); -972 classNames.add(className); -973 } -974 } -975 } catch (IOException ex) { -976 LOGGER.warn("Unable to open jar file '{}'.", dependency.getFileName()); -977 LOGGER.debug("", ex); -978 } finally { -979 if (jar != null) { -980 try { -981 jar.close(); -982 } catch (IOException ex) { -983 LOGGER.trace("", ex); -984 } -985 } -986 } -987 return classNames; -988 } -989 -990 /** -991 * Cycles through the list of class names and places the package levels 0-3 -992 * into the provided maps for vendor and product. This is helpful when -993 * analyzing vendor/product as many times this is included in the package -994 * name. -995 * -996 * @param classNames a list of class names -997 * @param vendor HashMap of possible vendor names from package names (e.g. -998 * owasp) -999 * @param product HashMap of possible product names from package names (e.g. -1000 * dependencycheck) -1001 */ -1002 private void analyzeFullyQualifiedClassNames(List<ClassNameInformation> classNames, -1003 Map<String, Integer> vendor, Map<String, Integer> product) { -1004 for (ClassNameInformation entry : classNames) { -1005 final List<String> list = entry.getPackageStructure(); -1006 addEntry(vendor, list.get(0)); -1007 -1008 if (list.size() == 2) { -1009 addEntry(product, list.get(1)); -1010 } -1011 if (list.size() == 3) { -1012 addEntry(vendor, list.get(1)); +799 vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +800 addMatchingValues(classInformation, value, vendorEvidence); +801 } else if (key.equalsIgnoreCase(Attributes.Name.SPECIFICATION_TITLE.toString())) { +802 foundSomething = true; +803 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +804 addMatchingValues(classInformation, value, productEvidence); +805 } +806 } +807 } +808 if (specificationVersion != null && !hasImplementationVersion) { +809 foundSomething = true; +810 versionEvidence.addEvidence(source, "specification-version", specificationVersion, Confidence.HIGH); +811 } +812 } finally { +813 if (jar != null) { +814 jar.close(); +815 } +816 } +817 return foundSomething; +818 } +819 +820 /** +821 * Adds a description to the given dependency. If the description contains +822 * one of the following strings beyond 100 characters, then the description +823 * used will be trimmed to that position: +824 * <ul><li>"such as"</li><li>"like "</li><li>"will use "</li><li>"* uses +825 * "</li></ul> +826 * +827 * @param dependency a dependency +828 * @param description the description +829 * @param source the source of the evidence +830 * @param key the "name" of the evidence +831 * @return if the description is trimmed, the trimmed version is returned; +832 * otherwise the original description is returned +833 */ +834 public static String addDescription(Dependency dependency, String description, String source, String key) { +835 if (dependency.getDescription() == null) { +836 dependency.setDescription(description); +837 } +838 String desc; +839 if (HTML_DETECTION_PATTERN.matcher(description).find()) { +840 desc = Jsoup.parse(description).text(); +841 } else { +842 desc = description; +843 } +844 dependency.setDescription(desc); +845 if (desc.length() > 100) { +846 desc = desc.replaceAll("\\s\\s+", " "); +847 final int posSuchAs = desc.toLowerCase().indexOf("such as ", 100); +848 final int posLike = desc.toLowerCase().indexOf("like ", 100); +849 final int posWillUse = desc.toLowerCase().indexOf("will use ", 100); +850 final int posUses = desc.toLowerCase().indexOf(" uses ", 100); +851 int pos = -1; +852 pos = Math.max(pos, posSuchAs); +853 if (pos >= 0 && posLike >= 0) { +854 pos = Math.min(pos, posLike); +855 } else { +856 pos = Math.max(pos, posLike); +857 } +858 if (pos >= 0 && posWillUse >= 0) { +859 pos = Math.min(pos, posWillUse); +860 } else { +861 pos = Math.max(pos, posWillUse); +862 } +863 if (pos >= 0 && posUses >= 0) { +864 pos = Math.min(pos, posUses); +865 } else { +866 pos = Math.max(pos, posUses); +867 } +868 +869 if (pos > 0) { +870 desc = desc.substring(0, pos) + "..."; +871 } +872 dependency.getProductEvidence().addEvidence(source, key, desc, Confidence.LOW); +873 dependency.getVendorEvidence().addEvidence(source, key, desc, Confidence.LOW); +874 } else { +875 dependency.getProductEvidence().addEvidence(source, key, desc, Confidence.MEDIUM); +876 dependency.getVendorEvidence().addEvidence(source, key, desc, Confidence.MEDIUM); +877 } +878 return desc; +879 } +880 +881 /** +882 * Adds a license to the given dependency. +883 * +884 * @param d a dependency +885 * @param license the license +886 */ +887 private void addLicense(Dependency d, String license) { +888 if (d.getLicense() == null) { +889 d.setLicense(license); +890 } else if (!d.getLicense().contains(license)) { +891 d.setLicense(d.getLicense() + NEWLINE + license); +892 } +893 } +894 +895 /** +896 * The parent directory for the individual directories per archive. +897 */ +898 private File tempFileLocation = null; +899 +900 /** +901 * Initializes the JarAnalyzer. +902 * +903 * @throws InitializationException is thrown if there is an exception +904 * creating a temporary directory +905 */ +906 @Override +907 public void initializeFileTypeAnalyzer() throws InitializationException { +908 try { +909 final File baseDir = Settings.getTempDirectory(); +910 tempFileLocation = File.createTempFile("check", "tmp", baseDir); +911 if (!tempFileLocation.delete()) { +912 final String msg = String.format("Unable to delete temporary file '%s'.", tempFileLocation.getAbsolutePath()); +913 setEnabled(false); +914 throw new InitializationException(msg); +915 } +916 if (!tempFileLocation.mkdirs()) { +917 final String msg = String.format("Unable to create directory '%s'.", tempFileLocation.getAbsolutePath()); +918 setEnabled(false); +919 throw new InitializationException(msg); +920 } +921 } catch (IOException ex) { +922 setEnabled(false); +923 throw new InitializationException("Unable to create a temporary file", ex); +924 } +925 } +926 +927 /** +928 * Deletes any files extracted from the JAR during analysis. +929 */ +930 @Override +931 public void close() { +932 if (tempFileLocation != null && tempFileLocation.exists()) { +933 LOGGER.debug("Attempting to delete temporary files"); +934 final boolean success = FileUtils.delete(tempFileLocation); +935 if (!success) { +936 LOGGER.warn("Failed to delete some temporary files, see the log for more details"); +937 } +938 } +939 } +940 +941 /** +942 * Determines if the key value pair from the manifest is for an "import" +943 * type entry for package names. +944 * +945 * @param key the key from the manifest +946 * @param value the value from the manifest +947 * @return true or false depending on if it is believed the entry is an +948 * "import" entry +949 */ +950 private boolean isImportPackage(String key, String value) { +951 final Pattern packageRx = Pattern.compile("^([a-zA-Z0-9_#\\$\\*\\.]+\\s*[,;]\\s*)+([a-zA-Z0-9_#\\$\\*\\.]+\\s*)?$"); +952 final boolean matches = packageRx.matcher(value).matches(); +953 return matches && (key.contains("import") || key.contains("include") || value.length() > 10); +954 } +955 +956 /** +957 * Cycles through an enumeration of JarEntries, contained within the +958 * dependency, and returns a list of the class names. This does not include +959 * core Java package names (i.e. java.* or javax.*). +960 * +961 * @param dependency the dependency being analyzed +962 * @return an list of fully qualified class names +963 */ +964 private List<ClassNameInformation> collectClassNames(Dependency dependency) { +965 final List<ClassNameInformation> classNames = new ArrayList<ClassNameInformation>(); +966 JarFile jar = null; +967 try { +968 jar = new JarFile(dependency.getActualFilePath()); +969 final Enumeration<JarEntry> entries = jar.entries(); +970 while (entries.hasMoreElements()) { +971 final JarEntry entry = entries.nextElement(); +972 final String name = entry.getName().toLowerCase(); +973 //no longer stripping "|com\\.sun" - there are some com.sun jar files with CVEs. +974 if (name.endsWith(".class") && !name.matches("^javax?\\..*$")) { +975 final ClassNameInformation className = new ClassNameInformation(name.substring(0, name.length() - 6)); +976 classNames.add(className); +977 } +978 } +979 } catch (IOException ex) { +980 LOGGER.warn("Unable to open jar file '{}'.", dependency.getFileName()); +981 LOGGER.debug("", ex); +982 } finally { +983 if (jar != null) { +984 try { +985 jar.close(); +986 } catch (IOException ex) { +987 LOGGER.trace("", ex); +988 } +989 } +990 } +991 return classNames; +992 } +993 +994 /** +995 * Cycles through the list of class names and places the package levels 0-3 +996 * into the provided maps for vendor and product. This is helpful when +997 * analyzing vendor/product as many times this is included in the package +998 * name. +999 * +1000 * @param classNames a list of class names +1001 * @param vendor HashMap of possible vendor names from package names (e.g. +1002 * owasp) +1003 * @param product HashMap of possible product names from package names (e.g. +1004 * dependencycheck) +1005 */ +1006 private void analyzeFullyQualifiedClassNames(List<ClassNameInformation> classNames, +1007 Map<String, Integer> vendor, Map<String, Integer> product) { +1008 for (ClassNameInformation entry : classNames) { +1009 final List<String> list = entry.getPackageStructure(); +1010 addEntry(vendor, list.get(0)); +1011 +1012 if (list.size() == 2) { 1013 addEntry(product, list.get(1)); -1014 addEntry(product, list.get(2)); -1015 } -1016 if (list.size() >= 4) { -1017 addEntry(vendor, list.get(1)); -1018 addEntry(vendor, list.get(2)); -1019 addEntry(product, list.get(1)); -1020 addEntry(product, list.get(2)); -1021 addEntry(product, list.get(3)); -1022 } -1023 } -1024 } -1025 -1026 /** -1027 * Adds an entry to the specified collection and sets the Integer (e.g. the -1028 * count) to 1. If the entry already exists in the collection then the -1029 * Integer is incremented by 1. -1030 * -1031 * @param collection a collection of strings and their occurrence count -1032 * @param key the key to add to the collection -1033 */ -1034 private void addEntry(Map<String, Integer> collection, String key) { -1035 if (collection.containsKey(key)) { -1036 collection.put(key, collection.get(key) + 1); -1037 } else { -1038 collection.put(key, 1); -1039 } -1040 } -1041 -1042 /** -1043 * Cycles through the collection of class name information to see if parts -1044 * of the package names are contained in the provided value. If found, it -1045 * will be added as the HIGHEST confidence evidence because we have more -1046 * then one source corroborating the value. -1047 * -1048 * @param classes a collection of class name information -1049 * @param value the value to check to see if it contains a package name -1050 * @param evidence the evidence collection to add new entries too -1051 */ -1052 private static void addMatchingValues(List<ClassNameInformation> classes, String value, EvidenceCollection evidence) { -1053 if (value == null || value.isEmpty() || classes == null || classes.isEmpty()) { -1054 return; -1055 } -1056 final String text = value.toLowerCase(); -1057 for (ClassNameInformation cni : classes) { -1058 for (String key : cni.getPackageStructure()) { -1059 final Pattern p = Pattern.compile("\b" + key + "\b"); -1060 if (p.matcher(text).find()) { -1061 //if (text.contains(key)) { //note, package structure elements are already lowercase. -1062 evidence.addEvidence("jar", "package name", key, Confidence.HIGHEST); -1063 } -1064 } -1065 } -1066 } -1067 -1068 /** -1069 * Simple check to see if the attribute from a manifest is just a package -1070 * name. -1071 * -1072 * @param key the key of the value to check -1073 * @param value the value to check -1074 * @return true if the value looks like a java package name, otherwise false -1075 */ -1076 private boolean isPackage(String key, String value) { -1077 -1078 return !key.matches(".*(version|title|vendor|name|license|description).*") -1079 && value.matches("^([a-zA-Z_][a-zA-Z0-9_\\$]*(\\.[a-zA-Z_][a-zA-Z0-9_\\$]*)*)?$"); -1080 -1081 } -1082 -1083 /** -1084 * Extracts the license information from the pom and adds it to the -1085 * dependency. -1086 * -1087 * @param pom the pom object -1088 * @param dependency the dependency to add license information too -1089 */ -1090 public static void extractLicense(Model pom, Dependency dependency) { -1091 //license -1092 if (pom.getLicenses() != null) { -1093 String license = null; -1094 for (License lic : pom.getLicenses()) { -1095 String tmp = null; -1096 if (lic.getName() != null) { -1097 tmp = lic.getName(); -1098 } -1099 if (lic.getUrl() != null) { -1100 if (tmp == null) { -1101 tmp = lic.getUrl(); -1102 } else { -1103 tmp += ": " + lic.getUrl(); -1104 } -1105 } -1106 if (tmp == null) { -1107 continue; -1108 } -1109 if (HTML_DETECTION_PATTERN.matcher(tmp).find()) { -1110 tmp = Jsoup.parse(tmp).text(); -1111 } -1112 if (license == null) { -1113 license = tmp; -1114 } else { -1115 license += "\n" + tmp; -1116 } -1117 } -1118 if (license != null) { -1119 dependency.setLicense(license); -1120 +1014 } +1015 if (list.size() == 3) { +1016 addEntry(vendor, list.get(1)); +1017 addEntry(product, list.get(1)); +1018 addEntry(product, list.get(2)); +1019 } +1020 if (list.size() >= 4) { +1021 addEntry(vendor, list.get(1)); +1022 addEntry(vendor, list.get(2)); +1023 addEntry(product, list.get(1)); +1024 addEntry(product, list.get(2)); +1025 addEntry(product, list.get(3)); +1026 } +1027 } +1028 } +1029 +1030 /** +1031 * Adds an entry to the specified collection and sets the Integer (e.g. the +1032 * count) to 1. If the entry already exists in the collection then the +1033 * Integer is incremented by 1. +1034 * +1035 * @param collection a collection of strings and their occurrence count +1036 * @param key the key to add to the collection +1037 */ +1038 private void addEntry(Map<String, Integer> collection, String key) { +1039 if (collection.containsKey(key)) { +1040 collection.put(key, collection.get(key) + 1); +1041 } else { +1042 collection.put(key, 1); +1043 } +1044 } +1045 +1046 /** +1047 * Cycles through the collection of class name information to see if parts +1048 * of the package names are contained in the provided value. If found, it +1049 * will be added as the HIGHEST confidence evidence because we have more +1050 * then one source corroborating the value. +1051 * +1052 * @param classes a collection of class name information +1053 * @param value the value to check to see if it contains a package name +1054 * @param evidence the evidence collection to add new entries too +1055 */ +1056 private static void addMatchingValues(List<ClassNameInformation> classes, String value, EvidenceCollection evidence) { +1057 if (value == null || value.isEmpty() || classes == null || classes.isEmpty()) { +1058 return; +1059 } +1060 final String text = value.toLowerCase(); +1061 for (ClassNameInformation cni : classes) { +1062 for (String key : cni.getPackageStructure()) { +1063 final Pattern p = Pattern.compile("\b" + key + "\b"); +1064 if (p.matcher(text).find()) { +1065 //if (text.contains(key)) { //note, package structure elements are already lowercase. +1066 evidence.addEvidence("jar", "package name", key, Confidence.HIGHEST); +1067 } +1068 } +1069 } +1070 } +1071 +1072 /** +1073 * Simple check to see if the attribute from a manifest is just a package +1074 * name. +1075 * +1076 * @param key the key of the value to check +1077 * @param value the value to check +1078 * @return true if the value looks like a java package name, otherwise false +1079 */ +1080 private boolean isPackage(String key, String value) { +1081 +1082 return !key.matches(".*(version|title|vendor|name|license|description).*") +1083 && value.matches("^([a-zA-Z_][a-zA-Z0-9_\\$]*(\\.[a-zA-Z_][a-zA-Z0-9_\\$]*)*)?$"); +1084 +1085 } +1086 +1087 /** +1088 * Extracts the license information from the pom and adds it to the +1089 * dependency. +1090 * +1091 * @param pom the pom object +1092 * @param dependency the dependency to add license information too +1093 */ +1094 public static void extractLicense(Model pom, Dependency dependency) { +1095 //license +1096 if (pom.getLicenses() != null) { +1097 String license = null; +1098 for (License lic : pom.getLicenses()) { +1099 String tmp = null; +1100 if (lic.getName() != null) { +1101 tmp = lic.getName(); +1102 } +1103 if (lic.getUrl() != null) { +1104 if (tmp == null) { +1105 tmp = lic.getUrl(); +1106 } else { +1107 tmp += ": " + lic.getUrl(); +1108 } +1109 } +1110 if (tmp == null) { +1111 continue; +1112 } +1113 if (HTML_DETECTION_PATTERN.matcher(tmp).find()) { +1114 tmp = Jsoup.parse(tmp).text(); +1115 } +1116 if (license == null) { +1117 license = tmp; +1118 } else { +1119 license += "\n" + tmp; +1120 } 1121 } -1122 } -1123 } +1122 if (license != null) { +1123 dependency.setLicense(license); 1124 -1125 /** -1126 * Stores information about a class name. -1127 */ -1128 protected static class ClassNameInformation { -1129 -1130 /** -1131 * <p> -1132 * Stores information about a given class name. This class will keep the -1133 * fully qualified class name and a list of the important parts of the -1134 * package structure. Up to the first four levels of the package -1135 * structure are stored, excluding a leading "org" or "com". -1136 * Example:</p> -1137 * <code>ClassNameInformation obj = new ClassNameInformation("org.owasp.dependencycheck.analyzer.JarAnalyzer"); -1138 * System.out.println(obj.getName()); -1139 * for (String p : obj.getPackageStructure()) -1140 * System.out.println(p); -1141 * </code> -1142 * <p> -1143 * Would result in:</p> -1144 * <code>org.owasp.dependencycheck.analyzer.JarAnalyzer -1145 * owasp -1146 * dependencycheck -1147 * analyzer -1148 * jaranalyzer</code> -1149 * -1150 * @param className a fully qualified class name -1151 */ -1152 ClassNameInformation(String className) { -1153 name = className; -1154 if (name.contains("/")) { -1155 final String[] tmp = className.toLowerCase().split("/"); -1156 int start = 0; -1157 int end = 3; -1158 if ("com".equals(tmp[0]) || "org".equals(tmp[0])) { -1159 start = 1; -1160 end = 4; -1161 } -1162 if (tmp.length <= end) { -1163 end = tmp.length - 1; -1164 } -1165 for (int i = start; i <= end; i++) { -1166 packageStructure.add(tmp[i]); -1167 } -1168 } else { -1169 packageStructure.add(name); -1170 } -1171 } -1172 /** -1173 * The fully qualified class name. -1174 */ -1175 private String name; -1176 -1177 /** -1178 * Get the value of name -1179 * -1180 * @return the value of name -1181 */ -1182 public String getName() { -1183 return name; -1184 } -1185 -1186 /** -1187 * Set the value of name -1188 * -1189 * @param name new value of name -1190 */ -1191 public void setName(String name) { -1192 this.name = name; -1193 } -1194 /** -1195 * Up to the first four levels of the package structure, excluding a -1196 * leading "org" or "com". -1197 */ -1198 private final ArrayList<String> packageStructure = new ArrayList<String>(); -1199 -1200 /** -1201 * Get the value of packageStructure -1202 * -1203 * @return the value of packageStructure -1204 */ -1205 public ArrayList<String> getPackageStructure() { -1206 return packageStructure; -1207 } -1208 } -1209 -1210 /** -1211 * Retrieves the next temporary directory to extract an archive too. -1212 * -1213 * @return a directory -1214 * @throws AnalysisException thrown if unable to create temporary directory -1215 */ -1216 private File getNextTempDirectory() throws AnalysisException { -1217 dirCount += 1; -1218 final File directory = new File(tempFileLocation, String.valueOf(dirCount)); -1219 //getting an exception for some directories not being able to be created; might be because the directory already exists? -1220 if (directory.exists()) { -1221 return getNextTempDirectory(); -1222 } -1223 if (!directory.mkdirs()) { -1224 final String msg = String.format("Unable to create temp directory '%s'.", directory.getAbsolutePath()); -1225 throw new AnalysisException(msg); +1125 } +1126 } +1127 } +1128 +1129 /** +1130 * Stores information about a class name. +1131 */ +1132 protected static class ClassNameInformation { +1133 +1134 /** +1135 * <p> +1136 * Stores information about a given class name. This class will keep the +1137 * fully qualified class name and a list of the important parts of the +1138 * package structure. Up to the first four levels of the package +1139 * structure are stored, excluding a leading "org" or "com". +1140 * Example:</p> +1141 * <code>ClassNameInformation obj = new ClassNameInformation("org.owasp.dependencycheck.analyzer.JarAnalyzer"); +1142 * System.out.println(obj.getName()); +1143 * for (String p : obj.getPackageStructure()) +1144 * System.out.println(p); +1145 * </code> +1146 * <p> +1147 * Would result in:</p> +1148 * <code>org.owasp.dependencycheck.analyzer.JarAnalyzer +1149 * owasp +1150 * dependencycheck +1151 * analyzer +1152 * jaranalyzer</code> +1153 * +1154 * @param className a fully qualified class name +1155 */ +1156 ClassNameInformation(String className) { +1157 name = className; +1158 if (name.contains("/")) { +1159 final String[] tmp = className.toLowerCase().split("/"); +1160 int start = 0; +1161 int end = 3; +1162 if ("com".equals(tmp[0]) || "org".equals(tmp[0])) { +1163 start = 1; +1164 end = 4; +1165 } +1166 if (tmp.length <= end) { +1167 end = tmp.length - 1; +1168 } +1169 for (int i = start; i <= end; i++) { +1170 packageStructure.add(tmp[i]); +1171 } +1172 } else { +1173 packageStructure.add(name); +1174 } +1175 } +1176 /** +1177 * The fully qualified class name. +1178 */ +1179 private String name; +1180 +1181 /** +1182 * Get the value of name +1183 * +1184 * @return the value of name +1185 */ +1186 public String getName() { +1187 return name; +1188 } +1189 +1190 /** +1191 * Set the value of name +1192 * +1193 * @param name new value of name +1194 */ +1195 public void setName(String name) { +1196 this.name = name; +1197 } +1198 /** +1199 * Up to the first four levels of the package structure, excluding a +1200 * leading "org" or "com". +1201 */ +1202 private final ArrayList<String> packageStructure = new ArrayList<String>(); +1203 +1204 /** +1205 * Get the value of packageStructure +1206 * +1207 * @return the value of packageStructure +1208 */ +1209 public ArrayList<String> getPackageStructure() { +1210 return packageStructure; +1211 } +1212 } +1213 +1214 /** +1215 * Retrieves the next temporary directory to extract an archive too. +1216 * +1217 * @return a directory +1218 * @throws AnalysisException thrown if unable to create temporary directory +1219 */ +1220 private File getNextTempDirectory() throws AnalysisException { +1221 dirCount += 1; +1222 final File directory = new File(tempFileLocation, String.valueOf(dirCount)); +1223 //getting an exception for some directories not being able to be created; might be because the directory already exists? +1224 if (directory.exists()) { +1225 return getNextTempDirectory(); 1226 } -1227 return directory; -1228 } -1229 } +1227 if (!directory.mkdirs()) { +1228 final String msg = String.format("Unable to create temp directory '%s'.", directory.getAbsolutePath()); +1229 throw new AnalysisException(msg); +1230 } +1231 return directory; +1232 } +1233 }
      diff --git a/xref/org/owasp/dependencycheck/analyzer/NexusAnalyzer.html b/xref/org/owasp/dependencycheck/analyzer/NexusAnalyzer.html index 28b6703c4..423630215 100644 --- a/xref/org/owasp/dependencycheck/analyzer/NexusAnalyzer.html +++ b/xref/org/owasp/dependencycheck/analyzer/NexusAnalyzer.html @@ -43,229 +43,234 @@ 35 import java.io.IOException; 36 import java.net.MalformedURLException; 37 import java.net.URL; -38 import org.owasp.dependencycheck.utils.DownloadFailedException; -39 import org.owasp.dependencycheck.utils.Downloader; -40 import org.owasp.dependencycheck.utils.FileFilterBuilder; -41 import org.owasp.dependencycheck.utils.InvalidSettingException; -42 import org.owasp.dependencycheck.utils.Settings; -43 -44 /** -45 * Analyzer which will attempt to locate a dependency on a Nexus service by SHA-1 digest of the dependency. -46 * -47 * There are two settings which govern this behavior: +38 import org.owasp.dependencycheck.exception.InitializationException; +39 import org.owasp.dependencycheck.utils.DownloadFailedException; +40 import org.owasp.dependencycheck.utils.Downloader; +41 import org.owasp.dependencycheck.utils.FileFilterBuilder; +42 import org.owasp.dependencycheck.utils.InvalidSettingException; +43 import org.owasp.dependencycheck.utils.Settings; +44 +45 /** +46 * Analyzer which will attempt to locate a dependency on a Nexus service by +47 * SHA-1 digest of the dependency. 48 * -49 * <ul> -50 * <li>{@link org.owasp.dependencycheck.utils.Settings.KEYS#ANALYZER_NEXUS_ENABLED} determines whether this analyzer is even -51 * enabled. This can be overridden by setting the system property.</li> -52 * <li>{@link org.owasp.dependencycheck.utils.Settings.KEYS#ANALYZER_NEXUS_URL} the URL to a Nexus service to search by SHA-1. -53 * There is an expected <code>%s</code> in this where the SHA-1 will get entered.</li> -54 * </ul> -55 * -56 * @author colezlaw -57 */ -58 public class NexusAnalyzer extends AbstractFileTypeAnalyzer { -59 -60 /** -61 * The default URL - this will be used by the CentralAnalyzer to determine whether to enable this. -62 */ -63 public static final String DEFAULT_URL = "https://repository.sonatype.org/service/local/"; -64 -65 /** -66 * The logger. +49 * There are two settings which govern this behavior: +50 * +51 * <ul> +52 * <li>{@link org.owasp.dependencycheck.utils.Settings.KEYS#ANALYZER_NEXUS_ENABLED} +53 * determines whether this analyzer is even enabled. This can be overridden by +54 * setting the system property.</li> +55 * <li>{@link org.owasp.dependencycheck.utils.Settings.KEYS#ANALYZER_NEXUS_URL} +56 * the URL to a Nexus service to search by SHA-1. There is an expected +57 * <code>%s</code> in this where the SHA-1 will get entered.</li> +58 * </ul> +59 * +60 * @author colezlaw +61 */ +62 public class NexusAnalyzer extends AbstractFileTypeAnalyzer { +63 +64 /** +65 * The default URL - this will be used by the CentralAnalyzer to determine +66 * whether to enable this. 67 */ -68 private static final Logger LOGGER = LoggerFactory.getLogger(NexusAnalyzer.class); +68 public static final String DEFAULT_URL = "https://repository.sonatype.org/service/local/"; 69 70 /** -71 * The name of the analyzer. +71 * The logger. 72 */ -73 private static final String ANALYZER_NAME = "Nexus Analyzer"; +73 private static final Logger LOGGER = LoggerFactory.getLogger(NexusAnalyzer.class); 74 75 /** -76 * The phase in which the analyzer runs. +76 * The name of the analyzer. 77 */ -78 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; +78 private static final String ANALYZER_NAME = "Nexus Analyzer"; 79 80 /** -81 * The types of files on which this will work. +81 * The phase in which the analyzer runs. 82 */ -83 private static final String SUPPORTED_EXTENSIONS = "jar"; +83 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; 84 85 /** -86 * The Nexus Search to be set up for this analyzer. +86 * The types of files on which this will work. 87 */ -88 private NexusSearch searcher; +88 private static final String SUPPORTED_EXTENSIONS = "jar"; 89 90 /** -91 * Field indicating if the analyzer is enabled. +91 * The Nexus Search to be set up for this analyzer. 92 */ -93 private final boolean enabled = checkEnabled(); +93 private NexusSearch searcher; 94 95 /** -96 * Determines if this analyzer is enabled -97 * -98 * @return <code>true</code> if the analyzer is enabled; otherwise <code>false</code> -99 */ -100 private boolean checkEnabled() { -101 /* Enable this analyzer ONLY if the Nexus URL has been set to something -102 other than the default one (if it's the default one, we'll use the -103 central one) and it's enabled by the user. -104 */ -105 boolean retval = false; -106 try { -107 if (!DEFAULT_URL.equals(Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL)) -108 && Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED)) { -109 LOGGER.info("Enabling Nexus analyzer"); -110 retval = true; -111 } else { -112 LOGGER.debug("Nexus analyzer disabled, using Central instead"); -113 } -114 } catch (InvalidSettingException ise) { -115 LOGGER.warn("Invalid setting. Disabling Nexus analyzer"); -116 } -117 -118 return retval; -119 } -120 -121 /** -122 * Determine whether to enable this analyzer or not. -123 * -124 * @return whether the analyzer should be enabled -125 */ -126 @Override -127 public boolean isEnabled() { -128 return enabled; -129 } -130 -131 /** -132 * Initializes the analyzer once before any analysis is performed. -133 * -134 * @throws Exception if there's an error during initialization -135 */ -136 @Override -137 public void initializeFileTypeAnalyzer() throws Exception { -138 LOGGER.debug("Initializing Nexus Analyzer"); -139 LOGGER.debug("Nexus Analyzer enabled: {}", isEnabled()); -140 if (isEnabled()) { -141 final String searchUrl = Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL); -142 LOGGER.debug("Nexus Analyzer URL: {}", searchUrl); -143 try { -144 searcher = new NexusSearch(new URL(searchUrl)); -145 if (!searcher.preflightRequest()) { -146 LOGGER.warn("There was an issue getting Nexus status. Disabling analyzer."); -147 setEnabled(false); -148 } -149 } catch (MalformedURLException mue) { -150 // I know that initialize can throw an exception, but we'll -151 // just disable the analyzer if the URL isn't valid -152 LOGGER.warn("Property {} not a valid URL. Nexus Analyzer disabled", searchUrl); -153 setEnabled(false); -154 } -155 } -156 } -157 -158 /** -159 * Returns the analyzer's name. -160 * -161 * @return the name of the analyzer -162 */ -163 @Override -164 public String getName() { -165 return ANALYZER_NAME; -166 } -167 -168 /** -169 * Returns the key used in the properties file to reference the analyzer's enabled property. -170 * -171 * @return the analyzer's enabled property setting key -172 */ -173 @Override -174 protected String getAnalyzerEnabledSettingKey() { -175 return Settings.KEYS.ANALYZER_NEXUS_ENABLED; -176 } -177 -178 /** -179 * Returns the analysis phase under which the analyzer runs. -180 * -181 * @return the phase under which this analyzer runs -182 */ -183 @Override -184 public AnalysisPhase getAnalysisPhase() { -185 return ANALYSIS_PHASE; -186 } -187 -188 /** -189 * The file filter used to determine which files this analyzer supports. -190 */ -191 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(SUPPORTED_EXTENSIONS).build(); +96 * Field indicating if the analyzer is enabled. +97 */ +98 private final boolean enabled = checkEnabled(); +99 +100 /** +101 * Determines if this analyzer is enabled +102 * +103 * @return <code>true</code> if the analyzer is enabled; otherwise +104 * <code>false</code> +105 */ +106 private boolean checkEnabled() { +107 /* Enable this analyzer ONLY if the Nexus URL has been set to something +108 other than the default one (if it's the default one, we'll use the +109 central one) and it's enabled by the user. +110 */ +111 boolean retval = false; +112 try { +113 if (!DEFAULT_URL.equals(Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL)) +114 && Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED)) { +115 LOGGER.info("Enabling Nexus analyzer"); +116 retval = true; +117 } else { +118 LOGGER.debug("Nexus analyzer disabled, using Central instead"); +119 } +120 } catch (InvalidSettingException ise) { +121 LOGGER.warn("Invalid setting. Disabling Nexus analyzer"); +122 } +123 +124 return retval; +125 } +126 +127 /** +128 * Determine whether to enable this analyzer or not. +129 * +130 * @return whether the analyzer should be enabled +131 */ +132 @Override +133 public boolean isEnabled() { +134 return enabled; +135 } +136 +137 /** +138 * Initializes the analyzer once before any analysis is performed. +139 * +140 * @throws InitializationException if there's an error during initialization +141 */ +142 @Override +143 public void initializeFileTypeAnalyzer() throws InitializationException { +144 LOGGER.debug("Initializing Nexus Analyzer"); +145 LOGGER.debug("Nexus Analyzer enabled: {}", isEnabled()); +146 if (isEnabled()) { +147 final String searchUrl = Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL); +148 LOGGER.debug("Nexus Analyzer URL: {}", searchUrl); +149 try { +150 searcher = new NexusSearch(new URL(searchUrl)); +151 if (!searcher.preflightRequest()) { +152 setEnabled(false); +153 throw new InitializationException("There was an issue getting Nexus status. Disabling analyzer."); +154 } +155 } catch (MalformedURLException mue) { +156 setEnabled(false); +157 throw new InitializationException("Malformed URL to Nexus: " + searchUrl, mue); +158 } +159 } +160 } +161 +162 /** +163 * Returns the analyzer's name. +164 * +165 * @return the name of the analyzer +166 */ +167 @Override +168 public String getName() { +169 return ANALYZER_NAME; +170 } +171 +172 /** +173 * Returns the key used in the properties file to reference the analyzer's +174 * enabled property. +175 * +176 * @return the analyzer's enabled property setting key +177 */ +178 @Override +179 protected String getAnalyzerEnabledSettingKey() { +180 return Settings.KEYS.ANALYZER_NEXUS_ENABLED; +181 } +182 +183 /** +184 * Returns the analysis phase under which the analyzer runs. +185 * +186 * @return the phase under which this analyzer runs +187 */ +188 @Override +189 public AnalysisPhase getAnalysisPhase() { +190 return ANALYSIS_PHASE; +191 } 192 193 /** -194 * Returns the FileFilter -195 * -196 * @return the FileFilter -197 */ -198 @Override -199 protected FileFilter getFileFilter() { -200 return FILTER; -201 } -202 -203 /** -204 * Performs the analysis. -205 * -206 * @param dependency the dependency to analyze -207 * @param engine the engine -208 * @throws AnalysisException when there's an exception during analysis -209 */ -210 @Override -211 public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { -212 if (!isEnabled()) { -213 return; -214 } -215 try { -216 final MavenArtifact ma = searcher.searchSha1(dependency.getSha1sum()); -217 dependency.addAsEvidence("nexus", ma, Confidence.HIGH); -218 boolean pomAnalyzed = false; -219 LOGGER.debug("POM URL {}", ma.getPomUrl()); -220 for (Evidence e : dependency.getVendorEvidence()) { -221 if ("pom".equals(e.getSource())) { -222 pomAnalyzed = true; -223 break; -224 } -225 } -226 if (!pomAnalyzed && ma.getPomUrl() != null) { -227 File pomFile = null; -228 try { -229 final File baseDir = Settings.getTempDirectory(); -230 pomFile = File.createTempFile("pom", ".xml", baseDir); -231 if (!pomFile.delete()) { -232 LOGGER.warn("Unable to fetch pom.xml for {} from Nexus repository; " -233 + "this could result in undetected CPE/CVEs.", dependency.getFileName()); -234 LOGGER.debug("Unable to delete temp file"); -235 } -236 LOGGER.debug("Downloading {}", ma.getPomUrl()); -237 Downloader.fetchFile(new URL(ma.getPomUrl()), pomFile); -238 PomUtils.analyzePOM(dependency, pomFile); -239 } catch (DownloadFailedException ex) { -240 LOGGER.warn("Unable to download pom.xml for {} from Nexus repository; " -241 + "this could result in undetected CPE/CVEs.", dependency.getFileName()); -242 } finally { -243 if (pomFile != null && !FileUtils.deleteQuietly(pomFile)) { -244 pomFile.deleteOnExit(); -245 } -246 } -247 } -248 } catch (IllegalArgumentException iae) { -249 //dependency.addAnalysisException(new AnalysisException("Invalid SHA-1")); -250 LOGGER.info("invalid sha-1 hash on {}", dependency.getFileName()); -251 } catch (FileNotFoundException fnfe) { -252 //dependency.addAnalysisException(new AnalysisException("Artifact not found on repository")); -253 LOGGER.debug("Artifact not found in repository '{}'", dependency.getFileName()); -254 LOGGER.debug(fnfe.getMessage(), fnfe); -255 } catch (IOException ioe) { -256 //dependency.addAnalysisException(new AnalysisException("Could not connect to repository", ioe)); -257 LOGGER.debug("Could not connect to nexus repository", ioe); -258 } -259 } -260 } +194 * The file filter used to determine which files this analyzer supports. +195 */ +196 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(SUPPORTED_EXTENSIONS).build(); +197 +198 /** +199 * Returns the FileFilter +200 * +201 * @return the FileFilter +202 */ +203 @Override +204 protected FileFilter getFileFilter() { +205 return FILTER; +206 } +207 +208 /** +209 * Performs the analysis. +210 * +211 * @param dependency the dependency to analyze +212 * @param engine the engine +213 * @throws AnalysisException when there's an exception during analysis +214 */ +215 @Override +216 public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { +217 if (!isEnabled()) { +218 return; +219 } +220 try { +221 final MavenArtifact ma = searcher.searchSha1(dependency.getSha1sum()); +222 dependency.addAsEvidence("nexus", ma, Confidence.HIGH); +223 boolean pomAnalyzed = false; +224 LOGGER.debug("POM URL {}", ma.getPomUrl()); +225 for (Evidence e : dependency.getVendorEvidence()) { +226 if ("pom".equals(e.getSource())) { +227 pomAnalyzed = true; +228 break; +229 } +230 } +231 if (!pomAnalyzed && ma.getPomUrl() != null) { +232 File pomFile = null; +233 try { +234 final File baseDir = Settings.getTempDirectory(); +235 pomFile = File.createTempFile("pom", ".xml", baseDir); +236 if (!pomFile.delete()) { +237 LOGGER.warn("Unable to fetch pom.xml for {} from Nexus repository; " +238 + "this could result in undetected CPE/CVEs.", dependency.getFileName()); +239 LOGGER.debug("Unable to delete temp file"); +240 } +241 LOGGER.debug("Downloading {}", ma.getPomUrl()); +242 Downloader.fetchFile(new URL(ma.getPomUrl()), pomFile); +243 PomUtils.analyzePOM(dependency, pomFile); +244 } catch (DownloadFailedException ex) { +245 LOGGER.warn("Unable to download pom.xml for {} from Nexus repository; " +246 + "this could result in undetected CPE/CVEs.", dependency.getFileName()); +247 } finally { +248 if (pomFile != null && !FileUtils.deleteQuietly(pomFile)) { +249 pomFile.deleteOnExit(); +250 } +251 } +252 } +253 } catch (IllegalArgumentException iae) { +254 //dependency.addAnalysisException(new AnalysisException("Invalid SHA-1")); +255 LOGGER.info("invalid sha-1 hash on {}", dependency.getFileName()); +256 } catch (FileNotFoundException fnfe) { +257 //dependency.addAnalysisException(new AnalysisException("Artifact not found on repository")); +258 LOGGER.debug("Artifact not found in repository '{}'", dependency.getFileName()); +259 LOGGER.debug(fnfe.getMessage(), fnfe); +260 } catch (IOException ioe) { +261 //dependency.addAnalysisException(new AnalysisException("Could not connect to repository", ioe)); +262 LOGGER.debug("Could not connect to nexus repository", ioe); +263 } +264 } +265 }
      diff --git a/xref/org/owasp/dependencycheck/analyzer/NodePackageAnalyzer.html b/xref/org/owasp/dependencycheck/analyzer/NodePackageAnalyzer.html index ebd893860..e4fbd96db 100644 --- a/xref/org/owasp/dependencycheck/analyzer/NodePackageAnalyzer.html +++ b/xref/org/owasp/dependencycheck/analyzer/NodePackageAnalyzer.html @@ -46,154 +46,157 @@ 38 import javax.json.JsonReader; 39 import javax.json.JsonString; 40 import javax.json.JsonValue; -41 -42 /** -43 * Used to analyze Node Package Manager (npm) package.json files, and collect information that can be used to determine the -44 * associated CPE. -45 * -46 * @author Dale Visser -47 */ -48 @Experimental -49 public class NodePackageAnalyzer extends AbstractFileTypeAnalyzer { -50 -51 /** -52 * The logger. -53 */ -54 private static final Logger LOGGER = LoggerFactory.getLogger(NodePackageAnalyzer.class); -55 -56 /** -57 * The name of the analyzer. -58 */ -59 private static final String ANALYZER_NAME = "Node.js Package Analyzer"; -60 -61 /** -62 * The phase that this analyzer is intended to run in. -63 */ -64 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; -65 -66 /** -67 * The file name to scan. -68 */ -69 public static final String PACKAGE_JSON = "package.json"; -70 /** -71 * Filter that detects files named "package.json". -72 */ -73 private static final FileFilter PACKAGE_JSON_FILTER = FileFilterBuilder.newInstance() -74 .addFilenames(PACKAGE_JSON).build(); -75 -76 /** -77 * Returns the FileFilter -78 * -79 * @return the FileFilter -80 */ -81 @Override -82 protected FileFilter getFileFilter() { -83 return PACKAGE_JSON_FILTER; -84 } -85 -86 @Override -87 protected void initializeFileTypeAnalyzer() throws Exception { -88 // NO-OP -89 } -90 -91 /** -92 * Returns the name of the analyzer. -93 * -94 * @return the name of the analyzer. -95 */ -96 @Override -97 public String getName() { -98 return ANALYZER_NAME; -99 } -100 -101 /** -102 * Returns the phase that the analyzer is intended to run in. -103 * -104 * @return the phase that the analyzer is intended to run in. -105 */ -106 @Override -107 public AnalysisPhase getAnalysisPhase() { -108 return ANALYSIS_PHASE; -109 } -110 -111 /** -112 * Returns the key used in the properties file to reference the analyzer's enabled property. -113 * -114 * @return the analyzer's enabled property setting key -115 */ -116 @Override -117 protected String getAnalyzerEnabledSettingKey() { -118 return Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED; -119 } -120 -121 @Override -122 protected void analyzeFileType(Dependency dependency, Engine engine) -123 throws AnalysisException { -124 final File file = dependency.getActualFile(); -125 JsonReader jsonReader; -126 try { -127 jsonReader = Json.createReader(FileUtils.openInputStream(file)); -128 } catch (IOException e) { -129 throw new AnalysisException( -130 "Problem occurred while reading dependency file.", e); -131 } -132 try { -133 final JsonObject json = jsonReader.readObject(); -134 final EvidenceCollection productEvidence = dependency.getProductEvidence(); -135 final EvidenceCollection vendorEvidence = dependency.getVendorEvidence(); -136 if (json.containsKey("name")) { -137 final Object value = json.get("name"); -138 if (value instanceof JsonString) { -139 final String valueString = ((JsonString) value).getString(); -140 productEvidence.addEvidence(PACKAGE_JSON, "name", valueString, Confidence.HIGHEST); -141 vendorEvidence.addEvidence(PACKAGE_JSON, "name_project", String.format("%s_project", valueString), Confidence.LOW); -142 } else { -143 LOGGER.warn("JSON value not string as expected: {}", value); -144 } -145 } -146 addToEvidence(json, productEvidence, "description"); -147 addToEvidence(json, vendorEvidence, "author"); -148 addToEvidence(json, dependency.getVersionEvidence(), "version"); -149 dependency.setDisplayFileName(String.format("%s/%s", file.getParentFile().getName(), file.getName())); -150 } catch (JsonException e) { -151 LOGGER.warn("Failed to parse package.json file.", e); -152 } finally { -153 jsonReader.close(); -154 } -155 } -156 -157 /** -158 * Adds information to an evidence collection from the node json configuration. -159 * -160 * @param json information from node.js -161 * @param collection a set of evidence about a dependency -162 * @param key the key to obtain the data from the json information -163 */ -164 private void addToEvidence(JsonObject json, EvidenceCollection collection, String key) { -165 if (json.containsKey(key)) { -166 final JsonValue value = json.get(key); -167 if (value instanceof JsonString) { -168 collection.addEvidence(PACKAGE_JSON, key, ((JsonString) value).getString(), Confidence.HIGHEST); -169 } else if (value instanceof JsonObject) { -170 final JsonObject jsonObject = (JsonObject) value; -171 for (final Map.Entry<String, JsonValue> entry : jsonObject.entrySet()) { -172 final String property = entry.getKey(); -173 final JsonValue subValue = entry.getValue(); -174 if (subValue instanceof JsonString) { -175 collection.addEvidence(PACKAGE_JSON, -176 String.format("%s.%s", key, property), -177 ((JsonString) subValue).getString(), -178 Confidence.HIGHEST); -179 } else { -180 LOGGER.warn("JSON sub-value not string as expected: {}", subValue); -181 } -182 } -183 } else { -184 LOGGER.warn("JSON value not string or JSON object as expected: {}", value); -185 } -186 } -187 } -188 } +41 import org.owasp.dependencycheck.exception.InitializationException; +42 +43 /** +44 * Used to analyze Node Package Manager (npm) package.json files, and collect +45 * information that can be used to determine the associated CPE. +46 * +47 * @author Dale Visser +48 */ +49 @Experimental +50 public class NodePackageAnalyzer extends AbstractFileTypeAnalyzer { +51 +52 /** +53 * The logger. +54 */ +55 private static final Logger LOGGER = LoggerFactory.getLogger(NodePackageAnalyzer.class); +56 +57 /** +58 * The name of the analyzer. +59 */ +60 private static final String ANALYZER_NAME = "Node.js Package Analyzer"; +61 +62 /** +63 * The phase that this analyzer is intended to run in. +64 */ +65 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; +66 +67 /** +68 * The file name to scan. +69 */ +70 public static final String PACKAGE_JSON = "package.json"; +71 /** +72 * Filter that detects files named "package.json". +73 */ +74 private static final FileFilter PACKAGE_JSON_FILTER = FileFilterBuilder.newInstance() +75 .addFilenames(PACKAGE_JSON).build(); +76 +77 /** +78 * Returns the FileFilter +79 * +80 * @return the FileFilter +81 */ +82 @Override +83 protected FileFilter getFileFilter() { +84 return PACKAGE_JSON_FILTER; +85 } +86 +87 @Override +88 protected void initializeFileTypeAnalyzer() throws InitializationException { +89 // NO-OP +90 } +91 +92 /** +93 * Returns the name of the analyzer. +94 * +95 * @return the name of the analyzer. +96 */ +97 @Override +98 public String getName() { +99 return ANALYZER_NAME; +100 } +101 +102 /** +103 * Returns the phase that the analyzer is intended to run in. +104 * +105 * @return the phase that the analyzer is intended to run in. +106 */ +107 @Override +108 public AnalysisPhase getAnalysisPhase() { +109 return ANALYSIS_PHASE; +110 } +111 +112 /** +113 * Returns the key used in the properties file to reference the analyzer's +114 * enabled property. +115 * +116 * @return the analyzer's enabled property setting key +117 */ +118 @Override +119 protected String getAnalyzerEnabledSettingKey() { +120 return Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED; +121 } +122 +123 @Override +124 protected void analyzeFileType(Dependency dependency, Engine engine) +125 throws AnalysisException { +126 final File file = dependency.getActualFile(); +127 JsonReader jsonReader; +128 try { +129 jsonReader = Json.createReader(FileUtils.openInputStream(file)); +130 } catch (IOException e) { +131 throw new AnalysisException( +132 "Problem occurred while reading dependency file.", e); +133 } +134 try { +135 final JsonObject json = jsonReader.readObject(); +136 final EvidenceCollection productEvidence = dependency.getProductEvidence(); +137 final EvidenceCollection vendorEvidence = dependency.getVendorEvidence(); +138 if (json.containsKey("name")) { +139 final Object value = json.get("name"); +140 if (value instanceof JsonString) { +141 final String valueString = ((JsonString) value).getString(); +142 productEvidence.addEvidence(PACKAGE_JSON, "name", valueString, Confidence.HIGHEST); +143 vendorEvidence.addEvidence(PACKAGE_JSON, "name_project", String.format("%s_project", valueString), Confidence.LOW); +144 } else { +145 LOGGER.warn("JSON value not string as expected: {}", value); +146 } +147 } +148 addToEvidence(json, productEvidence, "description"); +149 addToEvidence(json, vendorEvidence, "author"); +150 addToEvidence(json, dependency.getVersionEvidence(), "version"); +151 dependency.setDisplayFileName(String.format("%s/%s", file.getParentFile().getName(), file.getName())); +152 } catch (JsonException e) { +153 LOGGER.warn("Failed to parse package.json file.", e); +154 } finally { +155 jsonReader.close(); +156 } +157 } +158 +159 /** +160 * Adds information to an evidence collection from the node json +161 * configuration. +162 * +163 * @param json information from node.js +164 * @param collection a set of evidence about a dependency +165 * @param key the key to obtain the data from the json information +166 */ +167 private void addToEvidence(JsonObject json, EvidenceCollection collection, String key) { +168 if (json.containsKey(key)) { +169 final JsonValue value = json.get(key); +170 if (value instanceof JsonString) { +171 collection.addEvidence(PACKAGE_JSON, key, ((JsonString) value).getString(), Confidence.HIGHEST); +172 } else if (value instanceof JsonObject) { +173 final JsonObject jsonObject = (JsonObject) value; +174 for (final Map.Entry<String, JsonValue> entry : jsonObject.entrySet()) { +175 final String property = entry.getKey(); +176 final JsonValue subValue = entry.getValue(); +177 if (subValue instanceof JsonString) { +178 collection.addEvidence(PACKAGE_JSON, +179 String.format("%s.%s", key, property), +180 ((JsonString) subValue).getString(), +181 Confidence.HIGHEST); +182 } else { +183 LOGGER.warn("JSON sub-value not string as expected: {}", subValue); +184 } +185 } +186 } else { +187 LOGGER.warn("JSON value not string or JSON object as expected: {}", value); +188 } +189 } +190 } +191 }
      diff --git a/xref/org/owasp/dependencycheck/analyzer/NuspecAnalyzer.html b/xref/org/owasp/dependencycheck/analyzer/NuspecAnalyzer.html index 115aa3ccc..d211926f5 100644 --- a/xref/org/owasp/dependencycheck/analyzer/NuspecAnalyzer.html +++ b/xref/org/owasp/dependencycheck/analyzer/NuspecAnalyzer.html @@ -42,134 +42,136 @@ 34 import java.io.FileInputStream; 35 import java.io.FileNotFoundException; 36 import java.io.IOException; -37 -38 /** -39 * Analyzer which will parse a Nuspec file to gather module information. -40 * -41 * @author colezlaw -42 */ -43 public class NuspecAnalyzer extends AbstractFileTypeAnalyzer { -44 -45 /** -46 * The logger. -47 */ -48 private static final Logger LOGGER = LoggerFactory.getLogger(NuspecAnalyzer.class); -49 -50 /** -51 * The name of the analyzer. -52 */ -53 private static final String ANALYZER_NAME = "Nuspec Analyzer"; -54 -55 /** -56 * The phase in which the analyzer runs. -57 */ -58 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; -59 -60 /** -61 * The types of files on which this will work. -62 */ -63 private static final String SUPPORTED_EXTENSIONS = "nuspec"; -64 -65 /** -66 * Initializes the analyzer once before any analysis is performed. -67 * -68 * @throws Exception if there's an error during initialization -69 */ -70 @Override -71 public void initializeFileTypeAnalyzer() throws Exception { -72 } -73 -74 /** -75 * Returns the analyzer's name. -76 * -77 * @return the name of the analyzer -78 */ -79 @Override -80 public String getName() { -81 return ANALYZER_NAME; -82 } -83 -84 /** -85 * Returns the key used in the properties file to reference the analyzer's enabled property. -86 * -87 * @return the analyzer's enabled property setting key -88 */ -89 @Override -90 protected String getAnalyzerEnabledSettingKey() { -91 return Settings.KEYS.ANALYZER_NUSPEC_ENABLED; -92 } -93 -94 /** -95 * Returns the analysis phase under which the analyzer runs. -96 * -97 * @return the phase under which this analyzer runs -98 */ -99 @Override -100 public AnalysisPhase getAnalysisPhase() { -101 return ANALYSIS_PHASE; -102 } -103 -104 /** -105 * The file filter used to determine which files this analyzer supports. -106 */ -107 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions( -108 SUPPORTED_EXTENSIONS).build(); -109 -110 /** -111 * Returns the FileFilter -112 * -113 * @return the FileFilter -114 */ -115 @Override -116 protected FileFilter getFileFilter() { -117 return FILTER; -118 } -119 -120 /** -121 * Performs the analysis. -122 * -123 * @param dependency the dependency to analyze -124 * @param engine the engine -125 * @throws AnalysisException when there's an exception during analysis -126 */ -127 @Override -128 public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { -129 LOGGER.debug("Checking Nuspec file {}", dependency); -130 try { -131 final NuspecParser parser = new XPathNuspecParser(); -132 NugetPackage np = null; -133 FileInputStream fis = null; -134 try { -135 fis = new FileInputStream(dependency.getActualFilePath()); -136 np = parser.parse(fis); -137 } catch (NuspecParseException ex) { -138 throw new AnalysisException(ex); -139 } catch (FileNotFoundException ex) { +37 import org.owasp.dependencycheck.exception.InitializationException; +38 +39 /** +40 * Analyzer which will parse a Nuspec file to gather module information. +41 * +42 * @author colezlaw +43 */ +44 public class NuspecAnalyzer extends AbstractFileTypeAnalyzer { +45 +46 /** +47 * The logger. +48 */ +49 private static final Logger LOGGER = LoggerFactory.getLogger(NuspecAnalyzer.class); +50 +51 /** +52 * The name of the analyzer. +53 */ +54 private static final String ANALYZER_NAME = "Nuspec Analyzer"; +55 +56 /** +57 * The phase in which the analyzer runs. +58 */ +59 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; +60 +61 /** +62 * The types of files on which this will work. +63 */ +64 private static final String SUPPORTED_EXTENSIONS = "nuspec"; +65 +66 /** +67 * Initializes the analyzer once before any analysis is performed. +68 * +69 * @throws InitializationException if there's an error during initialization +70 */ +71 @Override +72 public void initializeFileTypeAnalyzer() throws InitializationException { +73 } +74 +75 /** +76 * Returns the analyzer's name. +77 * +78 * @return the name of the analyzer +79 */ +80 @Override +81 public String getName() { +82 return ANALYZER_NAME; +83 } +84 +85 /** +86 * Returns the key used in the properties file to reference the analyzer's +87 * enabled property. +88 * +89 * @return the analyzer's enabled property setting key +90 */ +91 @Override +92 protected String getAnalyzerEnabledSettingKey() { +93 return Settings.KEYS.ANALYZER_NUSPEC_ENABLED; +94 } +95 +96 /** +97 * Returns the analysis phase under which the analyzer runs. +98 * +99 * @return the phase under which this analyzer runs +100 */ +101 @Override +102 public AnalysisPhase getAnalysisPhase() { +103 return ANALYSIS_PHASE; +104 } +105 +106 /** +107 * The file filter used to determine which files this analyzer supports. +108 */ +109 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions( +110 SUPPORTED_EXTENSIONS).build(); +111 +112 /** +113 * Returns the FileFilter +114 * +115 * @return the FileFilter +116 */ +117 @Override +118 protected FileFilter getFileFilter() { +119 return FILTER; +120 } +121 +122 /** +123 * Performs the analysis. +124 * +125 * @param dependency the dependency to analyze +126 * @param engine the engine +127 * @throws AnalysisException when there's an exception during analysis +128 */ +129 @Override +130 public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { +131 LOGGER.debug("Checking Nuspec file {}", dependency); +132 try { +133 final NuspecParser parser = new XPathNuspecParser(); +134 NugetPackage np = null; +135 FileInputStream fis = null; +136 try { +137 fis = new FileInputStream(dependency.getActualFilePath()); +138 np = parser.parse(fis); +139 } catch (NuspecParseException ex) { 140 throw new AnalysisException(ex); -141 } finally { -142 if (fis != null) { -143 try { -144 fis.close(); -145 } catch (IOException e) { -146 LOGGER.debug("Error closing input stream"); -147 } -148 } -149 } -150 -151 if (np.getOwners() != null) { -152 dependency.getVendorEvidence().addEvidence("nuspec", "owners", np.getOwners(), Confidence.HIGHEST); -153 } -154 dependency.getVendorEvidence().addEvidence("nuspec", "authors", np.getAuthors(), Confidence.HIGH); -155 dependency.getVersionEvidence().addEvidence("nuspec", "version", np.getVersion(), Confidence.HIGHEST); -156 dependency.getProductEvidence().addEvidence("nuspec", "id", np.getId(), Confidence.HIGHEST); -157 if (np.getTitle() != null) { -158 dependency.getProductEvidence().addEvidence("nuspec", "title", np.getTitle(), Confidence.MEDIUM); -159 } -160 } catch (Throwable e) { -161 throw new AnalysisException(e); -162 } -163 } -164 } +141 } catch (FileNotFoundException ex) { +142 throw new AnalysisException(ex); +143 } finally { +144 if (fis != null) { +145 try { +146 fis.close(); +147 } catch (IOException e) { +148 LOGGER.debug("Error closing input stream"); +149 } +150 } +151 } +152 +153 if (np.getOwners() != null) { +154 dependency.getVendorEvidence().addEvidence("nuspec", "owners", np.getOwners(), Confidence.HIGHEST); +155 } +156 dependency.getVendorEvidence().addEvidence("nuspec", "authors", np.getAuthors(), Confidence.HIGH); +157 dependency.getVersionEvidence().addEvidence("nuspec", "version", np.getVersion(), Confidence.HIGHEST); +158 dependency.getProductEvidence().addEvidence("nuspec", "id", np.getId(), Confidence.HIGHEST); +159 if (np.getTitle() != null) { +160 dependency.getProductEvidence().addEvidence("nuspec", "title", np.getTitle(), Confidence.MEDIUM); +161 } +162 } catch (Throwable e) { +163 throw new AnalysisException(e); +164 } +165 } +166 }
      diff --git a/xref/org/owasp/dependencycheck/analyzer/NvdCveAnalyzer.html b/xref/org/owasp/dependencycheck/analyzer/NvdCveAnalyzer.html index 2a2c2c490..75128b17b 100644 --- a/xref/org/owasp/dependencycheck/analyzer/NvdCveAnalyzer.html +++ b/xref/org/owasp/dependencycheck/analyzer/NvdCveAnalyzer.html @@ -35,131 +35,150 @@ 27 import org.owasp.dependencycheck.dependency.Dependency; 28 import org.owasp.dependencycheck.dependency.Identifier; 29 import org.owasp.dependencycheck.dependency.Vulnerability; -30 -31 /** -32 * NvdCveAnalyzer is a utility class that takes a project dependency and attempts to discern if there is an associated -33 * CVEs. It uses the the identifiers found by other analyzers to lookup the CVE data. -34 * -35 * @author Jeremy Long -36 */ -37 public class NvdCveAnalyzer implements Analyzer { -38 -39 /** -40 * The maximum number of query results to return. -41 */ -42 static final int MAX_QUERY_RESULTS = 100; -43 /** -44 * The CVE Index. -45 */ -46 private CveDB cveDB; -47 +30 import org.owasp.dependencycheck.exception.InitializationException; +31 import org.slf4j.LoggerFactory; +32 +33 /** +34 * NvdCveAnalyzer is a utility class that takes a project dependency and attempts to discern if there is an associated +35 * CVEs. It uses the the identifiers found by other analyzers to lookup the CVE data. +36 * +37 * @author Jeremy Long +38 */ +39 public class NvdCveAnalyzer implements Analyzer { +40 /** +41 * The Logger for use throughout the class +42 */ +43 private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(NvdCveAnalyzer.class); +44 /** +45 * The maximum number of query results to return. +46 */ +47 static final int MAX_QUERY_RESULTS = 100; 48 /** -49 * Opens the data source. -50 * -51 * @throws SQLException thrown when there is a SQL Exception -52 * @throws IOException thrown when there is an IO Exception -53 * @throws DatabaseException thrown when there is a database exceptions -54 * @throws ClassNotFoundException thrown if the h2 database driver cannot be loaded -55 */ -56 public void open() throws SQLException, IOException, DatabaseException, ClassNotFoundException { -57 cveDB = new CveDB(); -58 cveDB.open(); -59 } -60 -61 /** -62 * Closes the data source. -63 */ -64 @Override -65 public void close() { -66 cveDB.close(); -67 cveDB = null; -68 } -69 -70 /** -71 * Returns the status of the data source - is the database open. -72 * -73 * @return true or false. -74 */ -75 public boolean isOpen() { -76 return cveDB != null; -77 } -78 -79 /** -80 * Ensures that the CVE Database is closed. -81 * -82 * @throws Throwable when a throwable is thrown. -83 */ -84 @Override -85 protected void finalize() throws Throwable { -86 super.finalize(); -87 if (isOpen()) { -88 close(); -89 } -90 } -91 -92 /** -93 * Analyzes a dependency and attempts to determine if there are any CPE identifiers for this dependency. -94 * -95 * @param dependency The Dependency to analyze -96 * @param engine The analysis engine -97 * @throws AnalysisException is thrown if there is an issue analyzing the dependency -98 */ -99 @Override -100 public void analyze(Dependency dependency, Engine engine) throws AnalysisException { -101 for (Identifier id : dependency.getIdentifiers()) { -102 if ("cpe".equals(id.getType())) { -103 try { -104 final String value = id.getValue(); -105 final List<Vulnerability> vulns = cveDB.getVulnerabilities(value); -106 dependency.getVulnerabilities().addAll(vulns); -107 } catch (DatabaseException ex) { -108 throw new AnalysisException(ex); -109 } -110 } -111 } -112 for (Identifier id : dependency.getSuppressedIdentifiers()) { -113 if ("cpe".equals(id.getType())) { -114 try { -115 final String value = id.getValue(); -116 final List<Vulnerability> vulns = cveDB.getVulnerabilities(value); -117 dependency.getSuppressedVulnerabilities().addAll(vulns); -118 } catch (DatabaseException ex) { -119 throw new AnalysisException(ex); -120 } -121 } -122 } -123 } -124 -125 /** -126 * Returns the name of this analyzer. -127 * -128 * @return the name of this analyzer. -129 */ -130 @Override -131 public String getName() { -132 return "NVD CVE Analyzer"; -133 } -134 -135 /** -136 * Returns the analysis phase that this analyzer should run in. -137 * -138 * @return the analysis phase that this analyzer should run in. -139 */ -140 @Override -141 public AnalysisPhase getAnalysisPhase() { -142 return AnalysisPhase.FINDING_ANALYSIS; -143 } -144 -145 /** -146 * Opens the database used to gather NVD CVE data. -147 * -148 * @throws Exception is thrown if there is an issue opening the index. -149 */ -150 @Override -151 public void initialize() throws Exception { -152 this.open(); -153 } -154 } +49 * The CVE Index. +50 */ +51 private CveDB cveDB; +52 +53 /** +54 * Opens the data source. +55 * +56 * @throws SQLException thrown when there is a SQL Exception +57 * @throws IOException thrown when there is an IO Exception +58 * @throws DatabaseException thrown when there is a database exceptions +59 * @throws ClassNotFoundException thrown if the h2 database driver cannot be loaded +60 */ +61 public void open() throws SQLException, IOException, DatabaseException, ClassNotFoundException { +62 cveDB = new CveDB(); +63 cveDB.open(); +64 } +65 +66 /** +67 * Closes the data source. +68 */ +69 @Override +70 public void close() { +71 cveDB.close(); +72 cveDB = null; +73 } +74 +75 /** +76 * Returns the status of the data source - is the database open. +77 * +78 * @return true or false. +79 */ +80 public boolean isOpen() { +81 return cveDB != null; +82 } +83 +84 /** +85 * Ensures that the CVE Database is closed. +86 * +87 * @throws Throwable an exception raised by this method +88 */ +89 @Override +90 protected void finalize() throws Throwable { +91 super.finalize(); +92 if (isOpen()) { +93 close(); +94 } +95 } +96 +97 /** +98 * Analyzes a dependency and attempts to determine if there are any CPE identifiers for this dependency. +99 * +100 * @param dependency The Dependency to analyze +101 * @param engine The analysis engine +102 * @throws AnalysisException thrown if there is an issue analyzing the dependency +103 */ +104 @Override +105 public void analyze(Dependency dependency, Engine engine) throws AnalysisException { +106 for (Identifier id : dependency.getIdentifiers()) { +107 if ("cpe".equals(id.getType())) { +108 try { +109 final String value = id.getValue(); +110 final List<Vulnerability> vulns = cveDB.getVulnerabilities(value); +111 dependency.getVulnerabilities().addAll(vulns); +112 } catch (DatabaseException ex) { +113 throw new AnalysisException(ex); +114 } +115 } +116 } +117 for (Identifier id : dependency.getSuppressedIdentifiers()) { +118 if ("cpe".equals(id.getType())) { +119 try { +120 final String value = id.getValue(); +121 final List<Vulnerability> vulns = cveDB.getVulnerabilities(value); +122 dependency.getSuppressedVulnerabilities().addAll(vulns); +123 } catch (DatabaseException ex) { +124 throw new AnalysisException(ex); +125 } +126 } +127 } +128 } +129 +130 /** +131 * Returns the name of this analyzer. +132 * +133 * @return the name of this analyzer. +134 */ +135 @Override +136 public String getName() { +137 return "NVD CVE Analyzer"; +138 } +139 +140 /** +141 * Returns the analysis phase that this analyzer should run in. +142 * +143 * @return the analysis phase that this analyzer should run in. +144 */ +145 @Override +146 public AnalysisPhase getAnalysisPhase() { +147 return AnalysisPhase.FINDING_ANALYSIS; +148 } +149 +150 /** +151 * Opens the database used to gather NVD CVE data. +152 * +153 * @throws InitializationException is thrown if there is an issue opening the index. +154 */ +155 @Override +156 public void initialize() throws InitializationException { +157 try { +158 this.open(); +159 } catch (SQLException ex) { +160 LOGGER.debug("SQL Exception initializing NvdCveAnalyzer", ex); +161 throw new InitializationException(ex); +162 } catch (IOException ex) { +163 LOGGER.debug("IO Exception initializing NvdCveAnalyzer", ex); +164 throw new InitializationException(ex); +165 } catch (DatabaseException ex) { +166 LOGGER.debug("Database Exception initializing NvdCveAnalyzer", ex); +167 throw new InitializationException(ex); +168 } catch (ClassNotFoundException ex) { +169 LOGGER.debug("Exception initializing NvdCveAnalyzer", ex); +170 throw new InitializationException(ex); +171 } +172 } +173 }
      diff --git a/xref/org/owasp/dependencycheck/analyzer/OpenSSLAnalyzer.html b/xref/org/owasp/dependencycheck/analyzer/OpenSSLAnalyzer.html index e59ace550..eab8d7e8f 100644 --- a/xref/org/owasp/dependencycheck/analyzer/OpenSSLAnalyzer.html +++ b/xref/org/owasp/dependencycheck/analyzer/OpenSSLAnalyzer.html @@ -39,186 +39,187 @@ 31 import java.nio.charset.Charset; 32 import java.util.regex.Matcher; 33 import java.util.regex.Pattern; -34 -35 /** -36 * Used to analyze OpenSSL source code present in the file system. -37 * -38 * @author Dale Visser -39 */ -40 public class OpenSSLAnalyzer extends AbstractFileTypeAnalyzer { -41 -42 /** -43 * Hexadecimal. -44 */ -45 private static final int HEXADECIMAL = 16; -46 /** -47 * Filename to analyze. All other .h files get removed from consideration. -48 */ -49 private static final String OPENSSLV_H = "opensslv.h"; -50 -51 /** -52 * Filter that detects files named "__init__.py". -53 */ -54 private static final FileFilter OPENSSLV_FILTER = FileFilterBuilder.newInstance().addFilenames(OPENSSLV_H).build(); -55 /** -56 * Open SSL Version number pattern. -57 */ -58 private static final Pattern VERSION_PATTERN = Pattern.compile( -59 "define\\s+OPENSSL_VERSION_NUMBER\\s+0x([0-9a-zA-Z]{8})L", Pattern.DOTALL -60 | Pattern.CASE_INSENSITIVE); -61 /** -62 * The offset of the major version number. -63 */ -64 private static final int MAJOR_OFFSET = 28; -65 /** -66 * The mask for the minor version number. -67 */ -68 private static final long MINOR_MASK = 0x0ff00000L; -69 /** -70 * The offset of the minor version number. -71 */ -72 private static final int MINOR_OFFSET = 20; -73 /** -74 * The max for the fix version. -75 */ -76 private static final long FIX_MASK = 0x000ff000L; -77 /** -78 * The offset for the fix version. -79 */ -80 private static final int FIX_OFFSET = 12; -81 /** -82 * The mask for the patch version. -83 */ -84 private static final long PATCH_MASK = 0x00000ff0L; -85 /** -86 * The offset for the patch version. -87 */ -88 private static final int PATCH_OFFSET = 4; -89 /** -90 * Number of letters. -91 */ -92 private static final int NUM_LETTERS = 26; -93 /** -94 * The status mask. -95 */ -96 private static final int STATUS_MASK = 0x0000000f; -97 -98 /** -99 * Returns the open SSL version as a string. -100 * -101 * @param openSSLVersionConstant The open SSL version -102 * @return the version of openssl -103 */ -104 static String getOpenSSLVersion(long openSSLVersionConstant) { -105 final long major = openSSLVersionConstant >>> MAJOR_OFFSET; -106 final long minor = (openSSLVersionConstant & MINOR_MASK) >>> MINOR_OFFSET; -107 final long fix = (openSSLVersionConstant & FIX_MASK) >>> FIX_OFFSET; -108 final long patchLevel = (openSSLVersionConstant & PATCH_MASK) >>> PATCH_OFFSET; -109 final String patch = 0 == patchLevel || patchLevel > NUM_LETTERS ? "" : String.valueOf((char) (patchLevel + 'a' - 1)); -110 final int statusCode = (int) (openSSLVersionConstant & STATUS_MASK); -111 final String status = 0xf == statusCode ? "" : (0 == statusCode ? "-dev" : "-beta" + statusCode); -112 return String.format("%d.%d.%d%s%s", major, minor, fix, patch, status); -113 } -114 -115 /** -116 * Returns the name of the Python Package Analyzer. -117 * -118 * @return the name of the analyzer -119 */ -120 @Override -121 public String getName() { -122 return "OpenSSL Source Analyzer"; -123 } -124 -125 /** -126 * Tell that we are used for information collection. -127 * -128 * @return INFORMATION_COLLECTION -129 */ -130 @Override -131 public AnalysisPhase getAnalysisPhase() { -132 return AnalysisPhase.INFORMATION_COLLECTION; -133 } -134 -135 /** -136 * Returns the set of supported file extensions. -137 * -138 * @return the set of supported file extensions -139 */ -140 @Override -141 protected FileFilter getFileFilter() { -142 return OPENSSLV_FILTER; -143 } -144 -145 /** -146 * No-op initializer implementation. -147 * -148 * @throws Exception never thrown -149 */ -150 @Override -151 protected void initializeFileTypeAnalyzer() throws Exception { -152 // Nothing to do here. -153 } -154 -155 /** -156 * Analyzes python packages and adds evidence to the dependency. -157 * -158 * @param dependency the dependency being analyzed -159 * @param engine the engine being used to perform the scan -160 * @throws AnalysisException thrown if there is an unrecoverable error -161 * analyzing the dependency -162 */ -163 @Override -164 protected void analyzeFileType(Dependency dependency, Engine engine) -165 throws AnalysisException { -166 final File file = dependency.getActualFile(); -167 final String parentName = file.getParentFile().getName(); -168 boolean found = false; -169 final String contents = getFileContents(file); -170 if (!contents.isEmpty()) { -171 final Matcher matcher = VERSION_PATTERN.matcher(contents); -172 if (matcher.find()) { -173 dependency.getVersionEvidence().addEvidence(OPENSSLV_H, "Version Constant", -174 getOpenSSLVersion(Long.parseLong(matcher.group(1), HEXADECIMAL)), Confidence.HIGH); -175 found = true; -176 } -177 } -178 if (found) { -179 dependency.setDisplayFileName(parentName + File.separatorChar + OPENSSLV_H); -180 dependency.getVendorEvidence().addEvidence(OPENSSLV_H, "Vendor", "OpenSSL", Confidence.HIGHEST); -181 dependency.getProductEvidence().addEvidence(OPENSSLV_H, "Product", "OpenSSL", Confidence.HIGHEST); -182 } else { -183 engine.getDependencies().remove(dependency); -184 } -185 } -186 -187 /** -188 * Retrieves the contents of a given file. -189 * -190 * @param actualFile the file to read -191 * @return the contents of the file -192 * @throws AnalysisException thrown if there is an IO Exception -193 */ -194 private String getFileContents(final File actualFile) -195 throws AnalysisException { -196 try { -197 return FileUtils.readFileToString(actualFile, Charset.defaultCharset()).trim(); -198 } catch (IOException e) { -199 throw new AnalysisException( -200 "Problem occurred while reading dependency file.", e); -201 } -202 } -203 -204 /** -205 * Returns the setting for the analyzer enabled setting key. -206 * -207 * @return the setting for the analyzer enabled setting key -208 */ -209 @Override -210 protected String getAnalyzerEnabledSettingKey() { -211 return Settings.KEYS.ANALYZER_OPENSSL_ENABLED; -212 } -213 } +34 import org.owasp.dependencycheck.exception.InitializationException; +35 +36 /** +37 * Used to analyze OpenSSL source code present in the file system. +38 * +39 * @author Dale Visser +40 */ +41 public class OpenSSLAnalyzer extends AbstractFileTypeAnalyzer { +42 +43 /** +44 * Hexadecimal. +45 */ +46 private static final int HEXADECIMAL = 16; +47 /** +48 * Filename to analyze. All other .h files get removed from consideration. +49 */ +50 private static final String OPENSSLV_H = "opensslv.h"; +51 +52 /** +53 * Filter that detects files named "__init__.py". +54 */ +55 private static final FileFilter OPENSSLV_FILTER = FileFilterBuilder.newInstance().addFilenames(OPENSSLV_H).build(); +56 /** +57 * Open SSL Version number pattern. +58 */ +59 private static final Pattern VERSION_PATTERN = Pattern.compile( +60 "define\\s+OPENSSL_VERSION_NUMBER\\s+0x([0-9a-zA-Z]{8})L", Pattern.DOTALL +61 | Pattern.CASE_INSENSITIVE); +62 /** +63 * The offset of the major version number. +64 */ +65 private static final int MAJOR_OFFSET = 28; +66 /** +67 * The mask for the minor version number. +68 */ +69 private static final long MINOR_MASK = 0x0ff00000L; +70 /** +71 * The offset of the minor version number. +72 */ +73 private static final int MINOR_OFFSET = 20; +74 /** +75 * The max for the fix version. +76 */ +77 private static final long FIX_MASK = 0x000ff000L; +78 /** +79 * The offset for the fix version. +80 */ +81 private static final int FIX_OFFSET = 12; +82 /** +83 * The mask for the patch version. +84 */ +85 private static final long PATCH_MASK = 0x00000ff0L; +86 /** +87 * The offset for the patch version. +88 */ +89 private static final int PATCH_OFFSET = 4; +90 /** +91 * Number of letters. +92 */ +93 private static final int NUM_LETTERS = 26; +94 /** +95 * The status mask. +96 */ +97 private static final int STATUS_MASK = 0x0000000f; +98 +99 /** +100 * Returns the open SSL version as a string. +101 * +102 * @param openSSLVersionConstant The open SSL version +103 * @return the version of openssl +104 */ +105 static String getOpenSSLVersion(long openSSLVersionConstant) { +106 final long major = openSSLVersionConstant >>> MAJOR_OFFSET; +107 final long minor = (openSSLVersionConstant & MINOR_MASK) >>> MINOR_OFFSET; +108 final long fix = (openSSLVersionConstant & FIX_MASK) >>> FIX_OFFSET; +109 final long patchLevel = (openSSLVersionConstant & PATCH_MASK) >>> PATCH_OFFSET; +110 final String patch = 0 == patchLevel || patchLevel > NUM_LETTERS ? "" : String.valueOf((char) (patchLevel + 'a' - 1)); +111 final int statusCode = (int) (openSSLVersionConstant & STATUS_MASK); +112 final String status = 0xf == statusCode ? "" : (0 == statusCode ? "-dev" : "-beta" + statusCode); +113 return String.format("%d.%d.%d%s%s", major, minor, fix, patch, status); +114 } +115 +116 /** +117 * Returns the name of the Python Package Analyzer. +118 * +119 * @return the name of the analyzer +120 */ +121 @Override +122 public String getName() { +123 return "OpenSSL Source Analyzer"; +124 } +125 +126 /** +127 * Tell that we are used for information collection. +128 * +129 * @return INFORMATION_COLLECTION +130 */ +131 @Override +132 public AnalysisPhase getAnalysisPhase() { +133 return AnalysisPhase.INFORMATION_COLLECTION; +134 } +135 +136 /** +137 * Returns the set of supported file extensions. +138 * +139 * @return the set of supported file extensions +140 */ +141 @Override +142 protected FileFilter getFileFilter() { +143 return OPENSSLV_FILTER; +144 } +145 +146 /** +147 * No-op initializer implementation. +148 * +149 * @throws InitializationException never thrown +150 */ +151 @Override +152 protected void initializeFileTypeAnalyzer() throws InitializationException { +153 // Nothing to do here. +154 } +155 +156 /** +157 * Analyzes python packages and adds evidence to the dependency. +158 * +159 * @param dependency the dependency being analyzed +160 * @param engine the engine being used to perform the scan +161 * @throws AnalysisException thrown if there is an unrecoverable error +162 * analyzing the dependency +163 */ +164 @Override +165 protected void analyzeFileType(Dependency dependency, Engine engine) +166 throws AnalysisException { +167 final File file = dependency.getActualFile(); +168 final String parentName = file.getParentFile().getName(); +169 boolean found = false; +170 final String contents = getFileContents(file); +171 if (!contents.isEmpty()) { +172 final Matcher matcher = VERSION_PATTERN.matcher(contents); +173 if (matcher.find()) { +174 dependency.getVersionEvidence().addEvidence(OPENSSLV_H, "Version Constant", +175 getOpenSSLVersion(Long.parseLong(matcher.group(1), HEXADECIMAL)), Confidence.HIGH); +176 found = true; +177 } +178 } +179 if (found) { +180 dependency.setDisplayFileName(parentName + File.separatorChar + OPENSSLV_H); +181 dependency.getVendorEvidence().addEvidence(OPENSSLV_H, "Vendor", "OpenSSL", Confidence.HIGHEST); +182 dependency.getProductEvidence().addEvidence(OPENSSLV_H, "Product", "OpenSSL", Confidence.HIGHEST); +183 } else { +184 engine.getDependencies().remove(dependency); +185 } +186 } +187 +188 /** +189 * Retrieves the contents of a given file. +190 * +191 * @param actualFile the file to read +192 * @return the contents of the file +193 * @throws AnalysisException thrown if there is an IO Exception +194 */ +195 private String getFileContents(final File actualFile) +196 throws AnalysisException { +197 try { +198 return FileUtils.readFileToString(actualFile, Charset.defaultCharset()).trim(); +199 } catch (IOException e) { +200 throw new AnalysisException( +201 "Problem occurred while reading dependency file.", e); +202 } +203 } +204 +205 /** +206 * Returns the setting for the analyzer enabled setting key. +207 * +208 * @return the setting for the analyzer enabled setting key +209 */ +210 @Override +211 protected String getAnalyzerEnabledSettingKey() { +212 return Settings.KEYS.ANALYZER_OPENSSL_ENABLED; +213 } +214 }
      diff --git a/xref/org/owasp/dependencycheck/analyzer/PythonDistributionAnalyzer.html b/xref/org/owasp/dependencycheck/analyzer/PythonDistributionAnalyzer.html index 0259a9aa0..e9aefa0d9 100644 --- a/xref/org/owasp/dependencycheck/analyzer/PythonDistributionAnalyzer.html +++ b/xref/org/owasp/dependencycheck/analyzer/PythonDistributionAnalyzer.html @@ -31,356 +31,373 @@ 23 import java.io.FileInputStream; 24 import java.io.FileNotFoundException; 25 import java.io.FilenameFilter; -26 import org.apache.commons.io.filefilter.NameFileFilter; -27 import org.apache.commons.io.filefilter.SuffixFileFilter; -28 import org.apache.commons.io.input.AutoCloseInputStream; -29 import org.apache.commons.lang3.StringUtils; -30 import org.owasp.dependencycheck.Engine; -31 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; -32 import org.owasp.dependencycheck.dependency.Confidence; -33 import org.owasp.dependencycheck.dependency.Dependency; -34 import org.owasp.dependencycheck.dependency.EvidenceCollection; -35 import org.slf4j.Logger; -36 import org.slf4j.LoggerFactory; -37 -38 import javax.mail.MessagingException; -39 import javax.mail.internet.InternetHeaders; -40 import org.owasp.dependencycheck.utils.ExtractionException; -41 import org.owasp.dependencycheck.utils.ExtractionUtil; -42 import org.owasp.dependencycheck.utils.FileFilterBuilder; -43 import org.owasp.dependencycheck.utils.FileUtils; -44 import org.owasp.dependencycheck.utils.Settings; -45 import org.owasp.dependencycheck.utils.UrlStringUtils; -46 -47 /** -48 * Used to analyze a Wheel or egg distribution files, or their contents in unzipped form, and collect information that can be used -49 * to determine the associated CPE. -50 * -51 * @author Dale Visser -52 */ -53 @Experimental -54 public class PythonDistributionAnalyzer extends AbstractFileTypeAnalyzer { -55 -56 /** -57 * Name of egg metadata files to analyze. -58 */ -59 private static final String PKG_INFO = "PKG-INFO"; -60 -61 /** -62 * Name of wheel metadata files to analyze. -63 */ -64 private static final String METADATA = "METADATA"; -65 -66 /** -67 * The logger. -68 */ -69 private static final Logger LOGGER = LoggerFactory -70 .getLogger(PythonDistributionAnalyzer.class); -71 -72 /** -73 * The count of directories created during analysis. This is used for creating temporary directories. -74 */ -75 private static int dirCount = 0; -76 -77 /** -78 * The name of the analyzer. -79 */ -80 private static final String ANALYZER_NAME = "Python Distribution Analyzer"; +26 import java.io.IOException; +27 import org.apache.commons.io.filefilter.NameFileFilter; +28 import org.apache.commons.io.filefilter.SuffixFileFilter; +29 import org.apache.commons.io.input.AutoCloseInputStream; +30 import org.apache.commons.lang3.StringUtils; +31 import org.owasp.dependencycheck.Engine; +32 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; +33 import org.owasp.dependencycheck.dependency.Confidence; +34 import org.owasp.dependencycheck.dependency.Dependency; +35 import org.owasp.dependencycheck.dependency.EvidenceCollection; +36 import org.slf4j.Logger; +37 import org.slf4j.LoggerFactory; +38 +39 import javax.mail.MessagingException; +40 import javax.mail.internet.InternetHeaders; +41 import org.owasp.dependencycheck.exception.InitializationException; +42 import org.owasp.dependencycheck.utils.ExtractionException; +43 import org.owasp.dependencycheck.utils.ExtractionUtil; +44 import org.owasp.dependencycheck.utils.FileFilterBuilder; +45 import org.owasp.dependencycheck.utils.FileUtils; +46 import org.owasp.dependencycheck.utils.Settings; +47 import org.owasp.dependencycheck.utils.UrlStringUtils; +48 +49 /** +50 * Used to analyze a Wheel or egg distribution files, or their contents in +51 * unzipped form, and collect information that can be used to determine the +52 * associated CPE. +53 * +54 * @author Dale Visser +55 */ +56 @Experimental +57 public class PythonDistributionAnalyzer extends AbstractFileTypeAnalyzer { +58 +59 /** +60 * Name of egg metadata files to analyze. +61 */ +62 private static final String PKG_INFO = "PKG-INFO"; +63 +64 /** +65 * Name of wheel metadata files to analyze. +66 */ +67 private static final String METADATA = "METADATA"; +68 +69 /** +70 * The logger. +71 */ +72 private static final Logger LOGGER = LoggerFactory +73 .getLogger(PythonDistributionAnalyzer.class); +74 +75 /** +76 * The count of directories created during analysis. This is used for +77 * creating temporary directories. +78 */ +79 private static int dirCount = 0; +80 81 /** -82 * The phase that this analyzer is intended to run in. +82 * The name of the analyzer. 83 */ -84 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; -85 -86 /** -87 * The set of file extensions supported by this analyzer. -88 */ -89 private static final String[] EXTENSIONS = {"whl", "egg", "zip"}; -90 -91 /** -92 * Used to match on egg archive candidate extensions. -93 */ -94 private static final FileFilter EGG_OR_ZIP = FileFilterBuilder.newInstance().addExtensions("egg", "zip").build(); -95 -96 /** -97 * Used to detect files with a .whl extension. -98 */ -99 private static final FileFilter WHL_FILTER = FileFilterBuilder.newInstance().addExtensions("whl").build(); -100 -101 /** -102 * The parent directory for the individual directories per archive. -103 */ -104 private File tempFileLocation; -105 -106 /** -107 * Filter that detects *.dist-info files (but doesn't verify they are directories. -108 */ -109 private static final FilenameFilter DIST_INFO_FILTER = new SuffixFileFilter( -110 ".dist-info"); -111 -112 /** -113 * Filter that detects files named "METADATA". -114 */ -115 private static final FilenameFilter EGG_INFO_FILTER = new NameFileFilter( -116 "EGG-INFO"); -117 -118 /** -119 * Filter that detects files named "METADATA". -120 */ -121 private static final NameFileFilter METADATA_FILTER = new NameFileFilter( -122 METADATA); -123 -124 /** -125 * Filter that detects files named "PKG-INFO". -126 */ -127 private static final NameFileFilter PKG_INFO_FILTER = new NameFileFilter( -128 PKG_INFO); -129 -130 /** -131 * The file filter used to determine which files this analyzer supports. -132 */ -133 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addFileFilters( -134 METADATA_FILTER, PKG_INFO_FILTER).addExtensions(EXTENSIONS).build(); -135 -136 /** -137 * Returns the FileFilter -138 * -139 * @return the FileFilter -140 */ -141 @Override -142 protected FileFilter getFileFilter() { -143 return FILTER; -144 } -145 -146 /** -147 * Returns the name of the analyzer. -148 * -149 * @return the name of the analyzer. -150 */ -151 @Override -152 public String getName() { -153 return ANALYZER_NAME; -154 } -155 -156 /** -157 * Returns the phase that the analyzer is intended to run in. -158 * -159 * @return the phase that the analyzer is intended to run in. -160 */ -161 @Override -162 public AnalysisPhase getAnalysisPhase() { -163 return ANALYSIS_PHASE; -164 } -165 -166 /** -167 * Returns the key used in the properties file to reference the analyzer's enabled property. -168 * -169 * @return the analyzer's enabled property setting key -170 */ -171 @Override -172 protected String getAnalyzerEnabledSettingKey() { -173 return Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED; -174 } -175 -176 @Override -177 protected void analyzeFileType(Dependency dependency, Engine engine) -178 throws AnalysisException { -179 final File actualFile = dependency.getActualFile(); -180 if (WHL_FILTER.accept(actualFile)) { -181 collectMetadataFromArchiveFormat(dependency, DIST_INFO_FILTER, -182 METADATA_FILTER); -183 } else if (EGG_OR_ZIP.accept(actualFile)) { -184 collectMetadataFromArchiveFormat(dependency, EGG_INFO_FILTER, -185 PKG_INFO_FILTER); -186 } else { -187 final String name = actualFile.getName(); -188 final boolean metadata = METADATA.equals(name); -189 if (metadata || PKG_INFO.equals(name)) { -190 final File parent = actualFile.getParentFile(); -191 final String parentName = parent.getName(); -192 dependency.setDisplayFileName(parentName + "/" + name); -193 if (parent.isDirectory() -194 && (metadata && parentName.endsWith(".dist-info") -195 || parentName.endsWith(".egg-info") || "EGG-INFO" -196 .equals(parentName))) { -197 collectWheelMetadata(dependency, actualFile); -198 } -199 } -200 } -201 } -202 -203 /** -204 * Collects the meta data from an archive. -205 * -206 * @param dependency the archive being scanned -207 * @param folderFilter the filter to apply to the folder -208 * @param metadataFilter the filter to apply to the meta data -209 * @throws AnalysisException thrown when there is a problem analyzing the dependency -210 */ -211 private void collectMetadataFromArchiveFormat(Dependency dependency, -212 FilenameFilter folderFilter, FilenameFilter metadataFilter) -213 throws AnalysisException { -214 final File temp = getNextTempDirectory(); -215 LOGGER.debug("{} exists? {}", temp, temp.exists()); -216 try { -217 ExtractionUtil.extractFilesUsingFilter( -218 new File(dependency.getActualFilePath()), temp, -219 metadataFilter); -220 } catch (ExtractionException ex) { -221 throw new AnalysisException(ex); -222 } -223 -224 collectWheelMetadata( -225 dependency, -226 getMatchingFile(getMatchingFile(temp, folderFilter), -227 metadataFilter)); -228 } -229 -230 /** -231 * Makes sure a usable temporary directory is available. -232 * -233 * @throws Exception an AnalyzeException is thrown when the temp directory cannot be created -234 */ -235 @Override -236 protected void initializeFileTypeAnalyzer() throws Exception { -237 final File baseDir = Settings.getTempDirectory(); -238 tempFileLocation = File.createTempFile("check", "tmp", baseDir); -239 if (!tempFileLocation.delete()) { -240 final String msg = String.format( -241 "Unable to delete temporary file '%s'.", -242 tempFileLocation.getAbsolutePath()); -243 throw new AnalysisException(msg); -244 } -245 if (!tempFileLocation.mkdirs()) { -246 final String msg = String.format( -247 "Unable to create directory '%s'.", -248 tempFileLocation.getAbsolutePath()); -249 throw new AnalysisException(msg); -250 } -251 } -252 -253 /** -254 * Deletes any files extracted from the Wheel during analysis. -255 */ -256 @Override -257 public void close() { -258 if (tempFileLocation != null && tempFileLocation.exists()) { -259 LOGGER.debug("Attempting to delete temporary files"); -260 final boolean success = FileUtils.delete(tempFileLocation); -261 if (!success) { -262 LOGGER.warn( -263 "Failed to delete some temporary files, see the log for more details"); -264 } +84 private static final String ANALYZER_NAME = "Python Distribution Analyzer"; +85 /** +86 * The phase that this analyzer is intended to run in. +87 */ +88 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; +89 +90 /** +91 * The set of file extensions supported by this analyzer. +92 */ +93 private static final String[] EXTENSIONS = {"whl", "egg", "zip"}; +94 +95 /** +96 * Used to match on egg archive candidate extensions. +97 */ +98 private static final FileFilter EGG_OR_ZIP = FileFilterBuilder.newInstance().addExtensions("egg", "zip").build(); +99 +100 /** +101 * Used to detect files with a .whl extension. +102 */ +103 private static final FileFilter WHL_FILTER = FileFilterBuilder.newInstance().addExtensions("whl").build(); +104 +105 /** +106 * The parent directory for the individual directories per archive. +107 */ +108 private File tempFileLocation; +109 +110 /** +111 * Filter that detects *.dist-info files (but doesn't verify they are +112 * directories. +113 */ +114 private static final FilenameFilter DIST_INFO_FILTER = new SuffixFileFilter( +115 ".dist-info"); +116 +117 /** +118 * Filter that detects files named "METADATA". +119 */ +120 private static final FilenameFilter EGG_INFO_FILTER = new NameFileFilter( +121 "EGG-INFO"); +122 +123 /** +124 * Filter that detects files named "METADATA". +125 */ +126 private static final NameFileFilter METADATA_FILTER = new NameFileFilter( +127 METADATA); +128 +129 /** +130 * Filter that detects files named "PKG-INFO". +131 */ +132 private static final NameFileFilter PKG_INFO_FILTER = new NameFileFilter( +133 PKG_INFO); +134 +135 /** +136 * The file filter used to determine which files this analyzer supports. +137 */ +138 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addFileFilters( +139 METADATA_FILTER, PKG_INFO_FILTER).addExtensions(EXTENSIONS).build(); +140 +141 /** +142 * Returns the FileFilter +143 * +144 * @return the FileFilter +145 */ +146 @Override +147 protected FileFilter getFileFilter() { +148 return FILTER; +149 } +150 +151 /** +152 * Returns the name of the analyzer. +153 * +154 * @return the name of the analyzer. +155 */ +156 @Override +157 public String getName() { +158 return ANALYZER_NAME; +159 } +160 +161 /** +162 * Returns the phase that the analyzer is intended to run in. +163 * +164 * @return the phase that the analyzer is intended to run in. +165 */ +166 @Override +167 public AnalysisPhase getAnalysisPhase() { +168 return ANALYSIS_PHASE; +169 } +170 +171 /** +172 * Returns the key used in the properties file to reference the analyzer's +173 * enabled property. +174 * +175 * @return the analyzer's enabled property setting key +176 */ +177 @Override +178 protected String getAnalyzerEnabledSettingKey() { +179 return Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED; +180 } +181 +182 @Override +183 protected void analyzeFileType(Dependency dependency, Engine engine) +184 throws AnalysisException { +185 final File actualFile = dependency.getActualFile(); +186 if (WHL_FILTER.accept(actualFile)) { +187 collectMetadataFromArchiveFormat(dependency, DIST_INFO_FILTER, +188 METADATA_FILTER); +189 } else if (EGG_OR_ZIP.accept(actualFile)) { +190 collectMetadataFromArchiveFormat(dependency, EGG_INFO_FILTER, +191 PKG_INFO_FILTER); +192 } else { +193 final String name = actualFile.getName(); +194 final boolean metadata = METADATA.equals(name); +195 if (metadata || PKG_INFO.equals(name)) { +196 final File parent = actualFile.getParentFile(); +197 final String parentName = parent.getName(); +198 dependency.setDisplayFileName(parentName + "/" + name); +199 if (parent.isDirectory() +200 && (metadata && parentName.endsWith(".dist-info") +201 || parentName.endsWith(".egg-info") || "EGG-INFO" +202 .equals(parentName))) { +203 collectWheelMetadata(dependency, actualFile); +204 } +205 } +206 } +207 } +208 +209 /** +210 * Collects the meta data from an archive. +211 * +212 * @param dependency the archive being scanned +213 * @param folderFilter the filter to apply to the folder +214 * @param metadataFilter the filter to apply to the meta data +215 * @throws AnalysisException thrown when there is a problem analyzing the +216 * dependency +217 */ +218 private void collectMetadataFromArchiveFormat(Dependency dependency, +219 FilenameFilter folderFilter, FilenameFilter metadataFilter) +220 throws AnalysisException { +221 final File temp = getNextTempDirectory(); +222 LOGGER.debug("{} exists? {}", temp, temp.exists()); +223 try { +224 ExtractionUtil.extractFilesUsingFilter( +225 new File(dependency.getActualFilePath()), temp, +226 metadataFilter); +227 } catch (ExtractionException ex) { +228 throw new AnalysisException(ex); +229 } +230 +231 collectWheelMetadata( +232 dependency, +233 getMatchingFile(getMatchingFile(temp, folderFilter), +234 metadataFilter)); +235 } +236 +237 /** +238 * Makes sure a usable temporary directory is available. +239 * +240 * @throws InitializationException an AnalyzeException is thrown when the +241 * temp directory cannot be created +242 */ +243 @Override +244 protected void initializeFileTypeAnalyzer() throws InitializationException { +245 try { +246 final File baseDir = Settings.getTempDirectory(); +247 tempFileLocation = File.createTempFile("check", "tmp", baseDir); +248 if (!tempFileLocation.delete()) { +249 setEnabled(false); +250 final String msg = String.format( +251 "Unable to delete temporary file '%s'.", +252 tempFileLocation.getAbsolutePath()); +253 throw new InitializationException(msg); +254 } +255 if (!tempFileLocation.mkdirs()) { +256 setEnabled(false); +257 final String msg = String.format( +258 "Unable to create directory '%s'.", +259 tempFileLocation.getAbsolutePath()); +260 throw new InitializationException(msg); +261 } +262 } catch (IOException ex) { +263 setEnabled(false); +264 throw new InitializationException("Unable to create a temporary file", ex); 265 } 266 } 267 268 /** -269 * Gathers evidence from the METADATA file. -270 * -271 * @param dependency the dependency being analyzed -272 * @param file a reference to the manifest/properties file -273 */ -274 private static void collectWheelMetadata(Dependency dependency, File file) { -275 final InternetHeaders headers = getManifestProperties(file); -276 addPropertyToEvidence(headers, dependency.getVersionEvidence(), -277 "Version", Confidence.HIGHEST); -278 addPropertyToEvidence(headers, dependency.getProductEvidence(), "Name", -279 Confidence.HIGHEST); -280 final String url = headers.getHeader("Home-page", null); -281 final EvidenceCollection vendorEvidence = dependency -282 .getVendorEvidence(); -283 if (StringUtils.isNotBlank(url)) { -284 if (UrlStringUtils.isUrl(url)) { -285 vendorEvidence.addEvidence(METADATA, "vendor", url, -286 Confidence.MEDIUM); -287 } -288 } -289 addPropertyToEvidence(headers, vendorEvidence, "Author", Confidence.LOW); -290 final String summary = headers.getHeader("Summary", null); -291 if (StringUtils.isNotBlank(summary)) { -292 JarAnalyzer -293 .addDescription(dependency, summary, METADATA, "summary"); -294 } -295 } -296 -297 /** -298 * Adds a value to the evidence collection. -299 * -300 * @param headers the properties collection -301 * @param evidence the evidence collection to add the value -302 * @param property the property name -303 * @param confidence the confidence of the evidence -304 */ -305 private static void addPropertyToEvidence(InternetHeaders headers, -306 EvidenceCollection evidence, String property, Confidence confidence) { -307 final String value = headers.getHeader(property, null); -308 LOGGER.debug("Property: {}, Value: {}", property, value); -309 if (StringUtils.isNotBlank(value)) { -310 evidence.addEvidence(METADATA, property, value, confidence); -311 } -312 } -313 -314 /** -315 * Returns a list of files that match the given filter, this does not recursively scan the directory. -316 * -317 * @param folder the folder to filter -318 * @param filter the filter to apply to the files in the directory -319 * @return the list of Files in the directory that match the provided filter -320 */ -321 private static File getMatchingFile(File folder, FilenameFilter filter) { -322 File result = null; -323 final File[] matches = folder.listFiles(filter); -324 if (null != matches && 1 == matches.length) { -325 result = matches[0]; +269 * Deletes any files extracted from the Wheel during analysis. +270 */ +271 @Override +272 public void close() { +273 if (tempFileLocation != null && tempFileLocation.exists()) { +274 LOGGER.debug("Attempting to delete temporary files"); +275 final boolean success = FileUtils.delete(tempFileLocation); +276 if (!success) { +277 LOGGER.warn( +278 "Failed to delete some temporary files, see the log for more details"); +279 } +280 } +281 } +282 +283 /** +284 * Gathers evidence from the METADATA file. +285 * +286 * @param dependency the dependency being analyzed +287 * @param file a reference to the manifest/properties file +288 */ +289 private static void collectWheelMetadata(Dependency dependency, File file) { +290 final InternetHeaders headers = getManifestProperties(file); +291 addPropertyToEvidence(headers, dependency.getVersionEvidence(), +292 "Version", Confidence.HIGHEST); +293 addPropertyToEvidence(headers, dependency.getProductEvidence(), "Name", +294 Confidence.HIGHEST); +295 final String url = headers.getHeader("Home-page", null); +296 final EvidenceCollection vendorEvidence = dependency +297 .getVendorEvidence(); +298 if (StringUtils.isNotBlank(url)) { +299 if (UrlStringUtils.isUrl(url)) { +300 vendorEvidence.addEvidence(METADATA, "vendor", url, +301 Confidence.MEDIUM); +302 } +303 } +304 addPropertyToEvidence(headers, vendorEvidence, "Author", Confidence.LOW); +305 final String summary = headers.getHeader("Summary", null); +306 if (StringUtils.isNotBlank(summary)) { +307 JarAnalyzer +308 .addDescription(dependency, summary, METADATA, "summary"); +309 } +310 } +311 +312 /** +313 * Adds a value to the evidence collection. +314 * +315 * @param headers the properties collection +316 * @param evidence the evidence collection to add the value +317 * @param property the property name +318 * @param confidence the confidence of the evidence +319 */ +320 private static void addPropertyToEvidence(InternetHeaders headers, +321 EvidenceCollection evidence, String property, Confidence confidence) { +322 final String value = headers.getHeader(property, null); +323 LOGGER.debug("Property: {}, Value: {}", property, value); +324 if (StringUtils.isNotBlank(value)) { +325 evidence.addEvidence(METADATA, property, value, confidence); 326 } -327 return result; -328 } -329 -330 /** -331 * Reads the manifest entries from the provided file. +327 } +328 +329 /** +330 * Returns a list of files that match the given filter, this does not +331 * recursively scan the directory. 332 * -333 * @param manifest the manifest -334 * @return the manifest entries -335 */ -336 private static InternetHeaders getManifestProperties(File manifest) { -337 final InternetHeaders result = new InternetHeaders(); -338 if (null == manifest) { -339 LOGGER.debug("Manifest file not found."); -340 } else { -341 try { -342 result.load(new AutoCloseInputStream(new BufferedInputStream( -343 new FileInputStream(manifest)))); -344 } catch (MessagingException e) { -345 LOGGER.warn(e.getMessage(), e); -346 } catch (FileNotFoundException e) { -347 LOGGER.warn(e.getMessage(), e); -348 } -349 } -350 return result; -351 } -352 -353 /** -354 * Retrieves the next temporary destination directory for extracting an archive. -355 * -356 * @return a directory -357 * @throws AnalysisException thrown if unable to create temporary directory -358 */ -359 private File getNextTempDirectory() throws AnalysisException { -360 File directory; -361 -362 // getting an exception for some directories not being able to be -363 // created; might be because the directory already exists? -364 do { -365 dirCount += 1; -366 directory = new File(tempFileLocation, String.valueOf(dirCount)); -367 } while (directory.exists()); -368 if (!directory.mkdirs()) { -369 throw new AnalysisException(String.format( -370 "Unable to create temp directory '%s'.", -371 directory.getAbsolutePath())); -372 } -373 return directory; -374 } -375 } +333 * @param folder the folder to filter +334 * @param filter the filter to apply to the files in the directory +335 * @return the list of Files in the directory that match the provided filter +336 */ +337 private static File getMatchingFile(File folder, FilenameFilter filter) { +338 File result = null; +339 final File[] matches = folder.listFiles(filter); +340 if (null != matches && 1 == matches.length) { +341 result = matches[0]; +342 } +343 return result; +344 } +345 +346 /** +347 * Reads the manifest entries from the provided file. +348 * +349 * @param manifest the manifest +350 * @return the manifest entries +351 */ +352 private static InternetHeaders getManifestProperties(File manifest) { +353 final InternetHeaders result = new InternetHeaders(); +354 if (null == manifest) { +355 LOGGER.debug("Manifest file not found."); +356 } else { +357 try { +358 result.load(new AutoCloseInputStream(new BufferedInputStream( +359 new FileInputStream(manifest)))); +360 } catch (MessagingException e) { +361 LOGGER.warn(e.getMessage(), e); +362 } catch (FileNotFoundException e) { +363 LOGGER.warn(e.getMessage(), e); +364 } +365 } +366 return result; +367 } +368 +369 /** +370 * Retrieves the next temporary destination directory for extracting an +371 * archive. +372 * +373 * @return a directory +374 * @throws AnalysisException thrown if unable to create temporary directory +375 */ +376 private File getNextTempDirectory() throws AnalysisException { +377 File directory; +378 +379 // getting an exception for some directories not being able to be +380 // created; might be because the directory already exists? +381 do { +382 dirCount += 1; +383 directory = new File(tempFileLocation, String.valueOf(dirCount)); +384 } while (directory.exists()); +385 if (!directory.mkdirs()) { +386 throw new AnalysisException(String.format( +387 "Unable to create temp directory '%s'.", +388 directory.getAbsolutePath())); +389 } +390 return directory; +391 } +392 }
      diff --git a/xref/org/owasp/dependencycheck/analyzer/PythonPackageAnalyzer.html b/xref/org/owasp/dependencycheck/analyzer/PythonPackageAnalyzer.html index e87b494a2..847ae696f 100644 --- a/xref/org/owasp/dependencycheck/analyzer/PythonPackageAnalyzer.html +++ b/xref/org/owasp/dependencycheck/analyzer/PythonPackageAnalyzer.html @@ -45,290 +45,291 @@ 37 import java.util.List; 38 import java.util.regex.Matcher; 39 import java.util.regex.Pattern; -40 -41 /** -42 * Used to analyze a Python package, and collect information that can be used to -43 * determine the associated CPE. -44 * -45 * @author Dale Visser -46 */ -47 @Experimental -48 public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer { -49 -50 /** -51 * Used when compiling file scanning regex patterns. -52 */ -53 private static final int REGEX_OPTIONS = Pattern.DOTALL -54 | Pattern.CASE_INSENSITIVE; -55 -56 /** -57 * Filename extensions for files to be analyzed. -58 */ -59 private static final String EXTENSIONS = "py"; -60 -61 /** -62 * Pattern for matching the module docstring in a source file. -63 */ -64 private static final Pattern MODULE_DOCSTRING = Pattern.compile( -65 "^(['\\\"]{3})(.*?)\\1", REGEX_OPTIONS); -66 -67 /** -68 * Matches assignments to version variables in Python source code. -69 */ -70 private static final Pattern VERSION_PATTERN = Pattern.compile( -71 "\\b(__)?version(__)? *= *(['\"]+)(\\d+\\.\\d+.*?)\\3", -72 REGEX_OPTIONS); -73 -74 /** -75 * Matches assignments to title variables in Python source code. -76 */ -77 private static final Pattern TITLE_PATTERN = compileAssignPattern("title"); -78 -79 /** -80 * Matches assignments to summary variables in Python source code. -81 */ -82 private static final Pattern SUMMARY_PATTERN = compileAssignPattern("summary"); -83 -84 /** -85 * Matches assignments to URL/URL variables in Python source code. -86 */ -87 private static final Pattern URI_PATTERN = compileAssignPattern("ur[il]"); -88 -89 /** -90 * Matches assignments to home page variables in Python source code. -91 */ -92 private static final Pattern HOMEPAGE_PATTERN = compileAssignPattern("home_?page"); -93 -94 /** -95 * Matches assignments to author variables in Python source code. -96 */ -97 private static final Pattern AUTHOR_PATTERN = compileAssignPattern("author"); -98 -99 /** -100 * Filter that detects files named "__init__.py". -101 */ -102 private static final FileFilter INIT_PY_FILTER = new NameFileFilter("__init__.py"); -103 -104 /** -105 * The file filter for python files. -106 */ -107 private static final FileFilter PY_FILTER = new SuffixFileFilter(".py"); -108 -109 /** -110 * Returns the name of the Python Package Analyzer. -111 * -112 * @return the name of the analyzer -113 */ -114 @Override -115 public String getName() { -116 return "Python Package Analyzer"; -117 } -118 -119 /** -120 * Tell that we are used for information collection. -121 * -122 * @return INFORMATION_COLLECTION -123 */ -124 @Override -125 public AnalysisPhase getAnalysisPhase() { -126 return AnalysisPhase.INFORMATION_COLLECTION; -127 } -128 -129 /** -130 * The file filter used to determine which files this analyzer supports. -131 */ -132 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(EXTENSIONS).build(); -133 -134 /** -135 * Returns the FileFilter -136 * -137 * @return the FileFilter -138 */ -139 @Override -140 protected FileFilter getFileFilter() { -141 return FILTER; -142 } -143 -144 /** -145 * No-op initializer implementation. -146 * -147 * @throws Exception never thrown -148 */ -149 @Override -150 protected void initializeFileTypeAnalyzer() throws Exception { -151 // Nothing to do here. -152 } -153 -154 /** -155 * Utility function to create a regex pattern matcher. -156 * -157 * @param name the value to use when constructing the assignment pattern -158 * @return the compiled Pattern -159 */ -160 private static Pattern compileAssignPattern(String name) { -161 return Pattern.compile( -162 String.format("\\b(__)?%s(__)?\\b *= *(['\"]+)(.*?)\\3", name), -163 REGEX_OPTIONS); -164 } -165 -166 /** -167 * Analyzes python packages and adds evidence to the dependency. -168 * -169 * @param dependency the dependency being analyzed -170 * @param engine the engine being used to perform the scan -171 * @throws AnalysisException thrown if there is an unrecoverable error -172 * analyzing the dependency -173 */ -174 @Override -175 protected void analyzeFileType(Dependency dependency, Engine engine) -176 throws AnalysisException { -177 final File file = dependency.getActualFile(); -178 final File parent = file.getParentFile(); -179 final String parentName = parent.getName(); -180 if (INIT_PY_FILTER.accept(file)) { -181 //by definition, the containing folder of __init__.py is considered the package, even the file is empty: -182 //"The __init__.py files are required to make Python treat the directories as containing packages" -183 //see section "6.4 Packages" from https://docs.python.org/2/tutorial/modules.html; -184 dependency.setDisplayFileName(parentName + "/__init__.py"); -185 dependency.getProductEvidence().addEvidence(file.getName(), -186 "PackageName", parentName, Confidence.HIGHEST); -187 -188 final File[] fileList = parent.listFiles(PY_FILTER); -189 if (fileList != null) { -190 for (final File sourceFile : fileList) { -191 analyzeFileContents(dependency, sourceFile); -192 } -193 } -194 } else { -195 // copy, alter and set in case some other thread is iterating over -196 final List<Dependency> dependencies = new ArrayList<Dependency>( -197 engine.getDependencies()); -198 dependencies.remove(dependency); -199 engine.setDependencies(dependencies); -200 } -201 } -202 -203 /** -204 * This should gather information from leading docstrings, file comments, -205 * and assignments to __version__, __title__, __summary__, __uri__, __url__, -206 * __home*page__, __author__, and their all caps equivalents. -207 * -208 * @param dependency the dependency being analyzed -209 * @param file the file name to analyze -210 * @return whether evidence was found -211 * @throws AnalysisException thrown if there is an unrecoverable error -212 */ -213 private boolean analyzeFileContents(Dependency dependency, File file) -214 throws AnalysisException { -215 String contents; -216 try { -217 contents = FileUtils.readFileToString(file, Charset.defaultCharset()).trim(); -218 } catch (IOException e) { -219 throw new AnalysisException( -220 "Problem occurred while reading dependency file.", e); -221 } -222 boolean found = false; -223 if (!contents.isEmpty()) { -224 final String source = file.getName(); -225 found = gatherEvidence(VERSION_PATTERN, contents, source, -226 dependency.getVersionEvidence(), "SourceVersion", -227 Confidence.MEDIUM); -228 found |= addSummaryInfo(dependency, SUMMARY_PATTERN, 4, contents, -229 source, "summary"); -230 if (INIT_PY_FILTER.accept(file)) { -231 found |= addSummaryInfo(dependency, MODULE_DOCSTRING, 2, -232 contents, source, "docstring"); -233 } -234 found |= gatherEvidence(TITLE_PATTERN, contents, source, -235 dependency.getProductEvidence(), "SourceTitle", -236 Confidence.LOW); -237 final EvidenceCollection vendorEvidence = dependency -238 .getVendorEvidence(); -239 found |= gatherEvidence(AUTHOR_PATTERN, contents, source, -240 vendorEvidence, "SourceAuthor", Confidence.MEDIUM); -241 found |= gatherHomePageEvidence(URI_PATTERN, vendorEvidence, -242 source, "URL", contents); -243 found |= gatherHomePageEvidence(HOMEPAGE_PATTERN, -244 vendorEvidence, source, "HomePage", contents); -245 } -246 return found; -247 } -248 -249 /** -250 * Adds summary information to the dependency -251 * -252 * @param dependency the dependency being analyzed -253 * @param pattern the pattern used to perform analysis -254 * @param group the group from the pattern that indicates the data to use -255 * @param contents the data being analyzed -256 * @param source the source name to use when recording the evidence -257 * @param key the key name to use when recording the evidence -258 * @return true if evidence was collected; otherwise false -259 */ -260 private boolean addSummaryInfo(Dependency dependency, Pattern pattern, -261 int group, String contents, String source, String key) { -262 final Matcher matcher = pattern.matcher(contents); -263 final boolean found = matcher.find(); -264 if (found) { -265 JarAnalyzer.addDescription(dependency, matcher.group(group), -266 source, key); -267 } -268 return found; -269 } -270 -271 /** -272 * Collects evidence from the home page URL. -273 * -274 * @param pattern the pattern to match -275 * @param evidence the evidence collection to add the evidence to -276 * @param source the source of the evidence -277 * @param name the name of the evidence -278 * @param contents the home page URL -279 * @return true if evidence was collected; otherwise false -280 */ -281 private boolean gatherHomePageEvidence(Pattern pattern, -282 EvidenceCollection evidence, String source, String name, -283 String contents) { -284 final Matcher matcher = pattern.matcher(contents); -285 boolean found = false; -286 if (matcher.find()) { -287 final String url = matcher.group(4); -288 if (UrlStringUtils.isUrl(url)) { -289 found = true; -290 evidence.addEvidence(source, name, url, Confidence.MEDIUM); -291 } -292 } -293 return found; -294 } -295 -296 /** -297 * Gather evidence from a Python source file using the given string -298 * assignment regex pattern. -299 * -300 * @param pattern to scan contents with -301 * @param contents of Python source file -302 * @param source for storing evidence -303 * @param evidence to store evidence in -304 * @param name of evidence -305 * @param confidence in evidence -306 * @return whether evidence was found -307 */ -308 private boolean gatherEvidence(Pattern pattern, String contents, -309 String source, EvidenceCollection evidence, String name, -310 Confidence confidence) { -311 final Matcher matcher = pattern.matcher(contents); -312 final boolean found = matcher.find(); -313 if (found) { -314 evidence.addEvidence(source, name, matcher.group(4), confidence); -315 } -316 return found; -317 } -318 -319 @Override -320 protected String getAnalyzerEnabledSettingKey() { -321 return Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED; -322 } -323 } +40 import org.owasp.dependencycheck.exception.InitializationException; +41 +42 /** +43 * Used to analyze a Python package, and collect information that can be used to +44 * determine the associated CPE. +45 * +46 * @author Dale Visser +47 */ +48 @Experimental +49 public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer { +50 +51 /** +52 * Used when compiling file scanning regex patterns. +53 */ +54 private static final int REGEX_OPTIONS = Pattern.DOTALL +55 | Pattern.CASE_INSENSITIVE; +56 +57 /** +58 * Filename extensions for files to be analyzed. +59 */ +60 private static final String EXTENSIONS = "py"; +61 +62 /** +63 * Pattern for matching the module docstring in a source file. +64 */ +65 private static final Pattern MODULE_DOCSTRING = Pattern.compile( +66 "^(['\\\"]{3})(.*?)\\1", REGEX_OPTIONS); +67 +68 /** +69 * Matches assignments to version variables in Python source code. +70 */ +71 private static final Pattern VERSION_PATTERN = Pattern.compile( +72 "\\b(__)?version(__)? *= *(['\"]+)(\\d+\\.\\d+.*?)\\3", +73 REGEX_OPTIONS); +74 +75 /** +76 * Matches assignments to title variables in Python source code. +77 */ +78 private static final Pattern TITLE_PATTERN = compileAssignPattern("title"); +79 +80 /** +81 * Matches assignments to summary variables in Python source code. +82 */ +83 private static final Pattern SUMMARY_PATTERN = compileAssignPattern("summary"); +84 +85 /** +86 * Matches assignments to URL/URL variables in Python source code. +87 */ +88 private static final Pattern URI_PATTERN = compileAssignPattern("ur[il]"); +89 +90 /** +91 * Matches assignments to home page variables in Python source code. +92 */ +93 private static final Pattern HOMEPAGE_PATTERN = compileAssignPattern("home_?page"); +94 +95 /** +96 * Matches assignments to author variables in Python source code. +97 */ +98 private static final Pattern AUTHOR_PATTERN = compileAssignPattern("author"); +99 +100 /** +101 * Filter that detects files named "__init__.py". +102 */ +103 private static final FileFilter INIT_PY_FILTER = new NameFileFilter("__init__.py"); +104 +105 /** +106 * The file filter for python files. +107 */ +108 private static final FileFilter PY_FILTER = new SuffixFileFilter(".py"); +109 +110 /** +111 * Returns the name of the Python Package Analyzer. +112 * +113 * @return the name of the analyzer +114 */ +115 @Override +116 public String getName() { +117 return "Python Package Analyzer"; +118 } +119 +120 /** +121 * Tell that we are used for information collection. +122 * +123 * @return INFORMATION_COLLECTION +124 */ +125 @Override +126 public AnalysisPhase getAnalysisPhase() { +127 return AnalysisPhase.INFORMATION_COLLECTION; +128 } +129 +130 /** +131 * The file filter used to determine which files this analyzer supports. +132 */ +133 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(EXTENSIONS).build(); +134 +135 /** +136 * Returns the FileFilter +137 * +138 * @return the FileFilter +139 */ +140 @Override +141 protected FileFilter getFileFilter() { +142 return FILTER; +143 } +144 +145 /** +146 * No-op initializer implementation. +147 * +148 * @throws InitializationException never thrown +149 */ +150 @Override +151 protected void initializeFileTypeAnalyzer() throws InitializationException { +152 // Nothing to do here. +153 } +154 +155 /** +156 * Utility function to create a regex pattern matcher. +157 * +158 * @param name the value to use when constructing the assignment pattern +159 * @return the compiled Pattern +160 */ +161 private static Pattern compileAssignPattern(String name) { +162 return Pattern.compile( +163 String.format("\\b(__)?%s(__)?\\b *= *(['\"]+)(.*?)\\3", name), +164 REGEX_OPTIONS); +165 } +166 +167 /** +168 * Analyzes python packages and adds evidence to the dependency. +169 * +170 * @param dependency the dependency being analyzed +171 * @param engine the engine being used to perform the scan +172 * @throws AnalysisException thrown if there is an unrecoverable error +173 * analyzing the dependency +174 */ +175 @Override +176 protected void analyzeFileType(Dependency dependency, Engine engine) +177 throws AnalysisException { +178 final File file = dependency.getActualFile(); +179 final File parent = file.getParentFile(); +180 final String parentName = parent.getName(); +181 if (INIT_PY_FILTER.accept(file)) { +182 //by definition, the containing folder of __init__.py is considered the package, even the file is empty: +183 //"The __init__.py files are required to make Python treat the directories as containing packages" +184 //see section "6.4 Packages" from https://docs.python.org/2/tutorial/modules.html; +185 dependency.setDisplayFileName(parentName + "/__init__.py"); +186 dependency.getProductEvidence().addEvidence(file.getName(), +187 "PackageName", parentName, Confidence.HIGHEST); +188 +189 final File[] fileList = parent.listFiles(PY_FILTER); +190 if (fileList != null) { +191 for (final File sourceFile : fileList) { +192 analyzeFileContents(dependency, sourceFile); +193 } +194 } +195 } else { +196 // copy, alter and set in case some other thread is iterating over +197 final List<Dependency> dependencies = new ArrayList<Dependency>( +198 engine.getDependencies()); +199 dependencies.remove(dependency); +200 engine.setDependencies(dependencies); +201 } +202 } +203 +204 /** +205 * This should gather information from leading docstrings, file comments, +206 * and assignments to __version__, __title__, __summary__, __uri__, __url__, +207 * __home*page__, __author__, and their all caps equivalents. +208 * +209 * @param dependency the dependency being analyzed +210 * @param file the file name to analyze +211 * @return whether evidence was found +212 * @throws AnalysisException thrown if there is an unrecoverable error +213 */ +214 private boolean analyzeFileContents(Dependency dependency, File file) +215 throws AnalysisException { +216 String contents; +217 try { +218 contents = FileUtils.readFileToString(file, Charset.defaultCharset()).trim(); +219 } catch (IOException e) { +220 throw new AnalysisException( +221 "Problem occurred while reading dependency file.", e); +222 } +223 boolean found = false; +224 if (!contents.isEmpty()) { +225 final String source = file.getName(); +226 found = gatherEvidence(VERSION_PATTERN, contents, source, +227 dependency.getVersionEvidence(), "SourceVersion", +228 Confidence.MEDIUM); +229 found |= addSummaryInfo(dependency, SUMMARY_PATTERN, 4, contents, +230 source, "summary"); +231 if (INIT_PY_FILTER.accept(file)) { +232 found |= addSummaryInfo(dependency, MODULE_DOCSTRING, 2, +233 contents, source, "docstring"); +234 } +235 found |= gatherEvidence(TITLE_PATTERN, contents, source, +236 dependency.getProductEvidence(), "SourceTitle", +237 Confidence.LOW); +238 final EvidenceCollection vendorEvidence = dependency +239 .getVendorEvidence(); +240 found |= gatherEvidence(AUTHOR_PATTERN, contents, source, +241 vendorEvidence, "SourceAuthor", Confidence.MEDIUM); +242 found |= gatherHomePageEvidence(URI_PATTERN, vendorEvidence, +243 source, "URL", contents); +244 found |= gatherHomePageEvidence(HOMEPAGE_PATTERN, +245 vendorEvidence, source, "HomePage", contents); +246 } +247 return found; +248 } +249 +250 /** +251 * Adds summary information to the dependency +252 * +253 * @param dependency the dependency being analyzed +254 * @param pattern the pattern used to perform analysis +255 * @param group the group from the pattern that indicates the data to use +256 * @param contents the data being analyzed +257 * @param source the source name to use when recording the evidence +258 * @param key the key name to use when recording the evidence +259 * @return true if evidence was collected; otherwise false +260 */ +261 private boolean addSummaryInfo(Dependency dependency, Pattern pattern, +262 int group, String contents, String source, String key) { +263 final Matcher matcher = pattern.matcher(contents); +264 final boolean found = matcher.find(); +265 if (found) { +266 JarAnalyzer.addDescription(dependency, matcher.group(group), +267 source, key); +268 } +269 return found; +270 } +271 +272 /** +273 * Collects evidence from the home page URL. +274 * +275 * @param pattern the pattern to match +276 * @param evidence the evidence collection to add the evidence to +277 * @param source the source of the evidence +278 * @param name the name of the evidence +279 * @param contents the home page URL +280 * @return true if evidence was collected; otherwise false +281 */ +282 private boolean gatherHomePageEvidence(Pattern pattern, +283 EvidenceCollection evidence, String source, String name, +284 String contents) { +285 final Matcher matcher = pattern.matcher(contents); +286 boolean found = false; +287 if (matcher.find()) { +288 final String url = matcher.group(4); +289 if (UrlStringUtils.isUrl(url)) { +290 found = true; +291 evidence.addEvidence(source, name, url, Confidence.MEDIUM); +292 } +293 } +294 return found; +295 } +296 +297 /** +298 * Gather evidence from a Python source file using the given string +299 * assignment regex pattern. +300 * +301 * @param pattern to scan contents with +302 * @param contents of Python source file +303 * @param source for storing evidence +304 * @param evidence to store evidence in +305 * @param name of evidence +306 * @param confidence in evidence +307 * @return whether evidence was found +308 */ +309 private boolean gatherEvidence(Pattern pattern, String contents, +310 String source, EvidenceCollection evidence, String name, +311 Confidence confidence) { +312 final Matcher matcher = pattern.matcher(contents); +313 final boolean found = matcher.find(); +314 if (found) { +315 evidence.addEvidence(source, name, matcher.group(4), confidence); +316 } +317 return found; +318 } +319 +320 @Override +321 protected String getAnalyzerEnabledSettingKey() { +322 return Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED; +323 } +324 }
      diff --git a/xref/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.html b/xref/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.html index d14417ea9..ac2dbd5cf 100644 --- a/xref/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.html +++ b/xref/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.html @@ -30,453 +30,479 @@ 22 import java.io.FileFilter; 23 import java.io.IOException; 24 import java.io.InputStreamReader; -25 import java.util.ArrayList; -26 import java.util.HashMap; -27 import java.util.List; -28 import java.util.Map; -29 import java.nio.charset.Charset; -30 import org.apache.commons.io.FileUtils; -31 import org.owasp.dependencycheck.Engine; -32 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; -33 import org.owasp.dependencycheck.data.nvdcve.CveDB; -34 import org.owasp.dependencycheck.dependency.Confidence; -35 import org.owasp.dependencycheck.dependency.Dependency; -36 import org.owasp.dependencycheck.dependency.Reference; -37 import org.owasp.dependencycheck.dependency.Vulnerability; -38 import org.owasp.dependencycheck.utils.FileFilterBuilder; -39 import org.owasp.dependencycheck.utils.Settings; -40 import org.slf4j.Logger; -41 import org.slf4j.LoggerFactory; -42 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; -43 -44 /** -45 * Used to analyze Ruby Bundler Gemspec.lock files utilizing the 3rd party -46 * bundle-audit tool. -47 * -48 * @author Dale Visser -49 */ -50 @Experimental -51 public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { -52 -53 private static final Logger LOGGER = LoggerFactory.getLogger(RubyBundleAuditAnalyzer.class); +25 import java.io.UnsupportedEncodingException; +26 import java.util.ArrayList; +27 import java.util.HashMap; +28 import java.util.List; +29 import java.util.Map; +30 import java.nio.charset.Charset; +31 import org.apache.commons.io.FileUtils; +32 import org.owasp.dependencycheck.Engine; +33 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; +34 import org.owasp.dependencycheck.data.nvdcve.CveDB; +35 import org.owasp.dependencycheck.dependency.Confidence; +36 import org.owasp.dependencycheck.dependency.Dependency; +37 import org.owasp.dependencycheck.dependency.Reference; +38 import org.owasp.dependencycheck.dependency.Vulnerability; +39 import org.owasp.dependencycheck.utils.FileFilterBuilder; +40 import org.owasp.dependencycheck.utils.Settings; +41 import org.slf4j.Logger; +42 import org.slf4j.LoggerFactory; +43 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; +44 import org.owasp.dependencycheck.exception.InitializationException; +45 +46 /** +47 * Used to analyze Ruby Bundler Gemspec.lock files utilizing the 3rd party +48 * bundle-audit tool. +49 * +50 * @author Dale Visser +51 */ +52 @Experimental +53 public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { 54 55 /** -56 * The name of the analyzer. +56 * The logger. 57 */ -58 private static final String ANALYZER_NAME = "Ruby Bundle Audit Analyzer"; +58 private static final Logger LOGGER = LoggerFactory.getLogger(RubyBundleAuditAnalyzer.class); 59 60 /** -61 * The phase that this analyzer is intended to run in. +61 * The name of the analyzer. 62 */ -63 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_INFORMATION_COLLECTION; -64 /** -65 * The filter defining which files will be analyzed. -66 */ -67 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addFilenames("Gemfile.lock").build(); -68 /** -69 * Name. -70 */ -71 public static final String NAME = "Name: "; -72 /** -73 * Version. -74 */ -75 public static final String VERSION = "Version: "; -76 /** -77 * Advisory. -78 */ -79 public static final String ADVISORY = "Advisory: "; -80 /** -81 * Criticality. -82 */ -83 public static final String CRITICALITY = "Criticality: "; -84 +63 private static final String ANALYZER_NAME = "Ruby Bundle Audit Analyzer"; +64 +65 /** +66 * The phase that this analyzer is intended to run in. +67 */ +68 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_INFORMATION_COLLECTION; +69 /** +70 * The filter defining which files will be analyzed. +71 */ +72 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addFilenames("Gemfile.lock").build(); +73 /** +74 * Name. +75 */ +76 public static final String NAME = "Name: "; +77 /** +78 * Version. +79 */ +80 public static final String VERSION = "Version: "; +81 /** +82 * Advisory. +83 */ +84 public static final String ADVISORY = "Advisory: "; 85 /** -86 * The DAL. +86 * Criticality. 87 */ -88 private CveDB cvedb; +88 public static final String CRITICALITY = "Criticality: "; 89 90 /** -91 * @return a filter that accepts files named Gemfile.lock +91 * The DAL. 92 */ -93 @Override -94 protected FileFilter getFileFilter() { -95 return FILTER; -96 } -97 -98 /** -99 * Launch bundle-audit. -100 * -101 * @param folder directory that contains bundle audit -102 * @return a handle to the process -103 * @throws AnalysisException thrown when there is an issue launching bundle -104 * audit -105 */ -106 private Process launchBundleAudit(File folder) throws AnalysisException { -107 if (!folder.isDirectory()) { -108 throw new AnalysisException(String.format("%s should have been a directory.", folder.getAbsolutePath())); -109 } -110 final List<String> args = new ArrayList<String>(); -111 final String bundleAuditPath = Settings.getString(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH); -112 args.add(null == bundleAuditPath ? "bundle-audit" : bundleAuditPath); -113 args.add("check"); -114 args.add("--verbose"); -115 final ProcessBuilder builder = new ProcessBuilder(args); -116 builder.directory(folder); -117 try { -118 LOGGER.info("Launching: " + args + " from " + folder); -119 return builder.start(); -120 } catch (IOException ioe) { -121 throw new AnalysisException("bundle-audit failure", ioe); -122 } -123 } -124 -125 /** -126 * Initialize the analyzer. In this case, extract GrokAssembly.exe to a -127 * temporary location. -128 * -129 * @throws Exception if anything goes wrong -130 */ -131 @Override -132 public void initializeFileTypeAnalyzer() throws Exception { -133 try { -134 cvedb = new CveDB(); -135 cvedb.open(); -136 } catch (DatabaseException ex) { -137 LOGGER.warn("Exception opening the database"); -138 LOGGER.debug("error", ex); -139 setEnabled(false); -140 throw ex; -141 } -142 // Now, need to see if bundle-audit actually runs from this location. -143 Process process = null; -144 try { -145 process = launchBundleAudit(Settings.getTempDirectory()); -146 } catch (AnalysisException ae) { -147 LOGGER.warn("Exception from bundle-audit process: {}. Disabling {}", ae.getCause(), ANALYZER_NAME); -148 setEnabled(false); -149 cvedb.close(); -150 cvedb = null; -151 throw ae; -152 } -153 -154 final int exitValue = process.waitFor(); -155 if (0 == exitValue) { -156 LOGGER.warn("Unexpected exit code from bundle-audit process. Disabling {}: {}", ANALYZER_NAME, exitValue); -157 setEnabled(false); -158 throw new AnalysisException("Unexpected exit code from bundle-audit process."); -159 } else { -160 BufferedReader reader = null; -161 try { -162 reader = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8")); -163 if (!reader.ready()) { -164 LOGGER.warn("Bundle-audit error stream unexpectedly not ready. Disabling " + ANALYZER_NAME); -165 setEnabled(false); -166 throw new AnalysisException("Bundle-audit error stream unexpectedly not ready."); -167 } else { -168 final String line = reader.readLine(); -169 if (line == null || !line.contains("Errno::ENOENT")) { -170 LOGGER.warn("Unexpected bundle-audit output. Disabling {}: {}", ANALYZER_NAME, line); -171 setEnabled(false); -172 throw new AnalysisException("Unexpected bundle-audit output."); -173 } -174 } -175 } finally { -176 if (null != reader) { -177 reader.close(); -178 } -179 } -180 } -181 -182 if (isEnabled()) { -183 LOGGER.info(ANALYZER_NAME + " is enabled. It is necessary to manually run \"bundle-audit update\" " -184 + "occasionally to keep its database up to date."); -185 } -186 } -187 -188 /** -189 * Returns the name of the analyzer. -190 * -191 * @return the name of the analyzer. -192 */ -193 @Override -194 public String getName() { -195 return ANALYZER_NAME; -196 } -197 -198 /** -199 * Returns the phase that the analyzer is intended to run in. -200 * -201 * @return the phase that the analyzer is intended to run in. -202 */ -203 @Override -204 public AnalysisPhase getAnalysisPhase() { -205 return ANALYSIS_PHASE; -206 } +93 private CveDB cvedb; +94 +95 /** +96 * @return a filter that accepts files named Gemfile.lock +97 */ +98 @Override +99 protected FileFilter getFileFilter() { +100 return FILTER; +101 } +102 +103 /** +104 * Launch bundle-audit. +105 * +106 * @param folder directory that contains bundle audit +107 * @return a handle to the process +108 * @throws AnalysisException thrown when there is an issue launching bundle +109 * audit +110 */ +111 private Process launchBundleAudit(File folder) throws AnalysisException { +112 if (!folder.isDirectory()) { +113 throw new AnalysisException(String.format("%s should have been a directory.", folder.getAbsolutePath())); +114 } +115 final List<String> args = new ArrayList<String>(); +116 final String bundleAuditPath = Settings.getString(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH); +117 args.add(null == bundleAuditPath ? "bundle-audit" : bundleAuditPath); +118 args.add("check"); +119 args.add("--verbose"); +120 final ProcessBuilder builder = new ProcessBuilder(args); +121 builder.directory(folder); +122 try { +123 LOGGER.info("Launching: " + args + " from " + folder); +124 return builder.start(); +125 } catch (IOException ioe) { +126 throw new AnalysisException("bundle-audit failure", ioe); +127 } +128 } +129 +130 /** +131 * Initialize the analyzer. In this case, extract GrokAssembly.exe to a +132 * temporary location. +133 * +134 * @throws InitializationException if anything goes wrong +135 */ +136 @Override +137 public void initializeFileTypeAnalyzer() throws InitializationException { +138 try { +139 cvedb = new CveDB(); +140 cvedb.open(); +141 } catch (DatabaseException ex) { +142 LOGGER.warn("Exception opening the database"); +143 LOGGER.debug("error", ex); +144 setEnabled(false); +145 throw new InitializationException("Error connecting to the database", ex); +146 } +147 // Now, need to see if bundle-audit actually runs from this location. +148 Process process = null; +149 try { +150 process = launchBundleAudit(Settings.getTempDirectory()); +151 } catch (AnalysisException ae) { +152 +153 setEnabled(false); +154 cvedb.close(); +155 cvedb = null; +156 final String msg = String.format("Exception from bundle-audit process: %s. Disabling %s", ae.getCause(), ANALYZER_NAME); +157 throw new InitializationException(msg, ae); +158 } catch (IOException ex) { +159 setEnabled(false); +160 throw new InitializationException("Unable to create temporary file, the Ruby Bundle Audit Analyzer will be disabled", ex); +161 } +162 +163 final int exitValue; +164 try { +165 exitValue = process.waitFor(); +166 } catch (InterruptedException ex) { +167 setEnabled(false); +168 final String msg = String.format("Bundle-audit process was interupted. Disabling %s", ANALYZER_NAME); +169 throw new InitializationException(msg); +170 } +171 if (0 == exitValue) { +172 setEnabled(false); +173 final String msg = String.format("Unexpected exit code from bundle-audit process. Disabling %s: %s", ANALYZER_NAME, exitValue); +174 throw new InitializationException(msg); +175 } else { +176 BufferedReader reader = null; +177 try { +178 reader = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8")); +179 if (!reader.ready()) { +180 LOGGER.warn("Bundle-audit error stream unexpectedly not ready. Disabling " + ANALYZER_NAME); +181 setEnabled(false); +182 throw new InitializationException("Bundle-audit error stream unexpectedly not ready."); +183 } else { +184 final String line = reader.readLine(); +185 if (line == null || !line.contains("Errno::ENOENT")) { +186 LOGGER.warn("Unexpected bundle-audit output. Disabling {}: {}", ANALYZER_NAME, line); +187 setEnabled(false); +188 throw new InitializationException("Unexpected bundle-audit output."); +189 } +190 } +191 } catch (UnsupportedEncodingException ex) { +192 setEnabled(false); +193 throw new InitializationException("Unexpected bundle-audit encoding.", ex); +194 } catch (IOException ex) { +195 setEnabled(false); +196 throw new InitializationException("Unable to read bundle-audit output.", ex); +197 } finally { +198 if (null != reader) { +199 try { +200 reader.close(); +201 } catch (IOException ex) { +202 LOGGER.debug("Error closing reader", ex); +203 } +204 } +205 } +206 } 207 -208 /** -209 * Returns the key used in the properties file to reference the analyzer's -210 * enabled property. -211 * -212 * @return the analyzer's enabled property setting key -213 */ -214 @Override -215 protected String getAnalyzerEnabledSettingKey() { -216 return Settings.KEYS.ANALYZER_BUNDLE_AUDIT_ENABLED; -217 } -218 -219 /** -220 * If {@link #analyzeFileType(Dependency, Engine)} is called, then we have -221 * successfully initialized, and it will be necessary to disable -222 * {@link RubyGemspecAnalyzer}. -223 */ -224 private boolean needToDisableGemspecAnalyzer = true; -225 -226 /** -227 * Determines if the analyzer can analyze the given file type. -228 * -229 * @param dependency the dependency to determine if it can analyze -230 * @param engine the dependency-check engine -231 * @throws AnalysisException thrown if there is an analysis exception. -232 */ -233 @Override -234 protected void analyzeFileType(Dependency dependency, Engine engine) -235 throws AnalysisException { -236 if (needToDisableGemspecAnalyzer) { -237 boolean failed = true; -238 final String className = RubyGemspecAnalyzer.class.getName(); -239 for (FileTypeAnalyzer analyzer : engine.getFileTypeAnalyzers()) { -240 if (analyzer instanceof RubyBundlerAnalyzer) { -241 ((RubyBundlerAnalyzer) analyzer).setEnabled(false); -242 LOGGER.info("Disabled " + RubyBundlerAnalyzer.class.getName() + " to avoid noisy duplicate results."); -243 } else if (analyzer instanceof RubyGemspecAnalyzer) { -244 ((RubyGemspecAnalyzer) analyzer).setEnabled(false); -245 LOGGER.info("Disabled " + className + " to avoid noisy duplicate results."); -246 failed = false; -247 } -248 } -249 if (failed) { -250 LOGGER.warn("Did not find " + className + '.'); -251 } -252 needToDisableGemspecAnalyzer = false; -253 } -254 final File parentFile = dependency.getActualFile().getParentFile(); -255 final Process process = launchBundleAudit(parentFile); -256 try { -257 process.waitFor(); -258 } catch (InterruptedException ie) { -259 throw new AnalysisException("bundle-audit process interrupted", ie); -260 } -261 BufferedReader rdr = null; -262 BufferedReader errReader = null; -263 try { -264 errReader = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8")); -265 while (errReader.ready()) { -266 final String error = errReader.readLine(); -267 LOGGER.warn(error); -268 } -269 rdr = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8")); -270 processBundlerAuditOutput(dependency, engine, rdr); -271 } catch (IOException ioe) { -272 LOGGER.warn("bundle-audit failure", ioe); -273 } finally { -274 if (errReader != null) { -275 try { -276 errReader.close(); -277 } catch (IOException ioe) { -278 LOGGER.warn("bundle-audit close failure", ioe); -279 } -280 } -281 if (null != rdr) { -282 try { -283 rdr.close(); -284 } catch (IOException ioe) { -285 LOGGER.warn("bundle-audit close failure", ioe); -286 } -287 } -288 } -289 -290 } -291 -292 /** -293 * Processes the bundler audit output. -294 * -295 * @param original the dependency -296 * @param engine the dependency-check engine -297 * @param rdr the reader of the report -298 * @throws IOException thrown if the report cannot be read. -299 */ -300 private void processBundlerAuditOutput(Dependency original, Engine engine, BufferedReader rdr) throws IOException { -301 final String parentName = original.getActualFile().getParentFile().getName(); -302 final String fileName = original.getFileName(); -303 final String filePath = original.getFilePath(); -304 Dependency dependency = null; -305 Vulnerability vulnerability = null; -306 String gem = null; -307 final Map<String, Dependency> map = new HashMap<String, Dependency>(); -308 boolean appendToDescription = false; -309 while (rdr.ready()) { -310 final String nextLine = rdr.readLine(); -311 if (null == nextLine) { -312 break; -313 } else if (nextLine.startsWith(NAME)) { -314 appendToDescription = false; -315 gem = nextLine.substring(NAME.length()); -316 if (!map.containsKey(gem)) { -317 map.put(gem, createDependencyForGem(engine, parentName, fileName, filePath, gem)); -318 } -319 dependency = map.get(gem); -320 LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); -321 } else if (nextLine.startsWith(VERSION)) { -322 vulnerability = createVulnerability(parentName, dependency, gem, nextLine); -323 } else if (nextLine.startsWith(ADVISORY)) { -324 setVulnerabilityName(parentName, dependency, vulnerability, nextLine); -325 } else if (nextLine.startsWith(CRITICALITY)) { -326 addCriticalityToVulnerability(parentName, vulnerability, nextLine); -327 } else if (nextLine.startsWith("URL: ")) { -328 addReferenceToVulnerability(parentName, vulnerability, nextLine); -329 } else if (nextLine.startsWith("Description:")) { -330 appendToDescription = true; -331 if (null != vulnerability) { -332 vulnerability.setDescription("*** Vulnerability obtained from bundle-audit verbose report. " -333 + "Title link may not work. CPE below is guessed. CVSS score is estimated (-1.0 " -334 + " indicates unknown). See link below for full details. *** "); -335 } -336 } else if (appendToDescription) { -337 if (null != vulnerability) { -338 vulnerability.setDescription(vulnerability.getDescription() + nextLine + "\n"); -339 } -340 } -341 } -342 } -343 -344 /** -345 * Sets the vulnerability name. -346 * -347 * @param parentName the parent name -348 * @param dependency the dependency -349 * @param vulnerability the vulnerability -350 * @param nextLine the line to parse -351 */ -352 private void setVulnerabilityName(String parentName, Dependency dependency, Vulnerability vulnerability, String nextLine) { -353 final String advisory = nextLine.substring((ADVISORY.length())); -354 if (null != vulnerability) { -355 vulnerability.setName(advisory); -356 } -357 if (null != dependency) { -358 dependency.getVulnerabilities().add(vulnerability); // needed to wait for vulnerability name to avoid NPE -359 } -360 LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); -361 } -362 -363 /** -364 * Adds a reference to the vulnerability. -365 * -366 * @param parentName the parent name -367 * @param vulnerability the vulnerability -368 * @param nextLine the line to parse -369 */ -370 private void addReferenceToVulnerability(String parentName, Vulnerability vulnerability, String nextLine) { -371 final String url = nextLine.substring(("URL: ").length()); -372 if (null != vulnerability) { -373 final Reference ref = new Reference(); -374 ref.setName(vulnerability.getName()); -375 ref.setSource("bundle-audit"); -376 ref.setUrl(url); -377 vulnerability.getReferences().add(ref); -378 } -379 LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); -380 } -381 -382 /** -383 * Adds the criticality to the vulnerability -384 * -385 * @param parentName the parent name -386 * @param vulnerability the vulnerability -387 * @param nextLine the line to parse -388 */ -389 private void addCriticalityToVulnerability(String parentName, Vulnerability vulnerability, String nextLine) { -390 if (null != vulnerability) { -391 final String criticality = nextLine.substring(CRITICALITY.length()).trim(); -392 float score = -1.0f; -393 Vulnerability v = null; -394 try { -395 v = cvedb.getVulnerability(vulnerability.getName()); -396 } catch (DatabaseException ex) { -397 LOGGER.debug("Unable to look up vulnerability {}", vulnerability.getName()); -398 } -399 if (v != null) { -400 score = v.getCvssScore(); -401 } else if ("High".equalsIgnoreCase(criticality)) { -402 score = 8.5f; -403 } else if ("Medium".equalsIgnoreCase(criticality)) { -404 score = 5.5f; -405 } else if ("Low".equalsIgnoreCase(criticality)) { -406 score = 2.0f; -407 } -408 vulnerability.setCvssScore(score); -409 } -410 LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); -411 } -412 -413 /** -414 * Creates a vulnerability. -415 * -416 * @param parentName the parent name -417 * @param dependency the dependency -418 * @param gem the gem name -419 * @param nextLine the line to parse -420 * @return the vulnerability -421 */ -422 private Vulnerability createVulnerability(String parentName, Dependency dependency, String gem, String nextLine) { -423 Vulnerability vulnerability = null; -424 if (null != dependency) { -425 final String version = nextLine.substring(VERSION.length()); -426 dependency.getVersionEvidence().addEvidence( -427 "bundler-audit", -428 "Version", -429 version, -430 Confidence.HIGHEST); -431 vulnerability = new Vulnerability(); // don't add to dependency until we have name set later -432 vulnerability.setMatchedCPE( -433 String.format("cpe:/a:%1$s_project:%1$s:%2$s::~~~ruby~~", gem, version), -434 null); -435 vulnerability.setCvssAccessVector("-"); -436 vulnerability.setCvssAccessComplexity("-"); -437 vulnerability.setCvssAuthentication("-"); -438 vulnerability.setCvssAvailabilityImpact("-"); -439 vulnerability.setCvssConfidentialityImpact("-"); -440 vulnerability.setCvssIntegrityImpact("-"); -441 } -442 LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); -443 return vulnerability; -444 } -445 -446 /** -447 * Creates the dependency based off of the gem. -448 * -449 * @param engine the engine used for scanning -450 * @param parentName the gem parent -451 * @param fileName the file name -452 * @param filePath the file path -453 * @param gem the gem name -454 * @return the dependency to add -455 * @throws IOException thrown if a temporary gem file could not be written -456 */ -457 private Dependency createDependencyForGem(Engine engine, String parentName, String fileName, String filePath, String gem) throws IOException { -458 final File gemFile = new File(Settings.getTempDirectory(), gem + "_Gemfile.lock"); -459 gemFile.createNewFile(); -460 final String displayFileName = String.format("%s%c%s:%s", parentName, File.separatorChar, fileName, gem); -461 -462 FileUtils.write(gemFile, displayFileName, Charset.defaultCharset()); // unique contents to avoid dependency bundling -463 final Dependency dependency = new Dependency(gemFile); -464 dependency.getProductEvidence().addEvidence("bundler-audit", "Name", gem, Confidence.HIGHEST); -465 dependency.setDisplayFileName(displayFileName); -466 dependency.setFileName(fileName); -467 dependency.setFilePath(filePath); -468 engine.getDependencies().add(dependency); -469 return dependency; +208 if (isEnabled()) { +209 LOGGER.info(ANALYZER_NAME + " is enabled. It is necessary to manually run \"bundle-audit update\" " +210 + "occasionally to keep its database up to date."); +211 } +212 } +213 +214 /** +215 * Returns the name of the analyzer. +216 * +217 * @return the name of the analyzer. +218 */ +219 @Override +220 public String getName() { +221 return ANALYZER_NAME; +222 } +223 +224 /** +225 * Returns the phase that the analyzer is intended to run in. +226 * +227 * @return the phase that the analyzer is intended to run in. +228 */ +229 @Override +230 public AnalysisPhase getAnalysisPhase() { +231 return ANALYSIS_PHASE; +232 } +233 +234 /** +235 * Returns the key used in the properties file to reference the analyzer's +236 * enabled property. +237 * +238 * @return the analyzer's enabled property setting key +239 */ +240 @Override +241 protected String getAnalyzerEnabledSettingKey() { +242 return Settings.KEYS.ANALYZER_BUNDLE_AUDIT_ENABLED; +243 } +244 +245 /** +246 * If {@link #analyzeFileType(Dependency, Engine)} is called, then we have +247 * successfully initialized, and it will be necessary to disable +248 * {@link RubyGemspecAnalyzer}. +249 */ +250 private boolean needToDisableGemspecAnalyzer = true; +251 +252 /** +253 * Determines if the analyzer can analyze the given file type. +254 * +255 * @param dependency the dependency to determine if it can analyze +256 * @param engine the dependency-check engine +257 * @throws AnalysisException thrown if there is an analysis exception. +258 */ +259 @Override +260 protected void analyzeFileType(Dependency dependency, Engine engine) +261 throws AnalysisException { +262 if (needToDisableGemspecAnalyzer) { +263 boolean failed = true; +264 final String className = RubyGemspecAnalyzer.class.getName(); +265 for (FileTypeAnalyzer analyzer : engine.getFileTypeAnalyzers()) { +266 if (analyzer instanceof RubyBundlerAnalyzer) { +267 ((RubyBundlerAnalyzer) analyzer).setEnabled(false); +268 LOGGER.info("Disabled " + RubyBundlerAnalyzer.class.getName() + " to avoid noisy duplicate results."); +269 } else if (analyzer instanceof RubyGemspecAnalyzer) { +270 ((RubyGemspecAnalyzer) analyzer).setEnabled(false); +271 LOGGER.info("Disabled " + className + " to avoid noisy duplicate results."); +272 failed = false; +273 } +274 } +275 if (failed) { +276 LOGGER.warn("Did not find " + className + '.'); +277 } +278 needToDisableGemspecAnalyzer = false; +279 } +280 final File parentFile = dependency.getActualFile().getParentFile(); +281 final Process process = launchBundleAudit(parentFile); +282 try { +283 process.waitFor(); +284 } catch (InterruptedException ie) { +285 throw new AnalysisException("bundle-audit process interrupted", ie); +286 } +287 BufferedReader rdr = null; +288 BufferedReader errReader = null; +289 try { +290 errReader = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8")); +291 while (errReader.ready()) { +292 final String error = errReader.readLine(); +293 LOGGER.warn(error); +294 } +295 rdr = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8")); +296 processBundlerAuditOutput(dependency, engine, rdr); +297 } catch (IOException ioe) { +298 LOGGER.warn("bundle-audit failure", ioe); +299 } finally { +300 if (errReader != null) { +301 try { +302 errReader.close(); +303 } catch (IOException ioe) { +304 LOGGER.warn("bundle-audit close failure", ioe); +305 } +306 } +307 if (null != rdr) { +308 try { +309 rdr.close(); +310 } catch (IOException ioe) { +311 LOGGER.warn("bundle-audit close failure", ioe); +312 } +313 } +314 } +315 +316 } +317 +318 /** +319 * Processes the bundler audit output. +320 * +321 * @param original the dependency +322 * @param engine the dependency-check engine +323 * @param rdr the reader of the report +324 * @throws IOException thrown if the report cannot be read. +325 */ +326 private void processBundlerAuditOutput(Dependency original, Engine engine, BufferedReader rdr) throws IOException { +327 final String parentName = original.getActualFile().getParentFile().getName(); +328 final String fileName = original.getFileName(); +329 final String filePath = original.getFilePath(); +330 Dependency dependency = null; +331 Vulnerability vulnerability = null; +332 String gem = null; +333 final Map<String, Dependency> map = new HashMap<String, Dependency>(); +334 boolean appendToDescription = false; +335 while (rdr.ready()) { +336 final String nextLine = rdr.readLine(); +337 if (null == nextLine) { +338 break; +339 } else if (nextLine.startsWith(NAME)) { +340 appendToDescription = false; +341 gem = nextLine.substring(NAME.length()); +342 if (!map.containsKey(gem)) { +343 map.put(gem, createDependencyForGem(engine, parentName, fileName, filePath, gem)); +344 } +345 dependency = map.get(gem); +346 LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); +347 } else if (nextLine.startsWith(VERSION)) { +348 vulnerability = createVulnerability(parentName, dependency, gem, nextLine); +349 } else if (nextLine.startsWith(ADVISORY)) { +350 setVulnerabilityName(parentName, dependency, vulnerability, nextLine); +351 } else if (nextLine.startsWith(CRITICALITY)) { +352 addCriticalityToVulnerability(parentName, vulnerability, nextLine); +353 } else if (nextLine.startsWith("URL: ")) { +354 addReferenceToVulnerability(parentName, vulnerability, nextLine); +355 } else if (nextLine.startsWith("Description:")) { +356 appendToDescription = true; +357 if (null != vulnerability) { +358 vulnerability.setDescription("*** Vulnerability obtained from bundle-audit verbose report. " +359 + "Title link may not work. CPE below is guessed. CVSS score is estimated (-1.0 " +360 + " indicates unknown). See link below for full details. *** "); +361 } +362 } else if (appendToDescription) { +363 if (null != vulnerability) { +364 vulnerability.setDescription(vulnerability.getDescription() + nextLine + "\n"); +365 } +366 } +367 } +368 } +369 +370 /** +371 * Sets the vulnerability name. +372 * +373 * @param parentName the parent name +374 * @param dependency the dependency +375 * @param vulnerability the vulnerability +376 * @param nextLine the line to parse +377 */ +378 private void setVulnerabilityName(String parentName, Dependency dependency, Vulnerability vulnerability, String nextLine) { +379 final String advisory = nextLine.substring((ADVISORY.length())); +380 if (null != vulnerability) { +381 vulnerability.setName(advisory); +382 } +383 if (null != dependency) { +384 dependency.getVulnerabilities().add(vulnerability); // needed to wait for vulnerability name to avoid NPE +385 } +386 LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); +387 } +388 +389 /** +390 * Adds a reference to the vulnerability. +391 * +392 * @param parentName the parent name +393 * @param vulnerability the vulnerability +394 * @param nextLine the line to parse +395 */ +396 private void addReferenceToVulnerability(String parentName, Vulnerability vulnerability, String nextLine) { +397 final String url = nextLine.substring(("URL: ").length()); +398 if (null != vulnerability) { +399 final Reference ref = new Reference(); +400 ref.setName(vulnerability.getName()); +401 ref.setSource("bundle-audit"); +402 ref.setUrl(url); +403 vulnerability.getReferences().add(ref); +404 } +405 LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); +406 } +407 +408 /** +409 * Adds the criticality to the vulnerability +410 * +411 * @param parentName the parent name +412 * @param vulnerability the vulnerability +413 * @param nextLine the line to parse +414 */ +415 private void addCriticalityToVulnerability(String parentName, Vulnerability vulnerability, String nextLine) { +416 if (null != vulnerability) { +417 final String criticality = nextLine.substring(CRITICALITY.length()).trim(); +418 float score = -1.0f; +419 Vulnerability v = null; +420 try { +421 v = cvedb.getVulnerability(vulnerability.getName()); +422 } catch (DatabaseException ex) { +423 LOGGER.debug("Unable to look up vulnerability {}", vulnerability.getName()); +424 } +425 if (v != null) { +426 score = v.getCvssScore(); +427 } else if ("High".equalsIgnoreCase(criticality)) { +428 score = 8.5f; +429 } else if ("Medium".equalsIgnoreCase(criticality)) { +430 score = 5.5f; +431 } else if ("Low".equalsIgnoreCase(criticality)) { +432 score = 2.0f; +433 } +434 vulnerability.setCvssScore(score); +435 } +436 LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); +437 } +438 +439 /** +440 * Creates a vulnerability. +441 * +442 * @param parentName the parent name +443 * @param dependency the dependency +444 * @param gem the gem name +445 * @param nextLine the line to parse +446 * @return the vulnerability +447 */ +448 private Vulnerability createVulnerability(String parentName, Dependency dependency, String gem, String nextLine) { +449 Vulnerability vulnerability = null; +450 if (null != dependency) { +451 final String version = nextLine.substring(VERSION.length()); +452 dependency.getVersionEvidence().addEvidence( +453 "bundler-audit", +454 "Version", +455 version, +456 Confidence.HIGHEST); +457 vulnerability = new Vulnerability(); // don't add to dependency until we have name set later +458 vulnerability.setMatchedCPE( +459 String.format("cpe:/a:%1$s_project:%1$s:%2$s::~~~ruby~~", gem, version), +460 null); +461 vulnerability.setCvssAccessVector("-"); +462 vulnerability.setCvssAccessComplexity("-"); +463 vulnerability.setCvssAuthentication("-"); +464 vulnerability.setCvssAvailabilityImpact("-"); +465 vulnerability.setCvssConfidentialityImpact("-"); +466 vulnerability.setCvssIntegrityImpact("-"); +467 } +468 LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); +469 return vulnerability; 470 } -471 } +471 +472 /** +473 * Creates the dependency based off of the gem. +474 * +475 * @param engine the engine used for scanning +476 * @param parentName the gem parent +477 * @param fileName the file name +478 * @param filePath the file path +479 * @param gem the gem name +480 * @return the dependency to add +481 * @throws IOException thrown if a temporary gem file could not be written +482 */ +483 private Dependency createDependencyForGem(Engine engine, String parentName, String fileName, String filePath, String gem) throws IOException { +484 final File gemFile = new File(Settings.getTempDirectory(), gem + "_Gemfile.lock"); +485 gemFile.createNewFile(); +486 final String displayFileName = String.format("%s%c%s:%s", parentName, File.separatorChar, fileName, gem); +487 +488 FileUtils.write(gemFile, displayFileName, Charset.defaultCharset()); // unique contents to avoid dependency bundling +489 final Dependency dependency = new Dependency(gemFile); +490 dependency.getProductEvidence().addEvidence("bundler-audit", "Name", gem, Confidence.HIGHEST); +491 dependency.setDisplayFileName(displayFileName); +492 dependency.setFileName(fileName); +493 dependency.setFilePath(filePath); +494 engine.getDependencies().add(dependency); +495 return dependency; +496 } +497 }
      diff --git a/xref/org/owasp/dependencycheck/analyzer/RubyBundlerAnalyzer.html b/xref/org/owasp/dependencycheck/analyzer/RubyBundlerAnalyzer.html index 127f09633..b461d876a 100644 --- a/xref/org/owasp/dependencycheck/analyzer/RubyBundlerAnalyzer.html +++ b/xref/org/owasp/dependencycheck/analyzer/RubyBundlerAnalyzer.html @@ -116,35 +116,36 @@ 108 final File gemsDir = new File(parentDir, GEMS); 109 if (gemsDir.exists()) { 110 final File[] matchingFiles = gemsDir.listFiles(new FilenameFilter() { -111 public boolean accept(File dir, String name) { -112 return name.equals(gemName); -113 } -114 }); -115 -116 if (matchingFiles != null && matchingFiles.length > 0) { -117 final String gemPath = matchingFiles[0].getAbsolutePath(); -118 if (dependency.getActualFilePath().equals(dependency.getFilePath())) { -119 if (gemPath != null) { -120 dependency.setPackagePath(gemPath); -121 } -122 } else { -123 //.gemspec's actualFilePath and filePath are different when it's from a compressed file -124 //in which case actualFilePath is the temp directory used by decompression. -125 //packagePath should use the filePath of the identified gem file in "gems" folder -126 final File gemspecStub = new File(dependency.getFilePath()); -127 final File specDir = gemspecStub.getParentFile(); -128 if (specDir != null && specDir.getName().equals(SPECIFICATIONS)) { -129 final File gemsDir2 = new File(specDir.getParentFile(), GEMS); -130 final File packageDir = new File(gemsDir2, gemName); -131 dependency.setPackagePath(packageDir.getAbsolutePath()); -132 } -133 } -134 } -135 } -136 } -137 } -138 } -139 } +111 @Override +112 public boolean accept(File dir, String name) { +113 return name.equals(gemName); +114 } +115 }); +116 +117 if (matchingFiles != null && matchingFiles.length > 0) { +118 final String gemPath = matchingFiles[0].getAbsolutePath(); +119 if (dependency.getActualFilePath().equals(dependency.getFilePath())) { +120 if (gemPath != null) { +121 dependency.setPackagePath(gemPath); +122 } +123 } else { +124 //.gemspec's actualFilePath and filePath are different when it's from a compressed file +125 //in which case actualFilePath is the temp directory used by decompression. +126 //packagePath should use the filePath of the identified gem file in "gems" folder +127 final File gemspecStub = new File(dependency.getFilePath()); +128 final File specDir = gemspecStub.getParentFile(); +129 if (specDir != null && specDir.getName().equals(SPECIFICATIONS)) { +130 final File gemsDir2 = new File(specDir.getParentFile(), GEMS); +131 final File packageDir = new File(gemsDir2, gemName); +132 dependency.setPackagePath(packageDir.getAbsolutePath()); +133 } +134 } +135 } +136 } +137 } +138 } +139 } +140 }
      diff --git a/xref/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.html b/xref/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.html index df6c70dd1..c6a328761 100644 --- a/xref/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.html +++ b/xref/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.html @@ -40,216 +40,218 @@ 32 import org.owasp.dependencycheck.dependency.Confidence; 33 import org.owasp.dependencycheck.dependency.Dependency; 34 import org.owasp.dependencycheck.dependency.EvidenceCollection; -35 import org.owasp.dependencycheck.utils.FileFilterBuilder; -36 import org.owasp.dependencycheck.utils.Settings; -37 import org.slf4j.Logger; -38 import org.slf4j.LoggerFactory; -39 -40 /** -41 * Used to analyze Ruby Gem specifications and collect information that can be -42 * used to determine the associated CPE. Regular expressions are used to parse -43 * the well-defined Ruby syntax that forms the specification. -44 * -45 * @author Dale Visser -46 */ -47 @Experimental -48 public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer { -49 -50 /** -51 * The logger. -52 */ -53 private static final Logger LOGGER = LoggerFactory.getLogger(RubyGemspecAnalyzer.class); -54 /** -55 * The name of the analyzer. -56 */ -57 private static final String ANALYZER_NAME = "Ruby Gemspec Analyzer"; -58 -59 /** -60 * The phase that this analyzer is intended to run in. -61 */ -62 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; -63 -64 /** -65 * The gemspec file extension. -66 */ -67 private static final String GEMSPEC = "gemspec"; -68 -69 /** -70 * The file filter containing the list of file extensions that can be -71 * analyzed. -72 */ -73 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(GEMSPEC).build(); -74 //TODO: support Rakefile -75 //= FileFilterBuilder.newInstance().addExtensions(GEMSPEC).addFilenames("Rakefile").build(); -76 -77 /** -78 * The name of the version file. -79 */ -80 private static final String VERSION_FILE_NAME = "VERSION"; -81 -82 /** -83 * @return a filter that accepts files matching the glob pattern, *.gemspec -84 */ -85 @Override -86 protected FileFilter getFileFilter() { -87 return FILTER; -88 } -89 -90 @Override -91 protected void initializeFileTypeAnalyzer() throws Exception { -92 // NO-OP -93 } -94 -95 /** -96 * Returns the name of the analyzer. -97 * -98 * @return the name of the analyzer. -99 */ -100 @Override -101 public String getName() { -102 return ANALYZER_NAME; -103 } -104 -105 /** -106 * Returns the phase that the analyzer is intended to run in. -107 * -108 * @return the phase that the analyzer is intended to run in. -109 */ -110 @Override -111 public AnalysisPhase getAnalysisPhase() { -112 return ANALYSIS_PHASE; -113 } -114 -115 /** -116 * Returns the key used in the properties file to reference the analyzer's -117 * enabled property. -118 * -119 * @return the analyzer's enabled property setting key -120 */ -121 @Override -122 protected String getAnalyzerEnabledSettingKey() { -123 return Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED; -124 } -125 -126 /** -127 * The capture group #1 is the block variable. -128 */ -129 private static final Pattern GEMSPEC_BLOCK_INIT = Pattern.compile("Gem::Specification\\.new\\s+?do\\s+?\\|(.+?)\\|"); -130 -131 @Override -132 protected void analyzeFileType(Dependency dependency, Engine engine) -133 throws AnalysisException { -134 String contents; -135 try { -136 contents = FileUtils.readFileToString(dependency.getActualFile(), Charset.defaultCharset()); -137 } catch (IOException e) { -138 throw new AnalysisException( -139 "Problem occurred while reading dependency file.", e); -140 } -141 final Matcher matcher = GEMSPEC_BLOCK_INIT.matcher(contents); -142 if (matcher.find()) { -143 contents = contents.substring(matcher.end()); -144 final String blockVariable = matcher.group(1); -145 -146 final EvidenceCollection vendor = dependency.getVendorEvidence(); -147 final EvidenceCollection product = dependency.getProductEvidence(); -148 final String name = addStringEvidence(product, contents, blockVariable, "name", "name", Confidence.HIGHEST); -149 if (!name.isEmpty()) { -150 vendor.addEvidence(GEMSPEC, "name_project", name + "_project", Confidence.LOW); -151 } -152 addStringEvidence(product, contents, blockVariable, "summary", "summary", Confidence.LOW); -153 -154 addStringEvidence(vendor, contents, blockVariable, "author", "authors?", Confidence.HIGHEST); -155 addStringEvidence(vendor, contents, blockVariable, "email", "emails?", Confidence.MEDIUM); -156 addStringEvidence(vendor, contents, blockVariable, "homepage", "homepage", Confidence.HIGHEST); -157 addStringEvidence(vendor, contents, blockVariable, "license", "licen[cs]es?", Confidence.HIGHEST); -158 -159 final String value = addStringEvidence(dependency.getVersionEvidence(), contents, -160 blockVariable, "version", "version", Confidence.HIGHEST); -161 if (value.length() < 1) { -162 addEvidenceFromVersionFile(dependency.getActualFile(), dependency.getVersionEvidence()); -163 } -164 } -165 -166 setPackagePath(dependency); -167 } -168 -169 /** -170 * Adds the specified evidence to the given evidence collection. -171 * -172 * @param evidences the collection to add the evidence to -173 * @param contents the evidence contents -174 * @param blockVariable the variable -175 * @param field the field -176 * @param fieldPattern the field pattern -177 * @param confidence the confidence of the evidence -178 * @return the evidence string value added -179 */ -180 private String addStringEvidence(EvidenceCollection evidences, String contents, -181 String blockVariable, String field, String fieldPattern, Confidence confidence) { -182 String value = ""; -183 -184 //capture array value between [ ] -185 final Matcher arrayMatcher = Pattern.compile( -186 String.format("\\s*?%s\\.%s\\s*?=\\s*?\\[(.*?)\\]", blockVariable, fieldPattern), Pattern.CASE_INSENSITIVE).matcher(contents); -187 if (arrayMatcher.find()) { -188 final String arrayValue = arrayMatcher.group(1); -189 value = arrayValue.replaceAll("['\"]", "").trim(); //strip quotes -190 } else { //capture single value between quotes -191 final Matcher matcher = Pattern.compile( -192 String.format("\\s*?%s\\.%s\\s*?=\\s*?(['\"])(.*?)\\1", blockVariable, fieldPattern), Pattern.CASE_INSENSITIVE).matcher(contents); -193 if (matcher.find()) { -194 value = matcher.group(2); -195 } -196 } -197 if (value.length() > 0) { -198 evidences.addEvidence(GEMSPEC, field, value, confidence); -199 } -200 -201 return value; -202 } -203 -204 /** -205 * Adds evidence from the version file. -206 * -207 * @param dependencyFile the dependency being analyzed -208 * @param versionEvidences the version evidence -209 */ -210 private void addEvidenceFromVersionFile(File dependencyFile, EvidenceCollection versionEvidences) { -211 final File parentDir = dependencyFile.getParentFile(); -212 if (parentDir != null) { -213 final File[] matchingFiles = parentDir.listFiles(new FilenameFilter() { -214 public boolean accept(File dir, String name) { -215 return name.contains(VERSION_FILE_NAME); -216 } -217 }); -218 for (File f : matchingFiles) { -219 try { -220 final List<String> lines = FileUtils.readLines(f, Charset.defaultCharset()); -221 if (lines.size() == 1) { //TODO other checking? -222 final String value = lines.get(0).trim(); -223 versionEvidences.addEvidence(GEMSPEC, "version", value, Confidence.HIGH); -224 } -225 } catch (IOException e) { -226 LOGGER.debug("Error reading gemspec", e); -227 } -228 } -229 } -230 } -231 -232 /** -233 * Sets the package path on the dependency. -234 * -235 * @param dep the dependency to alter -236 */ -237 private void setPackagePath(Dependency dep) { -238 final File file = new File(dep.getFilePath()); -239 final String parent = file.getParent(); -240 if (parent != null) { -241 dep.setPackagePath(parent); -242 } -243 } -244 } +35 import org.owasp.dependencycheck.exception.InitializationException; +36 import org.owasp.dependencycheck.utils.FileFilterBuilder; +37 import org.owasp.dependencycheck.utils.Settings; +38 import org.slf4j.Logger; +39 import org.slf4j.LoggerFactory; +40 +41 /** +42 * Used to analyze Ruby Gem specifications and collect information that can be +43 * used to determine the associated CPE. Regular expressions are used to parse +44 * the well-defined Ruby syntax that forms the specification. +45 * +46 * @author Dale Visser +47 */ +48 @Experimental +49 public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer { +50 +51 /** +52 * The logger. +53 */ +54 private static final Logger LOGGER = LoggerFactory.getLogger(RubyGemspecAnalyzer.class); +55 /** +56 * The name of the analyzer. +57 */ +58 private static final String ANALYZER_NAME = "Ruby Gemspec Analyzer"; +59 +60 /** +61 * The phase that this analyzer is intended to run in. +62 */ +63 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; +64 +65 /** +66 * The gemspec file extension. +67 */ +68 private static final String GEMSPEC = "gemspec"; +69 +70 /** +71 * The file filter containing the list of file extensions that can be +72 * analyzed. +73 */ +74 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(GEMSPEC).build(); +75 //TODO: support Rakefile +76 //= FileFilterBuilder.newInstance().addExtensions(GEMSPEC).addFilenames("Rakefile").build(); +77 +78 /** +79 * The name of the version file. +80 */ +81 private static final String VERSION_FILE_NAME = "VERSION"; +82 +83 /** +84 * @return a filter that accepts files matching the glob pattern, *.gemspec +85 */ +86 @Override +87 protected FileFilter getFileFilter() { +88 return FILTER; +89 } +90 +91 @Override +92 protected void initializeFileTypeAnalyzer() throws InitializationException { +93 // NO-OP +94 } +95 +96 /** +97 * Returns the name of the analyzer. +98 * +99 * @return the name of the analyzer. +100 */ +101 @Override +102 public String getName() { +103 return ANALYZER_NAME; +104 } +105 +106 /** +107 * Returns the phase that the analyzer is intended to run in. +108 * +109 * @return the phase that the analyzer is intended to run in. +110 */ +111 @Override +112 public AnalysisPhase getAnalysisPhase() { +113 return ANALYSIS_PHASE; +114 } +115 +116 /** +117 * Returns the key used in the properties file to reference the analyzer's +118 * enabled property. +119 * +120 * @return the analyzer's enabled property setting key +121 */ +122 @Override +123 protected String getAnalyzerEnabledSettingKey() { +124 return Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED; +125 } +126 +127 /** +128 * The capture group #1 is the block variable. +129 */ +130 private static final Pattern GEMSPEC_BLOCK_INIT = Pattern.compile("Gem::Specification\\.new\\s+?do\\s+?\\|(.+?)\\|"); +131 +132 @Override +133 protected void analyzeFileType(Dependency dependency, Engine engine) +134 throws AnalysisException { +135 String contents; +136 try { +137 contents = FileUtils.readFileToString(dependency.getActualFile(), Charset.defaultCharset()); +138 } catch (IOException e) { +139 throw new AnalysisException( +140 "Problem occurred while reading dependency file.", e); +141 } +142 final Matcher matcher = GEMSPEC_BLOCK_INIT.matcher(contents); +143 if (matcher.find()) { +144 contents = contents.substring(matcher.end()); +145 final String blockVariable = matcher.group(1); +146 +147 final EvidenceCollection vendor = dependency.getVendorEvidence(); +148 final EvidenceCollection product = dependency.getProductEvidence(); +149 final String name = addStringEvidence(product, contents, blockVariable, "name", "name", Confidence.HIGHEST); +150 if (!name.isEmpty()) { +151 vendor.addEvidence(GEMSPEC, "name_project", name + "_project", Confidence.LOW); +152 } +153 addStringEvidence(product, contents, blockVariable, "summary", "summary", Confidence.LOW); +154 +155 addStringEvidence(vendor, contents, blockVariable, "author", "authors?", Confidence.HIGHEST); +156 addStringEvidence(vendor, contents, blockVariable, "email", "emails?", Confidence.MEDIUM); +157 addStringEvidence(vendor, contents, blockVariable, "homepage", "homepage", Confidence.HIGHEST); +158 addStringEvidence(vendor, contents, blockVariable, "license", "licen[cs]es?", Confidence.HIGHEST); +159 +160 final String value = addStringEvidence(dependency.getVersionEvidence(), contents, +161 blockVariable, "version", "version", Confidence.HIGHEST); +162 if (value.length() < 1) { +163 addEvidenceFromVersionFile(dependency.getActualFile(), dependency.getVersionEvidence()); +164 } +165 } +166 +167 setPackagePath(dependency); +168 } +169 +170 /** +171 * Adds the specified evidence to the given evidence collection. +172 * +173 * @param evidences the collection to add the evidence to +174 * @param contents the evidence contents +175 * @param blockVariable the variable +176 * @param field the field +177 * @param fieldPattern the field pattern +178 * @param confidence the confidence of the evidence +179 * @return the evidence string value added +180 */ +181 private String addStringEvidence(EvidenceCollection evidences, String contents, +182 String blockVariable, String field, String fieldPattern, Confidence confidence) { +183 String value = ""; +184 +185 //capture array value between [ ] +186 final Matcher arrayMatcher = Pattern.compile( +187 String.format("\\s*?%s\\.%s\\s*?=\\s*?\\[(.*?)\\]", blockVariable, fieldPattern), Pattern.CASE_INSENSITIVE).matcher(contents); +188 if (arrayMatcher.find()) { +189 final String arrayValue = arrayMatcher.group(1); +190 value = arrayValue.replaceAll("['\"]", "").trim(); //strip quotes +191 } else { //capture single value between quotes +192 final Matcher matcher = Pattern.compile( +193 String.format("\\s*?%s\\.%s\\s*?=\\s*?(['\"])(.*?)\\1", blockVariable, fieldPattern), Pattern.CASE_INSENSITIVE).matcher(contents); +194 if (matcher.find()) { +195 value = matcher.group(2); +196 } +197 } +198 if (value.length() > 0) { +199 evidences.addEvidence(GEMSPEC, field, value, confidence); +200 } +201 +202 return value; +203 } +204 +205 /** +206 * Adds evidence from the version file. +207 * +208 * @param dependencyFile the dependency being analyzed +209 * @param versionEvidences the version evidence +210 */ +211 private void addEvidenceFromVersionFile(File dependencyFile, EvidenceCollection versionEvidences) { +212 final File parentDir = dependencyFile.getParentFile(); +213 if (parentDir != null) { +214 final File[] matchingFiles = parentDir.listFiles(new FilenameFilter() { +215 @Override +216 public boolean accept(File dir, String name) { +217 return name.contains(VERSION_FILE_NAME); +218 } +219 }); +220 for (File f : matchingFiles) { +221 try { +222 final List<String> lines = FileUtils.readLines(f, Charset.defaultCharset()); +223 if (lines.size() == 1) { //TODO other checking? +224 final String value = lines.get(0).trim(); +225 versionEvidences.addEvidence(GEMSPEC, "version", value, Confidence.HIGH); +226 } +227 } catch (IOException e) { +228 LOGGER.debug("Error reading gemspec", e); +229 } +230 } +231 } +232 } +233 +234 /** +235 * Sets the package path on the dependency. +236 * +237 * @param dep the dependency to alter +238 */ +239 private void setPackagePath(Dependency dep) { +240 final File file = new File(dep.getFilePath()); +241 final String parent = file.getParent(); +242 if (parent != null) { +243 dep.setPackagePath(parent); +244 } +245 } +246 }
      diff --git a/xref/org/owasp/dependencycheck/analyzer/VulnerabilitySuppressionAnalyzer.html b/xref/org/owasp/dependencycheck/analyzer/VulnerabilitySuppressionAnalyzer.html index 6ff5fddac..81854a4f9 100644 --- a/xref/org/owasp/dependencycheck/analyzer/VulnerabilitySuppressionAnalyzer.html +++ b/xref/org/owasp/dependencycheck/analyzer/VulnerabilitySuppressionAnalyzer.html @@ -28,7 +28,7 @@ 20 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; 21 import org.owasp.dependencycheck.Engine; 22 import org.owasp.dependencycheck.dependency.Dependency; -23 import org.owasp.dependencycheck.suppression.SuppressionRule; +23 import org.owasp.dependencycheck.xml.suppression.SuppressionRule; 24 25 /** 26 * The suppression analyzer processes an externally defined XML document that complies with the suppressions.xsd schema. diff --git a/xref/org/owasp/dependencycheck/analyzer/exception/package-frame.html b/xref/org/owasp/dependencycheck/analyzer/exception/package-frame.html index a60690b90..85ff8cbcd 100644 --- a/xref/org/owasp/dependencycheck/analyzer/exception/package-frame.html +++ b/xref/org/owasp/dependencycheck/analyzer/exception/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.analyzer.exception + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.analyzer.exception diff --git a/xref/org/owasp/dependencycheck/analyzer/exception/package-summary.html b/xref/org/owasp/dependencycheck/analyzer/exception/package-summary.html index 9b8409cbc..ff80f50bd 100644 --- a/xref/org/owasp/dependencycheck/analyzer/exception/package-summary.html +++ b/xref/org/owasp/dependencycheck/analyzer/exception/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.analyzer.exception + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.analyzer.exception diff --git a/xref/org/owasp/dependencycheck/analyzer/package-frame.html b/xref/org/owasp/dependencycheck/analyzer/package-frame.html index 19d87aa02..d0f34d2c1 100644 --- a/xref/org/owasp/dependencycheck/analyzer/package-frame.html +++ b/xref/org/owasp/dependencycheck/analyzer/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.analyzer + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.analyzer diff --git a/xref/org/owasp/dependencycheck/analyzer/package-summary.html b/xref/org/owasp/dependencycheck/analyzer/package-summary.html index d5813d8dc..7c7fb82dd 100644 --- a/xref/org/owasp/dependencycheck/analyzer/package-summary.html +++ b/xref/org/owasp/dependencycheck/analyzer/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.analyzer + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.analyzer diff --git a/xref/org/owasp/dependencycheck/ant/logging/package-frame.html b/xref/org/owasp/dependencycheck/ant/logging/package-frame.html index b09187c37..0423f6497 100644 --- a/xref/org/owasp/dependencycheck/ant/logging/package-frame.html +++ b/xref/org/owasp/dependencycheck/ant/logging/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.ant.logging + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.ant.logging diff --git a/xref/org/owasp/dependencycheck/ant/logging/package-summary.html b/xref/org/owasp/dependencycheck/ant/logging/package-summary.html index 1d38c16a2..f7f836f5c 100644 --- a/xref/org/owasp/dependencycheck/ant/logging/package-summary.html +++ b/xref/org/owasp/dependencycheck/ant/logging/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.ant.logging + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.ant.logging diff --git a/xref/org/owasp/dependencycheck/data/central/package-frame.html b/xref/org/owasp/dependencycheck/data/central/package-frame.html index 13d47f8df..a42026d23 100644 --- a/xref/org/owasp/dependencycheck/data/central/package-frame.html +++ b/xref/org/owasp/dependencycheck/data/central/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.central + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.central diff --git a/xref/org/owasp/dependencycheck/data/central/package-summary.html b/xref/org/owasp/dependencycheck/data/central/package-summary.html index 44353200c..a49bcaf80 100644 --- a/xref/org/owasp/dependencycheck/data/central/package-summary.html +++ b/xref/org/owasp/dependencycheck/data/central/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.central + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.central diff --git a/xref/org/owasp/dependencycheck/data/composer/package-frame.html b/xref/org/owasp/dependencycheck/data/composer/package-frame.html index c99a71c93..dfb5400ed 100644 --- a/xref/org/owasp/dependencycheck/data/composer/package-frame.html +++ b/xref/org/owasp/dependencycheck/data/composer/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.composer + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.composer diff --git a/xref/org/owasp/dependencycheck/data/composer/package-summary.html b/xref/org/owasp/dependencycheck/data/composer/package-summary.html index ce7e04939..4de001e3f 100644 --- a/xref/org/owasp/dependencycheck/data/composer/package-summary.html +++ b/xref/org/owasp/dependencycheck/data/composer/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.composer + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.composer diff --git a/xref/org/owasp/dependencycheck/data/cpe/CpeMemoryIndex.html b/xref/org/owasp/dependencycheck/data/cpe/CpeMemoryIndex.html index 9eae9c864..ed2431682 100644 --- a/xref/org/owasp/dependencycheck/data/cpe/CpeMemoryIndex.html +++ b/xref/org/owasp/dependencycheck/data/cpe/CpeMemoryIndex.html @@ -46,288 +46,278 @@ 38 import org.apache.lucene.search.Query; 39 import org.apache.lucene.search.TopDocs; 40 import org.apache.lucene.store.RAMDirectory; -41 import org.owasp.dependencycheck.data.lucene.FieldAnalyzer; -42 import org.owasp.dependencycheck.data.lucene.LuceneUtils; -43 import org.owasp.dependencycheck.data.lucene.SearchFieldAnalyzer; -44 import org.owasp.dependencycheck.data.nvdcve.CveDB; -45 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; -46 import org.owasp.dependencycheck.utils.Pair; -47 import org.slf4j.Logger; -48 import org.slf4j.LoggerFactory; -49 -50 /** -51 * An in memory lucene index that contains the vendor/product combinations from the CPE (application) identifiers within the NVD -52 * CVE data. -53 * -54 * @author Jeremy Long -55 */ -56 public final class CpeMemoryIndex { -57 -58 /** -59 * The logger. -60 */ -61 private static final Logger LOGGER = LoggerFactory.getLogger(CpeMemoryIndex.class); -62 /** -63 * singleton instance. -64 */ -65 private static final CpeMemoryIndex INSTANCE = new CpeMemoryIndex(); -66 -67 /** -68 * private constructor for singleton. -69 */ -70 private CpeMemoryIndex() { -71 } -72 -73 /** -74 * Gets the singleton instance of the CpeMemoryIndex. -75 * -76 * @return the instance of the CpeMemoryIndex -77 */ -78 public static CpeMemoryIndex getInstance() { -79 return INSTANCE; -80 } -81 /** -82 * The in memory Lucene index. -83 */ -84 private RAMDirectory index; -85 /** -86 * The Lucene IndexReader. -87 */ -88 private IndexReader indexReader; -89 /** -90 * The Lucene IndexSearcher. -91 */ -92 private IndexSearcher indexSearcher; -93 /** -94 * The Lucene Analyzer used for Searching. -95 */ -96 private Analyzer searchingAnalyzer; -97 /** -98 * The Lucene QueryParser used for Searching. -99 */ -100 private QueryParser queryParser; -101 /** -102 * The search field analyzer for the product field. -103 */ -104 private SearchFieldAnalyzer productSearchFieldAnalyzer; -105 /** -106 * The search field analyzer for the vendor field. -107 */ -108 private SearchFieldAnalyzer vendorSearchFieldAnalyzer; -109 -110 /** -111 * Creates and loads data into an in memory index. -112 * -113 * @param cve the data source to retrieve the cpe data -114 * @throws IndexException thrown if there is an error creating the index -115 */ -116 public void open(CveDB cve) throws IndexException { -117 synchronized (INSTANCE) { -118 if (!openState) { -119 index = new RAMDirectory(); -120 buildIndex(cve); -121 try { -122 indexReader = DirectoryReader.open(index); -123 } catch (IOException ex) { -124 throw new IndexException(ex); -125 } -126 indexSearcher = new IndexSearcher(indexReader); -127 searchingAnalyzer = createSearchingAnalyzer(); -128 queryParser = new QueryParser(LuceneUtils.CURRENT_VERSION, Fields.DOCUMENT_KEY, searchingAnalyzer); -129 openState = true; -130 } -131 } -132 } -133 /** -134 * A flag indicating whether or not the index is open. -135 */ -136 private boolean openState = false; -137 -138 /** -139 * returns whether or not the index is open. -140 * -141 * @return whether or not the index is open -142 */ -143 public boolean isOpen() { -144 return openState; -145 } -146 -147 /** -148 * Creates the indexing analyzer for the CPE Index. -149 * -150 * @return the CPE Analyzer. -151 */ -152 private Analyzer createIndexingAnalyzer() { -153 final Map<String, Analyzer> fieldAnalyzers = new HashMap<String, Analyzer>(); -154 fieldAnalyzers.put(Fields.DOCUMENT_KEY, new KeywordAnalyzer()); -155 return new PerFieldAnalyzerWrapper(new FieldAnalyzer(LuceneUtils.CURRENT_VERSION), fieldAnalyzers); -156 } -157 -158 /** -159 * Creates an Analyzer for searching the CPE Index. -160 * -161 * @return the CPE Analyzer. -162 */ -163 private Analyzer createSearchingAnalyzer() { -164 final Map<String, Analyzer> fieldAnalyzers = new HashMap<String, Analyzer>(); -165 fieldAnalyzers.put(Fields.DOCUMENT_KEY, new KeywordAnalyzer()); -166 productSearchFieldAnalyzer = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION); -167 vendorSearchFieldAnalyzer = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION); -168 fieldAnalyzers.put(Fields.PRODUCT, productSearchFieldAnalyzer); -169 fieldAnalyzers.put(Fields.VENDOR, vendorSearchFieldAnalyzer); -170 -171 return new PerFieldAnalyzerWrapper(new FieldAnalyzer(LuceneUtils.CURRENT_VERSION), fieldAnalyzers); -172 } -173 -174 /** -175 * Closes the CPE Index. -176 */ -177 public void close() { -178 if (searchingAnalyzer != null) { -179 searchingAnalyzer.close(); -180 searchingAnalyzer = null; -181 } -182 if (indexReader != null) { -183 try { -184 indexReader.close(); -185 } catch (IOException ex) { -186 LOGGER.trace("", ex); -187 } -188 indexReader = null; -189 } -190 queryParser = null; -191 indexSearcher = null; -192 if (index != null) { -193 index.close(); -194 index = null; -195 } -196 openState = false; -197 } -198 -199 /** -200 * Builds the CPE Lucene Index based off of the data within the CveDB. -201 * -202 * @param cve the data base containing the CPE data -203 * @throws IndexException thrown if there is an issue creating the index -204 */ -205 private void buildIndex(CveDB cve) throws IndexException { -206 Analyzer analyzer = null; -207 IndexWriter indexWriter = null; -208 try { -209 analyzer = createIndexingAnalyzer(); -210 final IndexWriterConfig conf = new IndexWriterConfig(LuceneUtils.CURRENT_VERSION, analyzer); -211 indexWriter = new IndexWriter(index, conf); -212 try { -213 // Tip: reuse the Document and Fields for performance... -214 // See "Re-use Document and Field instances" from -215 // http://wiki.apache.org/lucene-java/ImproveIndexingSpeed -216 final Document doc = new Document(); -217 final Field v = new TextField(Fields.VENDOR, Fields.VENDOR, Field.Store.YES); -218 final Field p = new TextField(Fields.PRODUCT, Fields.PRODUCT, Field.Store.YES); -219 doc.add(v); -220 doc.add(p); -221 -222 final Set<Pair<String, String>> data = cve.getVendorProductList(); -223 for (Pair<String, String> pair : data) { -224 v.setStringValue(pair.getLeft()); -225 p.setStringValue(pair.getRight()); -226 indexWriter.addDocument(doc); -227 } -228 } catch (DatabaseException ex) { -229 LOGGER.debug("", ex); -230 throw new IndexException("Error reading CPE data", ex); -231 } -232 } catch (CorruptIndexException ex) { -233 throw new IndexException("Unable to close an in-memory index", ex); -234 } catch (IOException ex) { -235 throw new IndexException("Unable to close an in-memory index", ex); -236 } finally { -237 if (indexWriter != null) { -238 try { -239 try { -240 indexWriter.commit(); -241 } finally { -242 indexWriter.close(true); -243 } -244 } catch (CorruptIndexException ex) { -245 throw new IndexException("Unable to close an in-memory index", ex); -246 } catch (IOException ex) { -247 throw new IndexException("Unable to close an in-memory index", ex); -248 } -249 if (analyzer != null) { -250 analyzer.close(); -251 } -252 } -253 } -254 } -255 -256 /** -257 * Resets the searching analyzers -258 */ -259 private void resetSearchingAnalyzer() { -260 if (productSearchFieldAnalyzer != null) { -261 productSearchFieldAnalyzer.clear(); -262 } -263 if (vendorSearchFieldAnalyzer != null) { -264 vendorSearchFieldAnalyzer.clear(); -265 } -266 } -267 -268 /** -269 * Searches the index using the given search string. -270 * -271 * @param searchString the query text -272 * @param maxQueryResults the maximum number of documents to return -273 * @return the TopDocs found by the search -274 * @throws ParseException thrown when the searchString is invalid -275 * @throws IOException is thrown if there is an issue with the underlying Index -276 */ -277 public TopDocs search(String searchString, int maxQueryResults) throws ParseException, IOException { -278 if (searchString == null || searchString.trim().isEmpty()) { -279 throw new ParseException("Query is null or empty"); -280 } -281 LOGGER.debug(searchString); -282 final Query query = queryParser.parse(searchString); -283 return search(query, maxQueryResults); -284 } -285 -286 /** -287 * Searches the index using the given query. -288 * -289 * @param query the query used to search the index -290 * @param maxQueryResults the max number of results to return -291 * @return the TopDocs found be the query -292 * @throws CorruptIndexException thrown if the Index is corrupt -293 * @throws IOException thrown if there is an IOException -294 */ -295 public TopDocs search(Query query, int maxQueryResults) throws CorruptIndexException, IOException { -296 resetSearchingAnalyzer(); -297 return indexSearcher.search(query, maxQueryResults); -298 } -299 -300 /** -301 * Retrieves a document from the Index. -302 * -303 * @param documentId the id of the document to retrieve -304 * @return the Document -305 * @throws IOException thrown if there is an IOException -306 */ -307 public Document getDocument(int documentId) throws IOException { -308 return indexSearcher.doc(documentId); -309 } -310 -311 /** -312 * Returns the number of CPE entries stored in the index. -313 * -314 * @return the number of CPE entries stored in the index -315 */ -316 public int numDocs() { -317 if (indexReader == null) { -318 return -1; -319 } -320 return indexReader.numDocs(); -321 } -322 } +41 import org.owasp.dependencycheck.data.lucene.LuceneUtils; +42 import org.owasp.dependencycheck.data.lucene.SearchFieldAnalyzer; +43 import org.owasp.dependencycheck.data.nvdcve.CveDB; +44 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; +45 import org.owasp.dependencycheck.utils.Pair; +46 import org.slf4j.Logger; +47 import org.slf4j.LoggerFactory; +48 +49 /** +50 * An in memory lucene index that contains the vendor/product combinations from +51 * the CPE (application) identifiers within the NVD CVE data. +52 * +53 * @author Jeremy Long +54 */ +55 public final class CpeMemoryIndex { +56 +57 /** +58 * The logger. +59 */ +60 private static final Logger LOGGER = LoggerFactory.getLogger(CpeMemoryIndex.class); +61 /** +62 * singleton instance. +63 */ +64 private static final CpeMemoryIndex INSTANCE = new CpeMemoryIndex(); +65 +66 /** +67 * private constructor for singleton. +68 */ +69 private CpeMemoryIndex() { +70 } +71 +72 /** +73 * Gets the singleton instance of the CpeMemoryIndex. +74 * +75 * @return the instance of the CpeMemoryIndex +76 */ +77 public static CpeMemoryIndex getInstance() { +78 return INSTANCE; +79 } +80 /** +81 * The in memory Lucene index. +82 */ +83 private RAMDirectory index; +84 /** +85 * The Lucene IndexReader. +86 */ +87 private IndexReader indexReader; +88 /** +89 * The Lucene IndexSearcher. +90 */ +91 private IndexSearcher indexSearcher; +92 /** +93 * The Lucene Analyzer used for Searching. +94 */ +95 private Analyzer searchingAnalyzer; +96 /** +97 * The Lucene QueryParser used for Searching. +98 */ +99 private QueryParser queryParser; +100 /** +101 * The search field analyzer for the product field. +102 */ +103 private SearchFieldAnalyzer productFieldAnalyzer; +104 /** +105 * The search field analyzer for the vendor field. +106 */ +107 private SearchFieldAnalyzer vendorFieldAnalyzer; +108 +109 /** +110 * Creates and loads data into an in memory index. +111 * +112 * @param cve the data source to retrieve the cpe data +113 * @throws IndexException thrown if there is an error creating the index +114 */ +115 public void open(CveDB cve) throws IndexException { +116 synchronized (INSTANCE) { +117 if (!openState) { +118 index = new RAMDirectory(); +119 buildIndex(cve); +120 try { +121 indexReader = DirectoryReader.open(index); +122 } catch (IOException ex) { +123 throw new IndexException(ex); +124 } +125 indexSearcher = new IndexSearcher(indexReader); +126 searchingAnalyzer = createSearchingAnalyzer(); +127 queryParser = new QueryParser(LuceneUtils.CURRENT_VERSION, Fields.DOCUMENT_KEY, searchingAnalyzer); +128 openState = true; +129 } +130 } +131 } +132 /** +133 * A flag indicating whether or not the index is open. +134 */ +135 private boolean openState = false; +136 +137 /** +138 * returns whether or not the index is open. +139 * +140 * @return whether or not the index is open +141 */ +142 public boolean isOpen() { +143 return openState; +144 } +145 +146 /** +147 * Creates an Analyzer for searching the CPE Index. +148 * +149 * @return the CPE Analyzer. +150 */ +151 private Analyzer createSearchingAnalyzer() { +152 final Map<String, Analyzer> fieldAnalyzers = new HashMap<String, Analyzer>(); +153 fieldAnalyzers.put(Fields.DOCUMENT_KEY, new KeywordAnalyzer()); +154 productFieldAnalyzer = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION); +155 vendorFieldAnalyzer = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION); +156 fieldAnalyzers.put(Fields.PRODUCT, productFieldAnalyzer); +157 fieldAnalyzers.put(Fields.VENDOR, vendorFieldAnalyzer); +158 +159 return new PerFieldAnalyzerWrapper(new KeywordAnalyzer(), fieldAnalyzers); +160 } +161 +162 /** +163 * Closes the CPE Index. +164 */ +165 public void close() { +166 if (searchingAnalyzer != null) { +167 searchingAnalyzer.close(); +168 searchingAnalyzer = null; +169 } +170 if (indexReader != null) { +171 try { +172 indexReader.close(); +173 } catch (IOException ex) { +174 LOGGER.trace("", ex); +175 } +176 indexReader = null; +177 } +178 queryParser = null; +179 indexSearcher = null; +180 if (index != null) { +181 index.close(); +182 index = null; +183 } +184 openState = false; +185 } +186 +187 /** +188 * Builds the CPE Lucene Index based off of the data within the CveDB. +189 * +190 * @param cve the data base containing the CPE data +191 * @throws IndexException thrown if there is an issue creating the index +192 */ +193 private void buildIndex(CveDB cve) throws IndexException { +194 Analyzer analyzer = null; +195 IndexWriter indexWriter = null; +196 try { +197 analyzer = createSearchingAnalyzer(); +198 final IndexWriterConfig conf = new IndexWriterConfig(LuceneUtils.CURRENT_VERSION, analyzer); +199 indexWriter = new IndexWriter(index, conf); +200 try { +201 // Tip: reuse the Document and Fields for performance... +202 // See "Re-use Document and Field instances" from +203 // http://wiki.apache.org/lucene-java/ImproveIndexingSpeed +204 final Document doc = new Document(); +205 final Field v = new TextField(Fields.VENDOR, Fields.VENDOR, Field.Store.YES); +206 final Field p = new TextField(Fields.PRODUCT, Fields.PRODUCT, Field.Store.YES); +207 doc.add(v); +208 doc.add(p); +209 +210 final Set<Pair<String, String>> data = cve.getVendorProductList(); +211 for (Pair<String, String> pair : data) { +212 v.setStringValue(pair.getLeft()); +213 p.setStringValue(pair.getRight()); +214 indexWriter.addDocument(doc); +215 resetFieldAnalyzer(); +216 } +217 } catch (DatabaseException ex) { +218 LOGGER.debug("", ex); +219 throw new IndexException("Error reading CPE data", ex); +220 } +221 } catch (CorruptIndexException ex) { +222 throw new IndexException("Unable to close an in-memory index", ex); +223 } catch (IOException ex) { +224 throw new IndexException("Unable to close an in-memory index", ex); +225 } finally { +226 if (indexWriter != null) { +227 try { +228 try { +229 indexWriter.commit(); +230 } finally { +231 indexWriter.close(true); +232 } +233 } catch (CorruptIndexException ex) { +234 throw new IndexException("Unable to close an in-memory index", ex); +235 } catch (IOException ex) { +236 throw new IndexException("Unable to close an in-memory index", ex); +237 } +238 if (analyzer != null) { +239 analyzer.close(); +240 } +241 } +242 } +243 } +244 +245 /** +246 * Resets the product and vendor field analyzers. +247 */ +248 private void resetFieldAnalyzer() { +249 if (productFieldAnalyzer != null) { +250 productFieldAnalyzer.clear(); +251 } +252 if (vendorFieldAnalyzer != null) { +253 vendorFieldAnalyzer.clear(); +254 } +255 } +256 +257 /** +258 * Searches the index using the given search string. +259 * +260 * @param searchString the query text +261 * @param maxQueryResults the maximum number of documents to return +262 * @return the TopDocs found by the search +263 * @throws ParseException thrown when the searchString is invalid +264 * @throws IOException is thrown if there is an issue with the underlying +265 * Index +266 */ +267 public TopDocs search(String searchString, int maxQueryResults) throws ParseException, IOException { +268 if (searchString == null || searchString.trim().isEmpty()) { +269 throw new ParseException("Query is null or empty"); +270 } +271 LOGGER.debug(searchString); +272 final Query query = queryParser.parse(searchString); +273 return search(query, maxQueryResults); +274 } +275 +276 /** +277 * Searches the index using the given query. +278 * +279 * @param query the query used to search the index +280 * @param maxQueryResults the max number of results to return +281 * @return the TopDocs found be the query +282 * @throws CorruptIndexException thrown if the Index is corrupt +283 * @throws IOException thrown if there is an IOException +284 */ +285 public TopDocs search(Query query, int maxQueryResults) throws CorruptIndexException, IOException { +286 resetFieldAnalyzer(); +287 return indexSearcher.search(query, maxQueryResults); +288 } +289 +290 /** +291 * Retrieves a document from the Index. +292 * +293 * @param documentId the id of the document to retrieve +294 * @return the Document +295 * @throws IOException thrown if there is an IOException +296 */ +297 public Document getDocument(int documentId) throws IOException { +298 return indexSearcher.doc(documentId); +299 } +300 +301 /** +302 * Returns the number of CPE entries stored in the index. +303 * +304 * @return the number of CPE entries stored in the index +305 */ +306 public int numDocs() { +307 if (indexReader == null) { +308 return -1; +309 } +310 return indexReader.numDocs(); +311 } +312 }
      diff --git a/xref/org/owasp/dependencycheck/data/cpe/package-frame.html b/xref/org/owasp/dependencycheck/data/cpe/package-frame.html index 9e005080b..2757b0930 100644 --- a/xref/org/owasp/dependencycheck/data/cpe/package-frame.html +++ b/xref/org/owasp/dependencycheck/data/cpe/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.cpe + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.cpe diff --git a/xref/org/owasp/dependencycheck/data/cpe/package-summary.html b/xref/org/owasp/dependencycheck/data/cpe/package-summary.html index abeb8638c..5ad4cf289 100644 --- a/xref/org/owasp/dependencycheck/data/cpe/package-summary.html +++ b/xref/org/owasp/dependencycheck/data/cpe/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.cpe + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.cpe diff --git a/xref/org/owasp/dependencycheck/data/cwe/package-frame.html b/xref/org/owasp/dependencycheck/data/cwe/package-frame.html index c022c3d52..a93fb5865 100644 --- a/xref/org/owasp/dependencycheck/data/cwe/package-frame.html +++ b/xref/org/owasp/dependencycheck/data/cwe/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.cwe + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.cwe diff --git a/xref/org/owasp/dependencycheck/data/cwe/package-summary.html b/xref/org/owasp/dependencycheck/data/cwe/package-summary.html index bc3afbb4d..f2208637a 100644 --- a/xref/org/owasp/dependencycheck/data/cwe/package-summary.html +++ b/xref/org/owasp/dependencycheck/data/cwe/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.cwe + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.cwe diff --git a/xref/org/owasp/dependencycheck/data/lucene/FieldAnalyzer.html b/xref/org/owasp/dependencycheck/data/lucene/FieldAnalyzer.html index f49b8afe9..f5499e92c 100644 --- a/xref/org/owasp/dependencycheck/data/lucene/FieldAnalyzer.html +++ b/xref/org/owasp/dependencycheck/data/lucene/FieldAnalyzer.html @@ -37,55 +37,59 @@ 29 30 /** 31 * <p> -32 * A Lucene Analyzer that utilizes the WhitespaceTokenizer, WordDelimiterFilter, LowerCaseFilter, and StopFilter. The intended -33 * purpose of this Analyzer is to index the CPE fields vendor and product.</p> -34 * -35 * @author Jeremy Long -36 */ -37 public class FieldAnalyzer extends Analyzer { -38 -39 /** -40 * The Lucene Version used. -41 */ -42 private final Version version; -43 -44 /** -45 * Creates a new FieldAnalyzer. -46 * -47 * @param version the Lucene version -48 */ -49 public FieldAnalyzer(Version version) { -50 this.version = version; -51 } -52 -53 /** -54 * Creates the TokenStreamComponents -55 * -56 * @param fieldName the field name being analyzed -57 * @param reader the reader containing the input -58 * @return the TokenStreamComponents -59 */ -60 @Override -61 protected TokenStreamComponents createComponents(String fieldName, Reader reader) { -62 final Tokenizer source = new AlphaNumericTokenizer(version, reader); -63 -64 TokenStream stream = source; -65 -66 stream = new WordDelimiterFilter(stream, -67 WordDelimiterFilter.CATENATE_WORDS -68 | WordDelimiterFilter.GENERATE_WORD_PARTS -69 | WordDelimiterFilter.GENERATE_NUMBER_PARTS -70 | WordDelimiterFilter.PRESERVE_ORIGINAL -71 | WordDelimiterFilter.SPLIT_ON_CASE_CHANGE -72 | WordDelimiterFilter.SPLIT_ON_NUMERICS -73 | WordDelimiterFilter.STEM_ENGLISH_POSSESSIVE, null); -74 -75 stream = new LowerCaseFilter(version, stream); -76 stream = new StopFilter(version, stream, StopAnalyzer.ENGLISH_STOP_WORDS_SET); -77 -78 return new TokenStreamComponents(source, stream); -79 } -80 } +32 * A Lucene Analyzer that utilizes the WhitespaceTokenizer, WordDelimiterFilter, +33 * LowerCaseFilter, and StopFilter. The intended purpose of this Analyzer is to +34 * index the CPE fields vendor and product.</p> +35 * +36 * @author Jeremy Long +37 * @deprecated the field analyzer should not be used, instead use the +38 * SearchFieldAnalyzer so that the token analyzing filter is used. +39 */ +40 @Deprecated +41 public class FieldAnalyzer extends Analyzer { +42 +43 /** +44 * The Lucene Version used. +45 */ +46 private final Version version; +47 +48 /** +49 * Creates a new FieldAnalyzer. +50 * +51 * @param version the Lucene version +52 */ +53 public FieldAnalyzer(Version version) { +54 this.version = version; +55 } +56 +57 /** +58 * Creates the TokenStreamComponents +59 * +60 * @param fieldName the field name being analyzed +61 * @param reader the reader containing the input +62 * @return the TokenStreamComponents +63 */ +64 @Override +65 protected TokenStreamComponents createComponents(String fieldName, Reader reader) { +66 final Tokenizer source = new AlphaNumericTokenizer(version, reader); +67 +68 TokenStream stream = source; +69 +70 stream = new WordDelimiterFilter(stream, +71 WordDelimiterFilter.CATENATE_WORDS +72 | WordDelimiterFilter.GENERATE_WORD_PARTS +73 | WordDelimiterFilter.GENERATE_NUMBER_PARTS +74 | WordDelimiterFilter.PRESERVE_ORIGINAL +75 | WordDelimiterFilter.SPLIT_ON_CASE_CHANGE +76 | WordDelimiterFilter.SPLIT_ON_NUMERICS +77 | WordDelimiterFilter.STEM_ENGLISH_POSSESSIVE, null); +78 +79 stream = new LowerCaseFilter(version, stream); +80 stream = new StopFilter(version, stream, StopAnalyzer.ENGLISH_STOP_WORDS_SET); +81 +82 return new TokenStreamComponents(source, stream); +83 } +84 }
      diff --git a/xref/org/owasp/dependencycheck/data/lucene/package-frame.html b/xref/org/owasp/dependencycheck/data/lucene/package-frame.html index 69e545e84..8d781fe1d 100644 --- a/xref/org/owasp/dependencycheck/data/lucene/package-frame.html +++ b/xref/org/owasp/dependencycheck/data/lucene/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.lucene + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.lucene diff --git a/xref/org/owasp/dependencycheck/data/lucene/package-summary.html b/xref/org/owasp/dependencycheck/data/lucene/package-summary.html index b48168f23..3ec952763 100644 --- a/xref/org/owasp/dependencycheck/data/lucene/package-summary.html +++ b/xref/org/owasp/dependencycheck/data/lucene/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.lucene + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.lucene diff --git a/xref/org/owasp/dependencycheck/data/nexus/package-frame.html b/xref/org/owasp/dependencycheck/data/nexus/package-frame.html index 91cc0d7e1..27cdda001 100644 --- a/xref/org/owasp/dependencycheck/data/nexus/package-frame.html +++ b/xref/org/owasp/dependencycheck/data/nexus/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.nexus + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.nexus diff --git a/xref/org/owasp/dependencycheck/data/nexus/package-summary.html b/xref/org/owasp/dependencycheck/data/nexus/package-summary.html index 5803397e0..8721636f3 100644 --- a/xref/org/owasp/dependencycheck/data/nexus/package-summary.html +++ b/xref/org/owasp/dependencycheck/data/nexus/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.nexus + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.nexus diff --git a/xref/org/owasp/dependencycheck/data/nuget/package-frame.html b/xref/org/owasp/dependencycheck/data/nuget/package-frame.html index b62b38691..a75ac4aa4 100644 --- a/xref/org/owasp/dependencycheck/data/nuget/package-frame.html +++ b/xref/org/owasp/dependencycheck/data/nuget/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.nuget + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.nuget diff --git a/xref/org/owasp/dependencycheck/data/nuget/package-summary.html b/xref/org/owasp/dependencycheck/data/nuget/package-summary.html index 80bf952de..bbc99da59 100644 --- a/xref/org/owasp/dependencycheck/data/nuget/package-summary.html +++ b/xref/org/owasp/dependencycheck/data/nuget/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.nuget + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.nuget diff --git a/xref/org/owasp/dependencycheck/data/nvdcve/ConnectionFactory.html b/xref/org/owasp/dependencycheck/data/nvdcve/ConnectionFactory.html index 95edc3f11..ed37e7d2b 100644 --- a/xref/org/owasp/dependencycheck/data/nvdcve/ConnectionFactory.html +++ b/xref/org/owasp/dependencycheck/data/nvdcve/ConnectionFactory.html @@ -28,7 +28,7 @@ 20 import java.io.File; 21 import java.io.IOException; 22 import java.io.InputStream; -23 import java.sql.CallableStatement; +23 import java.sql.PreparedStatement; 24 import java.sql.Connection; 25 import java.sql.Driver; 26 import java.sql.DriverManager; @@ -360,11 +360,11 @@ 352 */ 353 private static void ensureSchemaVersion(Connection conn) throws DatabaseException { 354 ResultSet rs = null; -355 CallableStatement cs = null; +355 PreparedStatement ps = null; 356 try { 357 //TODO convert this to use DatabaseProperties -358 cs = conn.prepareCall("SELECT value FROM properties WHERE id = 'version'"); -359 rs = cs.executeQuery(); +358 ps = conn.prepareStatement("SELECT value FROM properties WHERE id = 'version'"); +359 rs = ps.executeQuery(); 360 if (rs.next()) { 361 final DependencyVersion appDbVersion = DependencyVersionUtil.parseVersion(DB_SCHEMA_VERSION); 362 final DependencyVersion db = DependencyVersionUtil.parseVersion(rs.getString(1)); @@ -384,7 +384,7 @@ 376 throw new DatabaseException("Unable to check the database schema version"); 377 } finally { 378 DBUtils.closeResultSet(rs); -379 DBUtils.closeStatement(cs); +379 DBUtils.closeStatement(ps); 380 } 381 } 382 } diff --git a/xref/org/owasp/dependencycheck/data/nvdcve/CveDB.html b/xref/org/owasp/dependencycheck/data/nvdcve/CveDB.html index c9c5d0eef..9fae88f80 100644 --- a/xref/org/owasp/dependencycheck/data/nvdcve/CveDB.html +++ b/xref/org/owasp/dependencycheck/data/nvdcve/CveDB.html @@ -27,836 +27,834 @@ 19 20 import java.io.IOException; 21 import java.io.UnsupportedEncodingException; -22 import java.sql.CallableStatement; -23 import java.sql.Connection; -24 import java.sql.PreparedStatement; -25 import java.sql.ResultSet; -26 import java.sql.SQLException; -27 import java.sql.Statement; -28 import java.util.ArrayList; -29 import java.util.HashMap; -30 import java.util.HashSet; -31 import java.util.List; -32 import java.util.Locale; -33 import java.util.Map; -34 import java.util.Map.Entry; -35 import java.util.MissingResourceException; -36 import java.util.Properties; -37 import java.util.ResourceBundle; -38 import java.util.Set; -39 import org.owasp.dependencycheck.data.cwe.CweDB; -40 import org.owasp.dependencycheck.dependency.Reference; -41 import org.owasp.dependencycheck.dependency.Vulnerability; -42 import org.owasp.dependencycheck.dependency.VulnerableSoftware; -43 import org.owasp.dependencycheck.utils.DBUtils; -44 import org.owasp.dependencycheck.utils.DependencyVersion; -45 import org.owasp.dependencycheck.utils.DependencyVersionUtil; -46 import org.owasp.dependencycheck.utils.Pair; -47 import org.owasp.dependencycheck.utils.Settings; -48 import org.slf4j.Logger; -49 import org.slf4j.LoggerFactory; -50 -51 /** -52 * The database holding information about the NVD CVE data. -53 * -54 * @author Jeremy Long -55 */ -56 public class CveDB { -57 -58 /** -59 * The logger. -60 */ -61 private static final Logger LOGGER = LoggerFactory.getLogger(CveDB.class); -62 /** -63 * Database connection -64 */ -65 private Connection conn; -66 /** -67 * The bundle of statements used when accessing the database. -68 */ -69 private ResourceBundle statementBundle = null; -70 -71 /** -72 * Creates a new CveDB object and opens the database -73 * connection. Note, the connection must be closed by the caller by calling -74 * the close method. ======= Does the underlying connection support batch -75 * operations? -76 */ -77 private boolean batchSupported; -78 -79 /** -80 * Creates a new CveDB object and opens the database connection. Note, the -81 * connection must be closed by the caller by calling the close method. -82 * -83 * @throws DatabaseException thrown if there is an exception opening the -84 * database. -85 */ -86 public CveDB() throws DatabaseException { -87 super(); -88 try { -89 open(); -90 try { -91 final String databaseProductName = conn.getMetaData().getDatabaseProductName(); -92 batchSupported = conn.getMetaData().supportsBatchUpdates(); -93 LOGGER.debug("Database dialect: {}", databaseProductName); -94 final Locale dbDialect = new Locale(databaseProductName); -95 statementBundle = ResourceBundle.getBundle("data/dbStatements", dbDialect); -96 } catch (SQLException se) { -97 LOGGER.warn("Problem loading database specific dialect!", se); -98 statementBundle = ResourceBundle.getBundle("data/dbStatements"); -99 } -100 databaseProperties = new DatabaseProperties(this); -101 } catch (DatabaseException ex) { -102 throw ex; -103 } -104 } -105 -106 /** -107 * Returns the database connection. -108 * -109 * @return the database connection -110 */ -111 protected Connection getConnection() { -112 return conn; -113 } -114 -115 /** -116 * Opens the database connection. If the database does not exist, it will -117 * create a new one. -118 * -119 * @throws DatabaseException thrown if there is an error opening the -120 * database connection -121 */ -122 public final void open() throws DatabaseException { -123 if (!isOpen()) { -124 conn = ConnectionFactory.getConnection(); -125 } -126 } -127 -128 /** -129 * Closes the DB4O database. Close should be called on this object when it -130 * is done being used. -131 */ -132 public void close() { -133 if (conn != null) { -134 try { -135 conn.close(); -136 } catch (SQLException ex) { -137 LOGGER.error("There was an error attempting to close the CveDB, see the log for more details."); -138 LOGGER.debug("", ex); -139 } catch (Throwable ex) { -140 LOGGER.error("There was an exception attempting to close the CveDB, see the log for more details."); -141 LOGGER.debug("", ex); -142 } -143 conn = null; -144 } -145 } -146 -147 /** -148 * Returns whether the database connection is open or closed. -149 * -150 * @return whether the database connection is open or closed -151 */ -152 public boolean isOpen() { -153 return conn != null; -154 } -155 -156 /** -157 * Commits all completed transactions. -158 * -159 * @throws SQLException thrown if a SQL Exception occurs -160 */ -161 public void commit() throws SQLException { -162 //temporary remove this as autocommit is on. -163 //if (conn != null) { -164 // conn.commit(); -165 //} -166 } -167 -168 /** -169 * Cleans up the object and ensures that "close" has been called. -170 * -171 * @throws Throwable thrown if there is a problem -172 */ -173 @Override -174 @SuppressWarnings("FinalizeDeclaration") -175 protected void finalize() throws Throwable { -176 LOGGER.debug("Entering finalize"); -177 close(); -178 super.finalize(); -179 } -180 /** -181 * Database properties object containing the 'properties' from the database -182 * table. -183 */ -184 private DatabaseProperties databaseProperties; -185 -186 /** -187 * Get the value of databaseProperties. -188 * -189 * @return the value of databaseProperties -190 */ -191 public DatabaseProperties getDatabaseProperties() { -192 return databaseProperties; -193 } -194 -195 /** -196 * Searches the CPE entries in the database and retrieves all entries for a -197 * given vendor and product combination. The returned list will include all -198 * versions of the product that are registered in the NVD CVE data. -199 * -200 * @param vendor the identified vendor name of the dependency being analyzed -201 * @param product the identified name of the product of the dependency being -202 * analyzed -203 * @return a set of vulnerable software -204 */ -205 public Set<VulnerableSoftware> getCPEs(String vendor, String product) { -206 final Set<VulnerableSoftware> cpe = new HashSet<VulnerableSoftware>(); -207 ResultSet rs = null; -208 PreparedStatement ps = null; -209 try { -210 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_CPE_ENTRIES")); -211 ps.setString(1, vendor); -212 ps.setString(2, product); -213 rs = ps.executeQuery(); -214 -215 while (rs.next()) { -216 final VulnerableSoftware vs = new VulnerableSoftware(); -217 vs.setCpe(rs.getString(1)); -218 cpe.add(vs); -219 } -220 } catch (SQLException ex) { -221 LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details."); -222 LOGGER.debug("", ex); -223 } finally { -224 DBUtils.closeResultSet(rs); -225 DBUtils.closeStatement(ps); -226 } -227 return cpe; -228 } -229 -230 /** -231 * Returns the entire list of vendor/product combinations. -232 * -233 * @return the entire list of vendor/product combinations -234 * @throws DatabaseException thrown when there is an error retrieving the -235 * data from the DB -236 */ -237 public Set<Pair<String, String>> getVendorProductList() throws DatabaseException { -238 final Set<Pair<String, String>> data = new HashSet<Pair<String, String>>(); -239 ResultSet rs = null; -240 PreparedStatement ps = null; -241 try { -242 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_VENDOR_PRODUCT_LIST")); -243 rs = ps.executeQuery(); -244 while (rs.next()) { -245 data.add(new Pair<String, String>(rs.getString(1), rs.getString(2))); -246 } -247 } catch (SQLException ex) { -248 final String msg = "An unexpected SQL Exception occurred; please see the verbose log for more details."; -249 throw new DatabaseException(msg, ex); -250 } finally { -251 DBUtils.closeResultSet(rs); -252 DBUtils.closeStatement(ps); -253 } -254 return data; -255 } -256 -257 /** -258 * Returns a set of properties. -259 * -260 * @return the properties from the database -261 */ -262 Properties getProperties() { -263 final Properties prop = new Properties(); -264 PreparedStatement ps = null; -265 ResultSet rs = null; -266 try { -267 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_PROPERTIES")); -268 rs = ps.executeQuery(); -269 while (rs.next()) { -270 prop.setProperty(rs.getString(1), rs.getString(2)); -271 } -272 } catch (SQLException ex) { -273 LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details."); -274 LOGGER.debug("", ex); -275 } finally { -276 DBUtils.closeStatement(ps); -277 DBUtils.closeResultSet(rs); -278 } -279 return prop; -280 } -281 -282 /** -283 * Saves a property to the database. -284 * -285 * @param key the property key -286 * @param value the property value -287 */ -288 void saveProperty(String key, String value) { -289 try { -290 try { -291 final PreparedStatement mergeProperty = getConnection().prepareStatement(statementBundle.getString("MERGE_PROPERTY")); -292 try { -293 mergeProperty.setString(1, key); -294 mergeProperty.setString(2, value); -295 mergeProperty.executeUpdate(); -296 } finally { -297 DBUtils.closeStatement(mergeProperty); -298 } -299 } catch (MissingResourceException mre) { -300 // No Merge statement, so doing an Update/Insert... -301 PreparedStatement updateProperty = null; -302 PreparedStatement insertProperty = null; -303 try { -304 updateProperty = getConnection().prepareStatement(statementBundle.getString("UPDATE_PROPERTY")); -305 updateProperty.setString(1, value); -306 updateProperty.setString(2, key); -307 if (updateProperty.executeUpdate() == 0) { -308 insertProperty = getConnection().prepareStatement(statementBundle.getString("INSERT_PROPERTY")); -309 insertProperty.setString(1, key); -310 insertProperty.setString(2, value); -311 insertProperty.executeUpdate(); -312 } -313 } finally { -314 DBUtils.closeStatement(updateProperty); -315 DBUtils.closeStatement(insertProperty); -316 } -317 } -318 } catch (SQLException ex) { -319 LOGGER.warn("Unable to save property '{}' with a value of '{}' to the database", key, value); -320 LOGGER.debug("", ex); -321 } -322 } -323 -324 /** -325 * Retrieves the vulnerabilities associated with the specified CPE. -326 * -327 * @param cpeStr the CPE name -328 * @return a list of Vulnerabilities -329 * @throws DatabaseException thrown if there is an exception retrieving data -330 */ -331 public List<Vulnerability> getVulnerabilities(String cpeStr) throws DatabaseException { -332 final VulnerableSoftware cpe = new VulnerableSoftware(); -333 try { -334 cpe.parseName(cpeStr); -335 } catch (UnsupportedEncodingException ex) { -336 LOGGER.trace("", ex); -337 } -338 final DependencyVersion detectedVersion = parseDependencyVersion(cpe); -339 final List<Vulnerability> vulnerabilities = new ArrayList<Vulnerability>(); -340 -341 PreparedStatement ps = null; -342 ResultSet rs = null; -343 try { -344 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_CVE_FROM_SOFTWARE")); -345 ps.setString(1, cpe.getVendor()); -346 ps.setString(2, cpe.getProduct()); -347 rs = ps.executeQuery(); -348 String currentCVE = ""; -349 -350 final Map<String, Boolean> vulnSoftware = new HashMap<String, Boolean>(); -351 while (rs.next()) { -352 final String cveId = rs.getString(1); -353 if (!currentCVE.equals(cveId)) { //check for match and add -354 final Entry<String, Boolean> matchedCPE = getMatchingSoftware(vulnSoftware, cpe.getVendor(), cpe.getProduct(), detectedVersion); -355 if (matchedCPE != null) { -356 final Vulnerability v = getVulnerability(currentCVE); -357 v.setMatchedCPE(matchedCPE.getKey(), matchedCPE.getValue() ? "Y" : null); -358 vulnerabilities.add(v); -359 } -360 vulnSoftware.clear(); -361 currentCVE = cveId; -362 } -363 -364 final String cpeId = rs.getString(2); -365 final String previous = rs.getString(3); -366 final Boolean p = previous != null && !previous.isEmpty(); -367 vulnSoftware.put(cpeId, p); -368 } -369 //remember to process the last set of CVE/CPE entries -370 final Entry<String, Boolean> matchedCPE = getMatchingSoftware(vulnSoftware, cpe.getVendor(), cpe.getProduct(), detectedVersion); -371 if (matchedCPE != null) { -372 final Vulnerability v = getVulnerability(currentCVE); -373 v.setMatchedCPE(matchedCPE.getKey(), matchedCPE.getValue() ? "Y" : null); -374 vulnerabilities.add(v); -375 } -376 } catch (SQLException ex) { -377 throw new DatabaseException("Exception retrieving vulnerability for " + cpeStr, ex); -378 } finally { -379 DBUtils.closeResultSet(rs); -380 DBUtils.closeStatement(ps); -381 } -382 return vulnerabilities; -383 } -384 -385 /** -386 * Gets a vulnerability for the provided CVE. -387 * -388 * @param cve the CVE to lookup -389 * @return a vulnerability object -390 * @throws DatabaseException if an exception occurs -391 */ -392 public Vulnerability getVulnerability(String cve) throws DatabaseException { -393 PreparedStatement psV = null; -394 PreparedStatement psR = null; -395 PreparedStatement psS = null; -396 ResultSet rsV = null; -397 ResultSet rsR = null; -398 ResultSet rsS = null; -399 Vulnerability vuln = null; -400 -401 try { -402 psV = getConnection().prepareStatement(statementBundle.getString("SELECT_VULNERABILITY")); -403 psV.setString(1, cve); -404 rsV = psV.executeQuery(); -405 if (rsV.next()) { -406 vuln = new Vulnerability(); -407 vuln.setName(cve); -408 vuln.setDescription(rsV.getString(2)); -409 String cwe = rsV.getString(3); -410 if (cwe != null) { -411 final String name = CweDB.getCweName(cwe); -412 if (name != null) { -413 cwe += ' ' + name; -414 } -415 } -416 final int cveId = rsV.getInt(1); -417 vuln.setCwe(cwe); -418 vuln.setCvssScore(rsV.getFloat(4)); -419 vuln.setCvssAccessVector(rsV.getString(5)); -420 vuln.setCvssAccessComplexity(rsV.getString(6)); -421 vuln.setCvssAuthentication(rsV.getString(7)); -422 vuln.setCvssConfidentialityImpact(rsV.getString(8)); -423 vuln.setCvssIntegrityImpact(rsV.getString(9)); -424 vuln.setCvssAvailabilityImpact(rsV.getString(10)); -425 -426 psR = getConnection().prepareStatement(statementBundle.getString("SELECT_REFERENCES")); -427 psR.setInt(1, cveId); -428 rsR = psR.executeQuery(); -429 while (rsR.next()) { -430 vuln.addReference(rsR.getString(1), rsR.getString(2), rsR.getString(3)); -431 } -432 psS = getConnection().prepareStatement(statementBundle.getString("SELECT_SOFTWARE")); -433 psS.setInt(1, cveId); -434 rsS = psS.executeQuery(); -435 while (rsS.next()) { -436 final String cpe = rsS.getString(1); -437 final String prevVersion = rsS.getString(2); -438 if (prevVersion == null) { -439 vuln.addVulnerableSoftware(cpe); -440 } else { -441 vuln.addVulnerableSoftware(cpe, prevVersion); -442 } -443 } -444 } -445 } catch (SQLException ex) { -446 throw new DatabaseException("Error retrieving " + cve, ex); -447 } finally { -448 DBUtils.closeResultSet(rsV); -449 DBUtils.closeResultSet(rsR); -450 DBUtils.closeResultSet(rsS); -451 DBUtils.closeStatement(psV); -452 DBUtils.closeStatement(psR); -453 DBUtils.closeStatement(psS); -454 } -455 return vuln; -456 } -457 -458 /** -459 * Updates the vulnerability within the database. If the vulnerability does -460 * not exist it will be added. -461 * -462 * @param vuln the vulnerability to add to the database -463 * @throws DatabaseException is thrown if the database -464 */ -465 public void updateVulnerability(Vulnerability vuln) throws DatabaseException { -466 PreparedStatement selectVulnerabilityId = null; -467 PreparedStatement deleteVulnerability = null; -468 PreparedStatement deleteReferences = null; -469 PreparedStatement deleteSoftware = null; -470 PreparedStatement updateVulnerability = null; -471 PreparedStatement insertVulnerability = null; -472 PreparedStatement insertReference = null; -473 PreparedStatement selectCpeId = null; -474 PreparedStatement insertCpe = null; -475 PreparedStatement insertSoftware = null; -476 -477 try { -478 selectVulnerabilityId = getConnection().prepareStatement(statementBundle.getString("SELECT_VULNERABILITY_ID")); -479 deleteVulnerability = getConnection().prepareStatement(statementBundle.getString("DELETE_VULNERABILITY")); -480 deleteReferences = getConnection().prepareStatement(statementBundle.getString("DELETE_REFERENCE")); -481 deleteSoftware = getConnection().prepareStatement(statementBundle.getString("DELETE_SOFTWARE")); -482 updateVulnerability = getConnection().prepareStatement(statementBundle.getString("UPDATE_VULNERABILITY")); -483 final String[] ids = {"id"}; -484 insertVulnerability = getConnection().prepareStatement(statementBundle.getString("INSERT_VULNERABILITY"), -485 //Statement.RETURN_GENERATED_KEYS); -486 ids); -487 insertReference = getConnection().prepareStatement(statementBundle.getString("INSERT_REFERENCE")); -488 selectCpeId = getConnection().prepareStatement(statementBundle.getString("SELECT_CPE_ID")); -489 insertCpe = getConnection().prepareStatement(statementBundle.getString("INSERT_CPE"), -490 //Statement.RETURN_GENERATED_KEYS); -491 ids); -492 insertSoftware = getConnection().prepareStatement(statementBundle.getString("INSERT_SOFTWARE")); -493 int vulnerabilityId = 0; -494 selectVulnerabilityId.setString(1, vuln.getName()); -495 ResultSet rs = selectVulnerabilityId.executeQuery(); -496 if (rs.next()) { -497 vulnerabilityId = rs.getInt(1); -498 // first delete any existing vulnerability info. We don't know what was updated. yes, slower but atm easier. -499 deleteReferences.setInt(1, vulnerabilityId); -500 deleteReferences.execute(); -501 deleteSoftware.setInt(1, vulnerabilityId); -502 deleteSoftware.execute(); -503 } -504 DBUtils.closeResultSet(rs); -505 rs = null; -506 -507 if (vulnerabilityId != 0) { -508 if (vuln.getDescription().contains("** REJECT **")) { -509 deleteVulnerability.setInt(1, vulnerabilityId); -510 deleteVulnerability.executeUpdate(); -511 } else { -512 updateVulnerability.setString(1, vuln.getDescription()); -513 updateVulnerability.setString(2, vuln.getCwe()); -514 updateVulnerability.setFloat(3, vuln.getCvssScore()); -515 updateVulnerability.setString(4, vuln.getCvssAccessVector()); -516 updateVulnerability.setString(5, vuln.getCvssAccessComplexity()); -517 updateVulnerability.setString(6, vuln.getCvssAuthentication()); -518 updateVulnerability.setString(7, vuln.getCvssConfidentialityImpact()); -519 updateVulnerability.setString(8, vuln.getCvssIntegrityImpact()); -520 updateVulnerability.setString(9, vuln.getCvssAvailabilityImpact()); -521 updateVulnerability.setInt(10, vulnerabilityId); -522 updateVulnerability.executeUpdate(); -523 } -524 } else { -525 insertVulnerability.setString(1, vuln.getName()); -526 insertVulnerability.setString(2, vuln.getDescription()); -527 insertVulnerability.setString(3, vuln.getCwe()); -528 insertVulnerability.setFloat(4, vuln.getCvssScore()); -529 insertVulnerability.setString(5, vuln.getCvssAccessVector()); -530 insertVulnerability.setString(6, vuln.getCvssAccessComplexity()); -531 insertVulnerability.setString(7, vuln.getCvssAuthentication()); -532 insertVulnerability.setString(8, vuln.getCvssConfidentialityImpact()); -533 insertVulnerability.setString(9, vuln.getCvssIntegrityImpact()); -534 insertVulnerability.setString(10, vuln.getCvssAvailabilityImpact()); -535 insertVulnerability.execute(); -536 try { -537 rs = insertVulnerability.getGeneratedKeys(); -538 rs.next(); -539 vulnerabilityId = rs.getInt(1); -540 } catch (SQLException ex) { -541 final String msg = String.format("Unable to retrieve id for new vulnerability for '%s'", vuln.getName()); -542 throw new DatabaseException(msg, ex); -543 } finally { -544 DBUtils.closeResultSet(rs); -545 rs = null; -546 } -547 } -548 -549 for (Reference r : vuln.getReferences()) { -550 insertReference.setInt(1, vulnerabilityId); -551 insertReference.setString(2, r.getName()); -552 insertReference.setString(3, r.getUrl()); -553 insertReference.setString(4, r.getSource()); -554 -555 if (batchSupported) { -556 insertReference.addBatch(); -557 } else { -558 insertReference.execute(); -559 } -560 } -561 -562 if (batchSupported) { -563 insertReference.executeBatch(); -564 } -565 -566 for (VulnerableSoftware s : vuln.getVulnerableSoftware()) { -567 int cpeProductId = 0; -568 selectCpeId.setString(1, s.getName()); -569 try { -570 rs = selectCpeId.executeQuery(); -571 if (rs.next()) { -572 cpeProductId = rs.getInt(1); -573 } -574 } catch (SQLException ex) { -575 throw new DatabaseException("Unable to get primary key for new cpe: " + s.getName(), ex); -576 } finally { -577 DBUtils.closeResultSet(rs); -578 rs = null; -579 } -580 -581 if (cpeProductId == 0) { -582 insertCpe.setString(1, s.getName()); -583 insertCpe.setString(2, s.getVendor()); -584 insertCpe.setString(3, s.getProduct()); -585 insertCpe.executeUpdate(); -586 cpeProductId = DBUtils.getGeneratedKey(insertCpe); -587 } -588 if (cpeProductId == 0) { -589 throw new DatabaseException("Unable to retrieve cpeProductId - no data returned"); -590 } -591 -592 insertSoftware.setInt(1, vulnerabilityId); -593 insertSoftware.setInt(2, cpeProductId); -594 -595 if (s.getPreviousVersion() == null) { -596 insertSoftware.setNull(3, java.sql.Types.VARCHAR); -597 } else { -598 insertSoftware.setString(3, s.getPreviousVersion()); -599 } -600 if (batchSupported) { -601 insertSoftware.addBatch(); -602 } else { -603 try { -604 insertSoftware.execute(); -605 } catch (SQLException ex) { -606 if (ex.getMessage().contains("Duplicate entry")) { -607 final String msg = String.format("Duplicate software key identified in '%s:%s'", vuln.getName(), s.getName()); -608 LOGGER.debug(msg, ex); -609 } else { -610 throw ex; -611 } -612 } -613 } -614 } -615 if (batchSupported) { -616 insertSoftware.executeBatch(); -617 } -618 } catch (SQLException ex) { -619 final String msg = String.format("Error updating '%s'", vuln.getName()); -620 LOGGER.debug(msg, ex); -621 throw new DatabaseException(msg, ex); -622 } finally { -623 DBUtils.closeStatement(selectVulnerabilityId); -624 DBUtils.closeStatement(deleteReferences); -625 DBUtils.closeStatement(deleteSoftware); -626 DBUtils.closeStatement(updateVulnerability); -627 DBUtils.closeStatement(deleteVulnerability); -628 DBUtils.closeStatement(insertVulnerability); -629 DBUtils.closeStatement(insertReference); -630 DBUtils.closeStatement(selectCpeId); -631 DBUtils.closeStatement(insertCpe); -632 DBUtils.closeStatement(insertSoftware); -633 } -634 } -635 -636 /** -637 * Checks to see if data exists so that analysis can be performed. -638 * -639 * @return <code>true</code> if data exists; otherwise <code>false</code> -640 */ -641 public boolean dataExists() { -642 Statement cs = null; -643 ResultSet rs = null; -644 try { -645 cs = conn.createStatement(); -646 rs = cs.executeQuery("SELECT COUNT(*) records FROM cpeEntry"); -647 if (rs.next()) { -648 if (rs.getInt(1) > 0) { -649 return true; -650 } -651 } -652 } catch (SQLException ex) { -653 String dd; -654 try { -655 dd = Settings.getDataDirectory().getAbsolutePath(); -656 } catch (IOException ex1) { -657 dd = Settings.getString(Settings.KEYS.DATA_DIRECTORY); -658 } -659 LOGGER.error("Unable to access the local database.\n\nEnsure that '{}' is a writable directory. " -660 + "If the problem persist try deleting the files in '{}' and running {} again. If the problem continues, please " -661 + "create a log file (see documentation at http://jeremylong.github.io/DependencyCheck/) and open a ticket at " -662 + "https://github.com/jeremylong/DependencyCheck/issues and include the log file.\n\n", -663 dd, dd, Settings.getString(Settings.KEYS.APPLICATION_VAME)); -664 LOGGER.debug("", ex); -665 } finally { -666 DBUtils.closeResultSet(rs); -667 DBUtils.closeStatement(cs); -668 } -669 return false; -670 } -671 -672 /** -673 * It is possible that orphaned rows may be generated during database -674 * updates. This should be called after all updates have been completed to -675 * ensure orphan entries are removed. -676 */ -677 public void cleanupDatabase() { -678 PreparedStatement ps = null; -679 try { -680 ps = getConnection().prepareStatement(statementBundle.getString("CLEANUP_ORPHANS")); -681 if (ps != null) { -682 ps.executeUpdate(); -683 } -684 } catch (SQLException ex) { -685 LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details."); -686 LOGGER.debug("", ex); -687 } finally { -688 DBUtils.closeStatement(ps); -689 } -690 } -691 -692 /** -693 * Determines if the given identifiedVersion is affected by the given cpeId -694 * and previous version flag. A non-null, non-empty string passed to the -695 * previous version argument indicates that all previous versions are -696 * affected. -697 * -698 * @param vendor the vendor of the dependency being analyzed -699 * @param product the product name of the dependency being analyzed -700 * @param vulnerableSoftware a map of the vulnerable software with a boolean -701 * indicating if all previous versions are affected -702 * @param identifiedVersion the identified version of the dependency being -703 * analyzed -704 * @return true if the identified version is affected, otherwise false -705 */ -706 Entry<String, Boolean> getMatchingSoftware(Map<String, Boolean> vulnerableSoftware, String vendor, String product, -707 DependencyVersion identifiedVersion) { +22 import java.sql.Connection; +23 import java.sql.PreparedStatement; +24 import java.sql.ResultSet; +25 import java.sql.SQLException; +26 import java.sql.Statement; +27 import java.util.ArrayList; +28 import java.util.HashMap; +29 import java.util.HashSet; +30 import java.util.List; +31 import java.util.Locale; +32 import java.util.Map; +33 import java.util.Map.Entry; +34 import java.util.MissingResourceException; +35 import java.util.Properties; +36 import java.util.ResourceBundle; +37 import java.util.Set; +38 import org.owasp.dependencycheck.data.cwe.CweDB; +39 import org.owasp.dependencycheck.dependency.Reference; +40 import org.owasp.dependencycheck.dependency.Vulnerability; +41 import org.owasp.dependencycheck.dependency.VulnerableSoftware; +42 import org.owasp.dependencycheck.utils.DBUtils; +43 import org.owasp.dependencycheck.utils.DependencyVersion; +44 import org.owasp.dependencycheck.utils.DependencyVersionUtil; +45 import org.owasp.dependencycheck.utils.Pair; +46 import org.owasp.dependencycheck.utils.Settings; +47 import org.slf4j.Logger; +48 import org.slf4j.LoggerFactory; +49 +50 /** +51 * The database holding information about the NVD CVE data. +52 * +53 * @author Jeremy Long +54 */ +55 public class CveDB { +56 +57 /** +58 * The logger. +59 */ +60 private static final Logger LOGGER = LoggerFactory.getLogger(CveDB.class); +61 /** +62 * Database connection +63 */ +64 private Connection conn; +65 /** +66 * The bundle of statements used when accessing the database. +67 */ +68 private ResourceBundle statementBundle = null; +69 +70 /** +71 * Creates a new CveDB object and opens the database connection. Note, the +72 * connection must be closed by the caller by calling the close method. +73 * ======= Does the underlying connection support batch operations? +74 */ +75 private boolean batchSupported; +76 +77 /** +78 * Creates a new CveDB object and opens the database connection. Note, the +79 * connection must be closed by the caller by calling the close method. +80 * +81 * @throws DatabaseException thrown if there is an exception opening the +82 * database. +83 */ +84 public CveDB() throws DatabaseException { +85 super(); +86 try { +87 open(); +88 try { +89 final String databaseProductName = conn.getMetaData().getDatabaseProductName(); +90 batchSupported = conn.getMetaData().supportsBatchUpdates(); +91 LOGGER.debug("Database dialect: {}", databaseProductName); +92 final Locale dbDialect = new Locale(databaseProductName); +93 statementBundle = ResourceBundle.getBundle("data/dbStatements", dbDialect); +94 } catch (SQLException se) { +95 LOGGER.warn("Problem loading database specific dialect!", se); +96 statementBundle = ResourceBundle.getBundle("data/dbStatements"); +97 } +98 databaseProperties = new DatabaseProperties(this); +99 } catch (DatabaseException ex) { +100 throw ex; +101 } +102 } +103 +104 /** +105 * Returns the database connection. +106 * +107 * @return the database connection +108 */ +109 protected Connection getConnection() { +110 return conn; +111 } +112 +113 /** +114 * Opens the database connection. If the database does not exist, it will +115 * create a new one. +116 * +117 * @throws DatabaseException thrown if there is an error opening the +118 * database connection +119 */ +120 public final void open() throws DatabaseException { +121 if (!isOpen()) { +122 conn = ConnectionFactory.getConnection(); +123 } +124 } +125 +126 /** +127 * Closes the DB4O database. Close should be called on this object when it +128 * is done being used. +129 */ +130 public void close() { +131 if (conn != null) { +132 try { +133 conn.close(); +134 } catch (SQLException ex) { +135 LOGGER.error("There was an error attempting to close the CveDB, see the log for more details."); +136 LOGGER.debug("", ex); +137 } catch (Throwable ex) { +138 LOGGER.error("There was an exception attempting to close the CveDB, see the log for more details."); +139 LOGGER.debug("", ex); +140 } +141 conn = null; +142 } +143 } +144 +145 /** +146 * Returns whether the database connection is open or closed. +147 * +148 * @return whether the database connection is open or closed +149 */ +150 public boolean isOpen() { +151 return conn != null; +152 } +153 +154 /** +155 * Commits all completed transactions. +156 * +157 * @throws SQLException thrown if a SQL Exception occurs +158 */ +159 public void commit() throws SQLException { +160 //temporary remove this as autocommit is on. +161 //if (conn != null) { +162 // conn.commit(); +163 //} +164 } +165 +166 /** +167 * Cleans up the object and ensures that "close" has been called. +168 * +169 * @throws Throwable thrown if there is a problem +170 */ +171 @Override +172 @SuppressWarnings("FinalizeDeclaration") +173 protected void finalize() throws Throwable { +174 LOGGER.debug("Entering finalize"); +175 close(); +176 super.finalize(); +177 } +178 /** +179 * Database properties object containing the 'properties' from the database +180 * table. +181 */ +182 private DatabaseProperties databaseProperties; +183 +184 /** +185 * Get the value of databaseProperties. +186 * +187 * @return the value of databaseProperties +188 */ +189 public DatabaseProperties getDatabaseProperties() { +190 return databaseProperties; +191 } +192 +193 /** +194 * Searches the CPE entries in the database and retrieves all entries for a +195 * given vendor and product combination. The returned list will include all +196 * versions of the product that are registered in the NVD CVE data. +197 * +198 * @param vendor the identified vendor name of the dependency being analyzed +199 * @param product the identified name of the product of the dependency being +200 * analyzed +201 * @return a set of vulnerable software +202 */ +203 public Set<VulnerableSoftware> getCPEs(String vendor, String product) { +204 final Set<VulnerableSoftware> cpe = new HashSet<VulnerableSoftware>(); +205 ResultSet rs = null; +206 PreparedStatement ps = null; +207 try { +208 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_CPE_ENTRIES")); +209 ps.setString(1, vendor); +210 ps.setString(2, product); +211 rs = ps.executeQuery(); +212 +213 while (rs.next()) { +214 final VulnerableSoftware vs = new VulnerableSoftware(); +215 vs.setCpe(rs.getString(1)); +216 cpe.add(vs); +217 } +218 } catch (SQLException ex) { +219 LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details."); +220 LOGGER.debug("", ex); +221 } finally { +222 DBUtils.closeResultSet(rs); +223 DBUtils.closeStatement(ps); +224 } +225 return cpe; +226 } +227 +228 /** +229 * Returns the entire list of vendor/product combinations. +230 * +231 * @return the entire list of vendor/product combinations +232 * @throws DatabaseException thrown when there is an error retrieving the +233 * data from the DB +234 */ +235 public Set<Pair<String, String>> getVendorProductList() throws DatabaseException { +236 final Set<Pair<String, String>> data = new HashSet<Pair<String, String>>(); +237 ResultSet rs = null; +238 PreparedStatement ps = null; +239 try { +240 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_VENDOR_PRODUCT_LIST")); +241 rs = ps.executeQuery(); +242 while (rs.next()) { +243 data.add(new Pair<String, String>(rs.getString(1), rs.getString(2))); +244 } +245 } catch (SQLException ex) { +246 final String msg = "An unexpected SQL Exception occurred; please see the verbose log for more details."; +247 throw new DatabaseException(msg, ex); +248 } finally { +249 DBUtils.closeResultSet(rs); +250 DBUtils.closeStatement(ps); +251 } +252 return data; +253 } +254 +255 /** +256 * Returns a set of properties. +257 * +258 * @return the properties from the database +259 */ +260 Properties getProperties() { +261 final Properties prop = new Properties(); +262 PreparedStatement ps = null; +263 ResultSet rs = null; +264 try { +265 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_PROPERTIES")); +266 rs = ps.executeQuery(); +267 while (rs.next()) { +268 prop.setProperty(rs.getString(1), rs.getString(2)); +269 } +270 } catch (SQLException ex) { +271 LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details."); +272 LOGGER.debug("", ex); +273 } finally { +274 DBUtils.closeStatement(ps); +275 DBUtils.closeResultSet(rs); +276 } +277 return prop; +278 } +279 +280 /** +281 * Saves a property to the database. +282 * +283 * @param key the property key +284 * @param value the property value +285 */ +286 void saveProperty(String key, String value) { +287 try { +288 try { +289 final PreparedStatement mergeProperty = getConnection().prepareStatement(statementBundle.getString("MERGE_PROPERTY")); +290 try { +291 mergeProperty.setString(1, key); +292 mergeProperty.setString(2, value); +293 mergeProperty.executeUpdate(); +294 } finally { +295 DBUtils.closeStatement(mergeProperty); +296 } +297 } catch (MissingResourceException mre) { +298 // No Merge statement, so doing an Update/Insert... +299 PreparedStatement updateProperty = null; +300 PreparedStatement insertProperty = null; +301 try { +302 updateProperty = getConnection().prepareStatement(statementBundle.getString("UPDATE_PROPERTY")); +303 updateProperty.setString(1, value); +304 updateProperty.setString(2, key); +305 if (updateProperty.executeUpdate() == 0) { +306 insertProperty = getConnection().prepareStatement(statementBundle.getString("INSERT_PROPERTY")); +307 insertProperty.setString(1, key); +308 insertProperty.setString(2, value); +309 insertProperty.executeUpdate(); +310 } +311 } finally { +312 DBUtils.closeStatement(updateProperty); +313 DBUtils.closeStatement(insertProperty); +314 } +315 } +316 } catch (SQLException ex) { +317 LOGGER.warn("Unable to save property '{}' with a value of '{}' to the database", key, value); +318 LOGGER.debug("", ex); +319 } +320 } +321 +322 /** +323 * Retrieves the vulnerabilities associated with the specified CPE. +324 * +325 * @param cpeStr the CPE name +326 * @return a list of Vulnerabilities +327 * @throws DatabaseException thrown if there is an exception retrieving data +328 */ +329 public List<Vulnerability> getVulnerabilities(String cpeStr) throws DatabaseException { +330 final VulnerableSoftware cpe = new VulnerableSoftware(); +331 try { +332 cpe.parseName(cpeStr); +333 } catch (UnsupportedEncodingException ex) { +334 LOGGER.trace("", ex); +335 } +336 final DependencyVersion detectedVersion = parseDependencyVersion(cpe); +337 final List<Vulnerability> vulnerabilities = new ArrayList<Vulnerability>(); +338 +339 PreparedStatement ps = null; +340 ResultSet rs = null; +341 try { +342 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_CVE_FROM_SOFTWARE")); +343 ps.setString(1, cpe.getVendor()); +344 ps.setString(2, cpe.getProduct()); +345 rs = ps.executeQuery(); +346 String currentCVE = ""; +347 +348 final Map<String, Boolean> vulnSoftware = new HashMap<String, Boolean>(); +349 while (rs.next()) { +350 final String cveId = rs.getString(1); +351 if (!currentCVE.equals(cveId)) { //check for match and add +352 final Entry<String, Boolean> matchedCPE = getMatchingSoftware(vulnSoftware, cpe.getVendor(), cpe.getProduct(), detectedVersion); +353 if (matchedCPE != null) { +354 final Vulnerability v = getVulnerability(currentCVE); +355 v.setMatchedCPE(matchedCPE.getKey(), matchedCPE.getValue() ? "Y" : null); +356 vulnerabilities.add(v); +357 } +358 vulnSoftware.clear(); +359 currentCVE = cveId; +360 } +361 +362 final String cpeId = rs.getString(2); +363 final String previous = rs.getString(3); +364 final Boolean p = previous != null && !previous.isEmpty(); +365 vulnSoftware.put(cpeId, p); +366 } +367 //remember to process the last set of CVE/CPE entries +368 final Entry<String, Boolean> matchedCPE = getMatchingSoftware(vulnSoftware, cpe.getVendor(), cpe.getProduct(), detectedVersion); +369 if (matchedCPE != null) { +370 final Vulnerability v = getVulnerability(currentCVE); +371 v.setMatchedCPE(matchedCPE.getKey(), matchedCPE.getValue() ? "Y" : null); +372 vulnerabilities.add(v); +373 } +374 } catch (SQLException ex) { +375 throw new DatabaseException("Exception retrieving vulnerability for " + cpeStr, ex); +376 } finally { +377 DBUtils.closeResultSet(rs); +378 DBUtils.closeStatement(ps); +379 } +380 return vulnerabilities; +381 } +382 +383 /** +384 * Gets a vulnerability for the provided CVE. +385 * +386 * @param cve the CVE to lookup +387 * @return a vulnerability object +388 * @throws DatabaseException if an exception occurs +389 */ +390 public Vulnerability getVulnerability(String cve) throws DatabaseException { +391 PreparedStatement psV = null; +392 PreparedStatement psR = null; +393 PreparedStatement psS = null; +394 ResultSet rsV = null; +395 ResultSet rsR = null; +396 ResultSet rsS = null; +397 Vulnerability vuln = null; +398 +399 try { +400 psV = getConnection().prepareStatement(statementBundle.getString("SELECT_VULNERABILITY")); +401 psV.setString(1, cve); +402 rsV = psV.executeQuery(); +403 if (rsV.next()) { +404 vuln = new Vulnerability(); +405 vuln.setName(cve); +406 vuln.setDescription(rsV.getString(2)); +407 String cwe = rsV.getString(3); +408 if (cwe != null) { +409 final String name = CweDB.getCweName(cwe); +410 if (name != null) { +411 cwe += ' ' + name; +412 } +413 } +414 final int cveId = rsV.getInt(1); +415 vuln.setCwe(cwe); +416 vuln.setCvssScore(rsV.getFloat(4)); +417 vuln.setCvssAccessVector(rsV.getString(5)); +418 vuln.setCvssAccessComplexity(rsV.getString(6)); +419 vuln.setCvssAuthentication(rsV.getString(7)); +420 vuln.setCvssConfidentialityImpact(rsV.getString(8)); +421 vuln.setCvssIntegrityImpact(rsV.getString(9)); +422 vuln.setCvssAvailabilityImpact(rsV.getString(10)); +423 +424 psR = getConnection().prepareStatement(statementBundle.getString("SELECT_REFERENCES")); +425 psR.setInt(1, cveId); +426 rsR = psR.executeQuery(); +427 while (rsR.next()) { +428 vuln.addReference(rsR.getString(1), rsR.getString(2), rsR.getString(3)); +429 } +430 psS = getConnection().prepareStatement(statementBundle.getString("SELECT_SOFTWARE")); +431 psS.setInt(1, cveId); +432 rsS = psS.executeQuery(); +433 while (rsS.next()) { +434 final String cpe = rsS.getString(1); +435 final String prevVersion = rsS.getString(2); +436 if (prevVersion == null) { +437 vuln.addVulnerableSoftware(cpe); +438 } else { +439 vuln.addVulnerableSoftware(cpe, prevVersion); +440 } +441 } +442 } +443 } catch (SQLException ex) { +444 throw new DatabaseException("Error retrieving " + cve, ex); +445 } finally { +446 DBUtils.closeResultSet(rsV); +447 DBUtils.closeResultSet(rsR); +448 DBUtils.closeResultSet(rsS); +449 DBUtils.closeStatement(psV); +450 DBUtils.closeStatement(psR); +451 DBUtils.closeStatement(psS); +452 } +453 return vuln; +454 } +455 +456 /** +457 * Updates the vulnerability within the database. If the vulnerability does +458 * not exist it will be added. +459 * +460 * @param vuln the vulnerability to add to the database +461 * @throws DatabaseException is thrown if the database +462 */ +463 public void updateVulnerability(Vulnerability vuln) throws DatabaseException { +464 PreparedStatement selectVulnerabilityId = null; +465 PreparedStatement deleteVulnerability = null; +466 PreparedStatement deleteReferences = null; +467 PreparedStatement deleteSoftware = null; +468 PreparedStatement updateVulnerability = null; +469 PreparedStatement insertVulnerability = null; +470 PreparedStatement insertReference = null; +471 PreparedStatement selectCpeId = null; +472 PreparedStatement insertCpe = null; +473 PreparedStatement insertSoftware = null; +474 +475 try { +476 selectVulnerabilityId = getConnection().prepareStatement(statementBundle.getString("SELECT_VULNERABILITY_ID")); +477 deleteVulnerability = getConnection().prepareStatement(statementBundle.getString("DELETE_VULNERABILITY")); +478 deleteReferences = getConnection().prepareStatement(statementBundle.getString("DELETE_REFERENCE")); +479 deleteSoftware = getConnection().prepareStatement(statementBundle.getString("DELETE_SOFTWARE")); +480 updateVulnerability = getConnection().prepareStatement(statementBundle.getString("UPDATE_VULNERABILITY")); +481 final String[] ids = {"id"}; +482 insertVulnerability = getConnection().prepareStatement(statementBundle.getString("INSERT_VULNERABILITY"), +483 //Statement.RETURN_GENERATED_KEYS); +484 ids); +485 insertReference = getConnection().prepareStatement(statementBundle.getString("INSERT_REFERENCE")); +486 selectCpeId = getConnection().prepareStatement(statementBundle.getString("SELECT_CPE_ID")); +487 insertCpe = getConnection().prepareStatement(statementBundle.getString("INSERT_CPE"), +488 //Statement.RETURN_GENERATED_KEYS); +489 ids); +490 insertSoftware = getConnection().prepareStatement(statementBundle.getString("INSERT_SOFTWARE")); +491 int vulnerabilityId = 0; +492 selectVulnerabilityId.setString(1, vuln.getName()); +493 ResultSet rs = selectVulnerabilityId.executeQuery(); +494 if (rs.next()) { +495 vulnerabilityId = rs.getInt(1); +496 // first delete any existing vulnerability info. We don't know what was updated. yes, slower but atm easier. +497 deleteReferences.setInt(1, vulnerabilityId); +498 deleteReferences.execute(); +499 deleteSoftware.setInt(1, vulnerabilityId); +500 deleteSoftware.execute(); +501 } +502 DBUtils.closeResultSet(rs); +503 rs = null; +504 +505 if (vulnerabilityId != 0) { +506 if (vuln.getDescription().contains("** REJECT **")) { +507 deleteVulnerability.setInt(1, vulnerabilityId); +508 deleteVulnerability.executeUpdate(); +509 } else { +510 updateVulnerability.setString(1, vuln.getDescription()); +511 updateVulnerability.setString(2, vuln.getCwe()); +512 updateVulnerability.setFloat(3, vuln.getCvssScore()); +513 updateVulnerability.setString(4, vuln.getCvssAccessVector()); +514 updateVulnerability.setString(5, vuln.getCvssAccessComplexity()); +515 updateVulnerability.setString(6, vuln.getCvssAuthentication()); +516 updateVulnerability.setString(7, vuln.getCvssConfidentialityImpact()); +517 updateVulnerability.setString(8, vuln.getCvssIntegrityImpact()); +518 updateVulnerability.setString(9, vuln.getCvssAvailabilityImpact()); +519 updateVulnerability.setInt(10, vulnerabilityId); +520 updateVulnerability.executeUpdate(); +521 } +522 } else { +523 insertVulnerability.setString(1, vuln.getName()); +524 insertVulnerability.setString(2, vuln.getDescription()); +525 insertVulnerability.setString(3, vuln.getCwe()); +526 insertVulnerability.setFloat(4, vuln.getCvssScore()); +527 insertVulnerability.setString(5, vuln.getCvssAccessVector()); +528 insertVulnerability.setString(6, vuln.getCvssAccessComplexity()); +529 insertVulnerability.setString(7, vuln.getCvssAuthentication()); +530 insertVulnerability.setString(8, vuln.getCvssConfidentialityImpact()); +531 insertVulnerability.setString(9, vuln.getCvssIntegrityImpact()); +532 insertVulnerability.setString(10, vuln.getCvssAvailabilityImpact()); +533 insertVulnerability.execute(); +534 try { +535 rs = insertVulnerability.getGeneratedKeys(); +536 rs.next(); +537 vulnerabilityId = rs.getInt(1); +538 } catch (SQLException ex) { +539 final String msg = String.format("Unable to retrieve id for new vulnerability for '%s'", vuln.getName()); +540 throw new DatabaseException(msg, ex); +541 } finally { +542 DBUtils.closeResultSet(rs); +543 rs = null; +544 } +545 } +546 +547 for (Reference r : vuln.getReferences()) { +548 insertReference.setInt(1, vulnerabilityId); +549 insertReference.setString(2, r.getName()); +550 insertReference.setString(3, r.getUrl()); +551 insertReference.setString(4, r.getSource()); +552 +553 if (batchSupported) { +554 insertReference.addBatch(); +555 } else { +556 insertReference.execute(); +557 } +558 } +559 +560 if (batchSupported) { +561 insertReference.executeBatch(); +562 } +563 +564 for (VulnerableSoftware s : vuln.getVulnerableSoftware()) { +565 int cpeProductId = 0; +566 selectCpeId.setString(1, s.getName()); +567 try { +568 rs = selectCpeId.executeQuery(); +569 if (rs.next()) { +570 cpeProductId = rs.getInt(1); +571 } +572 } catch (SQLException ex) { +573 throw new DatabaseException("Unable to get primary key for new cpe: " + s.getName(), ex); +574 } finally { +575 DBUtils.closeResultSet(rs); +576 rs = null; +577 } +578 +579 if (cpeProductId == 0) { +580 insertCpe.setString(1, s.getName()); +581 insertCpe.setString(2, s.getVendor()); +582 insertCpe.setString(3, s.getProduct()); +583 insertCpe.executeUpdate(); +584 cpeProductId = DBUtils.getGeneratedKey(insertCpe); +585 } +586 if (cpeProductId == 0) { +587 throw new DatabaseException("Unable to retrieve cpeProductId - no data returned"); +588 } +589 +590 insertSoftware.setInt(1, vulnerabilityId); +591 insertSoftware.setInt(2, cpeProductId); +592 +593 if (s.getPreviousVersion() == null) { +594 insertSoftware.setNull(3, java.sql.Types.VARCHAR); +595 } else { +596 insertSoftware.setString(3, s.getPreviousVersion()); +597 } +598 if (batchSupported) { +599 insertSoftware.addBatch(); +600 } else { +601 try { +602 insertSoftware.execute(); +603 } catch (SQLException ex) { +604 if (ex.getMessage().contains("Duplicate entry")) { +605 final String msg = String.format("Duplicate software key identified in '%s:%s'", vuln.getName(), s.getName()); +606 LOGGER.debug(msg, ex); +607 } else { +608 throw ex; +609 } +610 } +611 } +612 } +613 if (batchSupported) { +614 insertSoftware.executeBatch(); +615 } +616 } catch (SQLException ex) { +617 final String msg = String.format("Error updating '%s'", vuln.getName()); +618 LOGGER.debug(msg, ex); +619 throw new DatabaseException(msg, ex); +620 } finally { +621 DBUtils.closeStatement(selectVulnerabilityId); +622 DBUtils.closeStatement(deleteReferences); +623 DBUtils.closeStatement(deleteSoftware); +624 DBUtils.closeStatement(updateVulnerability); +625 DBUtils.closeStatement(deleteVulnerability); +626 DBUtils.closeStatement(insertVulnerability); +627 DBUtils.closeStatement(insertReference); +628 DBUtils.closeStatement(selectCpeId); +629 DBUtils.closeStatement(insertCpe); +630 DBUtils.closeStatement(insertSoftware); +631 } +632 } +633 +634 /** +635 * Checks to see if data exists so that analysis can be performed. +636 * +637 * @return <code>true</code> if data exists; otherwise <code>false</code> +638 */ +639 public boolean dataExists() { +640 Statement cs = null; +641 ResultSet rs = null; +642 try { +643 cs = conn.createStatement(); +644 rs = cs.executeQuery("SELECT COUNT(*) records FROM cpeEntry"); +645 if (rs.next()) { +646 if (rs.getInt(1) > 0) { +647 return true; +648 } +649 } +650 } catch (SQLException ex) { +651 String dd; +652 try { +653 dd = Settings.getDataDirectory().getAbsolutePath(); +654 } catch (IOException ex1) { +655 dd = Settings.getString(Settings.KEYS.DATA_DIRECTORY); +656 } +657 LOGGER.error("Unable to access the local database.\n\nEnsure that '{}' is a writable directory. " +658 + "If the problem persist try deleting the files in '{}' and running {} again. If the problem continues, please " +659 + "create a log file (see documentation at http://jeremylong.github.io/DependencyCheck/) and open a ticket at " +660 + "https://github.com/jeremylong/DependencyCheck/issues and include the log file.\n\n", +661 dd, dd, Settings.getString(Settings.KEYS.APPLICATION_VAME)); +662 LOGGER.debug("", ex); +663 } finally { +664 DBUtils.closeResultSet(rs); +665 DBUtils.closeStatement(cs); +666 } +667 return false; +668 } +669 +670 /** +671 * It is possible that orphaned rows may be generated during database +672 * updates. This should be called after all updates have been completed to +673 * ensure orphan entries are removed. +674 */ +675 public void cleanupDatabase() { +676 PreparedStatement ps = null; +677 try { +678 ps = getConnection().prepareStatement(statementBundle.getString("CLEANUP_ORPHANS")); +679 if (ps != null) { +680 ps.executeUpdate(); +681 } +682 } catch (SQLException ex) { +683 LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details."); +684 LOGGER.debug("", ex); +685 } finally { +686 DBUtils.closeStatement(ps); +687 } +688 } +689 +690 /** +691 * Determines if the given identifiedVersion is affected by the given cpeId +692 * and previous version flag. A non-null, non-empty string passed to the +693 * previous version argument indicates that all previous versions are +694 * affected. +695 * +696 * @param vendor the vendor of the dependency being analyzed +697 * @param product the product name of the dependency being analyzed +698 * @param vulnerableSoftware a map of the vulnerable software with a boolean +699 * indicating if all previous versions are affected +700 * @param identifiedVersion the identified version of the dependency being +701 * analyzed +702 * @return true if the identified version is affected, otherwise false +703 */ +704 Entry<String, Boolean> getMatchingSoftware(Map<String, Boolean> vulnerableSoftware, String vendor, String product, +705 DependencyVersion identifiedVersion) { +706 +707 final boolean isVersionTwoADifferentProduct = "apache".equals(vendor) && "struts".equals(product); 708 -709 final boolean isVersionTwoADifferentProduct = "apache".equals(vendor) && "struts".equals(product); -710 -711 final Set<String> majorVersionsAffectingAllPrevious = new HashSet<String>(); -712 final boolean matchesAnyPrevious = identifiedVersion == null || "-".equals(identifiedVersion.toString()); -713 String majorVersionMatch = null; -714 for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) { -715 final DependencyVersion v = parseDependencyVersion(entry.getKey()); -716 if (v == null || "-".equals(v.toString())) { //all versions -717 return entry; -718 } -719 if (entry.getValue()) { -720 if (matchesAnyPrevious) { -721 return entry; -722 } -723 if (identifiedVersion != null && identifiedVersion.getVersionParts().get(0).equals(v.getVersionParts().get(0))) { -724 majorVersionMatch = v.getVersionParts().get(0); -725 } -726 majorVersionsAffectingAllPrevious.add(v.getVersionParts().get(0)); -727 } -728 } -729 if (matchesAnyPrevious) { -730 return null; -731 } -732 -733 final boolean canSkipVersions = majorVersionMatch != null && majorVersionsAffectingAllPrevious.size() > 1; -734 //yes, we are iterating over this twice. The first time we are skipping versions those that affect all versions -735 //then later we process those that affect all versions. This could be done with sorting... -736 for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) { -737 if (!entry.getValue()) { -738 final DependencyVersion v = parseDependencyVersion(entry.getKey()); -739 //this can't dereference a null 'majorVersionMatch' as canSkipVersions accounts for this. -740 if (canSkipVersions && !majorVersionMatch.equals(v.getVersionParts().get(0))) { -741 continue; -742 } -743 //this can't dereference a null 'identifiedVersion' because if it was null we would have exited -744 //in the above loop or just after loop (if matchesAnyPrevious return null). -745 if (identifiedVersion.equals(v)) { -746 return entry; -747 } -748 } -749 } -750 for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) { -751 if (entry.getValue()) { -752 final DependencyVersion v = parseDependencyVersion(entry.getKey()); -753 //this can't dereference a null 'majorVersionMatch' as canSkipVersions accounts for this. -754 if (canSkipVersions && !majorVersionMatch.equals(v.getVersionParts().get(0))) { -755 continue; -756 } -757 //this can't dereference a null 'identifiedVersion' because if it was null we would have exited -758 //in the above loop or just after loop (if matchesAnyPrevious return null). -759 if (entry.getValue() && identifiedVersion.compareTo(v) <= 0) { -760 if (!(isVersionTwoADifferentProduct && !identifiedVersion.getVersionParts().get(0).equals(v.getVersionParts().get(0)))) { -761 return entry; -762 } -763 } -764 } -765 } -766 return null; -767 } -768 -769 /** -770 * Parses the version (including revision) from a CPE identifier. If no -771 * version is identified then a '-' is returned. -772 * -773 * @param cpeStr a cpe identifier -774 * @return a dependency version -775 */ -776 private DependencyVersion parseDependencyVersion(String cpeStr) { -777 final VulnerableSoftware cpe = new VulnerableSoftware(); -778 try { -779 cpe.parseName(cpeStr); -780 } catch (UnsupportedEncodingException ex) { -781 //never going to happen. -782 LOGGER.trace("", ex); -783 } -784 return parseDependencyVersion(cpe); -785 } -786 -787 /** -788 * Takes a CPE and parses out the version number. If no version is -789 * identified then a '-' is returned. -790 * -791 * @param cpe a cpe object -792 * @return a dependency version -793 */ -794 private DependencyVersion parseDependencyVersion(VulnerableSoftware cpe) { -795 final DependencyVersion cpeVersion; -796 if (cpe.getVersion() != null && !cpe.getVersion().isEmpty()) { -797 final String versionText; -798 if (cpe.getUpdate() != null && !cpe.getUpdate().isEmpty()) { -799 versionText = String.format("%s.%s", cpe.getVersion(), cpe.getUpdate()); -800 } else { -801 versionText = cpe.getVersion(); -802 } -803 cpeVersion = DependencyVersionUtil.parseVersion(versionText); -804 } else { -805 cpeVersion = new DependencyVersion("-"); -806 } -807 return cpeVersion; -808 } -809 -810 /** -811 * This method is only referenced in unused code. -812 * -813 * Deletes unused dictionary entries from the database. -814 */ -815 public void deleteUnusedCpe() { -816 CallableStatement cs = null; -817 try { -818 cs = getConnection().prepareCall(statementBundle.getString("DELETE_UNUSED_DICT_CPE")); -819 cs.executeUpdate(); -820 } catch (SQLException ex) { -821 LOGGER.error("Unable to delete CPE dictionary entries", ex); -822 } finally { -823 DBUtils.closeStatement(cs); -824 } -825 } -826 -827 /** -828 * This method is only referenced in unused code and will likely break on -829 * MySQL if ever used due to the MERGE statement. +709 final Set<String> majorVersionsAffectingAllPrevious = new HashSet<String>(); +710 final boolean matchesAnyPrevious = identifiedVersion == null || "-".equals(identifiedVersion.toString()); +711 String majorVersionMatch = null; +712 for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) { +713 final DependencyVersion v = parseDependencyVersion(entry.getKey()); +714 if (v == null || "-".equals(v.toString())) { //all versions +715 return entry; +716 } +717 if (entry.getValue()) { +718 if (matchesAnyPrevious) { +719 return entry; +720 } +721 if (identifiedVersion != null && identifiedVersion.getVersionParts().get(0).equals(v.getVersionParts().get(0))) { +722 majorVersionMatch = v.getVersionParts().get(0); +723 } +724 majorVersionsAffectingAllPrevious.add(v.getVersionParts().get(0)); +725 } +726 } +727 if (matchesAnyPrevious) { +728 return null; +729 } +730 +731 final boolean canSkipVersions = majorVersionMatch != null && majorVersionsAffectingAllPrevious.size() > 1; +732 //yes, we are iterating over this twice. The first time we are skipping versions those that affect all versions +733 //then later we process those that affect all versions. This could be done with sorting... +734 for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) { +735 if (!entry.getValue()) { +736 final DependencyVersion v = parseDependencyVersion(entry.getKey()); +737 //this can't dereference a null 'majorVersionMatch' as canSkipVersions accounts for this. +738 if (canSkipVersions && !majorVersionMatch.equals(v.getVersionParts().get(0))) { +739 continue; +740 } +741 //this can't dereference a null 'identifiedVersion' because if it was null we would have exited +742 //in the above loop or just after loop (if matchesAnyPrevious return null). +743 if (identifiedVersion.equals(v)) { +744 return entry; +745 } +746 } +747 } +748 for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) { +749 if (entry.getValue()) { +750 final DependencyVersion v = parseDependencyVersion(entry.getKey()); +751 //this can't dereference a null 'majorVersionMatch' as canSkipVersions accounts for this. +752 if (canSkipVersions && !majorVersionMatch.equals(v.getVersionParts().get(0))) { +753 continue; +754 } +755 //this can't dereference a null 'identifiedVersion' because if it was null we would have exited +756 //in the above loop or just after loop (if matchesAnyPrevious return null). +757 if (entry.getValue() && identifiedVersion.compareTo(v) <= 0) { +758 if (!(isVersionTwoADifferentProduct && !identifiedVersion.getVersionParts().get(0).equals(v.getVersionParts().get(0)))) { +759 return entry; +760 } +761 } +762 } +763 } +764 return null; +765 } +766 +767 /** +768 * Parses the version (including revision) from a CPE identifier. If no +769 * version is identified then a '-' is returned. +770 * +771 * @param cpeStr a cpe identifier +772 * @return a dependency version +773 */ +774 private DependencyVersion parseDependencyVersion(String cpeStr) { +775 final VulnerableSoftware cpe = new VulnerableSoftware(); +776 try { +777 cpe.parseName(cpeStr); +778 } catch (UnsupportedEncodingException ex) { +779 //never going to happen. +780 LOGGER.trace("", ex); +781 } +782 return parseDependencyVersion(cpe); +783 } +784 +785 /** +786 * Takes a CPE and parses out the version number. If no version is +787 * identified then a '-' is returned. +788 * +789 * @param cpe a cpe object +790 * @return a dependency version +791 */ +792 private DependencyVersion parseDependencyVersion(VulnerableSoftware cpe) { +793 final DependencyVersion cpeVersion; +794 if (cpe.getVersion() != null && !cpe.getVersion().isEmpty()) { +795 final String versionText; +796 if (cpe.getUpdate() != null && !cpe.getUpdate().isEmpty()) { +797 versionText = String.format("%s.%s", cpe.getVersion(), cpe.getUpdate()); +798 } else { +799 versionText = cpe.getVersion(); +800 } +801 cpeVersion = DependencyVersionUtil.parseVersion(versionText); +802 } else { +803 cpeVersion = new DependencyVersion("-"); +804 } +805 return cpeVersion; +806 } +807 +808 /** +809 * This method is only referenced in unused code. +810 * +811 * Deletes unused dictionary entries from the database. +812 */ +813 public void deleteUnusedCpe() { +814 PreparedStatement ps = null; +815 try { +816 ps = getConnection().prepareStatement(statementBundle.getString("DELETE_UNUSED_DICT_CPE")); +817 ps.executeUpdate(); +818 } catch (SQLException ex) { +819 LOGGER.error("Unable to delete CPE dictionary entries", ex); +820 } finally { +821 DBUtils.closeStatement(ps); +822 } +823 } +824 +825 /** +826 * This method is only referenced in unused code and will likely break on +827 * MySQL if ever used due to the MERGE statement. +828 * +829 * Merges CPE entries into the database. 830 * -831 * Merges CPE entries into the database. -832 * -833 * @param cpe the CPE identifier -834 * @param vendor the CPE vendor -835 * @param product the CPE product -836 */ -837 public void addCpe(String cpe, String vendor, String product) { -838 PreparedStatement ps = null; -839 try { -840 ps = getConnection().prepareCall(statementBundle.getString("ADD_DICT_CPE")); -841 ps.setString(1, cpe); -842 ps.setString(2, vendor); -843 ps.setString(3, product); -844 ps.executeUpdate(); -845 } catch (SQLException ex) { -846 LOGGER.error("Unable to add CPE dictionary entry", ex); -847 } finally { -848 DBUtils.closeStatement(ps); -849 } -850 } -851 } +831 * @param cpe the CPE identifier +832 * @param vendor the CPE vendor +833 * @param product the CPE product +834 */ +835 public void addCpe(String cpe, String vendor, String product) { +836 PreparedStatement ps = null; +837 try { +838 ps = getConnection().prepareStatement(statementBundle.getString("ADD_DICT_CPE")); +839 ps.setString(1, cpe); +840 ps.setString(2, vendor); +841 ps.setString(3, product); +842 ps.executeUpdate(); +843 } catch (SQLException ex) { +844 LOGGER.error("Unable to add CPE dictionary entry", ex); +845 } finally { +846 DBUtils.closeStatement(ps); +847 } +848 } +849 }
      diff --git a/xref/org/owasp/dependencycheck/data/nvdcve/package-frame.html b/xref/org/owasp/dependencycheck/data/nvdcve/package-frame.html index d89cd7707..46555b90e 100644 --- a/xref/org/owasp/dependencycheck/data/nvdcve/package-frame.html +++ b/xref/org/owasp/dependencycheck/data/nvdcve/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.nvdcve + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.nvdcve diff --git a/xref/org/owasp/dependencycheck/data/nvdcve/package-summary.html b/xref/org/owasp/dependencycheck/data/nvdcve/package-summary.html index 88465d252..4fd072923 100644 --- a/xref/org/owasp/dependencycheck/data/nvdcve/package-summary.html +++ b/xref/org/owasp/dependencycheck/data/nvdcve/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.nvdcve + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.nvdcve diff --git a/xref/org/owasp/dependencycheck/data/update/EngineVersionCheck.html b/xref/org/owasp/dependencycheck/data/update/EngineVersionCheck.html index 819d97414..756ce7202 100644 --- a/xref/org/owasp/dependencycheck/data/update/EngineVersionCheck.html +++ b/xref/org/owasp/dependencycheck/data/update/EngineVersionCheck.html @@ -44,187 +44,203 @@ 36 import org.slf4j.LoggerFactory; 37 38 /** -39 * -40 * @author Jeremy Long -41 */ -42 public class EngineVersionCheck implements CachedWebDataSource { -43 -44 /** -45 * Static logger. -46 */ -47 private static final Logger LOGGER = LoggerFactory.getLogger(EngineVersionCheck.class); +39 * Checks the gh-pages dependency-check site to determine the current released +40 * version number. If the released version number is greater then the running +41 * version number a warning is printed recommending that an upgrade be +42 * performed. +43 * +44 * @author Jeremy Long +45 */ +46 public class EngineVersionCheck implements CachedWebDataSource { +47 48 /** -49 * The property key indicating when the last version check occurred. +49 * Static logger. 50 */ -51 public static final String ENGINE_VERSION_CHECKED_ON = "VersionCheckOn"; +51 private static final Logger LOGGER = LoggerFactory.getLogger(EngineVersionCheck.class); 52 /** 53 * The property key indicating when the last version check occurred. 54 */ -55 public static final String CURRENT_ENGINE_RELEASE = "CurrentEngineRelease"; +55 public static final String ENGINE_VERSION_CHECKED_ON = "VersionCheckOn"; 56 /** -57 * Reference to the Cve Database. +57 * The property key indicating when the last version check occurred. 58 */ -59 private CveDB cveDB = null; -60 -61 /** -62 * The version retrieved from the database properties or web to check against. -63 */ -64 private String updateToVersion; -65 -66 /** -67 * Getter for updateToVersion - only used for testing. Represents the version retrieved from the database. -68 * -69 * @return the version to test -70 */ -71 protected String getUpdateToVersion() { -72 return updateToVersion; -73 } -74 -75 /** -76 * Setter for updateToVersion - only used for testing. Represents the version retrieved from the database. -77 * -78 * @param version the version to test -79 */ -80 protected void setUpdateToVersion(String version) { -81 updateToVersion = version; -82 } -83 -84 @Override -85 public void update() throws UpdateException { -86 -87 try { -88 if (Settings.getBoolean(Settings.KEYS.AUTO_UPDATE)) { -89 openDatabase(); -90 LOGGER.debug("Begin Engine Version Check"); -91 final DatabaseProperties properties = cveDB.getDatabaseProperties(); -92 final long lastChecked = Long.parseLong(properties.getProperty(ENGINE_VERSION_CHECKED_ON, "0")); -93 final long now = System.currentTimeMillis(); -94 updateToVersion = properties.getProperty(CURRENT_ENGINE_RELEASE, ""); -95 final String currentVersion = Settings.getString(Settings.KEYS.APPLICATION_VERSION, "0.0.0"); -96 LOGGER.debug("Last checked: {}", lastChecked); -97 LOGGER.debug("Now: {}", now); -98 LOGGER.debug("Current version: {}", currentVersion); -99 final boolean updateNeeded = shouldUpdate(lastChecked, now, properties, currentVersion); -100 if (updateNeeded) { -101 LOGGER.warn("A new version of dependency-check is available. Consider updating to version {}.", -102 updateToVersion); -103 } -104 } -105 } catch (DatabaseException ex) { -106 LOGGER.debug("Database Exception opening databases to retrieve properties", ex); -107 throw new UpdateException("Error occured updating database properties."); -108 } catch (InvalidSettingException ex) { -109 LOGGER.debug("Unable to determine if autoupdate is enabled", ex); -110 } finally { -111 closeDatabase(); -112 -113 } -114 } -115 -116 /** -117 * Determines if a new version of the dependency-check engine has been released. -118 * -119 * @param lastChecked the epoch time of the last version check -120 * @param now the current epoch time -121 * @param properties the database properties object -122 * @param currentVersion the current version of dependency-check -123 * @return <code>true</code> if a newer version of the database has been released; otherwise <code>false</code> -124 * @throws UpdateException thrown if there is an error connecting to the github documentation site or accessing the local -125 * database. -126 */ -127 protected boolean shouldUpdate(final long lastChecked, final long now, final DatabaseProperties properties, -128 String currentVersion) throws UpdateException { -129 //check every 30 days if we know there is an update, otherwise check every 7 days -130 final int checkRange = 30; -131 if (!DateUtil.withinDateRange(lastChecked, now, checkRange)) { -132 LOGGER.debug("Checking web for new version."); -133 final String currentRelease = getCurrentReleaseVersion(); -134 if (currentRelease != null) { -135 final DependencyVersion v = new DependencyVersion(currentRelease); -136 if (v.getVersionParts() != null && v.getVersionParts().size() >= 3) { -137 updateToVersion = v.toString(); -138 if (!currentRelease.equals(updateToVersion)) { -139 properties.save(CURRENT_ENGINE_RELEASE, updateToVersion); -140 } -141 properties.save(ENGINE_VERSION_CHECKED_ON, Long.toString(now)); -142 } -143 } -144 LOGGER.debug("Current Release: {}", updateToVersion); -145 } -146 if (updateToVersion == null) { -147 LOGGER.debug("Unable to obtain current release"); -148 return false; -149 } -150 final DependencyVersion running = new DependencyVersion(currentVersion); -151 final DependencyVersion released = new DependencyVersion(updateToVersion); -152 if (running.compareTo(released) < 0) { -153 LOGGER.debug("Upgrade recommended"); -154 return true; -155 } -156 LOGGER.debug("Upgrade not needed"); -157 return false; -158 } -159 -160 /** -161 * Opens the CVE and CPE data stores. -162 * -163 * @throws DatabaseException thrown if a data store cannot be opened -164 */ -165 protected final void openDatabase() throws DatabaseException { -166 if (cveDB != null) { -167 return; -168 } -169 cveDB = new CveDB(); -170 cveDB.open(); -171 } -172 -173 /** -174 * Closes the CVE and CPE data stores. -175 */ -176 protected void closeDatabase() { -177 if (cveDB != null) { -178 try { -179 cveDB.close(); -180 cveDB = null; -181 } catch (Throwable ignore) { -182 LOGGER.trace("Error closing the cveDB", ignore); -183 } -184 } -185 } -186 -187 /** -188 * Retrieves the current released version number from the github documentation site. -189 * -190 * @return the current released version number -191 */ -192 protected String getCurrentReleaseVersion() { -193 HttpURLConnection conn = null; -194 try { -195 final String str = Settings.getString(Settings.KEYS.ENGINE_VERSION_CHECK_URL, "http://jeremylong.github.io/DependencyCheck/current.txt"); -196 final URL url = new URL(str); -197 conn = URLConnectionFactory.createHttpURLConnection(url); -198 conn.connect(); -199 if (conn.getResponseCode() != 200) { -200 return null; -201 } -202 final String releaseVersion = IOUtils.toString(conn.getInputStream(), "UTF-8"); -203 if (releaseVersion != null) { -204 return releaseVersion.trim(); -205 } -206 } catch (MalformedURLException ex) { -207 LOGGER.debug("unable to retrieve current release version of dependency-check", ex); -208 } catch (URLConnectionFailureException ex) { -209 LOGGER.debug("unable to retrieve current release version of dependency-check", ex); -210 } catch (IOException ex) { -211 LOGGER.debug("unable to retrieve current release version of dependency-check", ex); -212 } finally { -213 if (conn != null) { -214 conn.disconnect(); -215 } -216 } -217 return null; -218 } -219 } +59 public static final String CURRENT_ENGINE_RELEASE = "CurrentEngineRelease"; +60 /** +61 * Reference to the Cve Database. +62 */ +63 private CveDB cveDB = null; +64 +65 /** +66 * The version retrieved from the database properties or web to check +67 * against. +68 */ +69 private String updateToVersion; +70 +71 /** +72 * Getter for updateToVersion - only used for testing. Represents the +73 * version retrieved from the database. +74 * +75 * @return the version to test +76 */ +77 protected String getUpdateToVersion() { +78 return updateToVersion; +79 } +80 +81 /** +82 * Setter for updateToVersion - only used for testing. Represents the +83 * version retrieved from the database. +84 * +85 * @param version the version to test +86 */ +87 protected void setUpdateToVersion(String version) { +88 updateToVersion = version; +89 } +90 +91 /** +92 * Downloads the current released version number and compares it to the +93 * running engine's version number. If the released version number is newer +94 * a warning is printed recommending an upgrade. +95 * +96 * @throws UpdateException thrown if the local database properties could not +97 * be updated +98 */ +99 @Override +100 public void update() throws UpdateException { +101 try { +102 if (Settings.getBoolean(Settings.KEYS.AUTO_UPDATE)) { +103 openDatabase(); +104 LOGGER.debug("Begin Engine Version Check"); +105 final DatabaseProperties properties = cveDB.getDatabaseProperties(); +106 final long lastChecked = Long.parseLong(properties.getProperty(ENGINE_VERSION_CHECKED_ON, "0")); +107 final long now = System.currentTimeMillis(); +108 updateToVersion = properties.getProperty(CURRENT_ENGINE_RELEASE, ""); +109 final String currentVersion = Settings.getString(Settings.KEYS.APPLICATION_VERSION, "0.0.0"); +110 LOGGER.debug("Last checked: {}", lastChecked); +111 LOGGER.debug("Now: {}", now); +112 LOGGER.debug("Current version: {}", currentVersion); +113 final boolean updateNeeded = shouldUpdate(lastChecked, now, properties, currentVersion); +114 if (updateNeeded) { +115 LOGGER.warn("A new version of dependency-check is available. Consider updating to version {}.", +116 updateToVersion); +117 } +118 } +119 } catch (DatabaseException ex) { +120 LOGGER.debug("Database Exception opening databases to retrieve properties", ex); +121 throw new UpdateException("Error occured updating database properties."); +122 } catch (InvalidSettingException ex) { +123 LOGGER.debug("Unable to determine if autoupdate is enabled", ex); +124 } finally { +125 closeDatabase(); +126 } +127 } +128 +129 /** +130 * Determines if a new version of the dependency-check engine has been +131 * released. +132 * +133 * @param lastChecked the epoch time of the last version check +134 * @param now the current epoch time +135 * @param properties the database properties object +136 * @param currentVersion the current version of dependency-check +137 * @return <code>true</code> if a newer version of the database has been +138 * released; otherwise <code>false</code> +139 * @throws UpdateException thrown if there is an error connecting to the +140 * github documentation site or accessing the local database. +141 */ +142 protected boolean shouldUpdate(final long lastChecked, final long now, final DatabaseProperties properties, +143 String currentVersion) throws UpdateException { +144 //check every 30 days if we know there is an update, otherwise check every 7 days +145 final int checkRange = 30; +146 if (!DateUtil.withinDateRange(lastChecked, now, checkRange)) { +147 LOGGER.debug("Checking web for new version."); +148 final String currentRelease = getCurrentReleaseVersion(); +149 if (currentRelease != null) { +150 final DependencyVersion v = new DependencyVersion(currentRelease); +151 if (v.getVersionParts() != null && v.getVersionParts().size() >= 3) { +152 updateToVersion = v.toString(); +153 if (!currentRelease.equals(updateToVersion)) { +154 properties.save(CURRENT_ENGINE_RELEASE, updateToVersion); +155 } +156 properties.save(ENGINE_VERSION_CHECKED_ON, Long.toString(now)); +157 } +158 } +159 LOGGER.debug("Current Release: {}", updateToVersion); +160 } +161 if (updateToVersion == null) { +162 LOGGER.debug("Unable to obtain current release"); +163 return false; +164 } +165 final DependencyVersion running = new DependencyVersion(currentVersion); +166 final DependencyVersion released = new DependencyVersion(updateToVersion); +167 if (running.compareTo(released) < 0) { +168 LOGGER.debug("Upgrade recommended"); +169 return true; +170 } +171 LOGGER.debug("Upgrade not needed"); +172 return false; +173 } +174 +175 /** +176 * Opens the CVE and CPE data stores. +177 * +178 * @throws DatabaseException thrown if a data store cannot be opened +179 */ +180 protected final void openDatabase() throws DatabaseException { +181 if (cveDB != null) { +182 return; +183 } +184 cveDB = new CveDB(); +185 cveDB.open(); +186 } +187 +188 /** +189 * Closes the CVE and CPE data stores. +190 */ +191 protected void closeDatabase() { +192 if (cveDB != null) { +193 try { +194 cveDB.close(); +195 cveDB = null; +196 } catch (Throwable ignore) { +197 LOGGER.trace("Error closing the cveDB", ignore); +198 } +199 } +200 } +201 +202 /** +203 * Retrieves the current released version number from the github +204 * documentation site. +205 * +206 * @return the current released version number +207 */ +208 protected String getCurrentReleaseVersion() { +209 HttpURLConnection conn = null; +210 try { +211 final String str = Settings.getString(Settings.KEYS.ENGINE_VERSION_CHECK_URL, "http://jeremylong.github.io/DependencyCheck/current.txt"); +212 final URL url = new URL(str); +213 conn = URLConnectionFactory.createHttpURLConnection(url); +214 conn.connect(); +215 if (conn.getResponseCode() != 200) { +216 return null; +217 } +218 final String releaseVersion = IOUtils.toString(conn.getInputStream(), "UTF-8"); +219 if (releaseVersion != null) { +220 return releaseVersion.trim(); +221 } +222 } catch (MalformedURLException ex) { +223 LOGGER.debug("Unable to retrieve current release version of dependency-check", ex); +224 } catch (URLConnectionFailureException ex) { +225 LOGGER.debug("Unable to retrieve current release version of dependency-check", ex); +226 } catch (IOException ex) { +227 LOGGER.debug("Unable to retrieve current release version of dependency-check", ex); +228 } finally { +229 if (conn != null) { +230 conn.disconnect(); +231 } +232 } +233 return null; +234 } +235 }
      diff --git a/xref/org/owasp/dependencycheck/data/update/NvdCveUpdater.html b/xref/org/owasp/dependencycheck/data/update/NvdCveUpdater.html index 2e9ae7430..ccd49bf55 100644 --- a/xref/org/owasp/dependencycheck/data/update/NvdCveUpdater.html +++ b/xref/org/owasp/dependencycheck/data/update/NvdCveUpdater.html @@ -58,7 +58,7 @@ 50 public class NvdCveUpdater extends BaseUpdater implements CachedWebDataSource { 51 52 /** -53 * The logger +53 * The logger. 54 */ 55 private static final Logger LOGGER = LoggerFactory.getLogger(NvdCveUpdater.class); 56 /** @@ -67,301 +67,297 @@ 59 public static final int MAX_THREAD_POOL_SIZE = Settings.getInt(Settings.KEYS.MAX_DOWNLOAD_THREAD_POOL_SIZE, 3); 60 61 /** -62 * <p> -63 * Downloads the latest NVD CVE XML file from the web and imports it into -64 * the current CVE Database.</p> -65 * -66 * @throws UpdateException is thrown if there is an error updating the -67 * database -68 */ -69 @Override -70 public void update() throws UpdateException { -71 try { -72 openDataStores(); -73 boolean autoUpdate = true; -74 try { -75 autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE); -76 } catch (InvalidSettingException ex) { -77 LOGGER.debug("Invalid setting for auto-update; using true."); -78 } -79 if (autoUpdate && checkUpdate()) { -80 final UpdateableNvdCve updateable = getUpdatesNeeded(); -81 getProperties().save(DatabaseProperties.LAST_CHECKED, Long.toString(System.currentTimeMillis())); -82 if (updateable.isUpdateNeeded()) { -83 performUpdate(updateable); -84 } -85 } -86 } catch (MalformedURLException ex) { -87 LOGGER.warn( -88 "NVD CVE properties files contain an invalid URL, unable to update the data to use the most current data."); -89 LOGGER.debug("", ex); -90 } catch (DownloadFailedException ex) { -91 LOGGER.warn( -92 "Unable to download the NVD CVE data; the results may not include the most recent CPE/CVEs from the NVD."); -93 if (Settings.getString(Settings.KEYS.PROXY_SERVER) == null) { -94 LOGGER.info( -95 "If you are behind a proxy you may need to configure dependency-check to use the proxy."); -96 } -97 LOGGER.debug("", ex); -98 } finally { -99 closeDataStores(); -100 } -101 } -102 -103 /** -104 * Checks if the NVD CVE XML files were last checked recently. As an -105 * optimization, we can avoid repetitive checks against the NVD. Setting -106 * CVE_CHECK_VALID_FOR_HOURS determines the duration since last check before -107 * checking again. A database property stores the timestamp of the last -108 * check. -109 * -110 * @return true to proceed with the check, or false to skip. -111 * @throws UpdateException thrown when there is an issue checking for -112 * updates. -113 */ -114 private boolean checkUpdate() throws UpdateException { -115 boolean proceed = true; -116 // If the valid setting has not been specified, then we proceed to check... -117 final int validForHours = Settings.getInt(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, 0); -118 if (dataExists() && 0 < validForHours) { -119 // ms Valid = valid (hours) x 60 min/hour x 60 sec/min x 1000 ms/sec -120 final long msValid = validForHours * 60L * 60L * 1000L; -121 final long lastChecked = Long.parseLong(getProperties().getProperty(DatabaseProperties.LAST_CHECKED, "0")); -122 final long now = System.currentTimeMillis(); -123 proceed = (now - lastChecked) > msValid; -124 if (!proceed) { -125 LOGGER.info("Skipping NVD check since last check was within {} hours.", validForHours); -126 LOGGER.debug("Last NVD was at {}, and now {} is within {} ms.", -127 lastChecked, now, msValid); -128 } -129 } -130 return proceed; -131 } -132 -133 /** -134 * Checks the CVE Index to ensure data exists and analysis can continue. -135 * -136 * @return true if the database contains data -137 */ -138 private boolean dataExists() { -139 CveDB cve = null; -140 try { -141 cve = new CveDB(); -142 cve.open(); -143 return cve.dataExists(); -144 } catch (DatabaseException ex) { -145 return false; -146 } finally { -147 if (cve != null) { -148 cve.close(); -149 } -150 } -151 } -152 -153 /** -154 * Downloads the latest NVD CVE XML file from the web and imports it into -155 * the current CVE Database. -156 * -157 * @param updateable a collection of NVD CVE data file references that need -158 * to be downloaded and processed to update the database -159 * @throws UpdateException is thrown if there is an error updating the -160 * database -161 */ -162 public void performUpdate(UpdateableNvdCve updateable) throws UpdateException { -163 int maxUpdates = 0; -164 try { -165 for (NvdCveInfo cve : updateable) { -166 if (cve.getNeedsUpdate()) { -167 maxUpdates += 1; -168 } +62 * Downloads the latest NVD CVE XML file from the web and imports it into +63 * the current CVE Database. +64 * +65 * @throws UpdateException is thrown if there is an error updating the +66 * database +67 */ +68 @Override +69 public void update() throws UpdateException { +70 try { +71 openDataStores(); +72 boolean autoUpdate = true; +73 try { +74 autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE); +75 } catch (InvalidSettingException ex) { +76 LOGGER.debug("Invalid setting for auto-update; using true."); +77 } +78 if (autoUpdate && checkUpdate()) { +79 final UpdateableNvdCve updateable = getUpdatesNeeded(); +80 getProperties().save(DatabaseProperties.LAST_CHECKED, Long.toString(System.currentTimeMillis())); +81 if (updateable.isUpdateNeeded()) { +82 performUpdate(updateable); +83 } +84 } +85 } catch (MalformedURLException ex) { +86 throw new UpdateException("NVD CVE properties files contain an invalid URL, unable to update the data to use the most current data.", ex); +87 } catch (DownloadFailedException ex) { +88 LOGGER.warn( +89 "Unable to download the NVD CVE data; the results may not include the most recent CPE/CVEs from the NVD."); +90 if (Settings.getString(Settings.KEYS.PROXY_SERVER) == null) { +91 LOGGER.info( +92 "If you are behind a proxy you may need to configure dependency-check to use the proxy."); +93 } +94 throw new UpdateException("Unable to download the NVD CVE data.", ex); +95 } finally { +96 closeDataStores(); +97 } +98 } +99 +100 /** +101 * Checks if the NVD CVE XML files were last checked recently. As an +102 * optimization, we can avoid repetitive checks against the NVD. Setting +103 * CVE_CHECK_VALID_FOR_HOURS determines the duration since last check before +104 * checking again. A database property stores the timestamp of the last +105 * check. +106 * +107 * @return true to proceed with the check, or false to skip +108 * @throws UpdateException thrown when there is an issue checking for +109 * updates +110 */ +111 private boolean checkUpdate() throws UpdateException { +112 boolean proceed = true; +113 // If the valid setting has not been specified, then we proceed to check... +114 final int validForHours = Settings.getInt(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, 0); +115 if (dataExists() && 0 < validForHours) { +116 // ms Valid = valid (hours) x 60 min/hour x 60 sec/min x 1000 ms/sec +117 final long msValid = validForHours * 60L * 60L * 1000L; +118 final long lastChecked = Long.parseLong(getProperties().getProperty(DatabaseProperties.LAST_CHECKED, "0")); +119 final long now = System.currentTimeMillis(); +120 proceed = (now - lastChecked) > msValid; +121 if (!proceed) { +122 LOGGER.info("Skipping NVD check since last check was within {} hours.", validForHours); +123 LOGGER.debug("Last NVD was at {}, and now {} is within {} ms.", +124 lastChecked, now, msValid); +125 } +126 } +127 return proceed; +128 } +129 +130 /** +131 * Checks the CVE Index to ensure data exists and analysis can continue. +132 * +133 * @return true if the database contains data +134 */ +135 private boolean dataExists() { +136 CveDB cve = null; +137 try { +138 cve = new CveDB(); +139 cve.open(); +140 return cve.dataExists(); +141 } catch (DatabaseException ex) { +142 return false; +143 } finally { +144 if (cve != null) { +145 cve.close(); +146 } +147 } +148 } +149 +150 /** +151 * Downloads the latest NVD CVE XML file from the web and imports it into +152 * the current CVE Database. +153 * +154 * @param updateable a collection of NVD CVE data file references that need +155 * to be downloaded and processed to update the database +156 * @throws UpdateException is thrown if there is an error updating the +157 * database +158 */ +159 public void performUpdate(UpdateableNvdCve updateable) throws UpdateException { +160 int maxUpdates = 0; +161 try { +162 for (NvdCveInfo cve : updateable) { +163 if (cve.getNeedsUpdate()) { +164 maxUpdates += 1; +165 } +166 } +167 if (maxUpdates <= 0) { +168 return; 169 } -170 if (maxUpdates <= 0) { -171 return; +170 if (maxUpdates > 3) { +171 LOGGER.info("NVD CVE requires several updates; this could take a couple of minutes."); 172 } -173 if (maxUpdates > 3) { -174 LOGGER.info( -175 "NVD CVE requires several updates; this could take a couple of minutes."); -176 } -177 if (maxUpdates > 0) { -178 openDataStores(); -179 } -180 -181 final int poolSize = (MAX_THREAD_POOL_SIZE < maxUpdates) ? MAX_THREAD_POOL_SIZE : maxUpdates; -182 -183 final ExecutorService downloadExecutors = Executors.newFixedThreadPool(poolSize); -184 final ExecutorService processExecutor = Executors.newSingleThreadExecutor(); -185 final Set<Future<Future<ProcessTask>>> downloadFutures = new HashSet<Future<Future<ProcessTask>>>(maxUpdates); -186 for (NvdCveInfo cve : updateable) { -187 if (cve.getNeedsUpdate()) { -188 final DownloadTask call = new DownloadTask(cve, processExecutor, getCveDB(), Settings.getInstance()); -189 downloadFutures.add(downloadExecutors.submit(call)); -190 } -191 } -192 downloadExecutors.shutdown(); -193 -194 //next, move the future future processTasks to just future processTasks -195 final Set<Future<ProcessTask>> processFutures = new HashSet<Future<ProcessTask>>(maxUpdates); -196 for (Future<Future<ProcessTask>> future : downloadFutures) { -197 Future<ProcessTask> task = null; -198 try { -199 task = future.get(); -200 } catch (InterruptedException ex) { -201 downloadExecutors.shutdownNow(); -202 processExecutor.shutdownNow(); -203 -204 LOGGER.debug("Thread was interrupted during download", ex); -205 throw new UpdateException("The download was interrupted", ex); -206 } catch (ExecutionException ex) { -207 downloadExecutors.shutdownNow(); -208 processExecutor.shutdownNow(); -209 -210 LOGGER.debug("Thread was interrupted during download execution", ex); -211 throw new UpdateException("The execution of the download was interrupted", ex); -212 } -213 if (task == null) { -214 downloadExecutors.shutdownNow(); -215 processExecutor.shutdownNow(); -216 LOGGER.debug("Thread was interrupted during download"); -217 throw new UpdateException("The download was interrupted; unable to complete the update"); -218 } else { -219 processFutures.add(task); -220 } -221 } -222 -223 for (Future<ProcessTask> future : processFutures) { -224 try { -225 final ProcessTask task = future.get(); -226 if (task.getException() != null) { -227 throw task.getException(); -228 } -229 } catch (InterruptedException ex) { +173 if (maxUpdates > 0) { +174 openDataStores(); +175 } +176 +177 final int poolSize = (MAX_THREAD_POOL_SIZE < maxUpdates) ? MAX_THREAD_POOL_SIZE : maxUpdates; +178 +179 final ExecutorService downloadExecutors = Executors.newFixedThreadPool(poolSize); +180 final ExecutorService processExecutor = Executors.newSingleThreadExecutor(); +181 final Set<Future<Future<ProcessTask>>> downloadFutures = new HashSet<Future<Future<ProcessTask>>>(maxUpdates); +182 for (NvdCveInfo cve : updateable) { +183 if (cve.getNeedsUpdate()) { +184 final DownloadTask call = new DownloadTask(cve, processExecutor, getCveDB(), Settings.getInstance()); +185 downloadFutures.add(downloadExecutors.submit(call)); +186 } +187 } +188 downloadExecutors.shutdown(); +189 +190 //next, move the future future processTasks to just future processTasks +191 final Set<Future<ProcessTask>> processFutures = new HashSet<Future<ProcessTask>>(maxUpdates); +192 for (Future<Future<ProcessTask>> future : downloadFutures) { +193 Future<ProcessTask> task = null; +194 try { +195 task = future.get(); +196 } catch (InterruptedException ex) { +197 downloadExecutors.shutdownNow(); +198 processExecutor.shutdownNow(); +199 +200 LOGGER.debug("Thread was interrupted during download", ex); +201 throw new UpdateException("The download was interrupted", ex); +202 } catch (ExecutionException ex) { +203 downloadExecutors.shutdownNow(); +204 processExecutor.shutdownNow(); +205 +206 LOGGER.debug("Thread was interrupted during download execution", ex); +207 throw new UpdateException("The execution of the download was interrupted", ex); +208 } +209 if (task == null) { +210 downloadExecutors.shutdownNow(); +211 processExecutor.shutdownNow(); +212 LOGGER.debug("Thread was interrupted during download"); +213 throw new UpdateException("The download was interrupted; unable to complete the update"); +214 } else { +215 processFutures.add(task); +216 } +217 } +218 +219 for (Future<ProcessTask> future : processFutures) { +220 try { +221 final ProcessTask task = future.get(); +222 if (task.getException() != null) { +223 throw task.getException(); +224 } +225 } catch (InterruptedException ex) { +226 processExecutor.shutdownNow(); +227 LOGGER.debug("Thread was interrupted during processing", ex); +228 throw new UpdateException(ex); +229 } catch (ExecutionException ex) { 230 processExecutor.shutdownNow(); -231 LOGGER.debug("Thread was interrupted during processing", ex); +231 LOGGER.debug("Execution Exception during process", ex); 232 throw new UpdateException(ex); -233 } catch (ExecutionException ex) { -234 processExecutor.shutdownNow(); -235 LOGGER.debug("Execution Exception during process", ex); -236 throw new UpdateException(ex); -237 } finally { -238 processExecutor.shutdown(); -239 } -240 } -241 -242 if (maxUpdates >= 1) { //ensure the modified file date gets written (we may not have actually updated it) -243 getProperties().save(updateable.get(MODIFIED)); -244 LOGGER.info("Begin database maintenance."); -245 getCveDB().cleanupDatabase(); -246 LOGGER.info("End database maintenance."); -247 } -248 } finally { -249 closeDataStores(); -250 } -251 } -252 -253 /** -254 * Determines if the index needs to be updated. This is done by fetching the -255 * NVD CVE meta data and checking the last update date. If the data needs to -256 * be refreshed this method will return the NvdCveUrl for the files that -257 * need to be updated. -258 * -259 * @return the collection of files that need to be updated -260 * @throws MalformedURLException is thrown if the URL for the NVD CVE Meta -261 * data is incorrect -262 * @throws DownloadFailedException is thrown if there is an error. -263 * downloading the NVD CVE download data file -264 * @throws UpdateException Is thrown if there is an issue with the last -265 * updated properties file -266 */ -267 protected final UpdateableNvdCve getUpdatesNeeded() throws MalformedURLException, DownloadFailedException, UpdateException { -268 UpdateableNvdCve updates = null; -269 try { -270 updates = retrieveCurrentTimestampsFromWeb(); -271 } catch (InvalidDataException ex) { -272 final String msg = "Unable to retrieve valid timestamp from nvd cve downloads page"; -273 LOGGER.debug(msg, ex); -274 throw new DownloadFailedException(msg, ex); -275 } catch (InvalidSettingException ex) { -276 LOGGER.debug("Invalid setting found when retrieving timestamps", ex); -277 throw new DownloadFailedException("Invalid settings", ex); +233 } finally { +234 processExecutor.shutdown(); +235 } +236 } +237 +238 if (maxUpdates >= 1) { //ensure the modified file date gets written (we may not have actually updated it) +239 getProperties().save(updateable.get(MODIFIED)); +240 LOGGER.info("Begin database maintenance."); +241 getCveDB().cleanupDatabase(); +242 LOGGER.info("End database maintenance."); +243 } +244 } finally { +245 closeDataStores(); +246 } +247 } +248 +249 /** +250 * Determines if the index needs to be updated. This is done by fetching the +251 * NVD CVE meta data and checking the last update date. If the data needs to +252 * be refreshed this method will return the NvdCveUrl for the files that +253 * need to be updated. +254 * +255 * @return the collection of files that need to be updated +256 * @throws MalformedURLException is thrown if the URL for the NVD CVE Meta +257 * data is incorrect +258 * @throws DownloadFailedException is thrown if there is an error. +259 * downloading the NVD CVE download data file +260 * @throws UpdateException Is thrown if there is an issue with the last +261 * updated properties file +262 */ +263 protected final UpdateableNvdCve getUpdatesNeeded() throws MalformedURLException, DownloadFailedException, UpdateException { +264 UpdateableNvdCve updates = null; +265 try { +266 updates = retrieveCurrentTimestampsFromWeb(); +267 } catch (InvalidDataException ex) { +268 final String msg = "Unable to retrieve valid timestamp from nvd cve downloads page"; +269 LOGGER.debug(msg, ex); +270 throw new DownloadFailedException(msg, ex); +271 } catch (InvalidSettingException ex) { +272 LOGGER.debug("Invalid setting found when retrieving timestamps", ex); +273 throw new DownloadFailedException("Invalid settings", ex); +274 } +275 +276 if (updates == null) { +277 throw new DownloadFailedException("Unable to retrieve the timestamps of the currently published NVD CVE data"); 278 } -279 -280 if (updates == null) { -281 throw new DownloadFailedException("Unable to retrieve the timestamps of the currently published NVD CVE data"); -282 } -283 if (!getProperties().isEmpty()) { -284 try { -285 final long lastUpdated = Long.parseLong(getProperties().getProperty(DatabaseProperties.LAST_UPDATED, "0")); -286 final long now = System.currentTimeMillis(); -287 final int days = Settings.getInt(Settings.KEYS.CVE_MODIFIED_VALID_FOR_DAYS, 7); -288 if (lastUpdated == updates.getTimeStamp(MODIFIED)) { -289 updates.clear(); //we don't need to update anything. -290 } else if (DateUtil.withinDateRange(lastUpdated, now, days)) { -291 for (NvdCveInfo entry : updates) { -292 if (MODIFIED.equals(entry.getId())) { -293 entry.setNeedsUpdate(true); -294 } else { -295 entry.setNeedsUpdate(false); -296 } -297 } -298 } else { //we figure out which of the several XML files need to be downloaded. -299 for (NvdCveInfo entry : updates) { -300 if (MODIFIED.equals(entry.getId())) { -301 entry.setNeedsUpdate(true); -302 } else { -303 long currentTimestamp = 0; -304 try { -305 currentTimestamp = Long.parseLong(getProperties().getProperty(DatabaseProperties.LAST_UPDATED_BASE -306 + entry.getId(), "0")); -307 } catch (NumberFormatException ex) { -308 LOGGER.debug("Error parsing '{}' '{}' from nvdcve.lastupdated", -309 DatabaseProperties.LAST_UPDATED_BASE, entry.getId(), ex); -310 } -311 if (currentTimestamp == entry.getTimestamp()) { -312 entry.setNeedsUpdate(false); -313 } -314 } -315 } -316 } -317 } catch (NumberFormatException ex) { -318 LOGGER.warn("An invalid schema version or timestamp exists in the data.properties file."); -319 LOGGER.debug("", ex); -320 } -321 } -322 return updates; -323 } -324 -325 /** -326 * Retrieves the timestamps from the NVD CVE meta data file. -327 * -328 * @return the timestamp from the currently published nvdcve downloads page -329 * @throws MalformedURLException thrown if the URL for the NVD CCE Meta data -330 * is incorrect. -331 * @throws DownloadFailedException thrown if there is an error downloading -332 * the nvd cve meta data file -333 * @throws InvalidDataException thrown if there is an exception parsing the -334 * timestamps -335 * @throws InvalidSettingException thrown if the settings are invalid -336 */ -337 private UpdateableNvdCve retrieveCurrentTimestampsFromWeb() -338 throws MalformedURLException, DownloadFailedException, InvalidDataException, InvalidSettingException { -339 -340 final UpdateableNvdCve updates = new UpdateableNvdCve(); -341 updates.add(MODIFIED, Settings.getString(Settings.KEYS.CVE_MODIFIED_20_URL), -342 Settings.getString(Settings.KEYS.CVE_MODIFIED_12_URL), -343 false); -344 -345 final int start = Settings.getInt(Settings.KEYS.CVE_START_YEAR); -346 final int end = Calendar.getInstance().get(Calendar.YEAR); -347 final String baseUrl20 = Settings.getString(Settings.KEYS.CVE_SCHEMA_2_0); -348 final String baseUrl12 = Settings.getString(Settings.KEYS.CVE_SCHEMA_1_2); -349 for (int i = start; i <= end; i++) { -350 updates.add(Integer.toString(i), String.format(baseUrl20, i), -351 String.format(baseUrl12, i), -352 true); -353 } -354 return updates; -355 } -356 } +279 if (!getProperties().isEmpty()) { +280 try { +281 final long lastUpdated = Long.parseLong(getProperties().getProperty(DatabaseProperties.LAST_UPDATED, "0")); +282 final long now = System.currentTimeMillis(); +283 final int days = Settings.getInt(Settings.KEYS.CVE_MODIFIED_VALID_FOR_DAYS, 7); +284 if (lastUpdated == updates.getTimeStamp(MODIFIED)) { +285 updates.clear(); //we don't need to update anything. +286 } else if (DateUtil.withinDateRange(lastUpdated, now, days)) { +287 for (NvdCveInfo entry : updates) { +288 if (MODIFIED.equals(entry.getId())) { +289 entry.setNeedsUpdate(true); +290 } else { +291 entry.setNeedsUpdate(false); +292 } +293 } +294 } else { //we figure out which of the several XML files need to be downloaded. +295 for (NvdCveInfo entry : updates) { +296 if (MODIFIED.equals(entry.getId())) { +297 entry.setNeedsUpdate(true); +298 } else { +299 long currentTimestamp = 0; +300 try { +301 currentTimestamp = Long.parseLong(getProperties().getProperty(DatabaseProperties.LAST_UPDATED_BASE +302 + entry.getId(), "0")); +303 } catch (NumberFormatException ex) { +304 LOGGER.debug("Error parsing '{}' '{}' from nvdcve.lastupdated", +305 DatabaseProperties.LAST_UPDATED_BASE, entry.getId(), ex); +306 } +307 if (currentTimestamp == entry.getTimestamp()) { +308 entry.setNeedsUpdate(false); +309 } +310 } +311 } +312 } +313 } catch (NumberFormatException ex) { +314 LOGGER.warn("An invalid schema version or timestamp exists in the data.properties file."); +315 LOGGER.debug("", ex); +316 } +317 } +318 return updates; +319 } +320 +321 /** +322 * Retrieves the timestamps from the NVD CVE meta data file. +323 * +324 * @return the timestamp from the currently published nvdcve downloads page +325 * @throws MalformedURLException thrown if the URL for the NVD CCE Meta data +326 * is incorrect. +327 * @throws DownloadFailedException thrown if there is an error downloading +328 * the nvd cve meta data file +329 * @throws InvalidDataException thrown if there is an exception parsing the +330 * timestamps +331 * @throws InvalidSettingException thrown if the settings are invalid +332 */ +333 private UpdateableNvdCve retrieveCurrentTimestampsFromWeb() +334 throws MalformedURLException, DownloadFailedException, InvalidDataException, InvalidSettingException { +335 +336 final UpdateableNvdCve updates = new UpdateableNvdCve(); +337 updates.add(MODIFIED, Settings.getString(Settings.KEYS.CVE_MODIFIED_20_URL), +338 Settings.getString(Settings.KEYS.CVE_MODIFIED_12_URL), +339 false); +340 +341 final int start = Settings.getInt(Settings.KEYS.CVE_START_YEAR); +342 final int end = Calendar.getInstance().get(Calendar.YEAR); +343 final String baseUrl20 = Settings.getString(Settings.KEYS.CVE_SCHEMA_2_0); +344 final String baseUrl12 = Settings.getString(Settings.KEYS.CVE_SCHEMA_1_2); +345 for (int i = start; i <= end; i++) { +346 updates.add(Integer.toString(i), String.format(baseUrl20, i), +347 String.format(baseUrl12, i), +348 true); +349 } +350 return updates; +351 } +352 }
      diff --git a/xref/org/owasp/dependencycheck/data/update/cpe/CPEHandler.html b/xref/org/owasp/dependencycheck/data/update/cpe/CPEHandler.html index 80c05cb39..fcf7d052b 100644 --- a/xref/org/owasp/dependencycheck/data/update/cpe/CPEHandler.html +++ b/xref/org/owasp/dependencycheck/data/update/cpe/CPEHandler.html @@ -30,346 +30,357 @@ 22 import java.util.List; 23 import org.owasp.dependencycheck.data.update.NvdCveUpdater; 24 import org.owasp.dependencycheck.data.update.exception.InvalidDataException; -25 import org.slf4j.Logger; -26 import org.slf4j.LoggerFactory; -27 import org.xml.sax.Attributes; -28 import org.xml.sax.SAXException; -29 import org.xml.sax.helpers.DefaultHandler; -30 -31 /** -32 * A SAX Handler that will parse the CPE XML and load it into the databse. -33 * -34 * @author Jeremy Long -35 */ -36 public class CPEHandler extends DefaultHandler { -37 -38 /** -39 * The current CPE schema. -40 */ -41 private static final String CURRENT_SCHEMA_VERSION = "2.3"; -42 /** -43 * The text content of the node being processed. This can be used during the end element event. -44 */ -45 private StringBuilder nodeText = null; -46 /** -47 * A reference to the current element. -48 */ -49 private final Element current = new Element(); -50 /** -51 * The logger. -52 */ -53 private static final Logger LOGGER = LoggerFactory.getLogger(NvdCveUpdater.class); -54 /** -55 * The list of CPE values. -56 */ -57 private final List<Cpe> data = new ArrayList<Cpe>(); -58 -59 /** -60 * Returns the list of CPE values. -61 * -62 * @return the list of CPE values -63 */ -64 public List<Cpe> getData() { -65 return data; -66 } -67 -68 /** -69 * Handles the start element event. -70 * -71 * @param uri the elements uri -72 * @param localName the local name -73 * @param qName the qualified name -74 * @param attributes the attributes -75 * @throws SAXException thrown if there is an exception processing the element -76 */ -77 @Override -78 public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { -79 nodeText = null; -80 current.setNode(qName); -81 if (current.isCpeItemNode()) { -82 final String temp = attributes.getValue("deprecated"); -83 final String value = attributes.getValue("name"); -84 final boolean delete = "true".equalsIgnoreCase(temp); -85 if (!delete && value.startsWith("cpe:/a:") && value.length() > 7) { -86 try { -87 final Cpe cpe = new Cpe(value); -88 data.add(cpe); -89 } catch (UnsupportedEncodingException ex) { -90 LOGGER.debug("Unable to parse the CPE", ex); -91 } catch (InvalidDataException ex) { -92 LOGGER.debug("CPE is not the correct format", ex); -93 } -94 } -95 } else if (current.isSchemaVersionNode()) { -96 nodeText = new StringBuilder(3); -97 } -98 // } else if (current.isTitleNode()) { -99 // //do nothing -100 // } else if (current.isMetaNode()) { -101 // //do nothing -102 // } else if (current.isTimestampNode()) { -103 // //do nothing -104 // } else if (current.isCpeListNode()) { -105 // //do nothing -106 // } else if (current.isNotesNode()) { -107 // //do nothing -108 // } else if (current.isNoteNode()) { -109 // //do nothing -110 // } else if (current.isCheckNode()) { -111 // //do nothing -112 // } else if (current.isGeneratorNode()) { -113 // //do nothing -114 // } else if (current.isProductNameNode()) { -115 // //do nothing -116 // } else if (current.isProductVersionNode()) { -117 // //do nothing -118 } -119 -120 /** -121 * Reads the characters in the current node. -122 * -123 * @param ch the char array -124 * @param start the start position of the data read -125 * @param length the length of the data read -126 * @throws SAXException thrown if there is an exception processing the characters -127 */ -128 @Override -129 public void characters(char[] ch, int start, int length) throws SAXException { -130 if (nodeText != null) { -131 nodeText.append(ch, start, length); -132 } -133 } -134 -135 /** -136 * Handles the end element event. Stores the CPE data in the Cve Database if the cpe item node is ending. -137 * -138 * @param uri the element's uri -139 * @param localName the local name -140 * @param qName the qualified name -141 * @throws SAXException thrown if there is an exception processing the element -142 */ -143 @Override -144 public void endElement(String uri, String localName, String qName) throws SAXException { -145 current.setNode(qName); -146 if (current.isSchemaVersionNode() && !CURRENT_SCHEMA_VERSION.equals(nodeText.toString())) { -147 throw new SAXException("ERROR: Unexpecgted CPE Schema Version, expected: " -148 + CURRENT_SCHEMA_VERSION + ", file is: " + nodeText); -149 -150 } -151 // } else if (current.isCpeItemNode()) { -152 // //do nothing -153 // } else if (current.isTitleNode()) { -154 // //do nothing -155 // } else if (current.isCpeListNode()) { -156 // //do nothing -157 // } else if (current.isMetaNode()) { -158 // //do nothing -159 // } else if (current.isNotesNode()) { -160 // //do nothing -161 // } else if (current.isNoteNode()) { +25 import org.owasp.dependencycheck.utils.Settings; +26 import org.slf4j.Logger; +27 import org.slf4j.LoggerFactory; +28 import org.xml.sax.Attributes; +29 import org.xml.sax.SAXException; +30 import org.xml.sax.helpers.DefaultHandler; +31 +32 /** +33 * A SAX Handler that will parse the CPE XML and load it into the databse. +34 * +35 * @author Jeremy Long +36 */ +37 public class CPEHandler extends DefaultHandler { +38 +39 /** +40 * The current CPE schema. +41 */ +42 private static final String CURRENT_SCHEMA_VERSION = "2.3"; +43 /** +44 * The Starts with expression to filter CVE entries by CPE. +45 */ +46 private static final String CPE_STARTS_WITH = Settings.getString(Settings.KEYS.CVE_CPE_STARTS_WITH_FILTER, "cpe:/a:"); +47 /** +48 * The text content of the node being processed. This can be used during the +49 * end element event. +50 */ +51 private StringBuilder nodeText = null; +52 /** +53 * A reference to the current element. +54 */ +55 private final Element current = new Element(); +56 /** +57 * The logger. +58 */ +59 private static final Logger LOGGER = LoggerFactory.getLogger(NvdCveUpdater.class); +60 /** +61 * The list of CPE values. +62 */ +63 private final List<Cpe> data = new ArrayList<Cpe>(); +64 +65 /** +66 * Returns the list of CPE values. +67 * +68 * @return the list of CPE values +69 */ +70 public List<Cpe> getData() { +71 return data; +72 } +73 +74 /** +75 * Handles the start element event. +76 * +77 * @param uri the elements uri +78 * @param localName the local name +79 * @param qName the qualified name +80 * @param attributes the attributes +81 * @throws SAXException thrown if there is an exception processing the +82 * element +83 */ +84 @Override +85 public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { +86 nodeText = null; +87 current.setNode(qName); +88 if (current.isCpeItemNode()) { +89 final String temp = attributes.getValue("deprecated"); +90 final String value = attributes.getValue("name"); +91 final boolean delete = "true".equalsIgnoreCase(temp); +92 if (!delete && value.startsWith(CPE_STARTS_WITH) && value.length() > 7) { +93 try { +94 final Cpe cpe = new Cpe(value); +95 data.add(cpe); +96 } catch (UnsupportedEncodingException ex) { +97 LOGGER.debug("Unable to parse the CPE", ex); +98 } catch (InvalidDataException ex) { +99 LOGGER.debug("CPE is not the correct format", ex); +100 } +101 } +102 } else if (current.isSchemaVersionNode()) { +103 nodeText = new StringBuilder(3); +104 } +105 // } else if (current.isTitleNode()) { +106 // //do nothing +107 // } else if (current.isMetaNode()) { +108 // //do nothing +109 // } else if (current.isTimestampNode()) { +110 // //do nothing +111 // } else if (current.isCpeListNode()) { +112 // //do nothing +113 // } else if (current.isNotesNode()) { +114 // //do nothing +115 // } else if (current.isNoteNode()) { +116 // //do nothing +117 // } else if (current.isCheckNode()) { +118 // //do nothing +119 // } else if (current.isGeneratorNode()) { +120 // //do nothing +121 // } else if (current.isProductNameNode()) { +122 // //do nothing +123 // } else if (current.isProductVersionNode()) { +124 // //do nothing +125 } +126 +127 /** +128 * Reads the characters in the current node. +129 * +130 * @param ch the char array +131 * @param start the start position of the data read +132 * @param length the length of the data read +133 * @throws SAXException thrown if there is an exception processing the +134 * characters +135 */ +136 @Override +137 public void characters(char[] ch, int start, int length) throws SAXException { +138 if (nodeText != null) { +139 nodeText.append(ch, start, length); +140 } +141 } +142 +143 /** +144 * Handles the end element event. Stores the CPE data in the Cve Database if +145 * the cpe item node is ending. +146 * +147 * @param uri the element's uri +148 * @param localName the local name +149 * @param qName the qualified name +150 * @throws SAXException thrown if there is an exception processing the +151 * element +152 */ +153 @Override +154 public void endElement(String uri, String localName, String qName) throws SAXException { +155 current.setNode(qName); +156 if (current.isSchemaVersionNode() && !CURRENT_SCHEMA_VERSION.equals(nodeText.toString())) { +157 throw new SAXException("ERROR: Unexpecgted CPE Schema Version, expected: " +158 + CURRENT_SCHEMA_VERSION + ", file is: " + nodeText); +159 +160 } +161 // } else if (current.isCpeItemNode()) { 162 // //do nothing -163 // } else if (current.isCheckNode()) { +163 // } else if (current.isTitleNode()) { 164 // //do nothing -165 // } else if (current.isGeneratorNode()) { +165 // } else if (current.isCpeListNode()) { 166 // //do nothing -167 // } else if (current.isProductNameNode()) { +167 // } else if (current.isMetaNode()) { 168 // //do nothing -169 // } else if (current.isProductVersionNode()) { +169 // } else if (current.isNotesNode()) { 170 // //do nothing -171 // else if (current.isTimestampNode()) { +171 // } else if (current.isNoteNode()) { 172 // //do nothing -173 // } else { -174 // throw new SAXException("ERROR STATE: Unexpected qName '" + qName + "'"); -175 // } -176 } -177 -178 // <editor-fold defaultstate="collapsed" desc="The Element Class that maintains state information about the current node"> -179 /** -180 * A simple class to maintain information about the current element while parsing the CPE XML. -181 */ -182 protected static final class Element { -183 -184 /** -185 * A node type in the CPE Schema 2.2 -186 */ -187 public static final String CPE_LIST = "cpe-list"; -188 /** -189 * A node type in the CPE Schema 2.2 -190 */ -191 public static final String CPE_ITEM = "cpe-item"; -192 /** -193 * A node type in the CPE Schema 2.2 -194 */ -195 public static final String TITLE = "title"; -196 /** -197 * A node type in the CPE Schema 2.2 -198 */ -199 public static final String NOTES = "notes"; -200 /** -201 * A node type in the CPE Schema 2.2 -202 */ -203 public static final String NOTE = "note"; -204 /** -205 * A node type in the CPE Schema 2.2 -206 */ -207 public static final String CHECK = "check"; -208 /** -209 * A node type in the CPE Schema 2.2 -210 */ -211 public static final String META = "meta:item-metadata"; -212 /** -213 * A node type in the CPE Schema 2.2 -214 */ -215 public static final String GENERATOR = "generator"; -216 /** -217 * A node type in the CPE Schema 2.2 -218 */ -219 public static final String PRODUCT_NAME = "product_name"; -220 /** -221 * A node type in the CPE Schema 2.2 -222 */ -223 public static final String PRODUCT_VERSION = "product_version"; -224 /** -225 * A node type in the CPE Schema 2.2 -226 */ -227 public static final String SCHEMA_VERSION = "schema_version"; -228 /** -229 * A node type in the CPE Schema 2.2 -230 */ -231 public static final String TIMESTAMP = "timestamp"; -232 /** -233 * A reference to the current node. -234 */ -235 private String node = null; -236 -237 /** -238 * Gets the value of node -239 * -240 * @return the value of node +173 // } else if (current.isCheckNode()) { +174 // //do nothing +175 // } else if (current.isGeneratorNode()) { +176 // //do nothing +177 // } else if (current.isProductNameNode()) { +178 // //do nothing +179 // } else if (current.isProductVersionNode()) { +180 // //do nothing +181 // else if (current.isTimestampNode()) { +182 // //do nothing +183 // } else { +184 // throw new SAXException("ERROR STATE: Unexpected qName '" + qName + "'"); +185 // } +186 } +187 +188 // <editor-fold defaultstate="collapsed" desc="The Element Class that maintains state information about the current node"> +189 /** +190 * A simple class to maintain information about the current element while +191 * parsing the CPE XML. +192 */ +193 protected static final class Element { +194 +195 /** +196 * A node type in the CPE Schema 2.2 +197 */ +198 public static final String CPE_LIST = "cpe-list"; +199 /** +200 * A node type in the CPE Schema 2.2 +201 */ +202 public static final String CPE_ITEM = "cpe-item"; +203 /** +204 * A node type in the CPE Schema 2.2 +205 */ +206 public static final String TITLE = "title"; +207 /** +208 * A node type in the CPE Schema 2.2 +209 */ +210 public static final String NOTES = "notes"; +211 /** +212 * A node type in the CPE Schema 2.2 +213 */ +214 public static final String NOTE = "note"; +215 /** +216 * A node type in the CPE Schema 2.2 +217 */ +218 public static final String CHECK = "check"; +219 /** +220 * A node type in the CPE Schema 2.2 +221 */ +222 public static final String META = "meta:item-metadata"; +223 /** +224 * A node type in the CPE Schema 2.2 +225 */ +226 public static final String GENERATOR = "generator"; +227 /** +228 * A node type in the CPE Schema 2.2 +229 */ +230 public static final String PRODUCT_NAME = "product_name"; +231 /** +232 * A node type in the CPE Schema 2.2 +233 */ +234 public static final String PRODUCT_VERSION = "product_version"; +235 /** +236 * A node type in the CPE Schema 2.2 +237 */ +238 public static final String SCHEMA_VERSION = "schema_version"; +239 /** +240 * A node type in the CPE Schema 2.2 241 */ -242 public String getNode() { -243 return this.node; -244 } -245 -246 /** -247 * Sets the value of node -248 * -249 * @param node new value of node -250 */ -251 public void setNode(String node) { -252 this.node = node; -253 } -254 -255 /** -256 * Checks if the handler is at the CPE_LIST node -257 * -258 * @return true or false -259 */ -260 public boolean isCpeListNode() { -261 return CPE_LIST.equals(node); -262 } -263 -264 /** -265 * Checks if the handler is at the CPE_ITEM node -266 * -267 * @return true or false -268 */ -269 public boolean isCpeItemNode() { -270 return CPE_ITEM.equals(node); -271 } -272 -273 /** -274 * Checks if the handler is at the TITLE node -275 * -276 * @return true or false -277 */ -278 public boolean isTitleNode() { -279 return TITLE.equals(node); -280 } -281 -282 /** -283 * Checks if the handler is at the NOTES node -284 * -285 * @return true or false -286 */ -287 public boolean isNotesNode() { -288 return NOTES.equals(node); -289 } -290 -291 /** -292 * Checks if the handler is at the NOTE node -293 * -294 * @return true or false -295 */ -296 public boolean isNoteNode() { -297 return NOTE.equals(node); -298 } -299 -300 /** -301 * Checks if the handler is at the CHECK node -302 * -303 * @return true or false -304 */ -305 public boolean isCheckNode() { -306 return CHECK.equals(node); -307 } -308 -309 /** -310 * Checks if the handler is at the META node -311 * -312 * @return true or false -313 */ -314 public boolean isMetaNode() { -315 return META.equals(node); -316 } -317 -318 /** -319 * Checks if the handler is at the GENERATOR node -320 * -321 * @return true or false -322 */ -323 public boolean isGeneratorNode() { -324 return GENERATOR.equals(node); -325 } -326 -327 /** -328 * Checks if the handler is at the PRODUCT_NAME node -329 * -330 * @return true or false -331 */ -332 public boolean isProductNameNode() { -333 return PRODUCT_NAME.equals(node); -334 } -335 -336 /** -337 * Checks if the handler is at the PRODUCT_VERSION node -338 * -339 * @return true or false -340 */ -341 public boolean isProductVersionNode() { -342 return PRODUCT_VERSION.equals(node); -343 } -344 -345 /** -346 * Checks if the handler is at the SCHEMA_VERSION node -347 * -348 * @return true or false -349 */ -350 public boolean isSchemaVersionNode() { -351 return SCHEMA_VERSION.equals(node); -352 } -353 -354 /** -355 * Checks if the handler is at the TIMESTAMP node -356 * -357 * @return true or false -358 */ -359 public boolean isTimestampNode() { -360 return TIMESTAMP.equals(node); -361 } -362 } -363 // </editor-fold> -364 } +242 public static final String TIMESTAMP = "timestamp"; +243 /** +244 * A reference to the current node. +245 */ +246 private String node = null; +247 +248 /** +249 * Gets the value of node +250 * +251 * @return the value of node +252 */ +253 public String getNode() { +254 return this.node; +255 } +256 +257 /** +258 * Sets the value of node +259 * +260 * @param node new value of node +261 */ +262 public void setNode(String node) { +263 this.node = node; +264 } +265 +266 /** +267 * Checks if the handler is at the CPE_LIST node +268 * +269 * @return true or false +270 */ +271 public boolean isCpeListNode() { +272 return CPE_LIST.equals(node); +273 } +274 +275 /** +276 * Checks if the handler is at the CPE_ITEM node +277 * +278 * @return true or false +279 */ +280 public boolean isCpeItemNode() { +281 return CPE_ITEM.equals(node); +282 } +283 +284 /** +285 * Checks if the handler is at the TITLE node +286 * +287 * @return true or false +288 */ +289 public boolean isTitleNode() { +290 return TITLE.equals(node); +291 } +292 +293 /** +294 * Checks if the handler is at the NOTES node +295 * +296 * @return true or false +297 */ +298 public boolean isNotesNode() { +299 return NOTES.equals(node); +300 } +301 +302 /** +303 * Checks if the handler is at the NOTE node +304 * +305 * @return true or false +306 */ +307 public boolean isNoteNode() { +308 return NOTE.equals(node); +309 } +310 +311 /** +312 * Checks if the handler is at the CHECK node +313 * +314 * @return true or false +315 */ +316 public boolean isCheckNode() { +317 return CHECK.equals(node); +318 } +319 +320 /** +321 * Checks if the handler is at the META node +322 * +323 * @return true or false +324 */ +325 public boolean isMetaNode() { +326 return META.equals(node); +327 } +328 +329 /** +330 * Checks if the handler is at the GENERATOR node +331 * +332 * @return true or false +333 */ +334 public boolean isGeneratorNode() { +335 return GENERATOR.equals(node); +336 } +337 +338 /** +339 * Checks if the handler is at the PRODUCT_NAME node +340 * +341 * @return true or false +342 */ +343 public boolean isProductNameNode() { +344 return PRODUCT_NAME.equals(node); +345 } +346 +347 /** +348 * Checks if the handler is at the PRODUCT_VERSION node +349 * +350 * @return true or false +351 */ +352 public boolean isProductVersionNode() { +353 return PRODUCT_VERSION.equals(node); +354 } +355 +356 /** +357 * Checks if the handler is at the SCHEMA_VERSION node +358 * +359 * @return true or false +360 */ +361 public boolean isSchemaVersionNode() { +362 return SCHEMA_VERSION.equals(node); +363 } +364 +365 /** +366 * Checks if the handler is at the TIMESTAMP node +367 * +368 * @return true or false +369 */ +370 public boolean isTimestampNode() { +371 return TIMESTAMP.equals(node); +372 } +373 } +374 // </editor-fold> +375 }
      diff --git a/xref/org/owasp/dependencycheck/data/update/cpe/package-frame.html b/xref/org/owasp/dependencycheck/data/update/cpe/package-frame.html index e50f3bb2f..496874446 100644 --- a/xref/org/owasp/dependencycheck/data/update/cpe/package-frame.html +++ b/xref/org/owasp/dependencycheck/data/update/cpe/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.update.cpe + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.update.cpe diff --git a/xref/org/owasp/dependencycheck/data/update/cpe/package-summary.html b/xref/org/owasp/dependencycheck/data/update/cpe/package-summary.html index d93c53a57..3ca1837ec 100644 --- a/xref/org/owasp/dependencycheck/data/update/cpe/package-summary.html +++ b/xref/org/owasp/dependencycheck/data/update/cpe/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.update.cpe + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.update.cpe diff --git a/xref/org/owasp/dependencycheck/data/update/exception/UpdateException.html b/xref/org/owasp/dependencycheck/data/update/exception/UpdateException.html index 4b1964f16..613077854 100644 --- a/xref/org/owasp/dependencycheck/data/update/exception/UpdateException.html +++ b/xref/org/owasp/dependencycheck/data/update/exception/UpdateException.html @@ -25,55 +25,53 @@ 17 */ 18 package org.owasp.dependencycheck.data.update.exception; 19 -20 import java.io.IOException; -21 -22 /** -23 * An exception used when an error occurs reading a setting. -24 * -25 * @author Jeremy Long -26 */ -27 public class UpdateException extends IOException { -28 -29 /** -30 * The serial version uid. -31 */ -32 private static final long serialVersionUID = 1L; -33 -34 /** -35 * Creates a new UpdateException. -36 */ -37 public UpdateException() { -38 super(); -39 } -40 -41 /** -42 * Creates a new UpdateException. -43 * -44 * @param msg a message for the exception. -45 */ -46 public UpdateException(String msg) { -47 super(msg); -48 } -49 -50 /** -51 * Creates a new UpdateException. -52 * -53 * @param ex the cause of the update exception. -54 */ -55 public UpdateException(Throwable ex) { -56 super(ex); -57 } -58 -59 /** -60 * Creates a new UpdateException. -61 * -62 * @param msg a message for the exception. -63 * @param ex the cause of the update exception. -64 */ -65 public UpdateException(String msg, Throwable ex) { -66 super(msg, ex); -67 } -68 } +20 /** +21 * An exception used when an error occurs reading a setting. +22 * +23 * @author Jeremy Long +24 */ +25 public class UpdateException extends Exception { +26 +27 /** +28 * The serial version uid. +29 */ +30 private static final long serialVersionUID = 1L; +31 +32 /** +33 * Creates a new UpdateException. +34 */ +35 public UpdateException() { +36 super(); +37 } +38 +39 /** +40 * Creates a new UpdateException. +41 * +42 * @param msg a message for the exception. +43 */ +44 public UpdateException(String msg) { +45 super(msg); +46 } +47 +48 /** +49 * Creates a new UpdateException. +50 * +51 * @param ex the cause of the update exception. +52 */ +53 public UpdateException(Throwable ex) { +54 super(ex); +55 } +56 +57 /** +58 * Creates a new UpdateException. +59 * +60 * @param msg a message for the exception. +61 * @param ex the cause of the update exception. +62 */ +63 public UpdateException(String msg, Throwable ex) { +64 super(msg, ex); +65 } +66 }
      diff --git a/xref/org/owasp/dependencycheck/data/update/exception/package-frame.html b/xref/org/owasp/dependencycheck/data/update/exception/package-frame.html index b5b9b60ca..440168171 100644 --- a/xref/org/owasp/dependencycheck/data/update/exception/package-frame.html +++ b/xref/org/owasp/dependencycheck/data/update/exception/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.update.exception + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.update.exception diff --git a/xref/org/owasp/dependencycheck/data/update/exception/package-summary.html b/xref/org/owasp/dependencycheck/data/update/exception/package-summary.html index 199e952ce..97449ad9e 100644 --- a/xref/org/owasp/dependencycheck/data/update/exception/package-summary.html +++ b/xref/org/owasp/dependencycheck/data/update/exception/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.update.exception + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.update.exception diff --git a/xref/org/owasp/dependencycheck/data/update/nvd/UpdateableNvdCve.html b/xref/org/owasp/dependencycheck/data/update/nvd/UpdateableNvdCve.html index b709e5b89..f49ff0e69 100644 --- a/xref/org/owasp/dependencycheck/data/update/nvd/UpdateableNvdCve.html +++ b/xref/org/owasp/dependencycheck/data/update/nvd/UpdateableNvdCve.html @@ -33,163 +33,170 @@ 25 import java.util.TreeMap; 26 import org.owasp.dependencycheck.utils.DownloadFailedException; 27 import org.owasp.dependencycheck.utils.Downloader; -28 -29 /** -30 * Contains a collection of updateable NvdCveInfo objects. This is used to determine which files need to be downloaded and -31 * processed. -32 * -33 * @author Jeremy Long -34 */ -35 public class UpdateableNvdCve implements Iterable<NvdCveInfo>, Iterator<NvdCveInfo> { -36 -37 /** -38 * A collection of sources of data. -39 */ -40 private final Map<String, NvdCveInfo> collection = new TreeMap<String, NvdCveInfo>(); -41 -42 /** -43 * Returns the collection of NvdCveInfo objects. This method is mainly used for testing. -44 * -45 * @return the collection of NvdCveInfo objects -46 */ -47 protected Map<String, NvdCveInfo> getCollection() { -48 return collection; -49 } -50 -51 /** -52 * Gets whether or not an update is needed. -53 * -54 * @return true or false depending on whether an update is needed -55 */ -56 public boolean isUpdateNeeded() { -57 for (NvdCveInfo item : this) { -58 if (item.getNeedsUpdate()) { -59 return true; -60 } -61 } -62 return false; -63 } -64 -65 /** -66 * Adds a new entry of updateable information to the contained collection. -67 * -68 * @param id the key for the item to be added -69 * @param url the URL to download the item -70 * @param oldUrl the URL for the old version of the item (the NVD CVE old schema still contains useful data we need). -71 * @throws MalformedURLException thrown if the URL provided is invalid -72 * @throws DownloadFailedException thrown if the download fails. -73 */ -74 public void add(String id, String url, String oldUrl) throws MalformedURLException, DownloadFailedException { -75 add(id, url, oldUrl, false); -76 } -77 -78 /** -79 * Adds a new entry of updateable information to the contained collection. -80 * -81 * @param id the key for the item to be added -82 * @param url the URL to download the item -83 * @param oldUrl the URL for the old version of the item (the NVD CVE old schema still contains useful data we need). -84 * @param needsUpdate whether or not the data needs to be updated -85 * @throws MalformedURLException thrown if the URL provided is invalid -86 * @throws DownloadFailedException thrown if the download fails. -87 */ -88 public void add(String id, String url, String oldUrl, boolean needsUpdate) throws MalformedURLException, DownloadFailedException { -89 final NvdCveInfo item = new NvdCveInfo(); -90 item.setNeedsUpdate(needsUpdate); //the others default to true, to make life easier later this should default to false. -91 item.setId(id); -92 item.setUrl(url); -93 item.setOldSchemaVersionUrl(oldUrl); -94 item.setTimestamp(Downloader.getLastModified(new URL(url))); -95 collection.put(id, item); -96 } -97 -98 /** -99 * Clears the contained collection of NvdCveInfo entries. -100 */ -101 public void clear() { -102 collection.clear(); +28 import org.slf4j.Logger; +29 import org.slf4j.LoggerFactory; +30 +31 /** +32 * Contains a collection of updateable NvdCveInfo objects. This is used to determine which files need to be downloaded and +33 * processed. +34 * +35 * @author Jeremy Long +36 */ +37 public class UpdateableNvdCve implements Iterable<NvdCveInfo>, Iterator<NvdCveInfo> { +38 +39 /** +40 * A reference to the logger. +41 */ +42 private static final Logger LOGGER = LoggerFactory.getLogger(UpdateableNvdCve.class); +43 /** +44 * A collection of sources of data. +45 */ +46 private final Map<String, NvdCveInfo> collection = new TreeMap<String, NvdCveInfo>(); +47 +48 /** +49 * Returns the collection of NvdCveInfo objects. This method is mainly used for testing. +50 * +51 * @return the collection of NvdCveInfo objects +52 */ +53 protected Map<String, NvdCveInfo> getCollection() { +54 return collection; +55 } +56 +57 /** +58 * Gets whether or not an update is needed. +59 * +60 * @return true or false depending on whether an update is needed +61 */ +62 public boolean isUpdateNeeded() { +63 for (NvdCveInfo item : this) { +64 if (item.getNeedsUpdate()) { +65 return true; +66 } +67 } +68 return false; +69 } +70 +71 /** +72 * Adds a new entry of updateable information to the contained collection. +73 * +74 * @param id the key for the item to be added +75 * @param url the URL to download the item +76 * @param oldUrl the URL for the old version of the item (the NVD CVE old schema still contains useful data we need). +77 * @throws MalformedURLException thrown if the URL provided is invalid +78 * @throws DownloadFailedException thrown if the download fails. +79 */ +80 public void add(String id, String url, String oldUrl) throws MalformedURLException, DownloadFailedException { +81 add(id, url, oldUrl, false); +82 } +83 +84 /** +85 * Adds a new entry of updateable information to the contained collection. +86 * +87 * @param id the key for the item to be added +88 * @param url the URL to download the item +89 * @param oldUrl the URL for the old version of the item (the NVD CVE old schema still contains useful data we need). +90 * @param needsUpdate whether or not the data needs to be updated +91 * @throws MalformedURLException thrown if the URL provided is invalid +92 * @throws DownloadFailedException thrown if the download fails. +93 */ +94 public void add(String id, String url, String oldUrl, boolean needsUpdate) throws MalformedURLException, DownloadFailedException { +95 final NvdCveInfo item = new NvdCveInfo(); +96 item.setNeedsUpdate(needsUpdate); //the others default to true, to make life easier later this should default to false. +97 item.setId(id); +98 item.setUrl(url); +99 item.setOldSchemaVersionUrl(oldUrl); +100 LOGGER.debug("Checking for updates from: {}", url); +101 item.setTimestamp(Downloader.getLastModified(new URL(url))); +102 collection.put(id, item); 103 } 104 105 /** -106 * Returns the timestamp for the given entry. -107 * -108 * @param key the key to lookup in the collection of NvdCveInfo items -109 * @return the timestamp for the given entry -110 */ -111 public long getTimeStamp(String key) { -112 return collection.get(key).getTimestamp(); -113 } -114 /** -115 * An internal iterator used to implement iterable. -116 */ -117 private Iterator<Entry<String, NvdCveInfo>> iterableContent = null; -118 -119 /** -120 * <p> -121 * Returns an iterator for the NvdCveInfo contained.</p> -122 * <p> -123 * <b>This method is not thread safe.</b></p> -124 * -125 * @return an NvdCveInfo Iterator -126 */ -127 @Override -128 public Iterator<NvdCveInfo> iterator() { -129 iterableContent = collection.entrySet().iterator(); -130 return this; -131 } -132 -133 /** -134 * <p> -135 * Returns whether or not there is another item in the collection.</p> -136 * <p> -137 * <b>This method is not thread safe.</b></p> -138 * -139 * @return true or false depending on whether or not another item exists in the collection -140 */ -141 @Override -142 public boolean hasNext() { -143 return iterableContent.hasNext(); -144 } -145 -146 /** -147 * <p> -148 * Returns the next item in the collection.</p> -149 * <p> -150 * <b>This method is not thread safe.</b></p> -151 * -152 * @return the next NvdCveInfo item in the collection -153 */ -154 @Override -155 public NvdCveInfo next() { -156 return iterableContent.next().getValue(); -157 } -158 -159 /** -160 * <p> -161 * Removes the current NvdCveInfo object from the collection.</p> -162 * <p> -163 * <b>This method is not thread safe.</b></p> -164 */ -165 @Override -166 public void remove() { -167 iterableContent.remove(); -168 } -169 -170 /** -171 * Returns the specified item from the collection. -172 * -173 * @param key the key to lookup the return value -174 * @return the NvdCveInfo object stored using the specified key -175 */ -176 public NvdCveInfo get(String key) { -177 return collection.get(key); -178 } -179 -180 @Override -181 public String toString() { -182 return "Updateable{" + "size=" + collection.size() + '}'; -183 } -184 } +106 * Clears the contained collection of NvdCveInfo entries. +107 */ +108 public void clear() { +109 collection.clear(); +110 } +111 +112 /** +113 * Returns the timestamp for the given entry. +114 * +115 * @param key the key to lookup in the collection of NvdCveInfo items +116 * @return the timestamp for the given entry +117 */ +118 public long getTimeStamp(String key) { +119 return collection.get(key).getTimestamp(); +120 } +121 /** +122 * An internal iterator used to implement iterable. +123 */ +124 private Iterator<Entry<String, NvdCveInfo>> iterableContent = null; +125 +126 /** +127 * <p> +128 * Returns an iterator for the NvdCveInfo contained.</p> +129 * <p> +130 * <b>This method is not thread safe.</b></p> +131 * +132 * @return an NvdCveInfo Iterator +133 */ +134 @Override +135 public Iterator<NvdCveInfo> iterator() { +136 iterableContent = collection.entrySet().iterator(); +137 return this; +138 } +139 +140 /** +141 * <p> +142 * Returns whether or not there is another item in the collection.</p> +143 * <p> +144 * <b>This method is not thread safe.</b></p> +145 * +146 * @return true or false depending on whether or not another item exists in the collection +147 */ +148 @Override +149 public boolean hasNext() { +150 return iterableContent.hasNext(); +151 } +152 +153 /** +154 * <p> +155 * Returns the next item in the collection.</p> +156 * <p> +157 * <b>This method is not thread safe.</b></p> +158 * +159 * @return the next NvdCveInfo item in the collection +160 */ +161 @Override +162 public NvdCveInfo next() { +163 return iterableContent.next().getValue(); +164 } +165 +166 /** +167 * <p> +168 * Removes the current NvdCveInfo object from the collection.</p> +169 * <p> +170 * <b>This method is not thread safe.</b></p> +171 */ +172 @Override +173 public void remove() { +174 iterableContent.remove(); +175 } +176 +177 /** +178 * Returns the specified item from the collection. +179 * +180 * @param key the key to lookup the return value +181 * @return the NvdCveInfo object stored using the specified key +182 */ +183 public NvdCveInfo get(String key) { +184 return collection.get(key); +185 } +186 +187 @Override +188 public String toString() { +189 return "Updateable{" + "size=" + collection.size() + '}'; +190 } +191 }
      diff --git a/xref/org/owasp/dependencycheck/data/update/nvd/package-frame.html b/xref/org/owasp/dependencycheck/data/update/nvd/package-frame.html index fbf5e5736..5d67f7106 100644 --- a/xref/org/owasp/dependencycheck/data/update/nvd/package-frame.html +++ b/xref/org/owasp/dependencycheck/data/update/nvd/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.update.nvd + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.update.nvd diff --git a/xref/org/owasp/dependencycheck/data/update/nvd/package-summary.html b/xref/org/owasp/dependencycheck/data/update/nvd/package-summary.html index 31786faa1..ba128ad5c 100644 --- a/xref/org/owasp/dependencycheck/data/update/nvd/package-summary.html +++ b/xref/org/owasp/dependencycheck/data/update/nvd/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.update.nvd + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.update.nvd diff --git a/xref/org/owasp/dependencycheck/data/update/package-frame.html b/xref/org/owasp/dependencycheck/data/update/package-frame.html index a5bc35458..ab1f4a029 100644 --- a/xref/org/owasp/dependencycheck/data/update/package-frame.html +++ b/xref/org/owasp/dependencycheck/data/update/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.update + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.update diff --git a/xref/org/owasp/dependencycheck/data/update/package-summary.html b/xref/org/owasp/dependencycheck/data/update/package-summary.html index 9a922be2e..efda66383 100644 --- a/xref/org/owasp/dependencycheck/data/update/package-summary.html +++ b/xref/org/owasp/dependencycheck/data/update/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.data.update + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.data.update diff --git a/xref/org/owasp/dependencycheck/dependency/Vulnerability.html b/xref/org/owasp/dependencycheck/dependency/Vulnerability.html index f6382c0f0..fe0cd852f 100644 --- a/xref/org/owasp/dependencycheck/dependency/Vulnerability.html +++ b/xref/org/owasp/dependencycheck/dependency/Vulnerability.html @@ -29,448 +29,447 @@ 21 import java.util.Set; 22 import java.util.SortedSet; 23 import java.util.TreeSet; -24 import java.util.Iterator; -25 -26 /** -27 * Contains the information about a vulnerability. -28 * -29 * @author Jeremy Long -30 */ -31 public class Vulnerability implements Serializable, Comparable<Vulnerability> { -32 -33 /** -34 * The serial version uid. -35 */ -36 private static final long serialVersionUID = 307319490326651052L; -37 -38 /** -39 * The name of the vulnerability. -40 */ -41 private String name; -42 -43 /** -44 * Get the value of name. -45 * -46 * @return the value of name -47 */ -48 public String getName() { -49 return name; -50 } -51 -52 /** -53 * Set the value of name. -54 * -55 * @param name new value of name -56 */ -57 public void setName(String name) { -58 this.name = name; -59 } -60 /** -61 * the description of the vulnerability. -62 */ -63 private String description; -64 -65 /** -66 * Get the value of description. -67 * -68 * @return the value of description -69 */ -70 public String getDescription() { -71 return description; -72 } -73 -74 /** -75 * Set the value of description. -76 * -77 * @param description new value of description -78 */ -79 public void setDescription(String description) { -80 this.description = description; -81 } -82 /** -83 * References for this vulnerability. -84 */ -85 private SortedSet<Reference> references = new TreeSet<Reference>(); -86 -87 /** -88 * Get the value of references. -89 * -90 * @return the value of references -91 */ -92 public Set<Reference> getReferences() { -93 return references; -94 } -95 -96 /** -97 * Set the value of references. -98 * -99 * @param references new value of references -100 */ -101 public void setReferences(SortedSet<Reference> references) { -102 this.references = references; -103 } -104 -105 /** -106 * Adds a reference to the references collection. -107 * -108 * @param ref a reference for the vulnerability -109 */ -110 public void addReference(Reference ref) { -111 this.references.add(ref); -112 } -113 -114 /** -115 * Adds a reference. -116 * -117 * @param referenceSource the source of the reference -118 * @param referenceName the referenceName of the reference -119 * @param referenceUrl the url of the reference -120 */ -121 public void addReference(String referenceSource, String referenceName, String referenceUrl) { -122 final Reference ref = new Reference(); -123 ref.setSource(referenceSource); -124 ref.setName(referenceName); -125 ref.setUrl(referenceUrl); -126 this.references.add(ref); -127 } -128 /** -129 * A set of vulnerable software. -130 */ -131 private SortedSet<VulnerableSoftware> vulnerableSoftware = new TreeSet<VulnerableSoftware>(); -132 -133 /** -134 * Get the value of vulnerableSoftware. -135 * -136 * @return the value of vulnerableSoftware -137 */ -138 public Set<VulnerableSoftware> getVulnerableSoftware() { -139 return vulnerableSoftware; -140 } -141 -142 /** -143 * Set the value of vulnerableSoftware. -144 * -145 * @param vulnerableSoftware new value of vulnerableSoftware -146 */ -147 public void setVulnerableSoftware(SortedSet<VulnerableSoftware> vulnerableSoftware) { -148 this.vulnerableSoftware = vulnerableSoftware; -149 } -150 -151 /** -152 * Adds an entry for vulnerable software. -153 * -154 * @param cpe string representation of a CPE entry -155 * @return if the add succeeded -156 */ -157 public boolean addVulnerableSoftware(String cpe) { -158 return addVulnerableSoftware(cpe, null); -159 } -160 -161 /** -162 * Adds an entry for vulnerable software. -163 * -164 * @param cpe string representation of a cpe -165 * @param previousVersion the previous version (previousVersion - cpe would be considered vulnerable) -166 * @return if the add succeeded -167 */ -168 public boolean addVulnerableSoftware(String cpe, String previousVersion) { -169 final VulnerableSoftware vs = new VulnerableSoftware(); -170 vs.setCpe(cpe); -171 if (previousVersion != null) { -172 vs.setPreviousVersion(previousVersion); -173 } -174 return updateVulnerableSoftware(vs); -175 } -176 -177 /** -178 * Adds or updates a vulnerable software entry. -179 * -180 * @param vulnSoftware the vulnerable software -181 * @return if the update succeeded -182 */ -183 public boolean updateVulnerableSoftware(VulnerableSoftware vulnSoftware) { -184 if (vulnerableSoftware.contains(vulnSoftware)) { -185 vulnerableSoftware.remove(vulnSoftware); -186 } -187 return vulnerableSoftware.add(vulnSoftware); -188 } -189 /** -190 * The CWE for the vulnerability. -191 */ -192 private String cwe; -193 -194 /** -195 * Get the value of cwe. -196 * -197 * @return the value of cwe -198 */ -199 public String getCwe() { -200 return cwe; -201 } -202 -203 /** -204 * Set the value of cwe. -205 * -206 * @param cwe new value of cwe -207 */ -208 public void setCwe(String cwe) { -209 this.cwe = cwe; -210 } -211 /** -212 * CVSS Score. -213 */ -214 private float cvssScore; -215 -216 /** -217 * Get the value of cvssScore. -218 * -219 * @return the value of cvssScore -220 */ -221 public float getCvssScore() { -222 return cvssScore; -223 } -224 -225 /** -226 * Set the value of cvssScore. -227 * -228 * @param cvssScore new value of cvssScore -229 */ -230 public void setCvssScore(float cvssScore) { -231 this.cvssScore = cvssScore; -232 } -233 /** -234 * CVSS Access Vector. -235 */ -236 private String cvssAccessVector; -237 -238 /** -239 * Get the value of cvssAccessVector. -240 * -241 * @return the value of cvssAccessVector -242 */ -243 public String getCvssAccessVector() { -244 return cvssAccessVector; -245 } -246 -247 /** -248 * Set the value of cvssAccessVector. -249 * -250 * @param cvssAccessVector new value of cvssAccessVector -251 */ -252 public void setCvssAccessVector(String cvssAccessVector) { -253 this.cvssAccessVector = cvssAccessVector; -254 } -255 /** -256 * CVSS Access Complexity. -257 */ -258 private String cvssAccessComplexity; -259 -260 /** -261 * Get the value of cvssAccessComplexity. -262 * -263 * @return the value of cvssAccessComplexity -264 */ -265 public String getCvssAccessComplexity() { -266 return cvssAccessComplexity; -267 } -268 -269 /** -270 * Set the value of cvssAccessComplexity. -271 * -272 * @param cvssAccessComplexity new value of cvssAccessComplexity -273 */ -274 public void setCvssAccessComplexity(String cvssAccessComplexity) { -275 this.cvssAccessComplexity = cvssAccessComplexity; -276 } -277 /** -278 * CVSS Authentication. -279 */ -280 private String cvssAuthentication; -281 -282 /** -283 * Get the value of cvssAuthentication. -284 * -285 * @return the value of cvssAuthentication -286 */ -287 public String getCvssAuthentication() { -288 return cvssAuthentication; -289 } -290 -291 /** -292 * Set the value of cvssAuthentication. -293 * -294 * @param cvssAuthentication new value of cvssAuthentication -295 */ -296 public void setCvssAuthentication(String cvssAuthentication) { -297 this.cvssAuthentication = cvssAuthentication; -298 } -299 /** -300 * CVSS Confidentiality Impact. -301 */ -302 private String cvssConfidentialityImpact; -303 -304 /** -305 * Get the value of cvssConfidentialityImpact. -306 * -307 * @return the value of cvssConfidentialityImpact -308 */ -309 public String getCvssConfidentialityImpact() { -310 return cvssConfidentialityImpact; -311 } -312 -313 /** -314 * Set the value of cvssConfidentialityImpact. -315 * -316 * @param cvssConfidentialityImpact new value of cvssConfidentialityImpact -317 */ -318 public void setCvssConfidentialityImpact(String cvssConfidentialityImpact) { -319 this.cvssConfidentialityImpact = cvssConfidentialityImpact; -320 } -321 /** -322 * CVSS Integrity Impact. -323 */ -324 private String cvssIntegrityImpact; -325 -326 /** -327 * Get the value of cvssIntegrityImpact. -328 * -329 * @return the value of cvssIntegrityImpact -330 */ -331 public String getCvssIntegrityImpact() { -332 return cvssIntegrityImpact; -333 } -334 -335 /** -336 * Set the value of cvssIntegrityImpact. -337 * -338 * @param cvssIntegrityImpact new value of cvssIntegrityImpact -339 */ -340 public void setCvssIntegrityImpact(String cvssIntegrityImpact) { -341 this.cvssIntegrityImpact = cvssIntegrityImpact; -342 } -343 /** -344 * CVSS Availability Impact. -345 */ -346 private String cvssAvailabilityImpact; -347 -348 /** -349 * Get the value of cvssAvailabilityImpact. -350 * -351 * @return the value of cvssAvailabilityImpact -352 */ -353 public String getCvssAvailabilityImpact() { -354 return cvssAvailabilityImpact; -355 } -356 -357 /** -358 * Set the value of cvssAvailabilityImpact. -359 * -360 * @param cvssAvailabilityImpact new value of cvssAvailabilityImpact -361 */ -362 public void setCvssAvailabilityImpact(String cvssAvailabilityImpact) { -363 this.cvssAvailabilityImpact = cvssAvailabilityImpact; -364 } -365 -366 @Override -367 public boolean equals(Object obj) { -368 if (obj == null) { -369 return false; -370 } -371 if (getClass() != obj.getClass()) { -372 return false; -373 } -374 final Vulnerability other = (Vulnerability) obj; -375 if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) { -376 return false; -377 } -378 return true; -379 } -380 -381 @Override -382 public int hashCode() { -383 int hash = 5; -384 hash = 41 * hash + (this.name != null ? this.name.hashCode() : 0); -385 return hash; -386 } -387 -388 @Override -389 public String toString() { -390 final StringBuilder sb = new StringBuilder("Vulnerability "); -391 sb.append(this.name); -392 sb.append("\nReferences:\n"); -393 for (Iterator i = this.references.iterator(); i.hasNext();) { -394 sb.append("=> "); -395 sb.append(i.next()); -396 sb.append("\n"); -397 } -398 sb.append("\nSoftware:\n"); -399 for (Iterator i = this.vulnerableSoftware.iterator(); i.hasNext();) { -400 sb.append("=> "); -401 sb.append(i.next()); -402 sb.append("\n"); -403 } -404 return sb.toString(); -405 } -406 /** -407 * Compares two vulnerabilities. -408 * -409 * @param v a vulnerability to be compared -410 * @return a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than -411 * the specified vulnerability -412 */ -413 @Override -414 public int compareTo(Vulnerability v) { -415 return v.getName().compareTo(this.getName()); -416 } -417 -418 /** -419 * The CPE id that caused this vulnerability to be flagged. -420 */ -421 private String matchedCPE; -422 /** -423 * Whether or not all previous versions were affected. -424 */ -425 private String matchedAllPreviousCPE; -426 -427 /** -428 * Sets the CPE that caused this vulnerability to be flagged. -429 * -430 * @param cpeId a CPE identifier -431 * @param previous a flag indicating whether or not all previous versions were affected (any non-null value is -432 * considered true) -433 */ -434 public void setMatchedCPE(String cpeId, String previous) { -435 matchedCPE = cpeId; -436 matchedAllPreviousCPE = previous; -437 } -438 -439 /** -440 * Get the value of matchedCPE. -441 * -442 * @return the value of matchedCPE -443 */ -444 public String getMatchedCPE() { -445 return matchedCPE; -446 } -447 -448 /** -449 * Get the value of matchedAllPreviousCPE. -450 * -451 * @return the value of matchedAllPreviousCPE -452 */ -453 public String getMatchedAllPreviousCPE() { -454 return matchedAllPreviousCPE; -455 } -456 -457 /** -458 * Determines whether or not matchedAllPreviousCPE has been set. -459 * -460 * @return true if matchedAllPreviousCPE is not null; otherwise false -461 */ -462 public boolean hasMatchedAllPreviousCPE() { -463 return matchedAllPreviousCPE != null; -464 } -465 } +24 +25 /** +26 * Contains the information about a vulnerability. +27 * +28 * @author Jeremy Long +29 */ +30 public class Vulnerability implements Serializable, Comparable<Vulnerability> { +31 +32 /** +33 * The serial version uid. +34 */ +35 private static final long serialVersionUID = 307319490326651052L; +36 +37 /** +38 * The name of the vulnerability. +39 */ +40 private String name; +41 +42 /** +43 * Get the value of name. +44 * +45 * @return the value of name +46 */ +47 public String getName() { +48 return name; +49 } +50 +51 /** +52 * Set the value of name. +53 * +54 * @param name new value of name +55 */ +56 public void setName(String name) { +57 this.name = name; +58 } +59 /** +60 * the description of the vulnerability. +61 */ +62 private String description; +63 +64 /** +65 * Get the value of description. +66 * +67 * @return the value of description +68 */ +69 public String getDescription() { +70 return description; +71 } +72 +73 /** +74 * Set the value of description. +75 * +76 * @param description new value of description +77 */ +78 public void setDescription(String description) { +79 this.description = description; +80 } +81 /** +82 * References for this vulnerability. +83 */ +84 private SortedSet<Reference> references = new TreeSet<Reference>(); +85 +86 /** +87 * Get the value of references. +88 * +89 * @return the value of references +90 */ +91 public Set<Reference> getReferences() { +92 return references; +93 } +94 +95 /** +96 * Set the value of references. +97 * +98 * @param references new value of references +99 */ +100 public void setReferences(SortedSet<Reference> references) { +101 this.references = references; +102 } +103 +104 /** +105 * Adds a reference to the references collection. +106 * +107 * @param ref a reference for the vulnerability +108 */ +109 public void addReference(Reference ref) { +110 this.references.add(ref); +111 } +112 +113 /** +114 * Adds a reference. +115 * +116 * @param referenceSource the source of the reference +117 * @param referenceName the referenceName of the reference +118 * @param referenceUrl the url of the reference +119 */ +120 public void addReference(String referenceSource, String referenceName, String referenceUrl) { +121 final Reference ref = new Reference(); +122 ref.setSource(referenceSource); +123 ref.setName(referenceName); +124 ref.setUrl(referenceUrl); +125 this.references.add(ref); +126 } +127 /** +128 * A set of vulnerable software. +129 */ +130 private SortedSet<VulnerableSoftware> vulnerableSoftware = new TreeSet<VulnerableSoftware>(); +131 +132 /** +133 * Get the value of vulnerableSoftware. +134 * +135 * @return the value of vulnerableSoftware +136 */ +137 public Set<VulnerableSoftware> getVulnerableSoftware() { +138 return vulnerableSoftware; +139 } +140 +141 /** +142 * Set the value of vulnerableSoftware. +143 * +144 * @param vulnerableSoftware new value of vulnerableSoftware +145 */ +146 public void setVulnerableSoftware(SortedSet<VulnerableSoftware> vulnerableSoftware) { +147 this.vulnerableSoftware = vulnerableSoftware; +148 } +149 +150 /** +151 * Adds an entry for vulnerable software. +152 * +153 * @param cpe string representation of a CPE entry +154 * @return if the add succeeded +155 */ +156 public boolean addVulnerableSoftware(String cpe) { +157 return addVulnerableSoftware(cpe, null); +158 } +159 +160 /** +161 * Adds an entry for vulnerable software. +162 * +163 * @param cpe string representation of a cpe +164 * @param previousVersion the previous version (previousVersion - cpe would be considered vulnerable) +165 * @return if the add succeeded +166 */ +167 public boolean addVulnerableSoftware(String cpe, String previousVersion) { +168 final VulnerableSoftware vs = new VulnerableSoftware(); +169 vs.setCpe(cpe); +170 if (previousVersion != null) { +171 vs.setPreviousVersion(previousVersion); +172 } +173 return updateVulnerableSoftware(vs); +174 } +175 +176 /** +177 * Adds or updates a vulnerable software entry. +178 * +179 * @param vulnSoftware the vulnerable software +180 * @return if the update succeeded +181 */ +182 public boolean updateVulnerableSoftware(VulnerableSoftware vulnSoftware) { +183 if (vulnerableSoftware.contains(vulnSoftware)) { +184 vulnerableSoftware.remove(vulnSoftware); +185 } +186 return vulnerableSoftware.add(vulnSoftware); +187 } +188 /** +189 * The CWE for the vulnerability. +190 */ +191 private String cwe; +192 +193 /** +194 * Get the value of cwe. +195 * +196 * @return the value of cwe +197 */ +198 public String getCwe() { +199 return cwe; +200 } +201 +202 /** +203 * Set the value of cwe. +204 * +205 * @param cwe new value of cwe +206 */ +207 public void setCwe(String cwe) { +208 this.cwe = cwe; +209 } +210 /** +211 * CVSS Score. +212 */ +213 private float cvssScore; +214 +215 /** +216 * Get the value of cvssScore. +217 * +218 * @return the value of cvssScore +219 */ +220 public float getCvssScore() { +221 return cvssScore; +222 } +223 +224 /** +225 * Set the value of cvssScore. +226 * +227 * @param cvssScore new value of cvssScore +228 */ +229 public void setCvssScore(float cvssScore) { +230 this.cvssScore = cvssScore; +231 } +232 /** +233 * CVSS Access Vector. +234 */ +235 private String cvssAccessVector; +236 +237 /** +238 * Get the value of cvssAccessVector. +239 * +240 * @return the value of cvssAccessVector +241 */ +242 public String getCvssAccessVector() { +243 return cvssAccessVector; +244 } +245 +246 /** +247 * Set the value of cvssAccessVector. +248 * +249 * @param cvssAccessVector new value of cvssAccessVector +250 */ +251 public void setCvssAccessVector(String cvssAccessVector) { +252 this.cvssAccessVector = cvssAccessVector; +253 } +254 /** +255 * CVSS Access Complexity. +256 */ +257 private String cvssAccessComplexity; +258 +259 /** +260 * Get the value of cvssAccessComplexity. +261 * +262 * @return the value of cvssAccessComplexity +263 */ +264 public String getCvssAccessComplexity() { +265 return cvssAccessComplexity; +266 } +267 +268 /** +269 * Set the value of cvssAccessComplexity. +270 * +271 * @param cvssAccessComplexity new value of cvssAccessComplexity +272 */ +273 public void setCvssAccessComplexity(String cvssAccessComplexity) { +274 this.cvssAccessComplexity = cvssAccessComplexity; +275 } +276 /** +277 * CVSS Authentication. +278 */ +279 private String cvssAuthentication; +280 +281 /** +282 * Get the value of cvssAuthentication. +283 * +284 * @return the value of cvssAuthentication +285 */ +286 public String getCvssAuthentication() { +287 return cvssAuthentication; +288 } +289 +290 /** +291 * Set the value of cvssAuthentication. +292 * +293 * @param cvssAuthentication new value of cvssAuthentication +294 */ +295 public void setCvssAuthentication(String cvssAuthentication) { +296 this.cvssAuthentication = cvssAuthentication; +297 } +298 /** +299 * CVSS Confidentiality Impact. +300 */ +301 private String cvssConfidentialityImpact; +302 +303 /** +304 * Get the value of cvssConfidentialityImpact. +305 * +306 * @return the value of cvssConfidentialityImpact +307 */ +308 public String getCvssConfidentialityImpact() { +309 return cvssConfidentialityImpact; +310 } +311 +312 /** +313 * Set the value of cvssConfidentialityImpact. +314 * +315 * @param cvssConfidentialityImpact new value of cvssConfidentialityImpact +316 */ +317 public void setCvssConfidentialityImpact(String cvssConfidentialityImpact) { +318 this.cvssConfidentialityImpact = cvssConfidentialityImpact; +319 } +320 /** +321 * CVSS Integrity Impact. +322 */ +323 private String cvssIntegrityImpact; +324 +325 /** +326 * Get the value of cvssIntegrityImpact. +327 * +328 * @return the value of cvssIntegrityImpact +329 */ +330 public String getCvssIntegrityImpact() { +331 return cvssIntegrityImpact; +332 } +333 +334 /** +335 * Set the value of cvssIntegrityImpact. +336 * +337 * @param cvssIntegrityImpact new value of cvssIntegrityImpact +338 */ +339 public void setCvssIntegrityImpact(String cvssIntegrityImpact) { +340 this.cvssIntegrityImpact = cvssIntegrityImpact; +341 } +342 /** +343 * CVSS Availability Impact. +344 */ +345 private String cvssAvailabilityImpact; +346 +347 /** +348 * Get the value of cvssAvailabilityImpact. +349 * +350 * @return the value of cvssAvailabilityImpact +351 */ +352 public String getCvssAvailabilityImpact() { +353 return cvssAvailabilityImpact; +354 } +355 +356 /** +357 * Set the value of cvssAvailabilityImpact. +358 * +359 * @param cvssAvailabilityImpact new value of cvssAvailabilityImpact +360 */ +361 public void setCvssAvailabilityImpact(String cvssAvailabilityImpact) { +362 this.cvssAvailabilityImpact = cvssAvailabilityImpact; +363 } +364 +365 @Override +366 public boolean equals(Object obj) { +367 if (obj == null) { +368 return false; +369 } +370 if (getClass() != obj.getClass()) { +371 return false; +372 } +373 final Vulnerability other = (Vulnerability) obj; +374 if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) { +375 return false; +376 } +377 return true; +378 } +379 +380 @Override +381 public int hashCode() { +382 int hash = 5; +383 hash = 41 * hash + (this.name != null ? this.name.hashCode() : 0); +384 return hash; +385 } +386 +387 @Override +388 public String toString() { +389 final StringBuilder sb = new StringBuilder("Vulnerability "); +390 sb.append(this.name); +391 sb.append("\nReferences:\n"); +392 for (Reference reference : this.references) { +393 sb.append("=> "); +394 sb.append(reference); +395 sb.append("\n"); +396 } +397 sb.append("\nSoftware:\n"); +398 for (VulnerableSoftware software : this.vulnerableSoftware) { +399 sb.append("=> "); +400 sb.append(software); +401 sb.append("\n"); +402 } +403 return sb.toString(); +404 } +405 /** +406 * Compares two vulnerabilities. +407 * +408 * @param v a vulnerability to be compared +409 * @return a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than +410 * the specified vulnerability +411 */ +412 @Override +413 public int compareTo(Vulnerability v) { +414 return v.getName().compareTo(this.getName()); +415 } +416 +417 /** +418 * The CPE id that caused this vulnerability to be flagged. +419 */ +420 private String matchedCPE; +421 /** +422 * Whether or not all previous versions were affected. +423 */ +424 private String matchedAllPreviousCPE; +425 +426 /** +427 * Sets the CPE that caused this vulnerability to be flagged. +428 * +429 * @param cpeId a CPE identifier +430 * @param previous a flag indicating whether or not all previous versions were affected (any non-null value is +431 * considered true) +432 */ +433 public void setMatchedCPE(String cpeId, String previous) { +434 matchedCPE = cpeId; +435 matchedAllPreviousCPE = previous; +436 } +437 +438 /** +439 * Get the value of matchedCPE. +440 * +441 * @return the value of matchedCPE +442 */ +443 public String getMatchedCPE() { +444 return matchedCPE; +445 } +446 +447 /** +448 * Get the value of matchedAllPreviousCPE. +449 * +450 * @return the value of matchedAllPreviousCPE +451 */ +452 public String getMatchedAllPreviousCPE() { +453 return matchedAllPreviousCPE; +454 } +455 +456 /** +457 * Determines whether or not matchedAllPreviousCPE has been set. +458 * +459 * @return true if matchedAllPreviousCPE is not null; otherwise false +460 */ +461 public boolean hasMatchedAllPreviousCPE() { +462 return matchedAllPreviousCPE != null; +463 } +464 }
      diff --git a/xref/org/owasp/dependencycheck/dependency/package-frame.html b/xref/org/owasp/dependencycheck/dependency/package-frame.html index 44d09bf00..59d14bf44 100644 --- a/xref/org/owasp/dependencycheck/dependency/package-frame.html +++ b/xref/org/owasp/dependencycheck/dependency/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.dependency + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.dependency diff --git a/xref/org/owasp/dependencycheck/dependency/package-summary.html b/xref/org/owasp/dependencycheck/dependency/package-summary.html index 170bd9d72..76c196fce 100644 --- a/xref/org/owasp/dependencycheck/dependency/package-summary.html +++ b/xref/org/owasp/dependencycheck/dependency/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.dependency + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.dependency diff --git a/xref/org/owasp/dependencycheck/exception/ExceptionCollection.html b/xref/org/owasp/dependencycheck/exception/ExceptionCollection.html new file mode 100644 index 000000000..cdb8e053d --- /dev/null +++ b/xref/org/owasp/dependencycheck/exception/ExceptionCollection.html @@ -0,0 +1,227 @@ + + + +ExceptionCollection xref + + + +
      +1   /*
      +2    * This file is part of dependency-check-core.
      +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) 2016 Jeremy Long. All Rights Reserved.
      +17   */
      +18  package org.owasp.dependencycheck.exception;
      +19  
      +20  import java.io.PrintStream;
      +21  import java.io.PrintWriter;
      +22  import java.util.ArrayList;
      +23  import java.util.List;
      +24  
      +25  /**
      +26   * A collection of several exceptions.
      +27   *
      +28   * @author Jeremy Lomg
      +29   */
      +30  public class ExceptionCollection extends Exception {
      +31  
      +32      /**
      +33       * Instantiates a new exception collection.
      +34       *
      +35       * @param exceptions a list of exceptions
      +36       */
      +37      public ExceptionCollection(List<Throwable> exceptions) {
      +38          super();
      +39          this.exceptions = exceptions;
      +40      }
      +41  
      +42      /**
      +43       * Instantiates a new exception collection.
      +44       *
      +45       * @param msg the exception message
      +46       * @param exceptions a list of exceptions
      +47       */
      +48      public ExceptionCollection(String msg, List<Throwable> exceptions) {
      +49          super(msg);
      +50          this.exceptions = exceptions;
      +51      }
      +52  
      +53      /**
      +54       * Instantiates a new exception collection.
      +55       *
      +56       * @param exceptions a list of exceptions
      +57       * @param fatal indicates if the exception that occurred is fatal - meaning
      +58       * that no analysis was performed.
      +59       */
      +60      public ExceptionCollection(List<Throwable> exceptions, boolean fatal) {
      +61          super();
      +62          this.exceptions = exceptions;
      +63          this.fatal = fatal;
      +64      }
      +65  
      +66      /**
      +67       * Instantiates a new exception collection.
      +68       *
      +69       * @param msg the exception message
      +70       * @param exceptions a list of exceptions
      +71       * @param fatal indicates if the exception that occurred is fatal - meaning
      +72       * that no analysis was performed.
      +73       */
      +74      public ExceptionCollection(String msg, List<Throwable> exceptions, boolean fatal) {
      +75          super(msg);
      +76          this.exceptions = exceptions;
      +77          this.fatal = fatal;
      +78      }
      +79  
      +80      /**
      +81       * Instantiates a new exception collection.
      +82       *
      +83       * @param exceptions a list of exceptions
      +84       * @param fatal indicates if the exception that occurred is fatal - meaning
      +85       * that no analysis was performed.
      +86       */
      +87      public ExceptionCollection(Throwable exceptions, boolean fatal) {
      +88          super();
      +89          this.exceptions = new ArrayList<Throwable>();
      +90          this.exceptions.add(exceptions);
      +91          this.fatal = fatal;
      +92      }
      +93          /**
      +94       * Instantiates a new exception collection.
      +95       *
      +96       * @param msg the exception message
      +97       * @param exception a list of exceptions
      +98       */
      +99      public ExceptionCollection(String msg, Throwable exception) {
      +100         super(msg);
      +101         this.exceptions = new ArrayList<Throwable>();
      +102         this.exceptions.add(exception);
      +103         this.fatal = false;
      +104     }
      +105 
      +106     /**
      +107      * Instantiates a new exception collection.
      +108      */
      +109     public ExceptionCollection() {
      +110         super();
      +111         this.exceptions = new ArrayList<Throwable>();
      +112     }
      +113     /**
      +114      * The serial version uid.
      +115      */
      +116     private static final long serialVersionUID = 1L;
      +117 
      +118     /**
      +119      * A collection of exceptions.
      +120      */
      +121     private List<Throwable> exceptions;
      +122 
      +123     /**
      +124      * Get the value of exceptions.
      +125      *
      +126      * @return the value of exceptions
      +127      */
      +128     public List<Throwable> getExceptions() {
      +129         return exceptions;
      +130     }
      +131 
      +132     /**
      +133      * Adds an exception to the collection.
      +134      *
      +135      * @param ex the exception to add
      +136      */
      +137     public void addException(Throwable ex) {
      +138         this.exceptions.add(ex);
      +139     }
      +140 
      +141     /**
      +142      * Adds an exception to the collection.
      +143      *
      +144      * @param ex the exception to add
      +145      * @param fatal flag indicating if this is a fatal error
      +146      */
      +147     public void addException(Throwable ex, boolean fatal) {
      +148         addException(ex);
      +149         this.fatal = fatal;
      +150     }
      +151 
      +152     /**
      +153      * Flag indicating if a fatal exception occurred that would prevent the
      +154      * attempt at completing the analysis even if exceptions occurred.
      +155      */
      +156     private boolean fatal = false;
      +157 
      +158     /**
      +159      * Get the value of fatal.
      +160      *
      +161      * @return the value of fatal
      +162      */
      +163     public boolean isFatal() {
      +164         return fatal;
      +165     }
      +166 
      +167     /**
      +168      * Set the value of fatal.
      +169      *
      +170      * @param fatal new value of fatal
      +171      */
      +172     public void setFatal(boolean fatal) {
      +173         this.fatal = fatal;
      +174     }
      +175 
      +176     /**
      +177      * Prints the stack trace.
      +178      *
      +179      * @param s the writer to print to
      +180      */
      +181     @Override
      +182     public void printStackTrace(PrintWriter s) {
      +183         s.println("Multiple Exceptions Occured");
      +184         super.printStackTrace(s);
      +185         for (Throwable t : this.exceptions) {
      +186             s.println("Next Exception:");
      +187             t.printStackTrace(s);
      +188         }
      +189     }
      +190 
      +191     /**
      +192      * Prints the stack trace.
      +193      *
      +194      * @param s the stream to write the stack trace to
      +195      */
      +196     @Override
      +197     public void printStackTrace(PrintStream s) {
      +198         s.println("Multiple Exceptions Occured");
      +199         super.printStackTrace(s);
      +200         for (Throwable t : this.exceptions) {
      +201             s.println("Next Exception:");
      +202             t.printStackTrace(s);
      +203         }
      +204     }
      +205 
      +206     /**
      +207      * Prints the stack trace to standard error.
      +208      */
      +209     @Override
      +210     public void printStackTrace() {
      +211         this.printStackTrace(System.err);
      +212     }
      +213 
      +214 }
      +
      +
      + + + diff --git a/xref/org/owasp/dependencycheck/exception/InitializationException.html b/xref/org/owasp/dependencycheck/exception/InitializationException.html new file mode 100644 index 000000000..e607c467b --- /dev/null +++ b/xref/org/owasp/dependencycheck/exception/InitializationException.html @@ -0,0 +1,79 @@ + + + +InitializationException xref + + + +
      +1   /*
      +2    * This file is part of dependency-check-core.
      +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) 2016 Jeremy Long. All Rights Reserved.
      +17   */
      +18  package org.owasp.dependencycheck.exception;
      +19  
      +20  /**
      +21   * An exception used when initializing analyzers.
      +22   *
      +23   * @author Jeremy Long
      +24   */
      +25  public class InitializationException extends Exception {
      +26  
      +27      /**
      +28       * The serial version uid.
      +29       */
      +30      private static final long serialVersionUID = 1L;
      +31  
      +32      /**
      +33       * Creates a new InitializationException.
      +34       */
      +35      public InitializationException() {
      +36          super();
      +37      }
      +38  
      +39      /**
      +40       * Creates a new InitializationException.
      +41       *
      +42       * @param msg a message for the exception.
      +43       */
      +44      public InitializationException(String msg) {
      +45          super(msg);
      +46      }
      +47  
      +48      /**
      +49       * Creates a new InitializationException.
      +50       *
      +51       * @param ex the cause of the exception.
      +52       */
      +53      public InitializationException(Throwable ex) {
      +54          super(ex);
      +55      }
      +56  
      +57      /**
      +58       * Creates a new InitializationException.
      +59       *
      +60       * @param msg a message for the exception.
      +61       * @param ex the cause of the exception.
      +62       */
      +63      public InitializationException(String msg, Throwable ex) {
      +64          super(msg, ex);
      +65      }
      +66  }
      +
      +
      + + + diff --git a/xref/org/owasp/dependencycheck/exception/ReportException.html b/xref/org/owasp/dependencycheck/exception/ReportException.html new file mode 100644 index 000000000..54f50ed44 --- /dev/null +++ b/xref/org/owasp/dependencycheck/exception/ReportException.html @@ -0,0 +1,79 @@ + + + +ReportException xref + + + +
      +1   /*
      +2    * This file is part of dependency-check-core.
      +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) 2016 Jeremy Long. All Rights Reserved.
      +17   */
      +18  package org.owasp.dependencycheck.exception;
      +19  
      +20  /**
      +21   * An exception used when generating reports.
      +22   *
      +23   * @author Jeremy Long
      +24   */
      +25  public class ReportException extends Exception {
      +26  
      +27      /**
      +28       * The serial version uid.
      +29       */
      +30      private static final long serialVersionUID = 1L;
      +31  
      +32      /**
      +33       * Creates a new ReportException.
      +34       */
      +35      public ReportException() {
      +36          super();
      +37      }
      +38  
      +39      /**
      +40       * Creates a new ReportException.
      +41       *
      +42       * @param msg a message for the exception.
      +43       */
      +44      public ReportException(String msg) {
      +45          super(msg);
      +46      }
      +47  
      +48      /**
      +49       * Creates a new ReportException.
      +50       *
      +51       * @param ex the cause of the exception.
      +52       */
      +53      public ReportException(Throwable ex) {
      +54          super(ex);
      +55      }
      +56  
      +57      /**
      +58       * Creates a new ReportException.
      +59       *
      +60       * @param msg a message for the exception.
      +61       * @param ex the cause of the exception.
      +62       */
      +63      public ReportException(String msg, Throwable ex) {
      +64          super(msg, ex);
      +65      }
      +66  }
      +
      +
      + + + diff --git a/xref/org/owasp/dependencycheck/exception/package-frame.html b/xref/org/owasp/dependencycheck/exception/package-frame.html index 8bea63e53..350806464 100644 --- a/xref/org/owasp/dependencycheck/exception/package-frame.html +++ b/xref/org/owasp/dependencycheck/exception/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.exception + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.exception @@ -16,7 +16,16 @@
      • + ExceptionCollection +
      • +
      • + InitializationException +
      • +
      • NoDataException +
      • +
      • + ReportException
      • ScanAgentException diff --git a/xref/org/owasp/dependencycheck/exception/package-summary.html b/xref/org/owasp/dependencycheck/exception/package-summary.html index de92a70da..e62f31535 100644 --- a/xref/org/owasp/dependencycheck/exception/package-summary.html +++ b/xref/org/owasp/dependencycheck/exception/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.exception + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.exception @@ -36,9 +36,24 @@ + + ExceptionCollection + + + + + InitializationException + + + NoDataException + + + + ReportException + diff --git a/xref/org/owasp/dependencycheck/maven/AggregateMojo.html b/xref/org/owasp/dependencycheck/maven/AggregateMojo.html index bfc775f08..5291d3b9c 100644 --- a/xref/org/owasp/dependencycheck/maven/AggregateMojo.html +++ b/xref/org/owasp/dependencycheck/maven/AggregateMojo.html @@ -44,289 +44,349 @@ 36 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; 37 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; 38 import org.owasp.dependencycheck.dependency.Dependency; -39 import org.owasp.dependencycheck.utils.Settings; -40 -41 /** -42 * Maven Plugin that checks project dependencies and the dependencies of all child modules to see if they have any known published -43 * vulnerabilities. -44 * -45 * @author Jeremy Long -46 */ -47 @Mojo( -48 name = "aggregate", -49 defaultPhase = LifecyclePhase.VERIFY, -50 /*aggregator = true,*/ -51 threadSafe = false, -52 requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME, -53 requiresOnline = true -54 ) -55 public class AggregateMojo extends BaseDependencyCheckMojo { -56 -57 /** -58 * Executes the aggregate dependency-check goal. This runs dependency-check and generates the subsequent reports. -59 * -60 * @throws MojoExecutionException thrown if there is ane exception running the mojo -61 * @throws MojoFailureException thrown if dependency-check is configured to fail the build -62 */ -63 @Override -64 public void runCheck() throws MojoExecutionException, MojoFailureException { -65 final Engine engine = generateDataFile(); -66 -67 //if (getProject() == getReactorProjects().get(getReactorProjects().size() - 1)) { -68 if (getProject() == getLastProject()) { -69 -70 //ensure that the .ser file was created for each. -71 for (MavenProject current : getReactorProjects()) { -72 final File dataFile = getDataFile(current); -73 if (dataFile == null && !skipProject(current)) { //dc was never run on this project. write the ser to the target. -74 getLog().error(String.format("Module '%s' did not execute dependency-check; an attempt will be made to perform " -75 + "the check but dependencies may be missed resulting in false negatives.", current.getName())); -76 generateDataFile(engine, current); -77 } -78 } +39 import org.owasp.dependencycheck.exception.ExceptionCollection; +40 import org.owasp.dependencycheck.exception.ReportException; +41 import org.owasp.dependencycheck.utils.Settings; +42 +43 /** +44 * Maven Plugin that checks project dependencies and the dependencies of all +45 * child modules to see if they have any known published vulnerabilities. +46 * +47 * @author Jeremy Long +48 */ +49 @Mojo( +50 name = "aggregate", +51 defaultPhase = LifecyclePhase.VERIFY, +52 /*aggregator = true,*/ +53 threadSafe = false, +54 requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME, +55 requiresOnline = true +56 ) +57 public class AggregateMojo extends BaseDependencyCheckMojo { +58 +59 /** +60 * The key to store aggregate exception in the root Maven execution context. +61 */ +62 private static final String AGGREGATE_EXCEPTIONS = "AggregateExceptions"; +63 +64 /** +65 * Executes the aggregate dependency-check goal. This runs dependency-check +66 * and generates the subsequent reports. +67 * +68 * @throws MojoExecutionException thrown if there is ane exception running +69 * the mojo +70 * @throws MojoFailureException thrown if dependency-check is configured to +71 * fail the build +72 */ +73 @Override +74 public void runCheck() throws MojoExecutionException, MojoFailureException { +75 final MavenEngine engine = generateDataFile(); +76 if (engine == null) { +77 return; +78 } 79 -80 for (MavenProject current : getReactorProjects()) { -81 List<Dependency> dependencies = readDataFile(current); -82 if (dependencies == null) { -83 dependencies = new ArrayList<Dependency>(); -84 } -85 final Set<MavenProject> childProjects = getDescendants(current); -86 for (MavenProject reportOn : childProjects) { -87 final List<Dependency> childDeps = readDataFile(reportOn); -88 if (childDeps != null && !childDeps.isEmpty()) { -89 if (getLog().isDebugEnabled()) { -90 getLog().debug(String.format("Adding %d dependencies from %s", childDeps.size(), reportOn.getName())); -91 } -92 dependencies.addAll(childDeps); -93 } else { -94 if (getLog().isDebugEnabled()) { -95 getLog().debug(String.format("No dependencies read for %s", reportOn.getName())); -96 } -97 } -98 } -99 engine.getDependencies().clear(); -100 engine.getDependencies().addAll(dependencies); -101 final DependencyBundlingAnalyzer bundler = new DependencyBundlingAnalyzer(); -102 try { -103 if (getLog().isDebugEnabled()) { -104 getLog().debug(String.format("Dependency count pre-bundler: %s", engine.getDependencies().size())); +80 if (getProject() == getLastProject()) { +81 //ensure that the .ser file was created for each. +82 for (MavenProject current : getReactorProjects()) { +83 final File dataFile = getDataFile(current); +84 if (dataFile == null && !skipProject(current)) { //dc was never run on this project. write the ser to the target. +85 getLog().error(String.format("Module '%s' did not execute dependency-check; an attempt will be made to perform " +86 + "the check but dependencies may be missed resulting in false negatives.", current.getName())); +87 generateDataFile(engine, current); +88 } +89 } +90 for (MavenProject current : getReactorProjects()) { +91 List<Dependency> dependencies = readDataFile(current); +92 if (dependencies == null) { +93 dependencies = new ArrayList<Dependency>(); +94 } +95 final Set<MavenProject> childProjects = getDescendants(current); +96 for (MavenProject reportOn : childProjects) { +97 final List<Dependency> childDeps = readDataFile(reportOn); +98 if (childDeps != null && !childDeps.isEmpty()) { +99 if (getLog().isDebugEnabled()) { +100 getLog().debug(String.format("Adding %d dependencies from %s", childDeps.size(), reportOn.getName())); +101 } +102 dependencies.addAll(childDeps); +103 } else if (getLog().isDebugEnabled()) { +104 getLog().debug(String.format("No dependencies read for %s", reportOn.getName())); 105 } -106 bundler.analyze(null, engine); -107 if (getLog().isDebugEnabled()) { -108 getLog().debug(String.format("Dependency count post-bundler: %s", engine.getDependencies().size())); -109 } -110 } catch (AnalysisException ex) { -111 getLog().warn("An error occurred grouping the dependencies; duplicate entries may exist in the report", ex); -112 getLog().debug("Bundling Exception", ex); -113 } -114 -115 File outputDir = getCorrectOutputDirectory(current); -116 if (outputDir == null) { -117 //in some regards we shouldn't be writting this, but we are anyway. -118 //we shouldn't write this because nothing is configured to generate this report. -119 outputDir = new File(current.getBuild().getDirectory()); -120 } -121 writeReports(engine, current, outputDir); -122 } -123 } -124 engine.cleanup(); -125 Settings.cleanup(); -126 } -127 -128 /** -129 * Gets the last project in the reactor - taking into account skipped projects. -130 * -131 * @return the last project in the reactor -132 */ -133 private MavenProject getLastProject() { -134 for (int x = getReactorProjects().size() - 1; x >= 0; x--) { -135 final MavenProject p = getReactorProjects().get(x); -136 if (!skipProject(p)) { -137 return p; -138 } -139 -140 } -141 return null; -142 } -143 -144 /** -145 * Tests if the project is being skipped in the Maven site report. -146 * -147 * @param project a project in the reactor -148 * @return true if the project is skipped; otherwise false -149 */ -150 private boolean skipProject(MavenProject project) { -151 final String skip = (String) project.getProperties().get("maven.site.skip"); -152 return "true".equalsIgnoreCase(skip) && isGeneratingSite(); -153 } -154 -155 /** -156 * Returns a set containing all the descendant projects of the given project. -157 * -158 * @param project the project for which all descendants will be returned -159 * @return the set of descendant projects -160 */ -161 protected Set<MavenProject> getDescendants(MavenProject project) { -162 if (project == null) { -163 return Collections.emptySet(); -164 } -165 final Set<MavenProject> descendants = new HashSet<MavenProject>(); -166 int size = 0; -167 if (getLog().isDebugEnabled()) { -168 getLog().debug(String.format("Collecting descendants of %s", project.getName())); -169 } -170 for (String m : project.getModules()) { -171 for (MavenProject mod : getReactorProjects()) { -172 try { -173 File mpp = new File(project.getBasedir(), m); -174 mpp = mpp.getCanonicalFile(); -175 if (mpp.compareTo(mod.getBasedir()) == 0 && descendants.add(mod) -176 && getLog().isDebugEnabled()) { -177 getLog().debug(String.format("Decendent module %s added", mod.getName())); -178 -179 } -180 } catch (IOException ex) { -181 if (getLog().isDebugEnabled()) { -182 getLog().debug("Unable to determine module path", ex); -183 } -184 } -185 } -186 } -187 do { -188 size = descendants.size(); -189 for (MavenProject p : getReactorProjects()) { -190 if (project.equals(p.getParent()) || descendants.contains(p.getParent())) { -191 if (descendants.add(p) && getLog().isDebugEnabled()) { -192 getLog().debug(String.format("Decendent %s added", p.getName())); -193 -194 } -195 for (MavenProject modTest : getReactorProjects()) { -196 if (p.getModules() != null && p.getModules().contains(modTest.getName()) -197 && descendants.add(modTest) -198 && getLog().isDebugEnabled()) { -199 getLog().debug(String.format("Decendent %s added", modTest.getName())); -200 } -201 } -202 } -203 final Set<MavenProject> addedDescendants = new HashSet<MavenProject>(); -204 for (MavenProject dec : descendants) { -205 for (String mod : dec.getModules()) { -206 try { -207 File mpp = new File(dec.getBasedir(), mod); -208 mpp = mpp.getCanonicalFile(); -209 if (mpp.compareTo(p.getBasedir()) == 0) { -210 addedDescendants.add(p); -211 } -212 } catch (IOException ex) { -213 if (getLog().isDebugEnabled()) { -214 getLog().debug("Unable to determine module path", ex); -215 } -216 } +106 } +107 engine.getDependencies().clear(); +108 engine.getDependencies().addAll(dependencies); +109 final DependencyBundlingAnalyzer bundler = new DependencyBundlingAnalyzer(); +110 try { +111 if (getLog().isDebugEnabled()) { +112 getLog().debug(String.format("Dependency count pre-bundler: %s", engine.getDependencies().size())); +113 } +114 bundler.analyze(null, engine); +115 if (getLog().isDebugEnabled()) { +116 getLog().debug(String.format("Dependency count post-bundler: %s", engine.getDependencies().size())); +117 } +118 } catch (AnalysisException ex) { +119 getLog().warn("An error occurred grouping the dependencies; duplicate entries may exist in the report", ex); +120 getLog().debug("Bundling Exception", ex); +121 } +122 +123 File outputDir = getCorrectOutputDirectory(current); +124 if (outputDir == null) { +125 //in some regards we shouldn't be writting this, but we are anyway. +126 //we shouldn't write this because nothing is configured to generate this report. +127 outputDir = new File(current.getBuild().getDirectory()); +128 } +129 try { +130 writeReports(engine, current, outputDir); +131 } catch (ReportException ex) { +132 ExceptionCollection exCol = (ExceptionCollection) engine.getExecutionRoot().getContextValue(AGGREGATE_EXCEPTIONS); +133 if (exCol == null) { +134 exCol = new ExceptionCollection("Error writing aggregate report", ex); +135 } else { +136 exCol.addException(ex); +137 } +138 if (this.isFailOnError()) { +139 throw new MojoExecutionException("One or more exceptions occured during dependency-check analysis", exCol); +140 } else { +141 getLog().debug("One or more exceptions occured during dependency-check analysis", exCol); +142 } +143 } +144 } +145 } +146 engine.cleanup(); +147 Settings.cleanup(); +148 } +149 +150 /** +151 * Gets the last project in the reactor - taking into account skipped +152 * projects. +153 * +154 * @return the last project in the reactor +155 */ +156 private MavenProject getLastProject() { +157 for (int x = getReactorProjects().size() - 1; x >= 0; x--) { +158 final MavenProject p = getReactorProjects().get(x); +159 if (!skipProject(p)) { +160 return p; +161 } +162 } +163 return null; +164 } +165 +166 /** +167 * Tests if the project is being skipped in the Maven site report. +168 * +169 * @param project a project in the reactor +170 * @return true if the project is skipped; otherwise false +171 */ +172 private boolean skipProject(MavenProject project) { +173 final String skip = (String) project.getProperties().get("maven.site.skip"); +174 return "true".equalsIgnoreCase(skip) && isGeneratingSite(); +175 } +176 +177 /** +178 * Returns a set containing all the descendant projects of the given +179 * project. +180 * +181 * @param project the project for which all descendants will be returned +182 * @return the set of descendant projects +183 */ +184 protected Set<MavenProject> getDescendants(MavenProject project) { +185 if (project == null) { +186 return Collections.emptySet(); +187 } +188 final Set<MavenProject> descendants = new HashSet<MavenProject>(); +189 int size = 0; +190 if (getLog().isDebugEnabled()) { +191 getLog().debug(String.format("Collecting descendants of %s", project.getName())); +192 } +193 for (String m : project.getModules()) { +194 for (MavenProject mod : getReactorProjects()) { +195 try { +196 File mpp = new File(project.getBasedir(), m); +197 mpp = mpp.getCanonicalFile(); +198 if (mpp.compareTo(mod.getBasedir()) == 0 && descendants.add(mod) +199 && getLog().isDebugEnabled()) { +200 getLog().debug(String.format("Decendent module %s added", mod.getName())); +201 +202 } +203 } catch (IOException ex) { +204 if (getLog().isDebugEnabled()) { +205 getLog().debug("Unable to determine module path", ex); +206 } +207 } +208 } +209 } +210 do { +211 size = descendants.size(); +212 for (MavenProject p : getReactorProjects()) { +213 if (project.equals(p.getParent()) || descendants.contains(p.getParent())) { +214 if (descendants.add(p) && getLog().isDebugEnabled()) { +215 getLog().debug(String.format("Decendent %s added", p.getName())); +216 217 } -218 } -219 for (MavenProject addedDescendant : addedDescendants) { -220 if (descendants.add(addedDescendant) && getLog().isDebugEnabled()) { -221 getLog().debug(String.format("Decendent module %s added", addedDescendant.getName())); -222 } -223 } -224 } -225 } while (size != 0 && size != descendants.size()); -226 if (getLog().isDebugEnabled()) { -227 getLog().debug(String.format("%s has %d children", project, descendants.size())); -228 } -229 return descendants; -230 } -231 -232 /** -233 * Test if the project has pom packaging -234 * -235 * @param mavenProject Project to test -236 * @return <code>true</code> if it has a pom packaging; otherwise <code>false</code> -237 */ -238 protected boolean isMultiModule(MavenProject mavenProject) { -239 return "pom".equals(mavenProject.getPackaging()); -240 } -241 -242 /** -243 * Initilizes the engine, runs a scan, and writes the serialized dependencies to disk. -244 * -245 * @return the Engine used to execute dependency-check -246 * @throws MojoExecutionException thrown if there is an exception running the mojo -247 * @throws MojoFailureException thrown if dependency-check is configured to fail the build if severe CVEs are identified. -248 */ -249 protected Engine generateDataFile() throws MojoExecutionException, MojoFailureException { -250 final Engine engine; -251 try { -252 engine = initializeEngine(); -253 } catch (DatabaseException ex) { -254 if (getLog().isDebugEnabled()) { -255 getLog().debug("Database connection error", ex); -256 } -257 throw new MojoExecutionException("An exception occured connecting to the local database. Please see the log file for more details.", ex); -258 } -259 return generateDataFile(engine, getProject()); -260 } -261 -262 /** -263 * Runs dependency-check's Engine and writes the serialized dependencies to disk. -264 * -265 * @param engine the Engine to use when scanning. -266 * @param project the project to scan and generate the data file for -267 * @return the Engine used to execute dependency-check -268 * @throws MojoExecutionException thrown if there is an exception running the mojo -269 * @throws MojoFailureException thrown if dependency-check is configured to fail the build if severe CVEs are identified. -270 */ -271 protected Engine generateDataFile(Engine engine, MavenProject project) throws MojoExecutionException, MojoFailureException { -272 if (getLog().isDebugEnabled()) { -273 getLog().debug(String.format("Begin Scanning: %s", project.getName())); -274 } -275 engine.getDependencies().clear(); -276 engine.resetFileTypeAnalyzers(); -277 scanArtifacts(project, engine); -278 engine.analyzeDependencies(); -279 final File target = new File(project.getBuild().getDirectory()); -280 writeDataFile(project, target, engine.getDependencies()); -281 showSummary(project, engine.getDependencies()); -282 checkForFailure(engine.getDependencies()); -283 return engine; -284 } -285 -286 @Override -287 public boolean canGenerateReport() { -288 return true; //aggregate always returns true for now - we can look at a more complicated/acurate solution later -289 } -290 -291 /** -292 * The name of the report in the site. -293 */ -294 @SuppressWarnings("CanBeFinal") -295 @Parameter(property = "name", defaultValue = "dependency-check:aggregate", required = true) -296 private String name = "dependency-check:aggregate"; -297 -298 /** -299 * Returns the report name. -300 * -301 * @param locale the location -302 * @return the report name -303 */ -304 @Override -305 public String getName(Locale locale) { -306 return name; -307 } -308 -309 /** -310 * Gets the description of the Dependency-Check report to be displayed in the Maven Generated Reports page. -311 * -312 * @param locale The Locale to get the description for -313 * @return the description -314 */ -315 @Override -316 public String getDescription(Locale locale) { -317 return "Generates an aggregate report of all child Maven projects providing details on any " -318 + "published vulnerabilities within project dependencies. This report is a best " -319 + "effort and may contain false positives and false negatives."; -320 } -321 } +218 for (MavenProject modTest : getReactorProjects()) { +219 if (p.getModules() != null && p.getModules().contains(modTest.getName()) +220 && descendants.add(modTest) +221 && getLog().isDebugEnabled()) { +222 getLog().debug(String.format("Decendent %s added", modTest.getName())); +223 } +224 } +225 } +226 final Set<MavenProject> addedDescendants = new HashSet<MavenProject>(); +227 for (MavenProject dec : descendants) { +228 for (String mod : dec.getModules()) { +229 try { +230 File mpp = new File(dec.getBasedir(), mod); +231 mpp = mpp.getCanonicalFile(); +232 if (mpp.compareTo(p.getBasedir()) == 0) { +233 addedDescendants.add(p); +234 } +235 } catch (IOException ex) { +236 if (getLog().isDebugEnabled()) { +237 getLog().debug("Unable to determine module path", ex); +238 } +239 } +240 } +241 } +242 for (MavenProject addedDescendant : addedDescendants) { +243 if (descendants.add(addedDescendant) && getLog().isDebugEnabled()) { +244 getLog().debug(String.format("Decendent module %s added", addedDescendant.getName())); +245 } +246 } +247 } +248 } while (size != 0 && size != descendants.size()); +249 if (getLog().isDebugEnabled()) { +250 getLog().debug(String.format("%s has %d children", project, descendants.size())); +251 } +252 return descendants; +253 } +254 +255 /** +256 * Test if the project has pom packaging +257 * +258 * @param mavenProject Project to test +259 * @return <code>true</code> if it has a pom packaging; otherwise +260 * <code>false</code> +261 */ +262 protected boolean isMultiModule(MavenProject mavenProject) { +263 return "pom".equals(mavenProject.getPackaging()); +264 } +265 +266 /** +267 * Initializes the engine, runs a scan, and writes the serialized +268 * dependencies to disk. +269 * +270 * @return the MavenEngine used to execute dependency-check +271 * @throws MojoExecutionException thrown if there is an exception running +272 * the mojo +273 * @throws MojoFailureException thrown if dependency-check is configured to +274 * fail the build if severe CVEs are identified. +275 */ +276 protected MavenEngine generateDataFile() throws MojoExecutionException, MojoFailureException { +277 MavenEngine engine = null; +278 try { +279 engine = initializeEngine(); +280 } catch (DatabaseException ex) { +281 if (getLog().isDebugEnabled()) { +282 getLog().debug("Database connection error", ex); +283 } +284 final String msg = "An exception occured connecting to the local database. Please see the log file for more details."; +285 if (this.isFailOnError()) { +286 throw new MojoExecutionException(msg, ex); +287 } +288 getLog().error(msg, ex); +289 return null; +290 } +291 return generateDataFile(engine, getProject()); +292 } +293 +294 /** +295 * Runs dependency-check's MavenEngine and writes the serialized +296 * dependencies to disk. +297 * +298 * @param engine the MavenEngine to use when scanning. +299 * @param project the project to scan and generate the data file for +300 * @return the MavenEngine used to execute dependency-check +301 * @throws MojoExecutionException thrown if there is an exception running +302 * the mojo +303 * @throws MojoFailureException thrown if dependency-check is configured to +304 * fail the build if severe CVEs are identified. +305 */ +306 protected MavenEngine generateDataFile(MavenEngine engine, MavenProject project) throws MojoExecutionException, MojoFailureException { +307 if (getLog().isDebugEnabled()) { +308 getLog().debug(String.format("Begin Scanning: %s", project.getName())); +309 } +310 engine.getDependencies().clear(); +311 engine.resetFileTypeAnalyzers(); +312 scanArtifacts(project, engine); +313 try { +314 engine.analyzeDependencies(); +315 } catch (ExceptionCollection ex) { +316 ExceptionCollection col = (ExceptionCollection) engine.getExecutionRoot().getContextValue(AGGREGATE_EXCEPTIONS); +317 if (col == null) { +318 col = ex; +319 } else if (ex.isFatal()) { +320 col.setFatal(true); +321 col.getExceptions().addAll(ex.getExceptions()); +322 } +323 if (col.isFatal()) { +324 final String msg = String.format("Fatal exception(s) analyzing %s", project.getName()); +325 if (this.isFailOnError()) { +326 throw new MojoExecutionException(msg, ex); +327 } +328 getLog().error(msg, col); +329 return null; +330 } else { +331 final String msg = String.format("Exception(s) analyzing %s", project.getName()); +332 if (getLog().isDebugEnabled()) { +333 getLog().debug(msg, ex); +334 } +335 engine.getExecutionRoot().setContextValue(AGGREGATE_EXCEPTIONS, col); +336 } +337 } +338 final File target = new File(project.getBuild().getDirectory()); +339 writeDataFile(project, target, engine.getDependencies()); +340 showSummary(project, engine.getDependencies()); +341 checkForFailure(engine.getDependencies()); +342 return engine; +343 } +344 +345 @Override +346 public boolean canGenerateReport() { +347 return true; //aggregate always returns true for now - we can look at a more complicated/acurate solution later +348 } +349 +350 /** +351 * The name of the report in the site. +352 */ +353 @SuppressWarnings("CanBeFinal") +354 @Parameter(property = "name", defaultValue = "dependency-check:aggregate", required = true) +355 private String name = "dependency-check:aggregate"; +356 +357 /** +358 * Returns the report name. +359 * +360 * @param locale the location +361 * @return the report name +362 */ +363 @Override +364 public String getName(Locale locale) { +365 return name; +366 } +367 +368 /** +369 * Gets the description of the Dependency-Check report to be displayed in +370 * the Maven Generated Reports page. +371 * +372 * @param locale The Locale to get the description for +373 * @return the description +374 */ +375 @Override +376 public String getDescription(Locale locale) { +377 return "Generates an aggregate report of all child Maven projects providing details on any " +378 + "published vulnerabilities within project dependencies. This report is a best " +379 + "effort and may contain false positives and false negatives."; +380 } +381 }
        diff --git a/xref/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.html b/xref/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.html index 31f6bcfa6..e07c364c5 100644 --- a/xref/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.html +++ b/xref/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.html @@ -55,1087 +55,1093 @@ 47 import org.owasp.dependencycheck.dependency.Dependency; 48 import org.owasp.dependencycheck.dependency.Identifier; 49 import org.owasp.dependencycheck.dependency.Vulnerability; -50 import org.owasp.dependencycheck.reporting.ReportGenerator; -51 import org.owasp.dependencycheck.utils.ExpectedOjectInputStream; -52 import org.owasp.dependencycheck.utils.Settings; -53 import org.sonatype.plexus.components.sec.dispatcher.DefaultSecDispatcher; -54 import org.sonatype.plexus.components.sec.dispatcher.SecDispatcher; -55 import org.sonatype.plexus.components.sec.dispatcher.SecDispatcherException; -56 -57 /** -58 * -59 * @author Jeremy Long -60 */ -61 public abstract class BaseDependencyCheckMojo extends AbstractMojo implements MavenReport { -62 -63 //<editor-fold defaultstate="collapsed" desc="Private fields"> -64 /** -65 * The properties file location. -66 */ -67 private static final String PROPERTIES_FILE = "mojo.properties"; -68 /** -69 * System specific new line character. -70 */ -71 private static final String NEW_LINE = System.getProperty("line.separator", "\n").intern(); -72 /** -73 * Sets whether or not the external report format should be used. -74 */ -75 @Parameter(property = "metaFileName", defaultValue = "dependency-check.ser", required = true) -76 private String dataFileName; -77 -78 //</editor-fold> -79 // <editor-fold defaultstate="collapsed" desc="Maven bound parameters and components"> +50 import org.owasp.dependencycheck.exception.ReportException; +51 import org.owasp.dependencycheck.reporting.ReportGenerator; +52 import org.owasp.dependencycheck.utils.ExpectedOjectInputStream; +53 import org.owasp.dependencycheck.utils.Settings; +54 import org.sonatype.plexus.components.sec.dispatcher.DefaultSecDispatcher; +55 import org.sonatype.plexus.components.sec.dispatcher.SecDispatcher; +56 import org.sonatype.plexus.components.sec.dispatcher.SecDispatcherException; +57 +58 /** +59 * +60 * @author Jeremy Long +61 */ +62 public abstract class BaseDependencyCheckMojo extends AbstractMojo implements MavenReport { +63 +64 //<editor-fold defaultstate="collapsed" desc="Private fields"> +65 /** +66 * The properties file location. +67 */ +68 private static final String PROPERTIES_FILE = "mojo.properties"; +69 /** +70 * System specific new line character. +71 */ +72 private static final String NEW_LINE = System.getProperty("line.separator", "\n").intern(); +73 //</editor-fold> +74 // <editor-fold defaultstate="collapsed" desc="Maven bound parameters and components"> +75 /** +76 * Sets whether or not the external report format should be used. +77 */ +78 @Parameter(property = "metaFileName", defaultValue = "dependency-check.ser", required = true) +79 private String dataFileName; 80 /** -81 * The Maven Project Object. +81 * Sets whether or not the external report format should be used. 82 */ -83 @Parameter(property = "project", required = true, readonly = true) -84 private MavenProject project; -85 /** -86 * List of Maven project of the current build -87 */ -88 @Parameter(readonly = true, required = true, property = "reactorProjects") -89 private List<MavenProject> reactorProjects; -90 -91 /** -92 * The output directory. This generally maps to "target". -93 */ -94 @Parameter(defaultValue = "${project.build.directory}", required = true) -95 private File outputDirectory; -96 /** -97 * Specifies the destination directory for the generated Dependency-Check -98 * report. This generally maps to "target/site". -99 */ -100 @Parameter(property = "project.reporting.outputDirectory", required = true) -101 private File reportOutputDirectory; -102 /** -103 * Specifies if the build should be failed if a CVSS score above a specified -104 * level is identified. The default is 11 which means since the CVSS scores -105 * are 0-10, by default the build will never fail. -106 */ -107 @SuppressWarnings("CanBeFinal") -108 @Parameter(property = "failBuildOnCVSS", defaultValue = "11", required = true) -109 private float failBuildOnCVSS = 11; -110 /** -111 * Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not -112 * recommended that this be turned to false. Default is true. -113 */ -114 @SuppressWarnings("CanBeFinal") -115 @Parameter(property = "autoUpdate") -116 private Boolean autoUpdate; +83 @Parameter(property = "failOnError", defaultValue = "true", required = true) +84 private boolean failOnError; +85 +86 /** +87 * Returns if the mojo should fail the build if an exception occurs. +88 * +89 * @return whether or not the mojo should fail the build +90 */ +91 protected boolean isFailOnError() { +92 return failOnError; +93 } +94 +95 /** +96 * The Maven Project Object. +97 */ +98 @Parameter(property = "project", required = true, readonly = true) +99 private MavenProject project; +100 /** +101 * List of Maven project of the current build +102 */ +103 @Parameter(readonly = true, required = true, property = "reactorProjects") +104 private List<MavenProject> reactorProjects; +105 +106 /** +107 * The output directory. This generally maps to "target". +108 */ +109 @Parameter(defaultValue = "${project.build.directory}", required = true) +110 private File outputDirectory; +111 /** +112 * Specifies the destination directory for the generated Dependency-Check +113 * report. This generally maps to "target/site". +114 */ +115 @Parameter(property = "project.reporting.outputDirectory", required = true) +116 private File reportOutputDirectory; 117 /** -118 * Sets whether Experimental analyzers are enabled. Default is false. -119 */ -120 @SuppressWarnings("CanBeFinal") -121 @Parameter(property = "enableExperimental") -122 private Boolean enableExperimental; -123 /** -124 * Generate aggregate reports in multi-module projects. -125 * -126 * @deprecated use the aggregate goal instead -127 */ -128 @Parameter(property = "aggregate") -129 @Deprecated -130 private Boolean aggregate; +118 * Specifies if the build should be failed if a CVSS score above a specified +119 * level is identified. The default is 11 which means since the CVSS scores +120 * are 0-10, by default the build will never fail. +121 */ +122 @SuppressWarnings("CanBeFinal") +123 @Parameter(property = "failBuildOnCVSS", defaultValue = "11", required = true) +124 private float failBuildOnCVSS = 11; +125 /** +126 * Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not +127 * recommended that this be turned to false. Default is true. +128 */ +129 @Parameter(property = "autoUpdate") +130 private Boolean autoUpdate; 131 /** -132 * The report format to be generated (HTML, XML, VULN, ALL). This -133 * configuration option has no affect if using this within the Site plug-in -134 * unless the externalReport is set to true. Default is HTML. -135 */ -136 @SuppressWarnings("CanBeFinal") -137 @Parameter(property = "format", defaultValue = "HTML", required = true) -138 private String format = "HTML"; -139 /** -140 * The Maven settings. -141 */ -142 @Parameter(property = "mavenSettings", defaultValue = "${settings}", required = false) -143 private org.apache.maven.settings.Settings mavenSettings; -144 -145 /** -146 * The maven settings proxy id. -147 */ -148 @SuppressWarnings("CanBeFinal") -149 @Parameter(property = "mavenSettingsProxyId", required = false) -150 private String mavenSettingsProxyId; -151 +132 * Sets whether Experimental analyzers are enabled. Default is false. +133 */ +134 @Parameter(property = "enableExperimental") +135 private Boolean enableExperimental; +136 /** +137 * Generate aggregate reports in multi-module projects. +138 * +139 * @deprecated use the aggregate goal instead +140 */ +141 @Parameter(property = "aggregate") +142 @Deprecated +143 private Boolean aggregate; +144 /** +145 * The report format to be generated (HTML, XML, VULN, ALL). This +146 * configuration option has no affect if using this within the Site plug-in +147 * unless the externalReport is set to true. Default is HTML. +148 */ +149 @SuppressWarnings("CanBeFinal") +150 @Parameter(property = "format", defaultValue = "HTML", required = true) +151 private String format = "HTML"; 152 /** -153 * The Connection Timeout. +153 * The Maven settings. 154 */ -155 @Parameter(property = "connectionTimeout", defaultValue = "", required = false) -156 private String connectionTimeout; -157 /** -158 * The path to the suppression file. -159 */ -160 @Parameter(property = "suppressionFile", defaultValue = "", required = false) -161 private String suppressionFile; -162 /** -163 * Flag indicating whether or not to show a summary in the output. -164 */ -165 @Parameter(property = "showSummary", defaultValue = "true", required = false) -166 private boolean showSummary = true; -167 -168 /** -169 * Whether or not the Jar Analyzer is enabled. -170 */ -171 @Parameter(property = "jarAnalyzerEnabled", required = false) -172 private Boolean jarAnalyzerEnabled; -173 +155 @Parameter(property = "mavenSettings", defaultValue = "${settings}", required = false) +156 private org.apache.maven.settings.Settings mavenSettings; +157 +158 /** +159 * The maven settings proxy id. +160 */ +161 @Parameter(property = "mavenSettingsProxyId", required = false) +162 private String mavenSettingsProxyId; +163 +164 /** +165 * The Connection Timeout. +166 */ +167 @Parameter(property = "connectionTimeout", defaultValue = "", required = false) +168 private String connectionTimeout; +169 /** +170 * The path to the suppression file. +171 */ +172 @Parameter(property = "suppressionFile", defaultValue = "", required = false) +173 private String suppressionFile; 174 /** -175 * Whether or not the Archive Analyzer is enabled. +175 * Flag indicating whether or not to show a summary in the output. 176 */ -177 @Parameter(property = "archiveAnalyzerEnabled", required = false) -178 private Boolean archiveAnalyzerEnabled; -179 -180 /** -181 * Sets whether the Python Distribution Analyzer will be used. -182 */ -183 @Parameter(property = "pyDistributionAnalyzerEnabled", required = false) -184 private Boolean pyDistributionAnalyzerEnabled; -185 /** -186 * Sets whether the Python Package Analyzer will be used. -187 */ -188 @Parameter(property = "pyPackageAnalyzerEnabled", required = false) -189 private Boolean pyPackageAnalyzerEnabled; -190 /** -191 * Sets whether the Ruby Gemspec Analyzer will be used. -192 */ -193 @Parameter(property = "rubygemsAnalyzerEnabled", required = false) -194 private Boolean rubygemsAnalyzerEnabled; -195 /** -196 * Sets whether or not the openssl Analyzer should be used. -197 */ -198 @Parameter(property = "opensslAnalyzerEnabled", required = false) -199 private Boolean opensslAnalyzerEnabled; -200 /** -201 * Sets whether or not the CMake Analyzer should be used. -202 */ -203 @Parameter(property = "cmakeAnalyzerEnabled", required = false) -204 private Boolean cmakeAnalyzerEnabled; -205 /** -206 * Sets whether or not the autoconf Analyzer should be used. -207 */ -208 @Parameter(property = "autoconfAnalyzerEnabled", required = false) -209 private Boolean autoconfAnalyzerEnabled; -210 /** -211 * Sets whether or not the PHP Composer Lock File Analyzer should be used. -212 */ -213 @Parameter(property = "composerAnalyzerEnabled", required = false) -214 private Boolean composerAnalyzerEnabled; -215 /** -216 * Sets whether or not the Node.js Analyzer should be used. -217 */ -218 @Parameter(property = "nodeAnalyzerEnabled", required = false) -219 private Boolean nodeAnalyzerEnabled; -220 -221 /** -222 * Whether or not the .NET Assembly Analyzer is enabled. -223 */ -224 @Parameter(property = "assemblyAnalyzerEnabled", required = false) -225 private Boolean assemblyAnalyzerEnabled; -226 -227 /** -228 * Whether or not the .NET Nuspec Analyzer is enabled. -229 */ -230 @Parameter(property = "nuspecAnalyzerEnabled", required = false) -231 private Boolean nuspecAnalyzerEnabled; -232 -233 /** -234 * Whether or not the Central Analyzer is enabled. -235 */ -236 @Parameter(property = "centralAnalyzerEnabled", required = false) -237 private Boolean centralAnalyzerEnabled; -238 -239 /** -240 * Whether or not the Nexus Analyzer is enabled. -241 */ -242 @Parameter(property = "nexusAnalyzerEnabled", required = false) -243 private Boolean nexusAnalyzerEnabled; -244 -245 /** -246 * The URL of a Nexus server's REST API end point -247 * (http://domain/nexus/service/local). +177 @SuppressWarnings("CanBeFinal") +178 @Parameter(property = "showSummary", defaultValue = "true", required = false) +179 private boolean showSummary = true; +180 +181 /** +182 * Whether or not the Jar Analyzer is enabled. +183 */ +184 @Parameter(property = "jarAnalyzerEnabled", required = false) +185 private Boolean jarAnalyzerEnabled; +186 +187 /** +188 * Whether or not the Archive Analyzer is enabled. +189 */ +190 @Parameter(property = "archiveAnalyzerEnabled", required = false) +191 private Boolean archiveAnalyzerEnabled; +192 +193 /** +194 * Sets whether the Python Distribution Analyzer will be used. +195 */ +196 @Parameter(property = "pyDistributionAnalyzerEnabled", required = false) +197 private Boolean pyDistributionAnalyzerEnabled; +198 /** +199 * Sets whether the Python Package Analyzer will be used. +200 */ +201 @Parameter(property = "pyPackageAnalyzerEnabled", required = false) +202 private Boolean pyPackageAnalyzerEnabled; +203 /** +204 * Sets whether the Ruby Gemspec Analyzer will be used. +205 */ +206 @Parameter(property = "rubygemsAnalyzerEnabled", required = false) +207 private Boolean rubygemsAnalyzerEnabled; +208 /** +209 * Sets whether or not the openssl Analyzer should be used. +210 */ +211 @Parameter(property = "opensslAnalyzerEnabled", required = false) +212 private Boolean opensslAnalyzerEnabled; +213 /** +214 * Sets whether or not the CMake Analyzer should be used. +215 */ +216 @Parameter(property = "cmakeAnalyzerEnabled", required = false) +217 private Boolean cmakeAnalyzerEnabled; +218 /** +219 * Sets whether or not the autoconf Analyzer should be used. +220 */ +221 @Parameter(property = "autoconfAnalyzerEnabled", required = false) +222 private Boolean autoconfAnalyzerEnabled; +223 /** +224 * Sets whether or not the PHP Composer Lock File Analyzer should be used. +225 */ +226 @Parameter(property = "composerAnalyzerEnabled", required = false) +227 private Boolean composerAnalyzerEnabled; +228 /** +229 * Sets whether or not the Node.js Analyzer should be used. +230 */ +231 @Parameter(property = "nodeAnalyzerEnabled", required = false) +232 private Boolean nodeAnalyzerEnabled; +233 +234 /** +235 * Whether or not the .NET Assembly Analyzer is enabled. +236 */ +237 @Parameter(property = "assemblyAnalyzerEnabled", required = false) +238 private Boolean assemblyAnalyzerEnabled; +239 +240 /** +241 * Whether or not the .NET Nuspec Analyzer is enabled. +242 */ +243 @Parameter(property = "nuspecAnalyzerEnabled", required = false) +244 private Boolean nuspecAnalyzerEnabled; +245 +246 /** +247 * Whether or not the Central Analyzer is enabled. 248 */ -249 @Parameter(property = "nexusUrl", required = false) -250 private String nexusUrl; -251 /** -252 * Whether or not the configured proxy is used to connect to Nexus. -253 */ -254 @Parameter(property = "nexusUsesProxy", required = false) -255 private Boolean nexusUsesProxy; -256 /** -257 * The database connection string. -258 */ -259 @Parameter(property = "connectionString", defaultValue = "", required = false) -260 private String connectionString; -261 -262 /** -263 * Returns the connection string. -264 * -265 * @return the connection string +249 @Parameter(property = "centralAnalyzerEnabled", required = false) +250 private Boolean centralAnalyzerEnabled; +251 +252 /** +253 * Whether or not the Nexus Analyzer is enabled. +254 */ +255 @Parameter(property = "nexusAnalyzerEnabled", required = false) +256 private Boolean nexusAnalyzerEnabled; +257 +258 /** +259 * The URL of a Nexus server's REST API end point +260 * (http://domain/nexus/service/local). +261 */ +262 @Parameter(property = "nexusUrl", required = false) +263 private String nexusUrl; +264 /** +265 * Whether or not the configured proxy is used to connect to Nexus. 266 */ -267 protected String getConnectionString() { -268 return connectionString; -269 } -270 /** -271 * The database driver name. An example would be org.h2.Driver. -272 */ -273 @Parameter(property = "databaseDriverName", defaultValue = "", required = false) -274 private String databaseDriverName; +267 @Parameter(property = "nexusUsesProxy", required = false) +268 private Boolean nexusUsesProxy; +269 /** +270 * The database connection string. +271 */ +272 @Parameter(property = "connectionString", defaultValue = "", required = false) +273 private String connectionString; +274 275 /** -276 * The path to the database driver if it is not on the class path. -277 */ -278 @Parameter(property = "databaseDriverPath", defaultValue = "", required = false) -279 private String databaseDriverPath; -280 /** -281 * The server id in the settings.xml; used to retrieve encrypted passwords -282 * from the settings.xml. -283 */ -284 @Parameter(property = "serverId", defaultValue = "", required = false) -285 private String serverId; -286 /** -287 * A reference to the settings.xml settings. -288 */ -289 @Parameter(defaultValue = "${settings}", readonly = true, required = true) -290 private org.apache.maven.settings.Settings settingsXml; -291 /** -292 * The security dispatcher that can decrypt passwords in the settings.xml. -293 */ -294 @Component(role = SecDispatcher.class, hint = "default") -295 private SecDispatcher securityDispatcher; -296 /** -297 * The database user name. -298 */ -299 @Parameter(property = "databaseUser", defaultValue = "", required = false) -300 private String databaseUser; -301 /** -302 * The password to use when connecting to the database. -303 */ -304 @Parameter(property = "databasePassword", defaultValue = "", required = false) -305 private String databasePassword; -306 /** -307 * A comma-separated list of file extensions to add to analysis next to jar, -308 * zip, .... -309 */ -310 @Parameter(property = "zipExtensions", required = false) -311 private String zipExtensions; -312 /** -313 * Skip Dependency Check altogether. -314 */ -315 @SuppressWarnings("CanBeFinal") -316 @Parameter(property = "dependency-check.skip", defaultValue = "false", required = false) -317 private boolean skip = false; -318 /** -319 * Skip Analysis for Test Scope Dependencies. -320 */ -321 @SuppressWarnings("CanBeFinal") -322 @Parameter(property = "skipTestScope", defaultValue = "true", required = false) -323 private boolean skipTestScope = true; -324 /** -325 * Skip Analysis for Runtime Scope Dependencies. -326 */ -327 @SuppressWarnings("CanBeFinal") -328 @Parameter(property = "skipRuntimeScope", defaultValue = "false", required = false) -329 private boolean skipRuntimeScope = false; -330 /** -331 * Skip Analysis for Provided Scope Dependencies. -332 */ -333 @SuppressWarnings("CanBeFinal") -334 @Parameter(property = "skipProvidedScope", defaultValue = "false", required = false) -335 private boolean skipProvidedScope = false; -336 /** -337 * The data directory, hold DC SQL DB. -338 */ -339 @Parameter(property = "dataDirectory", defaultValue = "", required = false) -340 private String dataDirectory; -341 /** -342 * Data Mirror URL for CVE 1.2. -343 */ -344 @Parameter(property = "cveUrl12Modified", defaultValue = "", required = false) -345 private String cveUrl12Modified; -346 /** -347 * Data Mirror URL for CVE 2.0. -348 */ -349 @Parameter(property = "cveUrl20Modified", defaultValue = "", required = false) -350 private String cveUrl20Modified; -351 /** -352 * Base Data Mirror URL for CVE 1.2. -353 */ -354 @Parameter(property = "cveUrl12Base", defaultValue = "", required = false) -355 private String cveUrl12Base; -356 /** -357 * Data Mirror URL for CVE 2.0. -358 */ -359 @Parameter(property = "cveUrl20Base", defaultValue = "", required = false) -360 private String cveUrl20Base; -361 /** -362 * Optionally skip excessive CVE update checks for a designated duration in -363 * hours. -364 */ -365 @Parameter(property = "cveValidForHours", defaultValue = "", required = false) -366 private Integer cveValidForHours; -367 -368 /** -369 * The path to mono for .NET Assembly analysis on non-windows systems. -370 */ -371 @Parameter(property = "pathToMono", defaultValue = "", required = false) -372 private String pathToMono; -373 +276 * Returns the connection string. +277 * +278 * @return the connection string +279 */ +280 protected String getConnectionString() { +281 return connectionString; +282 } +283 /** +284 * The database driver name. An example would be org.h2.Driver. +285 */ +286 @Parameter(property = "databaseDriverName", defaultValue = "", required = false) +287 private String databaseDriverName; +288 /** +289 * The path to the database driver if it is not on the class path. +290 */ +291 @Parameter(property = "databaseDriverPath", defaultValue = "", required = false) +292 private String databaseDriverPath; +293 /** +294 * The server id in the settings.xml; used to retrieve encrypted passwords +295 * from the settings.xml. +296 */ +297 @Parameter(property = "serverId", defaultValue = "", required = false) +298 private String serverId; +299 /** +300 * A reference to the settings.xml settings. +301 */ +302 @Parameter(defaultValue = "${settings}", readonly = true, required = true) +303 private org.apache.maven.settings.Settings settingsXml; +304 /** +305 * The security dispatcher that can decrypt passwords in the settings.xml. +306 */ +307 @Component(role = SecDispatcher.class, hint = "default") +308 private SecDispatcher securityDispatcher; +309 /** +310 * The database user name. +311 */ +312 @Parameter(property = "databaseUser", defaultValue = "", required = false) +313 private String databaseUser; +314 /** +315 * The password to use when connecting to the database. +316 */ +317 @Parameter(property = "databasePassword", defaultValue = "", required = false) +318 private String databasePassword; +319 /** +320 * A comma-separated list of file extensions to add to analysis next to jar, +321 * zip, .... +322 */ +323 @Parameter(property = "zipExtensions", required = false) +324 private String zipExtensions; +325 /** +326 * Skip Dependency Check altogether. +327 */ +328 @SuppressWarnings("CanBeFinal") +329 @Parameter(property = "dependency-check.skip", defaultValue = "false", required = false) +330 private boolean skip = false; +331 /** +332 * Skip Analysis for Test Scope Dependencies. +333 */ +334 @SuppressWarnings("CanBeFinal") +335 @Parameter(property = "skipTestScope", defaultValue = "true", required = false) +336 private boolean skipTestScope = true; +337 /** +338 * Skip Analysis for Runtime Scope Dependencies. +339 */ +340 @SuppressWarnings("CanBeFinal") +341 @Parameter(property = "skipRuntimeScope", defaultValue = "false", required = false) +342 private boolean skipRuntimeScope = false; +343 /** +344 * Skip Analysis for Provided Scope Dependencies. +345 */ +346 @SuppressWarnings("CanBeFinal") +347 @Parameter(property = "skipProvidedScope", defaultValue = "false", required = false) +348 private boolean skipProvidedScope = false; +349 /** +350 * The data directory, hold DC SQL DB. +351 */ +352 @Parameter(property = "dataDirectory", defaultValue = "", required = false) +353 private String dataDirectory; +354 /** +355 * Data Mirror URL for CVE 1.2. +356 */ +357 @Parameter(property = "cveUrl12Modified", defaultValue = "", required = false) +358 private String cveUrl12Modified; +359 /** +360 * Data Mirror URL for CVE 2.0. +361 */ +362 @Parameter(property = "cveUrl20Modified", defaultValue = "", required = false) +363 private String cveUrl20Modified; +364 /** +365 * Base Data Mirror URL for CVE 1.2. +366 */ +367 @Parameter(property = "cveUrl12Base", defaultValue = "", required = false) +368 private String cveUrl12Base; +369 /** +370 * Data Mirror URL for CVE 2.0. +371 */ +372 @Parameter(property = "cveUrl20Base", defaultValue = "", required = false) +373 private String cveUrl20Base; 374 /** -375 * The Proxy URL. -376 * -377 * @deprecated Please use mavenSettings instead -378 */ -379 @SuppressWarnings("CanBeFinal") -380 @Parameter(property = "proxyUrl", defaultValue = "", required = false) -381 @Deprecated -382 private String proxyUrl = null; -383 /** -384 * Sets whether or not the external report format should be used. -385 * -386 * @deprecated the internal report is no longer supported -387 */ -388 @SuppressWarnings("CanBeFinal") -389 @Parameter(property = "externalReport") -390 @Deprecated -391 private String externalReport = null; -392 // </editor-fold> -393 //<editor-fold defaultstate="collapsed" desc="Base Maven implementation"> -394 -395 /** -396 * Executes dependency-check. -397 * -398 * @throws MojoExecutionException thrown if there is an exception executing -399 * the mojo -400 * @throws MojoFailureException thrown if dependency-check failed the build -401 */ -402 @Override -403 public void execute() throws MojoExecutionException, MojoFailureException { -404 generatingSite = false; -405 if (skip) { -406 getLog().info("Skipping " + getName(Locale.US)); -407 } else { -408 validateAggregate(); -409 project.setContextValue(getOutputDirectoryContextKey(), this.outputDirectory); -410 runCheck(); -411 } -412 } -413 -414 /** -415 * Checks if the aggregate configuration parameter has been set to true. If -416 * it has a MojoExecutionException is thrown because the aggregate -417 * configuration parameter is no longer supported. -418 * -419 * @throws MojoExecutionException thrown if aggregate is set to true -420 */ -421 private void validateAggregate() throws MojoExecutionException { -422 if (aggregate != null && aggregate) { -423 final String msg = "Aggregate configuration detected - as of dependency-check 1.2.8 this no longer supported. " -424 + "Please use the aggregate goal instead."; -425 throw new MojoExecutionException(msg); -426 } -427 } -428 -429 /** -430 * Generates the Dependency-Check Site Report. +375 * Optionally skip excessive CVE update checks for a designated duration in +376 * hours. +377 */ +378 @Parameter(property = "cveValidForHours", defaultValue = "", required = false) +379 private Integer cveValidForHours; +380 +381 /** +382 * The path to mono for .NET Assembly analysis on non-windows systems. +383 */ +384 @Parameter(property = "pathToMono", defaultValue = "", required = false) +385 private String pathToMono; +386 +387 /** +388 * The Proxy URL. +389 * +390 * @deprecated Please use mavenSettings instead +391 */ +392 @SuppressWarnings("CanBeFinal") +393 @Parameter(property = "proxyUrl", defaultValue = "", required = false) +394 @Deprecated +395 private String proxyUrl = null; +396 /** +397 * Sets whether or not the external report format should be used. +398 * +399 * @deprecated the internal report is no longer supported +400 */ +401 @SuppressWarnings("CanBeFinal") +402 @Parameter(property = "externalReport") +403 @Deprecated +404 private String externalReport = null; +405 // </editor-fold> +406 //<editor-fold defaultstate="collapsed" desc="Base Maven implementation"> +407 +408 /** +409 * Executes dependency-check. +410 * +411 * @throws MojoExecutionException thrown if there is an exception executing +412 * the mojo +413 * @throws MojoFailureException thrown if dependency-check failed the build +414 */ +415 @Override +416 public void execute() throws MojoExecutionException, MojoFailureException { +417 generatingSite = false; +418 if (skip) { +419 getLog().info("Skipping " + getName(Locale.US)); +420 } else { +421 validateAggregate(); +422 project.setContextValue(getOutputDirectoryContextKey(), this.outputDirectory); +423 runCheck(); +424 } +425 } +426 +427 /** +428 * Checks if the aggregate configuration parameter has been set to true. If +429 * it has a MojoExecutionException is thrown because the aggregate +430 * configuration parameter is no longer supported. 431 * -432 * @param sink the sink to write the report to -433 * @param locale the locale to use when generating the report -434 * @throws MavenReportException if a maven report exception occurs -435 * @deprecated use -436 * {@link #generate(org.apache.maven.doxia.sink.Sink, java.util.Locale)} -437 * instead. -438 */ -439 @Override -440 @Deprecated -441 public final void generate(@SuppressWarnings("deprecation") org.codehaus.doxia.sink.Sink sink, Locale locale) throws MavenReportException { -442 generate((Sink) sink, locale); -443 } -444 -445 /** -446 * A flag indicating whether or not the maven site is being generated. -447 */ -448 private boolean generatingSite = false; -449 -450 /** -451 * Returns true if the Maven site is being generated. -452 * -453 * @return true if the Maven site is being generated -454 */ -455 protected boolean isGeneratingSite() { -456 return generatingSite; -457 } -458 -459 /** -460 * Generates the Dependency-Check Site Report. -461 * -462 * @param sink the sink to write the report to -463 * @param locale the locale to use when generating the report -464 * @throws MavenReportException if a maven report exception occurs -465 */ -466 public void generate(Sink sink, Locale locale) throws MavenReportException { -467 generatingSite = true; -468 try { -469 validateAggregate(); -470 } catch (MojoExecutionException ex) { -471 throw new MavenReportException(ex.getMessage()); -472 } -473 project.setContextValue(getOutputDirectoryContextKey(), getReportOutputDirectory()); -474 try { -475 runCheck(); -476 } catch (MojoExecutionException ex) { -477 throw new MavenReportException(ex.getMessage(), ex); -478 } catch (MojoFailureException ex) { -479 getLog().warn("Vulnerabilities were identifies that exceed the CVSS threshold for failing the build"); -480 } -481 } -482 -483 /** -484 * Returns the correct output directory depending on if a site is being -485 * executed or not. -486 * -487 * @return the directory to write the report(s) -488 * @throws MojoExecutionException thrown if there is an error loading the -489 * file path -490 */ -491 protected File getCorrectOutputDirectory() throws MojoExecutionException { -492 return getCorrectOutputDirectory(this.project); -493 } -494 -495 /** -496 * Returns the correct output directory depending on if a site is being -497 * executed or not. -498 * -499 * @param current the Maven project to get the output directory from +432 * @throws MojoExecutionException thrown if aggregate is set to true +433 */ +434 private void validateAggregate() throws MojoExecutionException { +435 if (aggregate != null && aggregate) { +436 final String msg = "Aggregate configuration detected - as of dependency-check 1.2.8 this no longer supported. " +437 + "Please use the aggregate goal instead."; +438 throw new MojoExecutionException(msg); +439 } +440 } +441 +442 /** +443 * Generates the Dependency-Check Site Report. +444 * +445 * @param sink the sink to write the report to +446 * @param locale the locale to use when generating the report +447 * @throws MavenReportException if a maven report exception occurs +448 * @deprecated use +449 * {@link #generate(org.apache.maven.doxia.sink.Sink, java.util.Locale)} +450 * instead. +451 */ +452 @Override +453 @Deprecated +454 public final void generate(@SuppressWarnings("deprecation") org.codehaus.doxia.sink.Sink sink, Locale locale) throws MavenReportException { +455 generate((Sink) sink, locale); +456 } +457 +458 /** +459 * A flag indicating whether or not the maven site is being generated. +460 */ +461 private boolean generatingSite = false; +462 +463 /** +464 * Returns true if the Maven site is being generated. +465 * +466 * @return true if the Maven site is being generated +467 */ +468 protected boolean isGeneratingSite() { +469 return generatingSite; +470 } +471 +472 /** +473 * Generates the Dependency-Check Site Report. +474 * +475 * @param sink the sink to write the report to +476 * @param locale the locale to use when generating the report +477 * @throws MavenReportException if a maven report exception occurs +478 */ +479 public void generate(Sink sink, Locale locale) throws MavenReportException { +480 generatingSite = true; +481 try { +482 validateAggregate(); +483 } catch (MojoExecutionException ex) { +484 throw new MavenReportException(ex.getMessage()); +485 } +486 project.setContextValue(getOutputDirectoryContextKey(), getReportOutputDirectory()); +487 try { +488 runCheck(); +489 } catch (MojoExecutionException ex) { +490 throw new MavenReportException(ex.getMessage(), ex); +491 } catch (MojoFailureException ex) { +492 getLog().warn("Vulnerabilities were identifies that exceed the CVSS threshold for failing the build"); +493 } +494 } +495 +496 /** +497 * Returns the correct output directory depending on if a site is being +498 * executed or not. +499 * 500 * @return the directory to write the report(s) -501 */ -502 protected File getCorrectOutputDirectory(MavenProject current) { -503 final Object obj = current.getContextValue(getOutputDirectoryContextKey()); -504 if (obj != null && obj instanceof File) { -505 return (File) obj; -506 } -507 File target = new File(current.getBuild().getDirectory()); -508 if (target.getParentFile() != null && "target".equals(target.getParentFile().getName())) { -509 target = target.getParentFile(); -510 } -511 return target; -512 } -513 -514 /** -515 * Returns the correct output directory depending on if a site is being -516 * executed or not. -517 * -518 * @param current the Maven project to get the output directory from -519 * @return the directory to write the report(s) -520 */ -521 protected File getDataFile(MavenProject current) { -522 if (getLog().isDebugEnabled()) { -523 getLog().debug(String.format("Getting data filefor %s using key '%s'", current.getName(), getDataFileContextKey())); -524 } -525 final Object obj = current.getContextValue(getDataFileContextKey()); -526 if (obj != null) { -527 if (obj instanceof String) { -528 final File f = new File((String) obj); -529 return f; -530 } -531 } else if (getLog().isDebugEnabled()) { -532 getLog().debug("Context value not found"); -533 } -534 return null; -535 } -536 -537 /** -538 * Scans the project's artifacts and adds them to the engine's dependency -539 * list. -540 * -541 * @param project the project to scan the dependencies of -542 * @param engine the engine to use to scan the dependencies -543 */ -544 protected void scanArtifacts(MavenProject project, Engine engine) { -545 for (Artifact a : project.getArtifacts()) { -546 if (excludeFromScan(a)) { -547 continue; -548 } -549 final List<Dependency> deps = engine.scan(a.getFile().getAbsoluteFile()); -550 if (deps != null) { -551 if (deps.size() == 1) { -552 final Dependency d = deps.get(0); -553 if (d != null) { -554 final MavenArtifact ma = new MavenArtifact(a.getGroupId(), a.getArtifactId(), a.getVersion()); -555 d.addAsEvidence("pom", ma, Confidence.HIGHEST); -556 d.addProjectReference(project.getName()); -557 if (getLog().isDebugEnabled()) { -558 getLog().debug(String.format("Adding project reference %s on dependency %s", project.getName(), -559 d.getDisplayFileName())); -560 } -561 } -562 } else if (getLog().isDebugEnabled()) { -563 final String msg = String.format("More then 1 dependency was identified in first pass scan of '%s:%s:%s'", -564 a.getGroupId(), a.getArtifactId(), a.getVersion()); -565 getLog().debug(msg); -566 } -567 } -568 } -569 } -570 -571 /** -572 * Executes the dependency-check scan and generates the necassary report. -573 * -574 * @throws MojoExecutionException thrown if there is an exception running -575 * the scan -576 * @throws MojoFailureException thrown if dependency-check is configured to -577 * fail the build -578 */ -579 public abstract void runCheck() throws MojoExecutionException, MojoFailureException; -580 -581 /** -582 * Sets the Reporting output directory. -583 * -584 * @param directory the output directory -585 */ -586 @Override -587 public void setReportOutputDirectory(File directory) { -588 reportOutputDirectory = directory; -589 } -590 -591 /** -592 * Returns the report output directory. -593 * -594 * @return the report output directory -595 */ -596 @Override -597 public File getReportOutputDirectory() { -598 return reportOutputDirectory; -599 } -600 -601 /** -602 * Returns the output directory. -603 * -604 * @return the output directory -605 */ -606 public File getOutputDirectory() { -607 return outputDirectory; -608 } -609 -610 /** -611 * Returns whether this is an external report. This method always returns -612 * true. -613 * -614 * @return <code>true</code> -615 */ -616 @Override -617 public final boolean isExternalReport() { -618 return true; -619 } -620 -621 /** -622 * Returns the output name. -623 * -624 * @return the output name -625 */ -626 @Override -627 public String getOutputName() { -628 if ("HTML".equalsIgnoreCase(this.format) || "ALL".equalsIgnoreCase(this.format)) { -629 return "dependency-check-report"; -630 } else if ("XML".equalsIgnoreCase(this.format)) { -631 return "dependency-check-report.xml#"; -632 } else if ("VULN".equalsIgnoreCase(this.format)) { -633 return "dependency-check-vulnerability"; -634 } else { -635 getLog().warn("Unknown report format used during site generation."); -636 return "dependency-check-report"; -637 } -638 } -639 -640 /** -641 * Returns the category name. -642 * -643 * @return the category name -644 */ -645 @Override -646 public String getCategoryName() { -647 return MavenReport.CATEGORY_PROJECT_REPORTS; -648 } -649 //</editor-fold> -650 -651 /** -652 * Initializes a new <code>Engine</code> that can be used for scanning. -653 * -654 * @return a newly instantiated <code>Engine</code> -655 * @throws DatabaseException thrown if there is a database exception -656 */ -657 protected Engine initializeEngine() throws DatabaseException { -658 populateSettings(); -659 return new Engine(this.project, -660 this.reactorProjects); +501 * @throws MojoExecutionException thrown if there is an error loading the +502 * file path +503 */ +504 protected File getCorrectOutputDirectory() throws MojoExecutionException { +505 return getCorrectOutputDirectory(this.project); +506 } +507 +508 /** +509 * Returns the correct output directory depending on if a site is being +510 * executed or not. +511 * +512 * @param current the Maven project to get the output directory from +513 * @return the directory to write the report(s) +514 */ +515 protected File getCorrectOutputDirectory(MavenProject current) { +516 final Object obj = current.getContextValue(getOutputDirectoryContextKey()); +517 if (obj != null && obj instanceof File) { +518 return (File) obj; +519 } +520 File target = new File(current.getBuild().getDirectory()); +521 if (target.getParentFile() != null && "target".equals(target.getParentFile().getName())) { +522 target = target.getParentFile(); +523 } +524 return target; +525 } +526 +527 /** +528 * Returns the correct output directory depending on if a site is being +529 * executed or not. +530 * +531 * @param current the Maven project to get the output directory from +532 * @return the directory to write the report(s) +533 */ +534 protected File getDataFile(MavenProject current) { +535 if (getLog().isDebugEnabled()) { +536 getLog().debug(String.format("Getting data filefor %s using key '%s'", current.getName(), getDataFileContextKey())); +537 } +538 final Object obj = current.getContextValue(getDataFileContextKey()); +539 if (obj != null) { +540 if (obj instanceof String) { +541 final File f = new File((String) obj); +542 return f; +543 } +544 } else if (getLog().isDebugEnabled()) { +545 getLog().debug("Context value not found"); +546 } +547 return null; +548 } +549 +550 /** +551 * Scans the project's artifacts and adds them to the engine's dependency +552 * list. +553 * +554 * @param project the project to scan the dependencies of +555 * @param engine the engine to use to scan the dependencies +556 */ +557 protected void scanArtifacts(MavenProject project, MavenEngine engine) { +558 for (Artifact a : project.getArtifacts()) { +559 if (excludeFromScan(a)) { +560 continue; +561 } +562 final List<Dependency> deps = engine.scan(a.getFile().getAbsoluteFile()); +563 if (deps != null) { +564 if (deps.size() == 1) { +565 final Dependency d = deps.get(0); +566 if (d != null) { +567 final MavenArtifact ma = new MavenArtifact(a.getGroupId(), a.getArtifactId(), a.getVersion()); +568 d.addAsEvidence("pom", ma, Confidence.HIGHEST); +569 d.addProjectReference(project.getName()); +570 if (getLog().isDebugEnabled()) { +571 getLog().debug(String.format("Adding project reference %s on dependency %s", project.getName(), +572 d.getDisplayFileName())); +573 } +574 } +575 } else if (getLog().isDebugEnabled()) { +576 final String msg = String.format("More then 1 dependency was identified in first pass scan of '%s:%s:%s'", +577 a.getGroupId(), a.getArtifactId(), a.getVersion()); +578 getLog().debug(msg); +579 } +580 } +581 } +582 } +583 +584 /** +585 * Executes the dependency-check scan and generates the necassary report. +586 * +587 * @throws MojoExecutionException thrown if there is an exception running +588 * the scan +589 * @throws MojoFailureException thrown if dependency-check is configured to +590 * fail the build +591 */ +592 public abstract void runCheck() throws MojoExecutionException, MojoFailureException; +593 +594 /** +595 * Sets the Reporting output directory. +596 * +597 * @param directory the output directory +598 */ +599 @Override +600 public void setReportOutputDirectory(File directory) { +601 reportOutputDirectory = directory; +602 } +603 +604 /** +605 * Returns the report output directory. +606 * +607 * @return the report output directory +608 */ +609 @Override +610 public File getReportOutputDirectory() { +611 return reportOutputDirectory; +612 } +613 +614 /** +615 * Returns the output directory. +616 * +617 * @return the output directory +618 */ +619 public File getOutputDirectory() { +620 return outputDirectory; +621 } +622 +623 /** +624 * Returns whether this is an external report. This method always returns +625 * true. +626 * +627 * @return <code>true</code> +628 */ +629 @Override +630 public final boolean isExternalReport() { +631 return true; +632 } +633 +634 /** +635 * Returns the output name. +636 * +637 * @return the output name +638 */ +639 @Override +640 public String getOutputName() { +641 if ("HTML".equalsIgnoreCase(this.format) || "ALL".equalsIgnoreCase(this.format)) { +642 return "dependency-check-report"; +643 } else if ("XML".equalsIgnoreCase(this.format)) { +644 return "dependency-check-report.xml#"; +645 } else if ("VULN".equalsIgnoreCase(this.format)) { +646 return "dependency-check-vulnerability"; +647 } else { +648 getLog().warn("Unknown report format used during site generation."); +649 return "dependency-check-report"; +650 } +651 } +652 +653 /** +654 * Returns the category name. +655 * +656 * @return the category name +657 */ +658 @Override +659 public String getCategoryName() { +660 return MavenReport.CATEGORY_PROJECT_REPORTS; 661 } -662 -663 /** -664 * Takes the properties supplied and updates the dependency-check settings. -665 * Additionally, this sets the system properties required to change the -666 * proxy url, port, and connection timeout. -667 */ -668 protected void populateSettings() { -669 Settings.initialize(); -670 InputStream mojoProperties = null; -671 try { -672 mojoProperties = this.getClass().getClassLoader().getResourceAsStream(PROPERTIES_FILE); -673 Settings.mergeProperties(mojoProperties); -674 } catch (IOException ex) { -675 getLog().warn("Unable to load the dependency-check ant task.properties file."); -676 if (getLog().isDebugEnabled()) { -677 getLog().debug("", ex); -678 } -679 } finally { -680 if (mojoProperties != null) { -681 try { -682 mojoProperties.close(); -683 } catch (IOException ex) { -684 if (getLog().isDebugEnabled()) { -685 getLog().debug("", ex); -686 } -687 } -688 } -689 } -690 Settings.setBooleanIfNotNull(Settings.KEYS.AUTO_UPDATE, autoUpdate); -691 -692 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, enableExperimental); -693 -694 if (externalReport != null) { -695 getLog().warn("The 'externalReport' option was set; this configuration option has been removed. " -696 + "Please update the dependency-check-maven plugin's configuration"); -697 } -698 -699 if (proxyUrl != null && !proxyUrl.isEmpty()) { -700 getLog().warn("Deprecated configuration detected, proxyUrl will be ignored; use the maven settings " + "to configure the proxy instead"); -701 } -702 final Proxy proxy = getMavenProxy(); -703 if (proxy != null) { -704 Settings.setString(Settings.KEYS.PROXY_SERVER, proxy.getHost()); -705 Settings.setString(Settings.KEYS.PROXY_PORT, Integer.toString(proxy.getPort())); -706 final String userName = proxy.getUsername(); -707 final String password = proxy.getPassword(); -708 Settings.setStringIfNotNull(Settings.KEYS.PROXY_USERNAME, userName); -709 Settings.setStringIfNotNull(Settings.KEYS.PROXY_PASSWORD, password); -710 Settings.setStringIfNotNull(Settings.KEYS.PROXY_NON_PROXY_HOSTS, proxy.getNonProxyHosts()); -711 } -712 -713 Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout); -714 Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile); -715 -716 //File Type Analyzer Settings -717 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_JAR_ENABLED, jarAnalyzerEnabled); -718 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, nuspecAnalyzerEnabled); -719 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, centralAnalyzerEnabled); -720 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled); -721 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl); -722 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy); -723 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, assemblyAnalyzerEnabled); -724 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, archiveAnalyzerEnabled); -725 Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions); -726 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono); -727 -728 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, pyDistributionAnalyzerEnabled); -729 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, pyPackageAnalyzerEnabled); -730 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED, rubygemsAnalyzerEnabled); -731 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, opensslAnalyzerEnabled); -732 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CMAKE_ENABLED, cmakeAnalyzerEnabled); -733 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_AUTOCONF_ENABLED, autoconfAnalyzerEnabled); -734 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED, composerAnalyzerEnabled); -735 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED, nodeAnalyzerEnabled); -736 -737 //Database configuration -738 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName); -739 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath); -740 Settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString); -741 -742 if (databaseUser == null && databasePassword == null && serverId != null) { -743 final Server server = settingsXml.getServer(serverId); -744 if (server != null) { -745 databaseUser = server.getUsername(); -746 try { -747 //The following fix was copied from: -748 // https://github.com/bsorrentino/maven-confluence-plugin/blob/master/maven-confluence-reporting-plugin/src/main/java/org/bsc/maven/confluence/plugin/AbstractBaseConfluenceMojo.java -749 // -750 // FIX to resolve -751 // org.sonatype.plexus.components.sec.dispatcher.SecDispatcherException: -752 // java.io.FileNotFoundException: ~/.settings-security.xml (No such file or directory) -753 // -754 if (securityDispatcher instanceof DefaultSecDispatcher) { -755 ((DefaultSecDispatcher) securityDispatcher).setConfigurationFile("~/.m2/settings-security.xml"); -756 } -757 -758 databasePassword = securityDispatcher.decrypt(server.getPassword()); -759 } catch (SecDispatcherException ex) { -760 if (ex.getCause() instanceof FileNotFoundException -761 || (ex.getCause() != null && ex.getCause().getCause() instanceof FileNotFoundException)) { -762 //maybe its not encrypted? -763 final String tmp = server.getPassword(); -764 if (tmp.startsWith("{") && tmp.endsWith("}")) { -765 getLog().error(String.format( -766 "Unable to decrypt the server password for server id '%s' in settings.xml%n\tCause: %s", -767 serverId, ex.getMessage())); -768 } else { -769 databasePassword = tmp; -770 } -771 } else { -772 getLog().error(String.format( -773 "Unable to decrypt the server password for server id '%s' in settings.xml%n\tCause: %s", -774 serverId, ex.getMessage())); -775 } -776 } -777 } else { -778 getLog().error(String.format("Server '%s' not found in the settings.xml file", serverId)); -779 } -780 } -781 -782 Settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser); -783 Settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword); -784 Settings.setStringIfNotEmpty(Settings.KEYS.DATA_DIRECTORY, dataDirectory); -785 -786 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_12_URL, cveUrl12Modified); -787 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_20_URL, cveUrl20Modified); -788 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_1_2, cveUrl12Base); -789 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_2_0, cveUrl20Base); -790 Settings.setIntIfNotNull(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, cveValidForHours); -791 -792 } -793 -794 /** -795 * Returns the maven proxy. -796 * -797 * @return the maven proxy -798 */ -799 private Proxy getMavenProxy() { -800 if (mavenSettings != null) { -801 final List<Proxy> proxies = mavenSettings.getProxies(); -802 if (proxies != null && !proxies.isEmpty()) { -803 if (mavenSettingsProxyId != null) { -804 for (Proxy proxy : proxies) { -805 if (mavenSettingsProxyId.equalsIgnoreCase(proxy.getId())) { -806 return proxy; -807 } -808 } -809 } else if (proxies.size() == 1) { -810 return proxies.get(0); -811 } else { -812 getLog().warn("Multiple proxy definitions exist in the Maven settings. In the dependency-check " -813 + "configuration set the mavenSettingsProxyId so that the correct proxy will be used."); -814 throw new IllegalStateException("Ambiguous proxy definition"); -815 } -816 } -817 } -818 return null; -819 } -820 -821 /** -822 * Tests is the artifact should be included in the scan (i.e. is the -823 * dependency in a scope that is being scanned). -824 * -825 * @param a the Artifact to test -826 * @return <code>true</code> if the artifact is in an excluded scope; -827 * otherwise <code>false</code> -828 */ -829 protected boolean excludeFromScan(Artifact a) { -830 if (skipTestScope && Artifact.SCOPE_TEST.equals(a.getScope())) { -831 return true; -832 } -833 if (skipProvidedScope && Artifact.SCOPE_PROVIDED.equals(a.getScope())) { -834 return true; -835 } -836 if (skipRuntimeScope && !Artifact.SCOPE_RUNTIME.equals(a.getScope())) { -837 return true; -838 } -839 return false; -840 } -841 -842 /** -843 * Returns a reference to the current project. This method is used instead -844 * of auto-binding the project via component annotation in concrete -845 * implementations of this. If the child has a -846 * <code>@Component MavenProject project;</code> defined then the abstract -847 * class (i.e. this class) will not have access to the current project (just -848 * the way Maven works with the binding). -849 * -850 * @return returns a reference to the current project -851 */ -852 protected MavenProject getProject() { -853 return project; -854 } -855 -856 /** -857 * Returns the list of Maven Projects in this build. -858 * -859 * @return the list of Maven Projects in this build -860 */ -861 protected List<MavenProject> getReactorProjects() { -862 return reactorProjects; -863 } -864 -865 /** -866 * Returns the report format. -867 * -868 * @return the report format -869 */ -870 protected String getFormat() { -871 return format; -872 } -873 -874 /** -875 * Generates the reports for a given dependency-check engine. -876 * -877 * @param engine a dependency-check engine -878 * @param p the maven project -879 * @param outputDir the directory path to write the report(s). -880 */ -881 protected void writeReports(Engine engine, MavenProject p, File outputDir) { -882 DatabaseProperties prop = null; -883 CveDB cve = null; -884 try { -885 cve = new CveDB(); -886 cve.open(); -887 prop = cve.getDatabaseProperties(); -888 } catch (DatabaseException ex) { -889 if (getLog().isDebugEnabled()) { -890 getLog().debug("Unable to retrieve DB Properties", ex); -891 } -892 } finally { -893 if (cve != null) { -894 cve.close(); -895 } -896 } -897 final ReportGenerator r = new ReportGenerator(p.getName(), engine.getDependencies(), engine.getAnalyzers(), prop); +662 //</editor-fold> +663 +664 /** +665 * Initializes a new <code>MavenEngine</code> that can be used for scanning. +666 * +667 * @return a newly instantiated <code>MavenEngine</code> +668 * @throws DatabaseException thrown if there is a database exception +669 */ +670 protected MavenEngine initializeEngine() throws DatabaseException { +671 populateSettings(); +672 return new MavenEngine(this.project, +673 this.reactorProjects); +674 } +675 +676 /** +677 * Takes the properties supplied and updates the dependency-check settings. +678 * Additionally, this sets the system properties required to change the +679 * proxy url, port, and connection timeout. +680 */ +681 protected void populateSettings() { +682 Settings.initialize(); +683 InputStream mojoProperties = null; +684 try { +685 mojoProperties = this.getClass().getClassLoader().getResourceAsStream(PROPERTIES_FILE); +686 Settings.mergeProperties(mojoProperties); +687 } catch (IOException ex) { +688 getLog().warn("Unable to load the dependency-check ant task.properties file."); +689 if (getLog().isDebugEnabled()) { +690 getLog().debug("", ex); +691 } +692 } finally { +693 if (mojoProperties != null) { +694 try { +695 mojoProperties.close(); +696 } catch (IOException ex) { +697 if (getLog().isDebugEnabled()) { +698 getLog().debug("", ex); +699 } +700 } +701 } +702 } +703 Settings.setBooleanIfNotNull(Settings.KEYS.AUTO_UPDATE, autoUpdate); +704 +705 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, enableExperimental); +706 +707 if (externalReport != null) { +708 getLog().warn("The 'externalReport' option was set; this configuration option has been removed. " +709 + "Please update the dependency-check-maven plugin's configuration"); +710 } +711 +712 if (proxyUrl != null && !proxyUrl.isEmpty()) { +713 getLog().warn("Deprecated configuration detected, proxyUrl will be ignored; use the maven settings " + "to configure the proxy instead"); +714 } +715 final Proxy proxy = getMavenProxy(); +716 if (proxy != null) { +717 Settings.setString(Settings.KEYS.PROXY_SERVER, proxy.getHost()); +718 Settings.setString(Settings.KEYS.PROXY_PORT, Integer.toString(proxy.getPort())); +719 final String userName = proxy.getUsername(); +720 final String password = proxy.getPassword(); +721 Settings.setStringIfNotNull(Settings.KEYS.PROXY_USERNAME, userName); +722 Settings.setStringIfNotNull(Settings.KEYS.PROXY_PASSWORD, password); +723 Settings.setStringIfNotNull(Settings.KEYS.PROXY_NON_PROXY_HOSTS, proxy.getNonProxyHosts()); +724 } +725 +726 Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout); +727 Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile); +728 +729 //File Type Analyzer Settings +730 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_JAR_ENABLED, jarAnalyzerEnabled); +731 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, nuspecAnalyzerEnabled); +732 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, centralAnalyzerEnabled); +733 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled); +734 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl); +735 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy); +736 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, assemblyAnalyzerEnabled); +737 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, archiveAnalyzerEnabled); +738 Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions); +739 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono); +740 +741 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, pyDistributionAnalyzerEnabled); +742 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, pyPackageAnalyzerEnabled); +743 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED, rubygemsAnalyzerEnabled); +744 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, opensslAnalyzerEnabled); +745 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CMAKE_ENABLED, cmakeAnalyzerEnabled); +746 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_AUTOCONF_ENABLED, autoconfAnalyzerEnabled); +747 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED, composerAnalyzerEnabled); +748 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED, nodeAnalyzerEnabled); +749 +750 //Database configuration +751 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName); +752 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath); +753 Settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString); +754 +755 if (databaseUser == null && databasePassword == null && serverId != null) { +756 final Server server = settingsXml.getServer(serverId); +757 if (server != null) { +758 databaseUser = server.getUsername(); +759 try { +760 //The following fix was copied from: +761 // https://github.com/bsorrentino/maven-confluence-plugin/blob/master/maven-confluence-reporting-plugin/src/main/java/org/bsc/maven/confluence/plugin/AbstractBaseConfluenceMojo.java +762 // +763 // FIX to resolve +764 // org.sonatype.plexus.components.sec.dispatcher.SecDispatcherException: +765 // java.io.FileNotFoundException: ~/.settings-security.xml (No such file or directory) +766 // +767 if (securityDispatcher instanceof DefaultSecDispatcher) { +768 ((DefaultSecDispatcher) securityDispatcher).setConfigurationFile("~/.m2/settings-security.xml"); +769 } +770 +771 databasePassword = securityDispatcher.decrypt(server.getPassword()); +772 } catch (SecDispatcherException ex) { +773 if (ex.getCause() instanceof FileNotFoundException +774 || (ex.getCause() != null && ex.getCause().getCause() instanceof FileNotFoundException)) { +775 //maybe its not encrypted? +776 final String tmp = server.getPassword(); +777 if (tmp.startsWith("{") && tmp.endsWith("}")) { +778 getLog().error(String.format( +779 "Unable to decrypt the server password for server id '%s' in settings.xml%n\tCause: %s", +780 serverId, ex.getMessage())); +781 } else { +782 databasePassword = tmp; +783 } +784 } else { +785 getLog().error(String.format( +786 "Unable to decrypt the server password for server id '%s' in settings.xml%n\tCause: %s", +787 serverId, ex.getMessage())); +788 } +789 } +790 } else { +791 getLog().error(String.format("Server '%s' not found in the settings.xml file", serverId)); +792 } +793 } +794 +795 Settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser); +796 Settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword); +797 Settings.setStringIfNotEmpty(Settings.KEYS.DATA_DIRECTORY, dataDirectory); +798 +799 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_12_URL, cveUrl12Modified); +800 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_20_URL, cveUrl20Modified); +801 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_1_2, cveUrl12Base); +802 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_2_0, cveUrl20Base); +803 Settings.setIntIfNotNull(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, cveValidForHours); +804 +805 } +806 +807 /** +808 * Returns the maven proxy. +809 * +810 * @return the maven proxy +811 */ +812 private Proxy getMavenProxy() { +813 if (mavenSettings != null) { +814 final List<Proxy> proxies = mavenSettings.getProxies(); +815 if (proxies != null && !proxies.isEmpty()) { +816 if (mavenSettingsProxyId != null) { +817 for (Proxy proxy : proxies) { +818 if (mavenSettingsProxyId.equalsIgnoreCase(proxy.getId())) { +819 return proxy; +820 } +821 } +822 } else if (proxies.size() == 1) { +823 return proxies.get(0); +824 } else { +825 getLog().warn("Multiple proxy definitions exist in the Maven settings. In the dependency-check " +826 + "configuration set the mavenSettingsProxyId so that the correct proxy will be used."); +827 throw new IllegalStateException("Ambiguous proxy definition"); +828 } +829 } +830 } +831 return null; +832 } +833 +834 /** +835 * Tests is the artifact should be included in the scan (i.e. is the +836 * dependency in a scope that is being scanned). +837 * +838 * @param a the Artifact to test +839 * @return <code>true</code> if the artifact is in an excluded scope; +840 * otherwise <code>false</code> +841 */ +842 protected boolean excludeFromScan(Artifact a) { +843 if (skipTestScope && Artifact.SCOPE_TEST.equals(a.getScope())) { +844 return true; +845 } +846 if (skipProvidedScope && Artifact.SCOPE_PROVIDED.equals(a.getScope())) { +847 return true; +848 } +849 if (skipRuntimeScope && !Artifact.SCOPE_RUNTIME.equals(a.getScope())) { +850 return true; +851 } +852 return false; +853 } +854 +855 /** +856 * Returns a reference to the current project. This method is used instead +857 * of auto-binding the project via component annotation in concrete +858 * implementations of this. If the child has a +859 * <code>@Component MavenProject project;</code> defined then the abstract +860 * class (i.e. this class) will not have access to the current project (just +861 * the way Maven works with the binding). +862 * +863 * @return returns a reference to the current project +864 */ +865 protected MavenProject getProject() { +866 return project; +867 } +868 +869 /** +870 * Returns the list of Maven Projects in this build. +871 * +872 * @return the list of Maven Projects in this build +873 */ +874 protected List<MavenProject> getReactorProjects() { +875 return reactorProjects; +876 } +877 +878 /** +879 * Returns the report format. +880 * +881 * @return the report format +882 */ +883 protected String getFormat() { +884 return format; +885 } +886 +887 /** +888 * Generates the reports for a given dependency-check engine. +889 * +890 * @param engine a dependency-check engine +891 * @param p the Maven project +892 * @param outputDir the directory path to write the report(s) +893 * @throws ReportException thrown if there is an error writing the report +894 */ +895 protected void writeReports(MavenEngine engine, MavenProject p, File outputDir) throws ReportException { +896 DatabaseProperties prop = null; +897 CveDB cve = null; 898 try { -899 r.generateReports(outputDir.getAbsolutePath(), format); -900 } catch (IOException ex) { -901 getLog().error( -902 "Unexpected exception occurred during analysis; please see the verbose error log for more details."); +899 cve = new CveDB(); +900 cve.open(); +901 prop = cve.getDatabaseProperties(); +902 } catch (DatabaseException ex) { 903 if (getLog().isDebugEnabled()) { -904 getLog().debug("", ex); +904 getLog().debug("Unable to retrieve DB Properties", ex); 905 } -906 } catch (Throwable ex) { -907 getLog().error( -908 "Unexpected exception occurred during analysis; please see the verbose error log for more details."); -909 if (getLog().isDebugEnabled()) { -910 getLog().debug("", ex); -911 } -912 } -913 } -914 -915 //<editor-fold defaultstate="collapsed" desc="Methods to fail build or show summary"> -916 /** -917 * Checks to see if a vulnerability has been identified with a CVSS score -918 * that is above the threshold set in the configuration. -919 * -920 * @param dependencies the list of dependency objects -921 * @throws MojoFailureException thrown if a CVSS score is found that is -922 * higher then the threshold set -923 */ -924 protected void checkForFailure(List<Dependency> dependencies) throws MojoFailureException { -925 if (failBuildOnCVSS <= 10) { -926 final StringBuilder ids = new StringBuilder(); -927 for (Dependency d : dependencies) { -928 boolean addName = true; -929 for (Vulnerability v : d.getVulnerabilities()) { -930 if (v.getCvssScore() >= failBuildOnCVSS) { -931 if (addName) { -932 addName = false; -933 ids.append(NEW_LINE).append(d.getFileName()).append(": "); -934 ids.append(v.getName()); -935 } else { -936 ids.append(", ").append(v.getName()); -937 } -938 } -939 } -940 } -941 if (ids.length() > 0) { -942 final String msg = String.format("%n%nDependency-Check Failure:%n" -943 + "One or more dependencies were identified with vulnerabilities that have a CVSS score greater then '%.1f': %s%n" -944 + "See the dependency-check report for more details.%n%n", failBuildOnCVSS, ids.toString()); -945 throw new MojoFailureException(msg); +906 } finally { +907 if (cve != null) { +908 cve.close(); +909 } +910 } +911 final ReportGenerator r = new ReportGenerator(p.getName(), engine.getDependencies(), engine.getAnalyzers(), prop); +912 try { +913 r.generateReports(outputDir.getAbsolutePath(), format); +914 } catch (ReportException ex) { +915 final String msg = String.format("Error generating the report for %s", p.getName()); +916 throw new ReportException(msg, ex); +917 } +918 +919 } +920 +921 //<editor-fold defaultstate="collapsed" desc="Methods to fail build or show summary"> +922 /** +923 * Checks to see if a vulnerability has been identified with a CVSS score +924 * that is above the threshold set in the configuration. +925 * +926 * @param dependencies the list of dependency objects +927 * @throws MojoFailureException thrown if a CVSS score is found that is +928 * higher then the threshold set +929 */ +930 protected void checkForFailure(List<Dependency> dependencies) throws MojoFailureException { +931 if (failBuildOnCVSS <= 10) { +932 final StringBuilder ids = new StringBuilder(); +933 for (Dependency d : dependencies) { +934 boolean addName = true; +935 for (Vulnerability v : d.getVulnerabilities()) { +936 if (v.getCvssScore() >= failBuildOnCVSS) { +937 if (addName) { +938 addName = false; +939 ids.append(NEW_LINE).append(d.getFileName()).append(": "); +940 ids.append(v.getName()); +941 } else { +942 ids.append(", ").append(v.getName()); +943 } +944 } +945 } 946 } -947 } -948 } -949 -950 /** -951 * Generates a warning message listing a summary of dependencies and their -952 * associated CPE and CVE entries. -953 * -954 * @param mp the Maven project for which the summary is shown -955 * @param dependencies a list of dependency objects -956 */ -957 protected void showSummary(MavenProject mp, List<Dependency> dependencies) { -958 if (showSummary) { -959 final StringBuilder summary = new StringBuilder(); -960 for (Dependency d : dependencies) { -961 boolean firstEntry = true; -962 final StringBuilder ids = new StringBuilder(); -963 for (Vulnerability v : d.getVulnerabilities()) { -964 if (firstEntry) { -965 firstEntry = false; -966 } else { -967 ids.append(", "); -968 } -969 ids.append(v.getName()); -970 } -971 if (ids.length() > 0) { -972 summary.append(d.getFileName()).append(" ("); -973 firstEntry = true; -974 for (Identifier id : d.getIdentifiers()) { -975 if (firstEntry) { -976 firstEntry = false; -977 } else { -978 summary.append(", "); -979 } -980 summary.append(id.getValue()); -981 } -982 summary.append(") : ").append(ids).append(NEW_LINE); -983 } -984 } -985 if (summary.length() > 0) { -986 final String msg = String.format("%n%n" + "One or more dependencies were identified with known vulnerabilities in %s:%n%n%s" -987 + "%n%nSee the dependency-check report for more details.%n%n", mp.getName(), summary.toString()); -988 getLog().warn(msg); -989 } -990 } -991 } -992 -993 //</editor-fold> -994 //<editor-fold defaultstate="collapsed" desc="Methods to read/write the serialized data file"> -995 /** -996 * Returns the key used to store the path to the data file that is saved by -997 * <code>writeDataFile()</code>. This key is used in the -998 * <code>MavenProject.(set|get)ContextValue</code>. -999 * -1000 * @return the key used to store the path to the data file -1001 */ -1002 protected String getDataFileContextKey() { -1003 return "dependency-check-path-" + dataFileName; -1004 } -1005 -1006 /** -1007 * Returns the key used to store the path to the output directory. When -1008 * generating the report in the <code>executeAggregateReport()</code> the -1009 * output directory should be obtained by using this key. -1010 * -1011 * @return the key used to store the path to the output directory -1012 */ -1013 protected String getOutputDirectoryContextKey() { -1014 return "dependency-output-dir-" + dataFileName; -1015 } -1016 -1017 /** -1018 * Writes the scan data to disk. This is used to serialize the scan data -1019 * between the "check" and "aggregate" phase. -1020 * -1021 * @param mp the mMven project for which the data file was created -1022 * @param writeTo the directory to write the data file -1023 * @param dependencies the list of dependencies to serialize -1024 */ -1025 protected void writeDataFile(MavenProject mp, File writeTo, List<Dependency> dependencies) { -1026 File file; -1027 //check to see if this was already written out -1028 if (mp.getContextValue(this.getDataFileContextKey()) == null) { -1029 if (writeTo == null) { -1030 file = new File(mp.getBuild().getDirectory()); -1031 file = new File(file, dataFileName); -1032 } else { -1033 file = new File(writeTo, dataFileName); -1034 } -1035 final File parent = file.getParentFile(); -1036 if (!parent.isDirectory() && !parent.mkdirs()) { -1037 getLog().error(String.format("Directory '%s' does not exist and cannot be created; unable to write data file.", -1038 parent.getAbsolutePath())); -1039 } -1040 -1041 ObjectOutputStream out = null; -1042 try { -1043 if (dependencies != null) { -1044 out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file))); -1045 out.writeObject(dependencies); -1046 } -1047 if (getLog().isDebugEnabled()) { -1048 getLog().debug(String.format("Serialized data file written to '%s' for %s, referenced by key %s", -1049 file.getAbsolutePath(), mp.getName(), this.getDataFileContextKey())); -1050 } -1051 mp.setContextValue(this.getDataFileContextKey(), file.getAbsolutePath()); -1052 } catch (IOException ex) { -1053 getLog().warn("Unable to create data file used for report aggregation; " -1054 + "if report aggregation is being used the results may be incomplete."); -1055 if (getLog().isDebugEnabled()) { -1056 getLog().debug(ex.getMessage(), ex); -1057 } -1058 } finally { -1059 if (out != null) { -1060 try { -1061 out.close(); -1062 } catch (IOException ex) { -1063 if (getLog().isDebugEnabled()) { -1064 getLog().debug("ignore", ex); -1065 } -1066 } -1067 } -1068 } -1069 } -1070 } -1071 -1072 /** -1073 * Reads the serialized scan data from disk. This is used to serialize the -1074 * scan data between the "check" and "aggregate" phase. -1075 * -1076 * @param project the Maven project to read the data file from -1077 * @return a <code>Engine</code> object populated with dependencies if the -1078 * serialized data file exists; otherwise <code>null</code> is returned -1079 */ -1080 protected List<Dependency> readDataFile(MavenProject project) { -1081 final Object oPath = project.getContextValue(this.getDataFileContextKey()); -1082 if (oPath == null) { -1083 return null; -1084 } -1085 List<Dependency> ret = null; -1086 final String path = (String) oPath; -1087 //ObjectInputStream ois = null; -1088 ExpectedOjectInputStream ois = null; -1089 try { -1090 //ois = new ObjectInputStream(new FileInputStream(path)); -1091 ois = new ExpectedOjectInputStream(new FileInputStream(path), -1092 "java.util.ArrayList", -1093 "java.util.HashSet", -1094 "java.util.TreeSet", -1095 "java.lang.AbstractSet", -1096 "java.lang.AbstractCollection", -1097 "java.lang.Enum", -1098 "org.owasp.dependencycheck.dependency.Confidence", -1099 "org.owasp.dependencycheck.dependency.Dependency", -1100 "org.owasp.dependencycheck.dependency.Evidence", -1101 "org.owasp.dependencycheck.dependency.EvidenceCollection", -1102 "org.owasp.dependencycheck.dependency.Identifier", -1103 "org.owasp.dependencycheck.dependency.Reference", -1104 "org.owasp.dependencycheck.dependency.Vulnerability", -1105 "org.owasp.dependencycheck.dependency.VulnerabilityComparator", -1106 "org.owasp.dependencycheck.dependency.VulnerableSoftware", -1107 "org.owasp.dependencycheck.data.cpe.IndexEntry"); -1108 @SuppressWarnings("unchecked") -1109 final List<Dependency> depList = (List<Dependency>) ois.readObject(); -1110 ret = depList; -1111 } catch (FileNotFoundException ex) { -1112 //TODO fix logging -1113 getLog().error("", ex); -1114 } catch (IOException ex) { -1115 getLog().error("", ex); -1116 } catch (ClassNotFoundException ex) { -1117 getLog().error("", ex); -1118 } finally { -1119 if (ois != null) { -1120 try { -1121 ois.close(); -1122 } catch (IOException ex) { -1123 getLog().error("", ex); -1124 } -1125 } -1126 } -1127 return ret; -1128 } -1129 //</editor-fold> -1130 } +947 if (ids.length() > 0) { +948 final String msg = String.format("%n%nDependency-Check Failure:%n" +949 + "One or more dependencies were identified with vulnerabilities that have a CVSS score greater then '%.1f': %s%n" +950 + "See the dependency-check report for more details.%n%n", failBuildOnCVSS, ids.toString()); +951 throw new MojoFailureException(msg); +952 } +953 } +954 } +955 +956 /** +957 * Generates a warning message listing a summary of dependencies and their +958 * associated CPE and CVE entries. +959 * +960 * @param mp the Maven project for which the summary is shown +961 * @param dependencies a list of dependency objects +962 */ +963 protected void showSummary(MavenProject mp, List<Dependency> dependencies) { +964 if (showSummary) { +965 final StringBuilder summary = new StringBuilder(); +966 for (Dependency d : dependencies) { +967 boolean firstEntry = true; +968 final StringBuilder ids = new StringBuilder(); +969 for (Vulnerability v : d.getVulnerabilities()) { +970 if (firstEntry) { +971 firstEntry = false; +972 } else { +973 ids.append(", "); +974 } +975 ids.append(v.getName()); +976 } +977 if (ids.length() > 0) { +978 summary.append(d.getFileName()).append(" ("); +979 firstEntry = true; +980 for (Identifier id : d.getIdentifiers()) { +981 if (firstEntry) { +982 firstEntry = false; +983 } else { +984 summary.append(", "); +985 } +986 summary.append(id.getValue()); +987 } +988 summary.append(") : ").append(ids).append(NEW_LINE); +989 } +990 } +991 if (summary.length() > 0) { +992 final String msg = String.format("%n%n" + "One or more dependencies were identified with known vulnerabilities in %s:%n%n%s" +993 + "%n%nSee the dependency-check report for more details.%n%n", mp.getName(), summary.toString()); +994 getLog().warn(msg); +995 } +996 } +997 } +998 +999 //</editor-fold> +1000 //<editor-fold defaultstate="collapsed" desc="Methods to read/write the serialized data file"> +1001 /** +1002 * Returns the key used to store the path to the data file that is saved by +1003 * <code>writeDataFile()</code>. This key is used in the +1004 * <code>MavenProject.(set|get)ContextValue</code>. +1005 * +1006 * @return the key used to store the path to the data file +1007 */ +1008 protected String getDataFileContextKey() { +1009 return "dependency-check-path-" + dataFileName; +1010 } +1011 +1012 /** +1013 * Returns the key used to store the path to the output directory. When +1014 * generating the report in the <code>executeAggregateReport()</code> the +1015 * output directory should be obtained by using this key. +1016 * +1017 * @return the key used to store the path to the output directory +1018 */ +1019 protected String getOutputDirectoryContextKey() { +1020 return "dependency-output-dir-" + dataFileName; +1021 } +1022 +1023 /** +1024 * Writes the scan data to disk. This is used to serialize the scan data +1025 * between the "check" and "aggregate" phase. +1026 * +1027 * @param mp the mMven project for which the data file was created +1028 * @param writeTo the directory to write the data file +1029 * @param dependencies the list of dependencies to serialize +1030 */ +1031 protected void writeDataFile(MavenProject mp, File writeTo, List<Dependency> dependencies) { +1032 File file; +1033 //check to see if this was already written out +1034 if (mp.getContextValue(this.getDataFileContextKey()) == null) { +1035 if (writeTo == null) { +1036 file = new File(mp.getBuild().getDirectory()); +1037 file = new File(file, dataFileName); +1038 } else { +1039 file = new File(writeTo, dataFileName); +1040 } +1041 final File parent = file.getParentFile(); +1042 if (!parent.isDirectory() && !parent.mkdirs()) { +1043 getLog().error(String.format("Directory '%s' does not exist and cannot be created; unable to write data file.", +1044 parent.getAbsolutePath())); +1045 } +1046 +1047 ObjectOutputStream out = null; +1048 try { +1049 if (dependencies != null) { +1050 out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file))); +1051 out.writeObject(dependencies); +1052 } +1053 if (getLog().isDebugEnabled()) { +1054 getLog().debug(String.format("Serialized data file written to '%s' for %s, referenced by key %s", +1055 file.getAbsolutePath(), mp.getName(), this.getDataFileContextKey())); +1056 } +1057 mp.setContextValue(this.getDataFileContextKey(), file.getAbsolutePath()); +1058 } catch (IOException ex) { +1059 getLog().warn("Unable to create data file used for report aggregation; " +1060 + "if report aggregation is being used the results may be incomplete."); +1061 if (getLog().isDebugEnabled()) { +1062 getLog().debug(ex.getMessage(), ex); +1063 } +1064 } finally { +1065 if (out != null) { +1066 try { +1067 out.close(); +1068 } catch (IOException ex) { +1069 if (getLog().isDebugEnabled()) { +1070 getLog().debug("ignore", ex); +1071 } +1072 } +1073 } +1074 } +1075 } +1076 } +1077 +1078 /** +1079 * Reads the serialized scan data from disk. This is used to serialize the +1080 * scan data between the "check" and "aggregate" phase. +1081 * +1082 * @param project the Maven project to read the data file from +1083 * @return a <code>MavenEngine</code> object populated with dependencies if +1084 * the serialized data file exists; otherwise <code>null</code> is returned +1085 */ +1086 protected List<Dependency> readDataFile(MavenProject project) { +1087 final Object oPath = project.getContextValue(this.getDataFileContextKey()); +1088 if (oPath == null) { +1089 return null; +1090 } +1091 List<Dependency> ret = null; +1092 final String path = (String) oPath; +1093 //ObjectInputStream ois = null; +1094 ExpectedOjectInputStream ois = null; +1095 try { +1096 //ois = new ObjectInputStream(new FileInputStream(path)); +1097 ois = new ExpectedOjectInputStream(new FileInputStream(path), +1098 "java.util.ArrayList", +1099 "java.util.HashSet", +1100 "java.util.TreeSet", +1101 "java.lang.AbstractSet", +1102 "java.lang.AbstractCollection", +1103 "java.lang.Enum", +1104 "org.owasp.dependencycheck.dependency.Confidence", +1105 "org.owasp.dependencycheck.dependency.Dependency", +1106 "org.owasp.dependencycheck.dependency.Evidence", +1107 "org.owasp.dependencycheck.dependency.EvidenceCollection", +1108 "org.owasp.dependencycheck.dependency.Identifier", +1109 "org.owasp.dependencycheck.dependency.Reference", +1110 "org.owasp.dependencycheck.dependency.Vulnerability", +1111 "org.owasp.dependencycheck.dependency.VulnerabilityComparator", +1112 "org.owasp.dependencycheck.dependency.VulnerableSoftware", +1113 "org.owasp.dependencycheck.data.cpe.IndexEntry"); +1114 @SuppressWarnings("unchecked") +1115 final List<Dependency> depList = (List<Dependency>) ois.readObject(); +1116 ret = depList; +1117 } catch (FileNotFoundException ex) { +1118 //TODO fix logging +1119 getLog().error("", ex); +1120 } catch (IOException ex) { +1121 getLog().error("", ex); +1122 } catch (ClassNotFoundException ex) { +1123 getLog().error("", ex); +1124 } finally { +1125 if (ois != null) { +1126 try { +1127 ois.close(); +1128 } catch (IOException ex) { +1129 getLog().error("", ex); +1130 } +1131 } +1132 } +1133 return ret; +1134 } +1135 //</editor-fold> +1136 }
        diff --git a/xref/org/owasp/dependencycheck/maven/CheckMojo.html b/xref/org/owasp/dependencycheck/maven/CheckMojo.html index c1044e0d1..d49a01f5d 100644 --- a/xref/org/owasp/dependencycheck/maven/CheckMojo.html +++ b/xref/org/owasp/dependencycheck/maven/CheckMojo.html @@ -34,101 +34,138 @@ 26 import org.apache.maven.plugins.annotations.Parameter; 27 import org.apache.maven.plugins.annotations.ResolutionScope; 28 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; -29 import org.owasp.dependencycheck.utils.Settings; -30 -31 /** -32 * Maven Plugin that checks the project dependencies to see if they have any known published vulnerabilities. -33 * -34 * @author Jeremy Long -35 */ -36 @Mojo( -37 name = "check", -38 defaultPhase = LifecyclePhase.VERIFY, -39 threadSafe = false, -40 requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME, -41 requiresOnline = true -42 ) -43 public class CheckMojo extends BaseDependencyCheckMojo { -44 -45 /** -46 * Returns whether or not a the report can be generated. -47 * -48 * @return <code>true</code> if the report can be generated; otherwise <code>false</code> -49 */ -50 @Override -51 public boolean canGenerateReport() { -52 boolean isCapable = false; -53 for (Artifact a : getProject().getArtifacts()) { -54 if (!excludeFromScan(a)) { -55 isCapable = true; -56 break; -57 } -58 } -59 return isCapable; -60 } -61 -62 /** -63 * Executes the dependency-check engine on the project's dependencies and generates the report. -64 * -65 * @throws MojoExecutionException thrown if there is an exception executing the goal -66 * @throws MojoFailureException thrown if dependency-check is configured to fail the build -67 */ -68 @Override -69 public void runCheck() throws MojoExecutionException, MojoFailureException { -70 final Engine engine; -71 try { -72 engine = initializeEngine(); -73 } catch (DatabaseException ex) { -74 if (getLog().isDebugEnabled()) { -75 getLog().debug("Database connection error", ex); -76 } -77 throw new MojoExecutionException("An exception occured connecting to the local database. Please see the log file for more details.", ex); -78 } -79 scanArtifacts(getProject(), engine); -80 if (engine.getDependencies().isEmpty()) { -81 getLog().info("No dependencies were identified that could be analyzed by dependency-check"); -82 } else { -83 engine.analyzeDependencies(); -84 writeReports(engine, getProject(), getCorrectOutputDirectory()); -85 writeDataFile(getProject(), null, engine.getDependencies()); -86 showSummary(getProject(), engine.getDependencies()); -87 checkForFailure(engine.getDependencies()); -88 } -89 engine.cleanup(); -90 Settings.cleanup(); -91 } -92 -93 /** -94 * The name of the report in the site. -95 */ -96 @SuppressWarnings("CanBeFinal") -97 @Parameter(property = "name", defaultValue = "dependency-check", required = true) -98 private String name = "dependency-check"; -99 -100 /** -101 * Returns the report name. -102 * -103 * @param locale the location -104 * @return the report name -105 */ -106 @Override -107 public String getName(Locale locale) { -108 return name; -109 } -110 -111 /** -112 * Gets the description of the Dependency-Check report to be displayed in the Maven Generated Reports page. -113 * -114 * @param locale The Locale to get the description for -115 * @return the description -116 */ -117 @Override -118 public String getDescription(Locale locale) { -119 return "Generates a report providing details on any published vulnerabilities within project dependencies. " -120 + "This report is a best effort and may contain false positives and false negatives."; -121 } -122 -123 } +29 import org.owasp.dependencycheck.exception.ExceptionCollection; +30 import org.owasp.dependencycheck.exception.ReportException; +31 import org.owasp.dependencycheck.utils.Settings; +32 +33 /** +34 * Maven Plugin that checks the project dependencies to see if they have any +35 * known published vulnerabilities. +36 * +37 * @author Jeremy Long +38 */ +39 @Mojo( +40 name = "check", +41 defaultPhase = LifecyclePhase.VERIFY, +42 threadSafe = false, +43 requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME, +44 requiresOnline = true +45 ) +46 public class CheckMojo extends BaseDependencyCheckMojo { +47 +48 /** +49 * Returns whether or not a the report can be generated. +50 * +51 * @return <code>true</code> if the report can be generated; otherwise +52 * <code>false</code> +53 */ +54 @Override +55 public boolean canGenerateReport() { +56 boolean isCapable = false; +57 for (Artifact a : getProject().getArtifacts()) { +58 if (!excludeFromScan(a)) { +59 isCapable = true; +60 break; +61 } +62 } +63 return isCapable; +64 } +65 +66 /** +67 * Executes the dependency-check engine on the project's dependencies and +68 * generates the report. +69 * +70 * @throws MojoExecutionException thrown if there is an exception executing +71 * the goal +72 * @throws MojoFailureException thrown if dependency-check is configured to +73 * fail the build +74 */ +75 @Override +76 public void runCheck() throws MojoExecutionException, MojoFailureException { +77 MavenEngine engine = null; +78 try { +79 engine = initializeEngine(); +80 } catch (DatabaseException ex) { +81 if (getLog().isDebugEnabled()) { +82 getLog().debug("Database connection error", ex); +83 } +84 final String msg = "An exception occured connecting to the local database. Please see the log file for more details."; +85 if (this.isFailOnError()) { +86 throw new MojoExecutionException(msg, ex); +87 } +88 getLog().error(msg); +89 } +90 if (engine != null) { +91 scanArtifacts(getProject(), engine); +92 if (engine.getDependencies().isEmpty()) { +93 getLog().info("No dependencies were identified that could be analyzed by dependency-check"); +94 } else { +95 ExceptionCollection exCol = null; +96 try { +97 engine.analyzeDependencies(); +98 } catch (ExceptionCollection ex) { +99 if (this.isFailOnError() && ex.isFatal()) { +100 throw new MojoExecutionException("One or more exceptions occured during analysis", ex); +101 } +102 exCol = ex; +103 } +104 if (exCol == null || !exCol.isFatal()) { +105 try { +106 writeReports(engine, getProject(), getCorrectOutputDirectory()); +107 } catch (ReportException ex) { +108 if (this.isFailOnError()) { +109 if (exCol != null) { +110 exCol.addException(ex); +111 } else { +112 exCol = new ExceptionCollection("Unable to write the dependency-check report", ex); +113 } +114 } +115 } +116 writeDataFile(getProject(), null, engine.getDependencies()); +117 showSummary(getProject(), engine.getDependencies()); +118 checkForFailure(engine.getDependencies()); +119 if (exCol != null && this.isFailOnError()) { +120 throw new MojoExecutionException("One or more exceptions occured during dependency-check analysis", exCol); +121 } +122 } +123 } +124 engine.cleanup(); +125 } +126 Settings.cleanup(); +127 } +128 +129 /** +130 * The name of the report in the site. +131 */ +132 @SuppressWarnings("CanBeFinal") +133 @Parameter(property = "name", defaultValue = "dependency-check", required = true) +134 private String name = "dependency-check"; +135 +136 /** +137 * Returns the report name. +138 * +139 * @param locale the location +140 * @return the report name +141 */ +142 @Override +143 public String getName(Locale locale) { +144 return name; +145 } +146 +147 /** +148 * Gets the description of the Dependency-Check report to be displayed in +149 * the Maven Generated Reports page. +150 * +151 * @param locale The Locale to get the description for +152 * @return the description +153 */ +154 @Override +155 public String getDescription(Locale locale) { +156 return "Generates a report providing details on any published vulnerabilities within project dependencies. " +157 + "This report is a best effort and may contain false positives and false negatives."; +158 } +159 +160 }
        diff --git a/xref/org/owasp/dependencycheck/maven/MavenEngine.html b/xref/org/owasp/dependencycheck/maven/MavenEngine.html new file mode 100644 index 000000000..47a5d6b8b --- /dev/null +++ b/xref/org/owasp/dependencycheck/maven/MavenEngine.html @@ -0,0 +1,255 @@ + + + +MavenEngine xref + + + +
        +1   /*
        +2    * This file is part of dependency-check-maven.
        +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) 2014 Jeremy Long. All Rights Reserved.
        +17   */
        +18  package org.owasp.dependencycheck.maven;
        +19  
        +20  import java.util.List;
        +21  import org.apache.maven.project.MavenProject;
        +22  import org.owasp.dependencycheck.analyzer.Analyzer;
        +23  import org.owasp.dependencycheck.analyzer.CPEAnalyzer;
        +24  import org.owasp.dependencycheck.analyzer.FileTypeAnalyzer;
        +25  import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
        +26  import org.owasp.dependencycheck.data.update.exception.UpdateException;
        +27  import org.owasp.dependencycheck.exception.ExceptionCollection;
        +28  import org.owasp.dependencycheck.exception.InitializationException;
        +29  import org.owasp.dependencycheck.utils.Settings;
        +30  import org.slf4j.Logger;
        +31  import org.slf4j.LoggerFactory;
        +32  
        +33  /**
        +34   * A modified version of the core engine specifically designed to persist some
        +35   * data between multiple executions of a multi-module Maven project.
        +36   *
        +37   * @author Jeremy Long
        +38   */
        +39  public class MavenEngine extends org.owasp.dependencycheck.Engine {
        +40  
        +41      /**
        +42       * The logger.
        +43       */
        +44      private static final transient Logger LOGGER = LoggerFactory.getLogger(MavenEngine.class);
        +45      /**
        +46       * A key used to persist an object in the MavenProject.
        +47       */
        +48      private static final String CPE_ANALYZER_KEY = "dependency-check-CPEAnalyzer";
        +49      /**
        +50       * The current MavenProject.
        +51       */
        +52      private MavenProject currentProject;
        +53      /**
        +54       * The list of MavenProjects that are part of the current build.
        +55       */
        +56      private List<MavenProject> reactorProjects;
        +57      /**
        +58       * Key used in the MavenProject context values to note whether or not an
        +59       * update has been executed.
        +60       */
        +61      public static final String UPDATE_EXECUTED_FLAG = "dependency-check-update-executed";
        +62  
        +63      /**
        +64       * Creates a new Engine to perform analysis on dependencies.
        +65       *
        +66       * @param project the current Maven project
        +67       * @param reactorProjects the reactor projects for the current Maven
        +68       * execution
        +69       * @throws DatabaseException thrown if there is an issue connecting to the
        +70       * database
        +71       */
        +72      public MavenEngine(MavenProject project, List<MavenProject> reactorProjects) throws DatabaseException {
        +73          this.currentProject = project;
        +74          this.reactorProjects = reactorProjects;
        +75          initializeEngine();
        +76      }
        +77  
        +78      /**
        +79       * Runs the analyzers against all of the dependencies.
        +80       *
        +81       * @throws ExceptionCollection thrown if an exception occurred; contains a
        +82       * collection of exceptions that occurred during analysis.
        +83       */
        +84      @Override
        +85      public void analyzeDependencies() throws ExceptionCollection {
        +86          final MavenProject root = getExecutionRoot();
        +87          if (root != null) {
        +88              LOGGER.debug("Checking root project, {}, if updates have already been completed", root.getArtifactId());
        +89          } else {
        +90              LOGGER.debug("Checking root project, null, if updates have already been completed");
        +91          }
        +92          if (root != null && root.getContextValue(UPDATE_EXECUTED_FLAG) != null) {
        +93              System.setProperty(Settings.KEYS.AUTO_UPDATE, Boolean.FALSE.toString());
        +94          }
        +95          super.analyzeDependencies();
        +96          if (root != null) {
        +97              root.setContextValue(UPDATE_EXECUTED_FLAG, Boolean.TRUE);
        +98          }
        +99      }
        +100 
        +101     /**
        +102      * Runs the update steps of dependency-check.
        +103      *
        +104      * @throws UpdateException thrown if there is an exception
        +105      */
        +106     public void update() throws UpdateException {
        +107         final MavenProject root = getExecutionRoot();
        +108         if (root != null && root.getContextValue(UPDATE_EXECUTED_FLAG) != null) {
        +109             System.setProperty(Settings.KEYS.AUTO_UPDATE, Boolean.FALSE.toString());
        +110         }
        +111         this.doUpdates();
        +112     }
        +113 
        +114     /**
        +115      * This constructor should not be called. Use Engine(MavenProject) instead.
        +116      *
        +117      * @throws DatabaseException thrown if there is an issue connecting to the
        +118      * database
        +119      */
        +120     private MavenEngine() throws DatabaseException {
        +121     }
        +122 
        +123     /**
        +124      * Initializes the given analyzer. This skips the initialization of the
        +125      * CPEAnalyzer if it has been initialized by a previous execution.
        +126      *
        +127      * @param analyzer the analyzer to initialize
        +128      * @return the initialized analyzer
        +129      */
        +130     @Override
        +131     protected Analyzer initializeAnalyzer(Analyzer analyzer) throws InitializationException {
        +132         if (analyzer instanceof CPEAnalyzer) {
        +133             CPEAnalyzer cpe = getPreviouslyLoadedCPEAnalyzer();
        +134             if (cpe != null && cpe.isOpen()) {
        +135                 return cpe;
        +136             }
        +137             cpe = (CPEAnalyzer) super.initializeAnalyzer(analyzer);
        +138             storeCPEAnalyzer(cpe);
        +139         }
        +140         return super.initializeAnalyzer(analyzer);
        +141     }
        +142 
        +143     /**
        +144      * Releases resources used by the analyzers by calling close() on each
        +145      * analyzer.
        +146      */
        +147     @Override
        +148     public void cleanup() {
        +149         super.cleanup();
        +150         if (currentProject == null || reactorProjects == null) {
        +151             return;
        +152         }
        +153         if (this.currentProject == reactorProjects.get(reactorProjects.size() - 1)) {
        +154             final CPEAnalyzer cpe = getPreviouslyLoadedCPEAnalyzer();
        +155             if (cpe != null) {
        +156                 cpe.close();
        +157             }
        +158         }
        +159     }
        +160 
        +161     /**
        +162      * Closes the given analyzer. This skips closing the CPEAnalyzer.
        +163      *
        +164      * @param analyzer the analyzer to close
        +165      */
        +166     @Override
        +167     protected void closeAnalyzer(Analyzer analyzer) {
        +168         if (analyzer instanceof CPEAnalyzer) {
        +169             if (getPreviouslyLoadedCPEAnalyzer() == null) {
        +170                 super.closeAnalyzer(analyzer);
        +171             }
        +172         } else {
        +173             super.closeAnalyzer(analyzer);
        +174         }
        +175     }
        +176 
        +177     /**
        +178      * Gets the CPEAnalyzer from the root Maven Project.
        +179      *
        +180      * @return an initialized CPEAnalyzer
        +181      */
        +182     private CPEAnalyzer getPreviouslyLoadedCPEAnalyzer() {
        +183         CPEAnalyzer cpe = null;
        +184         final MavenProject project = getExecutionRoot();
        +185         if (project != null) {
        +186             final Object obj = project.getContextValue(CPE_ANALYZER_KEY);
        +187             if (obj != null && obj instanceof CPEAnalyzer) {
        +188                 cpe = (CPEAnalyzer) project.getContextValue(CPE_ANALYZER_KEY);
        +189             }
        +190         }
        +191         return cpe;
        +192     }
        +193 
        +194     /**
        +195      * Stores a CPEAnalyzer in the root Maven Project.
        +196      *
        +197      * @param cpe the CPEAnalyzer to store
        +198      */
        +199     private void storeCPEAnalyzer(CPEAnalyzer cpe) {
        +200         final MavenProject p = getExecutionRoot();
        +201         if (p != null) {
        +202             p.setContextValue(CPE_ANALYZER_KEY, cpe);
        +203         }
        +204     }
        +205 
        +206     /**
        +207      * Returns the root Maven Project.
        +208      *
        +209      * @return the root Maven Project
        +210      */
        +211     MavenProject getExecutionRoot() {
        +212         if (reactorProjects == null) {
        +213             return null;
        +214         }
        +215         for (MavenProject p : reactorProjects) {
        +216             if (p.isExecutionRoot()) {
        +217                 return p;
        +218             }
        +219         }
        +220         //the following should  never run, but leaving it as a failsafe.
        +221         if (this.currentProject == null) {
        +222             return null;
        +223         }
        +224         MavenProject p = this.currentProject;
        +225         while (p.getParent() != null) {
        +226             p = p.getParent();
        +227         }
        +228         return p;
        +229     }
        +230 
        +231     /**
        +232      * Resets the file type analyzers so that they can be re-used to scan
        +233      * additional directories. Without the reset the analyzer might be disabled
        +234      * because the first scan/analyze did not identify any files that could be
        +235      * processed by the analyzer.
        +236      */
        +237     public void resetFileTypeAnalyzers() {
        +238         for (FileTypeAnalyzer a : getFileTypeAnalyzers()) {
        +239             a.reset();
        +240         }
        +241     }
        +242 }
        +
        +
        + + + diff --git a/xref/org/owasp/dependencycheck/maven/PurgeMojo.html b/xref/org/owasp/dependencycheck/maven/PurgeMojo.html index e616e9898..dc27053db 100644 --- a/xref/org/owasp/dependencycheck/maven/PurgeMojo.html +++ b/xref/org/owasp/dependencycheck/maven/PurgeMojo.html @@ -62,58 +62,77 @@ 54 /** 55 * Purges the local copy of the NVD. 56 * -57 * @throws MojoExecutionException thrown if there is an exception executing the goal -58 * @throws MojoFailureException thrown if dependency-check is configured to fail the build -59 */ -60 @Override -61 public void runCheck() throws MojoExecutionException, MojoFailureException { -62 -63 if (getConnectionString() != null && !getConnectionString().isEmpty()) { -64 getLog().error("Unable to purge the local NVD when using a non-default connection string"); -65 } else { -66 populateSettings(); -67 File db; -68 try { -69 db = new File(Settings.getDataDirectory(), "dc.h2.db"); -70 if (db.exists()) { -71 if (db.delete()) { -72 getLog().info("Database file purged; local copy of the NVD has been removed"); -73 } else { -74 getLog().error(String.format("Unable to delete '%s'; please delete the file manually", db.getAbsolutePath())); -75 } -76 } else { -77 getLog().error(String.format("Unable to purge database; the database file does not exists: %s", db.getAbsolutePath())); -78 } -79 } catch (IOException ex) { -80 getLog().error("Unable to delete the database"); -81 } -82 Settings.cleanup(); -83 } -84 } -85 -86 /** -87 * Returns the report name. -88 * -89 * @param locale the location -90 * @return the report name -91 */ -92 @Override -93 public String getName(Locale locale) { -94 return "dependency-check-purge"; -95 } -96 -97 /** -98 * Gets the description of the Dependency-Check report to be displayed in the Maven Generated Reports page. -99 * -100 * @param locale The Locale to get the description for -101 * @return the description -102 */ -103 @Override -104 public String getDescription(Locale locale) { -105 return "Purges the local cache of the NVD dataT."; -106 } -107 -108 } +57 * @throws MojoExecutionException thrown if there is an exception executing +58 * the goal +59 * @throws MojoFailureException thrown if dependency-check is configured to +60 * fail the build +61 */ +62 @Override +63 public void runCheck() throws MojoExecutionException, MojoFailureException { +64 +65 if (getConnectionString() != null && !getConnectionString().isEmpty()) { +66 final String msg = "Unable to purge the local NVD when using a non-default connection string"; +67 if (this.isFailOnError()) { +68 throw new MojoFailureException(msg); +69 } +70 getLog().error(msg); +71 } else { +72 populateSettings(); +73 File db; +74 try { +75 db = new File(Settings.getDataDirectory(), "dc.h2.db"); +76 if (db.exists()) { +77 if (db.delete()) { +78 getLog().info("Database file purged; local copy of the NVD has been removed"); +79 } else { +80 final String msg = String.format("Unable to delete '%s'; please delete the file manually", db.getAbsolutePath()); +81 if (this.isFailOnError()) { +82 throw new MojoFailureException(msg); +83 } +84 getLog().error(msg); +85 } +86 } else { +87 final String msg = String.format("Unable to purge database; the database file does not exists: %s", db.getAbsolutePath()); +88 if (this.isFailOnError()) { +89 throw new MojoFailureException(msg); +90 } +91 getLog().error(msg); +92 } +93 } catch (IOException ex) { +94 final String msg = "Unable to delete the database"; +95 if (this.isFailOnError()) { +96 throw new MojoExecutionException(msg, ex); +97 } +98 getLog().error(msg); +99 } +100 Settings.cleanup(); +101 } +102 } +103 +104 /** +105 * Returns the report name. +106 * +107 * @param locale the location +108 * @return the report name +109 */ +110 @Override +111 public String getName(Locale locale) { +112 return "dependency-check-purge"; +113 } +114 +115 /** +116 * Gets the description of the Dependency-Check report to be displayed in +117 * the Maven Generated Reports page. +118 * +119 * @param locale The Locale to get the description for +120 * @return the description +121 */ +122 @Override +123 public String getDescription(Locale locale) { +124 return "Purges the local cache of the NVD dataT."; +125 } +126 +127 }
        diff --git a/xref/org/owasp/dependencycheck/maven/UpdateMojo.html b/xref/org/owasp/dependencycheck/maven/UpdateMojo.html index 3ab5b82dd..1bb793f02 100644 --- a/xref/org/owasp/dependencycheck/maven/UpdateMojo.html +++ b/xref/org/owasp/dependencycheck/maven/UpdateMojo.html @@ -32,77 +32,94 @@ 24 import org.apache.maven.plugins.annotations.Mojo; 25 import org.apache.maven.plugins.annotations.ResolutionScope; 26 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; -27 import org.owasp.dependencycheck.utils.Settings; -28 -29 /** -30 * Maven Plugin that checks the project dependencies to see if they have any known published vulnerabilities. -31 * -32 * @author Jeremy Long -33 */ -34 @Mojo( -35 name = "update-only", -36 defaultPhase = LifecyclePhase.GENERATE_RESOURCES, -37 threadSafe = false, -38 requiresDependencyResolution = ResolutionScope.NONE, -39 requiresOnline = true -40 ) -41 public class UpdateMojo extends BaseDependencyCheckMojo { -42 -43 /** -44 * Returns false; this mojo cannot generate a report. -45 * -46 * @return <code>false</code> -47 */ -48 @Override -49 public boolean canGenerateReport() { -50 return false; -51 } -52 -53 /** -54 * Executes the dependency-check engine on the project's dependencies and generates the report. -55 * -56 * @throws MojoExecutionException thrown if there is an exception executing the goal -57 * @throws MojoFailureException thrown if dependency-check is configured to fail the build -58 */ -59 @Override -60 public void runCheck() throws MojoExecutionException, MojoFailureException { -61 final Engine engine; -62 try { -63 engine = initializeEngine(); -64 engine.update(); -65 } catch (DatabaseException ex) { -66 if (getLog().isDebugEnabled()) { -67 getLog().debug("Database connection error", ex); -68 } -69 throw new MojoExecutionException("An exception occured connecting to the local database. Please see the log file for more details.", ex); -70 } -71 engine.cleanup(); -72 Settings.cleanup(); -73 } -74 -75 /** -76 * Returns the report name. -77 * -78 * @param locale the location -79 * @return the report name -80 */ -81 @Override -82 public String getName(Locale locale) { -83 return "dependency-check-update"; -84 } -85 -86 /** -87 * Gets the description of the Dependency-Check report to be displayed in the Maven Generated Reports page. -88 * -89 * @param locale The Locale to get the description for -90 * @return the description -91 */ -92 @Override -93 public String getDescription(Locale locale) { -94 return "Updates the local cache of the NVD data from NIST."; -95 } -96 -97 } +27 import org.owasp.dependencycheck.data.update.exception.UpdateException; +28 import org.owasp.dependencycheck.utils.Settings; +29 +30 /** +31 * Maven Plugin that checks the project dependencies to see if they have any +32 * known published vulnerabilities. +33 * +34 * @author Jeremy Long +35 */ +36 @Mojo( +37 name = "update-only", +38 defaultPhase = LifecyclePhase.GENERATE_RESOURCES, +39 threadSafe = false, +40 requiresDependencyResolution = ResolutionScope.NONE, +41 requiresOnline = true +42 ) +43 public class UpdateMojo extends BaseDependencyCheckMojo { +44 +45 /** +46 * Returns false; this mojo cannot generate a report. +47 * +48 * @return <code>false</code> +49 */ +50 @Override +51 public boolean canGenerateReport() { +52 return false; +53 } +54 +55 /** +56 * Executes the dependency-check engine on the project's dependencies and +57 * generates the report. +58 * +59 * @throws MojoExecutionException thrown if there is an exception executing +60 * the goal +61 * @throws MojoFailureException thrown if dependency-check is configured to +62 * fail the build +63 */ +64 @Override +65 public void runCheck() throws MojoExecutionException, MojoFailureException { +66 MavenEngine engine = null; +67 try { +68 engine = initializeEngine(); +69 engine.update(); +70 } catch (DatabaseException ex) { +71 if (getLog().isDebugEnabled()) { +72 getLog().debug("Database connection error", ex); +73 } +74 final String msg = "An exception occured connecting to the local database. Please see the log file for more details."; +75 if (this.isFailOnError()) { +76 throw new MojoExecutionException(msg, ex); +77 } +78 getLog().error(msg); +79 } catch (UpdateException ex) { +80 final String msg = "An exception occured while downloading updates. Please see the log file for more details."; +81 if (this.isFailOnError()) { +82 throw new MojoExecutionException(msg, ex); +83 } +84 getLog().error(msg); +85 } +86 if (engine != null) { +87 engine.cleanup(); +88 } +89 Settings.cleanup(); +90 } +91 +92 /** +93 * Returns the report name. +94 * +95 * @param locale the location +96 * @return the report name +97 */ +98 @Override +99 public String getName(Locale locale) { +100 return "dependency-check-update"; +101 } +102 +103 /** +104 * Gets the description of the Dependency-Check report to be displayed in +105 * the Maven Generated Reports page. +106 * +107 * @param locale The Locale to get the description for +108 * @return the description +109 */ +110 @Override +111 public String getDescription(Locale locale) { +112 return "Updates the local cache of the NVD data from NIST."; +113 } +114 }
        diff --git a/xref/org/owasp/dependencycheck/maven/package-frame.html b/xref/org/owasp/dependencycheck/maven/package-frame.html index 65d71d367..cd2155977 100644 --- a/xref/org/owasp/dependencycheck/maven/package-frame.html +++ b/xref/org/owasp/dependencycheck/maven/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.maven + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.maven @@ -25,7 +25,7 @@ CheckMojo
      • - Engine + MavenEngine
      • PurgeMojo diff --git a/xref/org/owasp/dependencycheck/maven/package-summary.html b/xref/org/owasp/dependencycheck/maven/package-summary.html index 4f8be274f..5705d0756 100644 --- a/xref/org/owasp/dependencycheck/maven/package-summary.html +++ b/xref/org/owasp/dependencycheck/maven/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.maven + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.maven @@ -52,7 +52,7 @@ - Engine + MavenEngine diff --git a/xref/org/owasp/dependencycheck/maven/slf4j/package-frame.html b/xref/org/owasp/dependencycheck/maven/slf4j/package-frame.html index f1f621aea..ed4603c8a 100644 --- a/xref/org/owasp/dependencycheck/maven/slf4j/package-frame.html +++ b/xref/org/owasp/dependencycheck/maven/slf4j/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.maven.slf4j + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.maven.slf4j diff --git a/xref/org/owasp/dependencycheck/maven/slf4j/package-summary.html b/xref/org/owasp/dependencycheck/maven/slf4j/package-summary.html index f3f081922..db02684a9 100644 --- a/xref/org/owasp/dependencycheck/maven/slf4j/package-summary.html +++ b/xref/org/owasp/dependencycheck/maven/slf4j/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.maven.slf4j + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.maven.slf4j diff --git a/xref/org/owasp/dependencycheck/package-frame.html b/xref/org/owasp/dependencycheck/package-frame.html index 8b7202d7d..3efd2f233 100644 --- a/xref/org/owasp/dependencycheck/package-frame.html +++ b/xref/org/owasp/dependencycheck/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck diff --git a/xref/org/owasp/dependencycheck/package-summary.html b/xref/org/owasp/dependencycheck/package-summary.html index d591d92c8..19284ef74 100644 --- a/xref/org/owasp/dependencycheck/package-summary.html +++ b/xref/org/owasp/dependencycheck/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck diff --git a/xref/org/owasp/dependencycheck/reporting/ReportGenerator.html b/xref/org/owasp/dependencycheck/reporting/ReportGenerator.html index c6e732a21..0f596023d 100644 --- a/xref/org/owasp/dependencycheck/reporting/ReportGenerator.html +++ b/xref/org/owasp/dependencycheck/reporting/ReportGenerator.html @@ -34,296 +34,308 @@ 26 import java.io.InputStreamReader; 27 import java.io.OutputStream; 28 import java.io.OutputStreamWriter; -29 import java.text.DateFormat; -30 import java.text.SimpleDateFormat; -31 import java.util.Date; -32 import java.util.List; -33 import org.apache.velocity.VelocityContext; -34 import org.apache.velocity.app.VelocityEngine; -35 import org.apache.velocity.context.Context; -36 import org.apache.velocity.runtime.RuntimeConstants; -37 import org.owasp.dependencycheck.analyzer.Analyzer; -38 import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties; -39 import org.owasp.dependencycheck.dependency.Dependency; -40 import org.owasp.dependencycheck.utils.Settings; -41 import org.slf4j.Logger; -42 import org.slf4j.LoggerFactory; -43 -44 /** -45 * The ReportGenerator is used to, as the name implies, generate reports. Internally the generator uses the Velocity -46 * Templating Engine. The ReportGenerator exposes a list of Dependencies to the template when generating the report. -47 * -48 * @author Jeremy Long -49 */ -50 public class ReportGenerator { -51 -52 /** -53 * The logger. -54 */ -55 private static final Logger LOGGER = LoggerFactory.getLogger(ReportGenerator.class); -56 -57 /** -58 * An enumeration of the report formats. -59 */ -60 public enum Format { -61 -62 /** -63 * Generate all reports. -64 */ -65 ALL, +29 import java.io.UnsupportedEncodingException; +30 import java.text.DateFormat; +31 import java.text.SimpleDateFormat; +32 import java.util.Date; +33 import java.util.List; +34 import org.apache.velocity.VelocityContext; +35 import org.apache.velocity.app.VelocityEngine; +36 import org.apache.velocity.context.Context; +37 import org.apache.velocity.runtime.RuntimeConstants; +38 import org.owasp.dependencycheck.analyzer.Analyzer; +39 import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties; +40 import org.owasp.dependencycheck.dependency.Dependency; +41 import org.owasp.dependencycheck.exception.ReportException; +42 import org.owasp.dependencycheck.utils.Settings; +43 import org.slf4j.Logger; +44 import org.slf4j.LoggerFactory; +45 +46 /** +47 * The ReportGenerator is used to, as the name implies, generate reports. +48 * Internally the generator uses the Velocity Templating Engine. The +49 * ReportGenerator exposes a list of Dependencies to the template when +50 * generating the report. +51 * +52 * @author Jeremy Long +53 */ +54 public class ReportGenerator { +55 +56 /** +57 * The logger. +58 */ +59 private static final Logger LOGGER = LoggerFactory.getLogger(ReportGenerator.class); +60 +61 /** +62 * An enumeration of the report formats. +63 */ +64 public enum Format { +65 66 /** -67 * Generate XML report. +67 * Generate all reports. 68 */ -69 XML, +69 ALL, 70 /** -71 * Generate HTML report. +71 * Generate XML report. 72 */ -73 HTML, +73 XML, 74 /** -75 * Generate HTML Vulnerability report. +75 * Generate HTML report. 76 */ -77 VULN -78 } -79 /** -80 * The Velocity Engine. -81 */ -82 private final VelocityEngine engine; +77 HTML, +78 /** +79 * Generate HTML Vulnerability report. +80 */ +81 VULN +82 } 83 /** -84 * The Velocity Engine Context. +84 * The Velocity Engine. 85 */ -86 private final Context context; -87 -88 /** -89 * Constructs a new ReportGenerator. -90 * -91 * @param applicationName the application name being analyzed -92 * @param dependencies the list of dependencies -93 * @param analyzers the list of analyzers used -94 * @param properties the database properties (containing timestamps of the NVD CVE data) -95 */ -96 public ReportGenerator(String applicationName, List<Dependency> dependencies, List<Analyzer> analyzers, DatabaseProperties properties) { -97 engine = createVelocityEngine(); -98 context = createContext(); -99 -100 engine.init(); -101 -102 final DateFormat dateFormat = new SimpleDateFormat("MMM d, yyyy 'at' HH:mm:ss z"); -103 final DateFormat dateFormatXML = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); -104 final Date d = new Date(); -105 final String scanDate = dateFormat.format(d); -106 final String scanDateXML = dateFormatXML.format(d); -107 final EscapeTool enc = new EscapeTool(); -108 -109 context.put("applicationName", applicationName); -110 context.put("dependencies", dependencies); -111 context.put("analyzers", analyzers); -112 context.put("properties", properties); -113 context.put("scanDate", scanDate); -114 context.put("scanDateXML", scanDateXML); -115 context.put("enc", enc); -116 context.put("version", Settings.getString(Settings.KEYS.APPLICATION_VERSION, "Unknown")); -117 } -118 -119 /** -120 * Creates a new Velocity Engine. -121 * -122 * @return a velocity engine. -123 */ -124 private VelocityEngine createVelocityEngine() { -125 final VelocityEngine engine = new VelocityEngine(); -126 // Logging redirection for Velocity - Required by Jenkins and other server applications -127 engine.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, VelocityLoggerRedirect.class.getName()); -128 return engine; -129 } -130 -131 /** -132 * Creates a new Velocity Context. -133 * -134 * @return a Velocity Context. -135 */ -136 private Context createContext() { -137 return new VelocityContext(); -138 } -139 -140 /** -141 * Generates the Dependency Reports for the identified dependencies. -142 * -143 * @param outputStream the OutputStream to send the generated report to -144 * @param format the format the report should be written in -145 * @throws IOException is thrown when the template file does not exist -146 * @throws Exception is thrown if there is an error writing out the reports. -147 */ -148 public void generateReports(OutputStream outputStream, Format format) throws IOException, Exception { -149 if (format == Format.XML || format == Format.ALL) { -150 generateReport("XmlReport", outputStream); -151 } -152 if (format == Format.HTML || format == Format.ALL) { -153 generateReport("HtmlReport", outputStream); -154 } -155 if (format == Format.VULN || format == Format.ALL) { -156 generateReport("VulnerabilityReport", outputStream); -157 } -158 } -159 -160 /** -161 * Generates the Dependency Reports for the identified dependencies. -162 * -163 * @param outputDir the path where the reports should be written -164 * @param format the format the report should be written in -165 * @throws IOException is thrown when the template file does not exist -166 * @throws Exception is thrown if there is an error writing out the reports. -167 */ -168 public void generateReports(String outputDir, Format format) throws IOException, Exception { -169 if (format == Format.XML || format == Format.ALL) { -170 generateReport("XmlReport", outputDir + File.separator + "dependency-check-report.xml"); -171 } -172 if (format == Format.HTML || format == Format.ALL) { -173 generateReport("HtmlReport", outputDir + File.separator + "dependency-check-report.html"); -174 } -175 if (format == Format.VULN || format == Format.ALL) { -176 generateReport("VulnerabilityReport", outputDir + File.separator + "dependency-check-vulnerability.html"); -177 } -178 } -179 -180 /** -181 * Generates the Dependency Reports for the identified dependencies. -182 * -183 * @param outputDir the path where the reports should be written -184 * @param outputFormat the format the report should be written in (XML, HTML, ALL) -185 * @throws IOException is thrown when the template file does not exist -186 * @throws Exception is thrown if there is an error writing out the reports. -187 */ -188 public void generateReports(String outputDir, String outputFormat) throws IOException, Exception { -189 final String format = outputFormat.toUpperCase(); -190 final String pathToCheck = outputDir.toLowerCase(); -191 if (format.matches("^(XML|HTML|VULN|ALL)$")) { -192 if ("XML".equalsIgnoreCase(format)) { -193 if (pathToCheck.endsWith(".xml")) { -194 generateReport("XmlReport", outputDir); -195 } else { -196 generateReports(outputDir, Format.XML); -197 } -198 } -199 if ("HTML".equalsIgnoreCase(format)) { -200 if (pathToCheck.endsWith(".html") || pathToCheck.endsWith(".htm")) { -201 generateReport("HtmlReport", outputDir); -202 } else { -203 generateReports(outputDir, Format.HTML); -204 } -205 } -206 if ("VULN".equalsIgnoreCase(format)) { -207 if (pathToCheck.endsWith(".html") || pathToCheck.endsWith(".htm")) { -208 generateReport("VulnReport", outputDir); -209 } else { -210 generateReports(outputDir, Format.VULN); -211 } -212 } -213 if ("ALL".equalsIgnoreCase(format)) { -214 generateReports(outputDir, Format.ALL); -215 } -216 } -217 } -218 -219 /** -220 * Generates a report from a given Velocity Template. The template name provided can be the name of a template -221 * contained in the jar file, such as 'XmlReport' or 'HtmlReport', or the template name can be the path to a -222 * template file. -223 * -224 * @param templateName the name of the template to load. -225 * @param outputStream the OutputStream to write the report to. -226 * @throws IOException is thrown when the template file does not exist. -227 * @throws Exception is thrown when an exception occurs. -228 */ -229 protected void generateReport(String templateName, OutputStream outputStream) throws IOException, Exception { -230 InputStream input = null; -231 String templatePath = null; -232 final File f = new File(templateName); -233 if (f.exists() && f.isFile()) { -234 try { -235 templatePath = templateName; -236 input = new FileInputStream(f); -237 } catch (FileNotFoundException ex) { -238 LOGGER.error("Unable to generate the report, the report template file could not be found."); -239 LOGGER.debug("", ex); -240 } -241 } else { -242 templatePath = "templates/" + templateName + ".vsl"; -243 input = this.getClass().getClassLoader().getResourceAsStream(templatePath); -244 } -245 if (input == null) { -246 throw new IOException("Template file doesn't exist"); -247 } -248 -249 final InputStreamReader reader = new InputStreamReader(input, "UTF-8"); -250 OutputStreamWriter writer = null; -251 -252 try { -253 writer = new OutputStreamWriter(outputStream, "UTF-8"); -254 -255 if (!engine.evaluate(context, writer, templatePath, reader)) { -256 throw new Exception("Failed to convert the template into html."); -257 } -258 writer.flush(); -259 } finally { -260 if (writer != null) { -261 try { -262 writer.close(); -263 } catch (IOException ex) { -264 LOGGER.trace("", ex); -265 } -266 } -267 if (outputStream != null) { -268 try { -269 outputStream.close(); -270 } catch (IOException ex) { -271 LOGGER.trace("", ex); -272 } -273 } -274 try { -275 reader.close(); -276 } catch (IOException ex) { -277 LOGGER.trace("", ex); -278 } -279 } -280 } -281 -282 /** -283 * Generates a report from a given Velocity Template. The template name provided can be the name of a template -284 * contained in the jar file, such as 'XmlReport' or 'HtmlReport', or the template name can be the path to a -285 * template file. -286 * -287 * @param templateName the name of the template to load. -288 * @param outFileName the filename and path to write the report to. -289 * @throws IOException is thrown when the template file does not exist. -290 * @throws Exception is thrown when an exception occurs. -291 */ -292 protected void generateReport(String templateName, String outFileName) throws Exception { -293 File outFile = new File(outFileName); -294 if (outFile.getParentFile() == null) { -295 outFile = new File(".", outFileName); -296 } -297 if (!outFile.getParentFile().exists()) { -298 final boolean created = outFile.getParentFile().mkdirs(); -299 if (!created) { -300 throw new Exception("Unable to create directory '" + outFile.getParentFile().getAbsolutePath() + "'."); -301 } -302 } -303 -304 OutputStream outputSteam = null; -305 try { -306 outputSteam = new FileOutputStream(outFile); -307 generateReport(templateName, outputSteam); -308 } finally { -309 if (outputSteam != null) { -310 try { -311 outputSteam.close(); -312 } catch (IOException ex) { -313 LOGGER.trace("ignore", ex); -314 } -315 } -316 } -317 } -318 } +86 private final VelocityEngine velocityEngine; +87 /** +88 * The Velocity Engine Context. +89 */ +90 private final Context context; +91 +92 /** +93 * Constructs a new ReportGenerator. +94 * +95 * @param applicationName the application name being analyzed +96 * @param dependencies the list of dependencies +97 * @param analyzers the list of analyzers used +98 * @param properties the database properties (containing timestamps of the +99 * NVD CVE data) +100 */ +101 public ReportGenerator(String applicationName, List<Dependency> dependencies, List<Analyzer> analyzers, DatabaseProperties properties) { +102 velocityEngine = createVelocityEngine(); +103 context = createContext(); +104 +105 velocityEngine.init(); +106 +107 final DateFormat dateFormat = new SimpleDateFormat("MMM d, yyyy 'at' HH:mm:ss z"); +108 final DateFormat dateFormatXML = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); +109 final Date d = new Date(); +110 final String scanDate = dateFormat.format(d); +111 final String scanDateXML = dateFormatXML.format(d); +112 final EscapeTool enc = new EscapeTool(); +113 +114 context.put("applicationName", applicationName); +115 context.put("dependencies", dependencies); +116 context.put("analyzers", analyzers); +117 context.put("properties", properties); +118 context.put("scanDate", scanDate); +119 context.put("scanDateXML", scanDateXML); +120 context.put("enc", enc); +121 context.put("version", Settings.getString(Settings.KEYS.APPLICATION_VERSION, "Unknown")); +122 } +123 +124 /** +125 * Creates a new Velocity Engine. +126 * +127 * @return a velocity engine +128 */ +129 private VelocityEngine createVelocityEngine() { +130 final VelocityEngine velocity = new VelocityEngine(); +131 // Logging redirection for Velocity - Required by Jenkins and other server applications +132 velocity.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, VelocityLoggerRedirect.class.getName()); +133 return velocity; +134 } +135 +136 /** +137 * Creates a new Velocity Context. +138 * +139 * @return a Velocity Context +140 */ +141 private Context createContext() { +142 return new VelocityContext(); +143 } +144 +145 /** +146 * Generates the Dependency Reports for the identified dependencies. +147 * +148 * @param outputStream the OutputStream to send the generated report to +149 * @param format the format the report should be written in +150 * @throws IOException is thrown when the template file does not exist +151 * @throws Exception is thrown if there is an error writing out the reports +152 */ +153 public void generateReports(OutputStream outputStream, Format format) throws IOException, Exception { +154 if (format == Format.XML || format == Format.ALL) { +155 generateReport("XmlReport", outputStream); +156 } +157 if (format == Format.HTML || format == Format.ALL) { +158 generateReport("HtmlReport", outputStream); +159 } +160 if (format == Format.VULN || format == Format.ALL) { +161 generateReport("VulnerabilityReport", outputStream); +162 } +163 } +164 +165 /** +166 * Generates the Dependency Reports for the identified dependencies. +167 * +168 * @param outputDir the path where the reports should be written +169 * @param format the format the report should be written in +170 * @throws ReportException is thrown if there is an error writing out the reports +171 */ +172 public void generateReports(String outputDir, Format format) throws ReportException { +173 if (format == Format.XML || format == Format.ALL) { +174 generateReport("XmlReport", outputDir + File.separator + "dependency-check-report.xml"); +175 } +176 if (format == Format.HTML || format == Format.ALL) { +177 generateReport("HtmlReport", outputDir + File.separator + "dependency-check-report.html"); +178 } +179 if (format == Format.VULN || format == Format.ALL) { +180 generateReport("VulnerabilityReport", outputDir + File.separator + "dependency-check-vulnerability.html"); +181 } +182 } +183 +184 /** +185 * Generates the Dependency Reports for the identified dependencies. +186 * +187 * @param outputDir the path where the reports should be written +188 * @param outputFormat the format the report should be written in (XML, +189 * HTML, ALL) +190 * @throws ReportException is thrown if there is an error creating out the +191 * reports +192 */ +193 public void generateReports(String outputDir, String outputFormat) throws ReportException { +194 final String format = outputFormat.toUpperCase(); +195 final String pathToCheck = outputDir.toLowerCase(); +196 if (format.matches("^(XML|HTML|VULN|ALL)$")) { +197 if ("XML".equalsIgnoreCase(format)) { +198 if (pathToCheck.endsWith(".xml")) { +199 generateReport("XmlReport", outputDir); +200 } else { +201 generateReports(outputDir, Format.XML); +202 } +203 } +204 if ("HTML".equalsIgnoreCase(format)) { +205 if (pathToCheck.endsWith(".html") || pathToCheck.endsWith(".htm")) { +206 generateReport("HtmlReport", outputDir); +207 } else { +208 generateReports(outputDir, Format.HTML); +209 } +210 } +211 if ("VULN".equalsIgnoreCase(format)) { +212 if (pathToCheck.endsWith(".html") || pathToCheck.endsWith(".htm")) { +213 generateReport("VulnReport", outputDir); +214 } else { +215 generateReports(outputDir, Format.VULN); +216 } +217 } +218 if ("ALL".equalsIgnoreCase(format)) { +219 generateReports(outputDir, Format.ALL); +220 } +221 } +222 } +223 +224 /** +225 * Generates a report from a given Velocity Template. The template name +226 * provided can be the name of a template contained in the jar file, such as +227 * 'XmlReport' or 'HtmlReport', or the template name can be the path to a +228 * template file. +229 * +230 * @param templateName the name of the template to load +231 * @param outputStream the OutputStream to write the report to +232 * @throws ReportException is thrown when an exception occurs +233 */ +234 protected void generateReport(String templateName, OutputStream outputStream) throws ReportException { +235 InputStream input = null; +236 String templatePath = null; +237 final File f = new File(templateName); +238 if (f.exists() && f.isFile()) { +239 try { +240 templatePath = templateName; +241 input = new FileInputStream(f); +242 } catch (FileNotFoundException ex) { +243 throw new ReportException("Unable to locate template file: " + templateName, ex); +244 } +245 } else { +246 templatePath = "templates/" + templateName + ".vsl"; +247 input = this.getClass().getClassLoader().getResourceAsStream(templatePath); +248 } +249 if (input == null) { +250 throw new ReportException("Template file doesn't exist: " + templatePath); +251 } +252 +253 InputStreamReader reader = null; +254 OutputStreamWriter writer = null; +255 +256 try { +257 reader = new InputStreamReader(input, "UTF-8"); +258 writer = new OutputStreamWriter(outputStream, "UTF-8"); +259 if (!velocityEngine.evaluate(context, writer, templatePath, reader)) { +260 throw new ReportException("Failed to convert the template into html."); +261 } +262 writer.flush(); +263 } catch (UnsupportedEncodingException ex) { +264 throw new ReportException("Unable to generate the report using UTF-8", ex); +265 } catch (IOException ex) { +266 throw new ReportException("Unable to write the report", ex); +267 } finally { +268 if (writer != null) { +269 try { +270 writer.close(); +271 } catch (IOException ex) { +272 LOGGER.trace("", ex); +273 } +274 } +275 if (outputStream != null) { +276 try { +277 outputStream.close(); +278 } catch (IOException ex) { +279 LOGGER.trace("", ex); +280 } +281 } +282 if (reader != null) { +283 try { +284 reader.close(); +285 } catch (IOException ex) { +286 LOGGER.trace("", ex); +287 } +288 } +289 } +290 } +291 +292 /** +293 * Generates a report from a given Velocity Template. The template name +294 * provided can be the name of a template contained in the jar file, such as +295 * 'XmlReport' or 'HtmlReport', or the template name can be the path to a +296 * template file. +297 * +298 * @param templateName the name of the template to load +299 * @param outFileName the filename and path to write the report to +300 * @throws ReportException is thrown when the report cannot be generated +301 */ +302 protected void generateReport(String templateName, String outFileName) throws ReportException { +303 File outFile = new File(outFileName); +304 if (outFile.getParentFile() == null) { +305 outFile = new File(".", outFileName); +306 } +307 if (!outFile.getParentFile().exists()) { +308 final boolean created = outFile.getParentFile().mkdirs(); +309 if (!created) { +310 throw new ReportException("Unable to create directory '" + outFile.getParentFile().getAbsolutePath() + "'."); +311 } +312 } +313 +314 OutputStream outputSteam = null; +315 try { +316 outputSteam = new FileOutputStream(outFile); +317 generateReport(templateName, outputSteam); +318 } catch (FileNotFoundException ex) { +319 throw new ReportException("Unable to write to file: " + outFile, ex); +320 } finally { +321 if (outputSteam != null) { +322 try { +323 outputSteam.close(); +324 } catch (IOException ex) { +325 LOGGER.trace("ignore", ex); +326 } +327 } +328 } +329 } +330 }
        diff --git a/xref/org/owasp/dependencycheck/reporting/package-frame.html b/xref/org/owasp/dependencycheck/reporting/package-frame.html index 68e26ec0a..f0c8b99b2 100644 --- a/xref/org/owasp/dependencycheck/reporting/package-frame.html +++ b/xref/org/owasp/dependencycheck/reporting/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.reporting + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.reporting diff --git a/xref/org/owasp/dependencycheck/reporting/package-summary.html b/xref/org/owasp/dependencycheck/reporting/package-summary.html index 5705948b1..7b6ff33b8 100644 --- a/xref/org/owasp/dependencycheck/reporting/package-summary.html +++ b/xref/org/owasp/dependencycheck/reporting/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.reporting + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.reporting diff --git a/xref/org/owasp/dependencycheck/taskdefs/Check.html b/xref/org/owasp/dependencycheck/taskdefs/Check.html index fabfdab3a..806c8cc4b 100644 --- a/xref/org/owasp/dependencycheck/taskdefs/Check.html +++ b/xref/org/owasp/dependencycheck/taskdefs/Check.html @@ -26,989 +26,1006 @@ 18 package org.owasp.dependencycheck.taskdefs; 19 20 import java.io.File; -21 import java.io.IOException; -22 import java.util.List; -23 import org.apache.tools.ant.BuildException; -24 import org.apache.tools.ant.Project; -25 import org.apache.tools.ant.types.EnumeratedAttribute; -26 import org.apache.tools.ant.types.Reference; -27 import org.apache.tools.ant.types.Resource; -28 import org.apache.tools.ant.types.ResourceCollection; -29 import org.apache.tools.ant.types.resources.FileProvider; -30 import org.apache.tools.ant.types.resources.Resources; -31 import org.owasp.dependencycheck.Engine; -32 import org.owasp.dependencycheck.data.nvdcve.CveDB; -33 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; -34 import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties; +21 import java.util.List; +22 import org.apache.tools.ant.BuildException; +23 import org.apache.tools.ant.Project; +24 import org.apache.tools.ant.types.EnumeratedAttribute; +25 import org.apache.tools.ant.types.Reference; +26 import org.apache.tools.ant.types.Resource; +27 import org.apache.tools.ant.types.ResourceCollection; +28 import org.apache.tools.ant.types.resources.FileProvider; +29 import org.apache.tools.ant.types.resources.Resources; +30 import org.owasp.dependencycheck.Engine; +31 import org.owasp.dependencycheck.data.nvdcve.CveDB; +32 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; +33 import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties; +34 import org.owasp.dependencycheck.data.update.exception.UpdateException; 35 import org.owasp.dependencycheck.dependency.Dependency; 36 import org.owasp.dependencycheck.dependency.Identifier; 37 import org.owasp.dependencycheck.dependency.Vulnerability; -38 import org.owasp.dependencycheck.reporting.ReportGenerator; -39 import org.owasp.dependencycheck.reporting.ReportGenerator.Format; -40 import org.owasp.dependencycheck.utils.Settings; -41 import org.slf4j.impl.StaticLoggerBinder; -42 -43 /** -44 * An Ant task definition to execute dependency-check during an Ant build. -45 * -46 * @author Jeremy Long -47 */ -48 public class Check extends Update { -49 -50 /** -51 * System specific new line character. -52 */ -53 private static final String NEW_LINE = System.getProperty("line.separator", "\n").intern(); -54 -55 /** -56 * Construct a new DependencyCheckTask. -57 */ -58 public Check() { -59 super(); -60 // Call this before Dependency Check Core starts logging anything - this way, all SLF4J messages from -61 // core end up coming through this tasks logger -62 StaticLoggerBinder.getSingleton().setTask(this); -63 } -64 //The following code was copied Apache Ant PathConvert -65 //BEGIN COPY from org.apache.tools.ant.taskdefs.PathConvert -66 /** -67 * Path to be converted -68 */ -69 private Resources path = null; -70 /** -71 * Reference to path/fileset to convert -72 */ -73 private Reference refid = null; -74 -75 /** -76 * Add an arbitrary ResourceCollection. -77 * -78 * @param rc the ResourceCollection to add. -79 * @since Ant 1.7 -80 */ -81 public void add(ResourceCollection rc) { -82 if (isReference()) { -83 throw new BuildException("Nested elements are not allowed when using the refid attribute."); -84 } -85 getPath().add(rc); -86 } -87 -88 /** -89 * Returns the path. If the path has not been initialized yet, this class is -90 * synchronized, and will instantiate the path object. -91 * -92 * @return the path -93 */ -94 private synchronized Resources getPath() { -95 if (path == null) { -96 path = new Resources(getProject()); -97 path.setCache(true); -98 } -99 return path; -100 } -101 -102 /** -103 * Learn whether the refid attribute of this element been set. -104 * -105 * @return true if refid is valid. -106 */ -107 public boolean isReference() { -108 return refid != null; -109 } -110 -111 /** -112 * Add a reference to a Path, FileSet, DirSet, or FileList defined -113 * elsewhere. -114 * -115 * @param r the reference to a path, fileset, dirset or filelist. -116 */ -117 public void setRefid(Reference r) { -118 if (path != null) { -119 throw new BuildException("Nested elements are not allowed when using the refid attribute."); -120 } -121 refid = r; -122 } -123 -124 /** -125 * If this is a reference, this method will add the referenced resource -126 * collection to the collection of paths. -127 * -128 * @throws BuildException if the reference is not to a resource collection -129 */ -130 private void dealWithReferences() throws BuildException { -131 if (isReference()) { -132 final Object o = refid.getReferencedObject(getProject()); -133 if (!(o instanceof ResourceCollection)) { -134 throw new BuildException("refid '" + refid.getRefId() -135 + "' does not refer to a resource collection."); -136 } -137 getPath().add((ResourceCollection) o); -138 } -139 } -140 // END COPY from org.apache.tools.ant.taskdefs -141 /** -142 * The application name for the report. -143 * -144 * @deprecated use projectName instead. -145 */ -146 @Deprecated -147 private String applicationName = null; -148 -149 /** -150 * Get the value of applicationName. -151 * -152 * @return the value of applicationName +38 import org.owasp.dependencycheck.exception.ExceptionCollection; +39 import org.owasp.dependencycheck.exception.ReportException; +40 import org.owasp.dependencycheck.reporting.ReportGenerator; +41 import org.owasp.dependencycheck.reporting.ReportGenerator.Format; +42 import org.owasp.dependencycheck.utils.Settings; +43 import org.slf4j.impl.StaticLoggerBinder; +44 +45 /** +46 * An Ant task definition to execute dependency-check during an Ant build. +47 * +48 * @author Jeremy Long +49 */ +50 public class Check extends Update { +51 +52 /** +53 * System specific new line character. +54 */ +55 private static final String NEW_LINE = System.getProperty("line.separator", "\n").intern(); +56 +57 /** +58 * Construct a new DependencyCheckTask. +59 */ +60 public Check() { +61 super(); +62 // Call this before Dependency Check Core starts logging anything - this way, all SLF4J messages from +63 // core end up coming through this tasks logger +64 StaticLoggerBinder.getSingleton().setTask(this); +65 } +66 //The following code was copied Apache Ant PathConvert +67 //BEGIN COPY from org.apache.tools.ant.taskdefs.PathConvert +68 /** +69 * Path to be converted +70 */ +71 private Resources path = null; +72 /** +73 * Reference to path/fileset to convert +74 */ +75 private Reference refid = null; +76 +77 /** +78 * Add an arbitrary ResourceCollection. +79 * +80 * @param rc the ResourceCollection to add. +81 * @since Ant 1.7 +82 */ +83 public void add(ResourceCollection rc) { +84 if (isReference()) { +85 throw new BuildException("Nested elements are not allowed when using the refid attribute."); +86 } +87 getPath().add(rc); +88 } +89 +90 /** +91 * Returns the path. If the path has not been initialized yet, this class is +92 * synchronized, and will instantiate the path object. +93 * +94 * @return the path +95 */ +96 private synchronized Resources getPath() { +97 if (path == null) { +98 path = new Resources(getProject()); +99 path.setCache(true); +100 } +101 return path; +102 } +103 +104 /** +105 * Learn whether the refid attribute of this element been set. +106 * +107 * @return true if refid is valid. +108 */ +109 public boolean isReference() { +110 return refid != null; +111 } +112 +113 /** +114 * Add a reference to a Path, FileSet, DirSet, or FileList defined +115 * elsewhere. +116 * +117 * @param r the reference to a path, fileset, dirset or filelist. +118 */ +119 public void setRefid(Reference r) { +120 if (path != null) { +121 throw new BuildException("Nested elements are not allowed when using the refid attribute."); +122 } +123 refid = r; +124 } +125 +126 /** +127 * If this is a reference, this method will add the referenced resource +128 * collection to the collection of paths. +129 * +130 * @throws BuildException if the reference is not to a resource collection +131 */ +132 private void dealWithReferences() throws BuildException { +133 if (isReference()) { +134 final Object o = refid.getReferencedObject(getProject()); +135 if (!(o instanceof ResourceCollection)) { +136 throw new BuildException("refid '" + refid.getRefId() +137 + "' does not refer to a resource collection."); +138 } +139 getPath().add((ResourceCollection) o); +140 } +141 } +142 // END COPY from org.apache.tools.ant.taskdefs +143 /** +144 * The application name for the report. +145 * +146 * @deprecated use projectName instead. +147 */ +148 @Deprecated +149 private String applicationName = null; +150 +151 /** +152 * Get the value of applicationName. 153 * -154 * @deprecated use projectName instead. -155 */ -156 @Deprecated -157 public String getApplicationName() { -158 return applicationName; -159 } -160 -161 /** -162 * Set the value of applicationName. -163 * -164 * @param applicationName new value of applicationName -165 * @deprecated use projectName instead. -166 */ -167 @Deprecated -168 public void setApplicationName(String applicationName) { -169 this.applicationName = applicationName; -170 } -171 /** -172 * The name of the project being analyzed. -173 */ -174 private String projectName = "dependency-check"; -175 -176 /** -177 * Get the value of projectName. -178 * -179 * @return the value of projectName -180 */ -181 public String getProjectName() { -182 if (applicationName != null) { -183 log("Configuration 'applicationName' has been deprecated, please use 'projectName' instead", Project.MSG_WARN); -184 if ("dependency-check".equals(projectName)) { -185 projectName = applicationName; -186 } -187 } -188 return projectName; -189 } -190 -191 /** -192 * Set the value of projectName. -193 * -194 * @param projectName new value of projectName -195 */ -196 public void setProjectName(String projectName) { -197 this.projectName = projectName; -198 } -199 -200 /** -201 * Specifies the destination directory for the generated Dependency-Check -202 * report. -203 */ -204 private String reportOutputDirectory = "."; -205 -206 /** -207 * Get the value of reportOutputDirectory. -208 * -209 * @return the value of reportOutputDirectory -210 */ -211 public String getReportOutputDirectory() { -212 return reportOutputDirectory; -213 } -214 -215 /** -216 * Set the value of reportOutputDirectory. -217 * -218 * @param reportOutputDirectory new value of reportOutputDirectory -219 */ -220 public void setReportOutputDirectory(String reportOutputDirectory) { -221 this.reportOutputDirectory = reportOutputDirectory; -222 } -223 /** -224 * Specifies if the build should be failed if a CVSS score above a specified -225 * level is identified. The default is 11 which means since the CVSS scores -226 * are 0-10, by default the build will never fail and the CVSS score is set -227 * to 11. The valid range for the fail build on CVSS is 0 to 11, where -228 * anything above 10 will not cause the build to fail. -229 */ -230 private float failBuildOnCVSS = 11; -231 -232 /** -233 * Get the value of failBuildOnCVSS. -234 * -235 * @return the value of failBuildOnCVSS -236 */ -237 public float getFailBuildOnCVSS() { -238 return failBuildOnCVSS; -239 } -240 -241 /** -242 * Set the value of failBuildOnCVSS. -243 * -244 * @param failBuildOnCVSS new value of failBuildOnCVSS -245 */ -246 public void setFailBuildOnCVSS(float failBuildOnCVSS) { -247 this.failBuildOnCVSS = failBuildOnCVSS; -248 } -249 /** -250 * Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not -251 * recommended that this be turned to false. Default is true. -252 */ -253 private Boolean autoUpdate; -254 -255 /** -256 * Get the value of autoUpdate. -257 * -258 * @return the value of autoUpdate -259 */ -260 public Boolean isAutoUpdate() { -261 return autoUpdate; -262 } -263 -264 /** -265 * Set the value of autoUpdate. -266 * -267 * @param autoUpdate new value of autoUpdate -268 */ -269 public void setAutoUpdate(Boolean autoUpdate) { -270 this.autoUpdate = autoUpdate; -271 } -272 /** -273 * Whether only the update phase should be executed. -274 * -275 * @deprecated Use the update task instead -276 */ -277 @Deprecated -278 private boolean updateOnly = false; -279 -280 /** -281 * Get the value of updateOnly. -282 * -283 * @return the value of updateOnly -284 * @deprecated Use the update task instead -285 */ -286 @Deprecated -287 public boolean isUpdateOnly() { -288 return updateOnly; -289 } -290 -291 /** -292 * Set the value of updateOnly. -293 * -294 * @param updateOnly new value of updateOnly -295 * @deprecated Use the update task instead -296 */ -297 @Deprecated -298 public void setUpdateOnly(boolean updateOnly) { -299 this.updateOnly = updateOnly; -300 } -301 -302 /** -303 * The report format to be generated (HTML, XML, VULN, ALL). Default is -304 * HTML. -305 */ -306 private String reportFormat = "HTML"; -307 -308 /** -309 * Get the value of reportFormat. -310 * -311 * @return the value of reportFormat -312 */ -313 public String getReportFormat() { -314 return reportFormat; -315 } -316 -317 /** -318 * Set the value of reportFormat. -319 * -320 * @param reportFormat new value of reportFormat -321 */ -322 public void setReportFormat(ReportFormats reportFormat) { -323 this.reportFormat = reportFormat.getValue(); -324 } -325 /** -326 * The path to the suppression file. -327 */ -328 private String suppressionFile; -329 -330 /** -331 * Get the value of suppressionFile. -332 * -333 * @return the value of suppressionFile -334 */ -335 public String getSuppressionFile() { -336 return suppressionFile; -337 } -338 -339 /** -340 * Set the value of suppressionFile. -341 * -342 * @param suppressionFile new value of suppressionFile -343 */ -344 public void setSuppressionFile(String suppressionFile) { -345 this.suppressionFile = suppressionFile; -346 } -347 /** -348 * flag indicating whether or not to show a summary of findings. -349 */ -350 private boolean showSummary = true; -351 -352 /** -353 * Get the value of showSummary. -354 * -355 * @return the value of showSummary -356 */ -357 public boolean isShowSummary() { -358 return showSummary; -359 } -360 -361 /** -362 * Set the value of showSummary. -363 * -364 * @param showSummary new value of showSummary -365 */ -366 public void setShowSummary(boolean showSummary) { -367 this.showSummary = showSummary; -368 } -369 -370 /** -371 * Whether experimental analyzers are enabled. -372 */ -373 private Boolean enableExperimental; -374 -375 /** -376 * Get the value of enableExperimental. -377 * -378 * @return the value of enableExperimental -379 */ -380 public Boolean isEnableExperimental() { -381 return enableExperimental; -382 } -383 -384 /** -385 * Set the value of enableExperimental. -386 * -387 * @param enableExperimental new value of enableExperimental -388 */ -389 public void setEnableExperimental(Boolean enableExperimental) { -390 this.enableExperimental = enableExperimental; -391 } -392 -393 /** -394 * Whether or not the Jar Analyzer is enabled. -395 */ -396 private Boolean jarAnalyzerEnabled; -397 -398 /** -399 * Returns whether or not the analyzer is enabled. -400 * -401 * @return true if the analyzer is enabled -402 */ -403 public Boolean isJarAnalyzerEnabled() { -404 return jarAnalyzerEnabled; -405 } -406 -407 /** -408 * Sets whether or not the analyzer is enabled. -409 * -410 * @param jarAnalyzerEnabled the value of the new setting -411 */ -412 public void setJarAnalyzerEnabled(Boolean jarAnalyzerEnabled) { -413 this.jarAnalyzerEnabled = jarAnalyzerEnabled; -414 } -415 /** -416 * Whether or not the Archive Analyzer is enabled. -417 */ -418 private Boolean archiveAnalyzerEnabled; -419 -420 /** -421 * Returns whether or not the analyzer is enabled. -422 * -423 * @return true if the analyzer is enabled -424 */ -425 public Boolean isArchiveAnalyzerEnabled() { -426 return archiveAnalyzerEnabled; -427 } -428 /** -429 * Whether or not the .NET Assembly Analyzer is enabled. -430 */ -431 private Boolean assemblyAnalyzerEnabled; -432 -433 /** -434 * Sets whether or not the analyzer is enabled. -435 * -436 * @param archiveAnalyzerEnabled the value of the new setting -437 */ -438 public void setArchiveAnalyzerEnabled(Boolean archiveAnalyzerEnabled) { -439 this.archiveAnalyzerEnabled = archiveAnalyzerEnabled; -440 } -441 -442 /** -443 * Returns whether or not the analyzer is enabled. -444 * -445 * @return true if the analyzer is enabled -446 */ -447 public Boolean isAssemblyAnalyzerEnabled() { -448 return assemblyAnalyzerEnabled; -449 } -450 -451 /** -452 * Sets whether or not the analyzer is enabled. -453 * -454 * @param assemblyAnalyzerEnabled the value of the new setting -455 */ -456 public void setAssemblyAnalyzerEnabled(Boolean assemblyAnalyzerEnabled) { -457 this.assemblyAnalyzerEnabled = assemblyAnalyzerEnabled; -458 } -459 /** -460 * Whether or not the .NET Nuspec Analyzer is enabled. -461 */ -462 private Boolean nuspecAnalyzerEnabled; -463 -464 /** -465 * Returns whether or not the analyzer is enabled. -466 * -467 * @return true if the analyzer is enabled -468 */ -469 public Boolean isNuspecAnalyzerEnabled() { -470 return nuspecAnalyzerEnabled; -471 } -472 -473 /** -474 * Sets whether or not the analyzer is enabled. -475 * -476 * @param nuspecAnalyzerEnabled the value of the new setting -477 */ -478 public void setNuspecAnalyzerEnabled(Boolean nuspecAnalyzerEnabled) { -479 this.nuspecAnalyzerEnabled = nuspecAnalyzerEnabled; -480 } -481 /** -482 * Whether or not the PHP Composer Analyzer is enabled. -483 */ -484 private Boolean composerAnalyzerEnabled; -485 -486 /** -487 * Get the value of composerAnalyzerEnabled. -488 * -489 * @return the value of composerAnalyzerEnabled -490 */ -491 public Boolean isComposerAnalyzerEnabled() { -492 return composerAnalyzerEnabled; -493 } -494 -495 /** -496 * Set the value of composerAnalyzerEnabled. -497 * -498 * @param composerAnalyzerEnabled new value of composerAnalyzerEnabled -499 */ -500 public void setComposerAnalyzerEnabled(Boolean composerAnalyzerEnabled) { -501 this.composerAnalyzerEnabled = composerAnalyzerEnabled; -502 } -503 /** -504 * Whether the autoconf analyzer should be enabled. -505 */ -506 private Boolean autoconfAnalyzerEnabled; -507 -508 /** -509 * Get the value of autoconfAnalyzerEnabled. -510 * -511 * @return the value of autoconfAnalyzerEnabled -512 */ -513 public Boolean isAutoconfAnalyzerEnabled() { -514 return autoconfAnalyzerEnabled; -515 } -516 -517 /** -518 * Set the value of autoconfAnalyzerEnabled. -519 * -520 * @param autoconfAnalyzerEnabled new value of autoconfAnalyzerEnabled -521 */ -522 public void setAutoconfAnalyzerEnabled(Boolean autoconfAnalyzerEnabled) { -523 this.autoconfAnalyzerEnabled = autoconfAnalyzerEnabled; -524 } -525 /** -526 * Whether the CMake analyzer should be enabled. -527 */ -528 private Boolean cmakeAnalyzerEnabled; -529 -530 /** -531 * Get the value of cmakeAnalyzerEnabled. -532 * -533 * @return the value of cmakeAnalyzerEnabled -534 */ -535 public Boolean isCMakeAnalyzerEnabled() { -536 return cmakeAnalyzerEnabled; -537 } -538 -539 /** -540 * Set the value of cmakeAnalyzerEnabled. -541 * -542 * @param cmakeAnalyzerEnabled new value of cmakeAnalyzerEnabled -543 */ -544 public void setCMakeAnalyzerEnabled(Boolean cmakeAnalyzerEnabled) { -545 this.cmakeAnalyzerEnabled = cmakeAnalyzerEnabled; -546 } -547 /** -548 * Whether or not the openssl analyzer is enabled. -549 */ -550 private Boolean opensslAnalyzerEnabled; -551 -552 /** -553 * Get the value of opensslAnalyzerEnabled. -554 * -555 * @return the value of opensslAnalyzerEnabled -556 */ -557 public Boolean isOpensslAnalyzerEnabled() { -558 return opensslAnalyzerEnabled; -559 } -560 -561 /** -562 * Set the value of opensslAnalyzerEnabled. -563 * -564 * @param opensslAnalyzerEnabled new value of opensslAnalyzerEnabled -565 */ -566 public void setOpensslAnalyzerEnabled(Boolean opensslAnalyzerEnabled) { -567 this.opensslAnalyzerEnabled = opensslAnalyzerEnabled; -568 } -569 /** -570 * Whether or not the Node.js Analyzer is enabled. -571 */ -572 private Boolean nodeAnalyzerEnabled; -573 -574 /** -575 * Get the value of nodeAnalyzerEnabled. -576 * -577 * @return the value of nodeAnalyzerEnabled -578 */ -579 public Boolean isNodeAnalyzerEnabled() { -580 return nodeAnalyzerEnabled; -581 } -582 -583 /** -584 * Set the value of nodeAnalyzerEnabled. -585 * -586 * @param nodeAnalyzerEnabled new value of nodeAnalyzerEnabled -587 */ -588 public void setNodeAnalyzerEnabled(Boolean nodeAnalyzerEnabled) { -589 this.nodeAnalyzerEnabled = nodeAnalyzerEnabled; -590 } -591 /** -592 * Whether the ruby gemspec analyzer should be enabled. -593 */ -594 private Boolean rubygemsAnalyzerEnabled; -595 -596 /** -597 * Get the value of rubygemsAnalyzerEnabled. -598 * -599 * @return the value of rubygemsAnalyzerEnabled -600 */ -601 public Boolean isRubygemsAnalyzerEnabled() { -602 return rubygemsAnalyzerEnabled; -603 } -604 -605 /** -606 * Set the value of rubygemsAnalyzerEnabled. -607 * -608 * @param rubygemsAnalyzerEnabled new value of rubygemsAnalyzerEnabled -609 */ -610 public void setRubygemsAnalyzerEnabled(Boolean rubygemsAnalyzerEnabled) { -611 this.rubygemsAnalyzerEnabled = rubygemsAnalyzerEnabled; -612 } -613 /** -614 * Whether the python package analyzer should be enabled. -615 */ -616 private Boolean pyPackageAnalyzerEnabled; -617 -618 /** -619 * Get the value of pyPackageAnalyzerEnabled. -620 * -621 * @return the value of pyPackageAnalyzerEnabled -622 */ -623 public Boolean isPyPackageAnalyzerEnabled() { -624 return pyPackageAnalyzerEnabled; -625 } -626 -627 /** -628 * Set the value of pyPackageAnalyzerEnabled. -629 * -630 * @param pyPackageAnalyzerEnabled new value of pyPackageAnalyzerEnabled -631 */ -632 public void setPyPackageAnalyzerEnabled(Boolean pyPackageAnalyzerEnabled) { -633 this.pyPackageAnalyzerEnabled = pyPackageAnalyzerEnabled; -634 } -635 -636 /** -637 * Whether the python distribution analyzer should be enabled. -638 */ -639 private Boolean pyDistributionAnalyzerEnabled; -640 -641 /** -642 * Get the value of pyDistributionAnalyzerEnabled. -643 * -644 * @return the value of pyDistributionAnalyzerEnabled -645 */ -646 public Boolean isPyDistributionAnalyzerEnabled() { -647 return pyDistributionAnalyzerEnabled; -648 } -649 -650 /** -651 * Set the value of pyDistributionAnalyzerEnabled. -652 * -653 * @param pyDistributionAnalyzerEnabled new value of -654 * pyDistributionAnalyzerEnabled -655 */ -656 public void setPyDistributionAnalyzerEnabled(Boolean pyDistributionAnalyzerEnabled) { -657 this.pyDistributionAnalyzerEnabled = pyDistributionAnalyzerEnabled; -658 } -659 -660 /** -661 * Whether or not the central analyzer is enabled. -662 */ -663 private Boolean centralAnalyzerEnabled; -664 -665 /** -666 * Get the value of centralAnalyzerEnabled. -667 * -668 * @return the value of centralAnalyzerEnabled -669 */ -670 public Boolean isCentralAnalyzerEnabled() { -671 return centralAnalyzerEnabled; -672 } -673 -674 /** -675 * Set the value of centralAnalyzerEnabled. -676 * -677 * @param centralAnalyzerEnabled new value of centralAnalyzerEnabled -678 */ -679 public void setCentralAnalyzerEnabled(Boolean centralAnalyzerEnabled) { -680 this.centralAnalyzerEnabled = centralAnalyzerEnabled; -681 } -682 -683 /** -684 * Whether or not the nexus analyzer is enabled. -685 */ -686 private Boolean nexusAnalyzerEnabled; -687 -688 /** -689 * Get the value of nexusAnalyzerEnabled. -690 * -691 * @return the value of nexusAnalyzerEnabled -692 */ -693 public Boolean isNexusAnalyzerEnabled() { -694 return nexusAnalyzerEnabled; -695 } -696 -697 /** -698 * Set the value of nexusAnalyzerEnabled. -699 * -700 * @param nexusAnalyzerEnabled new value of nexusAnalyzerEnabled -701 */ -702 public void setNexusAnalyzerEnabled(Boolean nexusAnalyzerEnabled) { -703 this.nexusAnalyzerEnabled = nexusAnalyzerEnabled; -704 } -705 -706 /** -707 * The URL of a Nexus server's REST API end point -708 * (http://domain/nexus/service/local). -709 */ -710 private String nexusUrl; -711 -712 /** -713 * Get the value of nexusUrl. -714 * -715 * @return the value of nexusUrl -716 */ -717 public String getNexusUrl() { -718 return nexusUrl; -719 } -720 -721 /** -722 * Set the value of nexusUrl. -723 * -724 * @param nexusUrl new value of nexusUrl -725 */ -726 public void setNexusUrl(String nexusUrl) { -727 this.nexusUrl = nexusUrl; -728 } -729 /** -730 * Whether or not the defined proxy should be used when connecting to Nexus. -731 */ -732 private Boolean nexusUsesProxy; -733 -734 /** -735 * Get the value of nexusUsesProxy. -736 * -737 * @return the value of nexusUsesProxy -738 */ -739 public Boolean isNexusUsesProxy() { -740 return nexusUsesProxy; -741 } -742 -743 /** -744 * Set the value of nexusUsesProxy. -745 * -746 * @param nexusUsesProxy new value of nexusUsesProxy -747 */ -748 public void setNexusUsesProxy(Boolean nexusUsesProxy) { -749 this.nexusUsesProxy = nexusUsesProxy; -750 } -751 -752 /** -753 * Additional ZIP File extensions to add analyze. This should be a -754 * comma-separated list of file extensions to treat like ZIP files. -755 */ -756 private String zipExtensions; -757 -758 /** -759 * Get the value of zipExtensions. -760 * -761 * @return the value of zipExtensions -762 */ -763 public String getZipExtensions() { -764 return zipExtensions; -765 } -766 -767 /** -768 * Set the value of zipExtensions. -769 * -770 * @param zipExtensions new value of zipExtensions -771 */ -772 public void setZipExtensions(String zipExtensions) { -773 this.zipExtensions = zipExtensions; -774 } -775 -776 /** -777 * The path to Mono for .NET assembly analysis on non-windows systems. -778 */ -779 private String pathToMono; -780 -781 /** -782 * Get the value of pathToMono. -783 * -784 * @return the value of pathToMono -785 */ -786 public String getPathToMono() { -787 return pathToMono; -788 } -789 -790 /** -791 * Set the value of pathToMono. -792 * -793 * @param pathToMono new value of pathToMono -794 */ -795 public void setPathToMono(String pathToMono) { -796 this.pathToMono = pathToMono; -797 } -798 -799 @Override -800 public void execute() throws BuildException { -801 dealWithReferences(); -802 validateConfiguration(); -803 populateSettings(); -804 Engine engine = null; -805 try { -806 engine = new Engine(Check.class.getClassLoader()); -807 if (isUpdateOnly()) { -808 log("Deprecated 'UpdateOnly' property set; please use the UpdateTask instead", Project.MSG_WARN); -809 engine.doUpdates(); -810 } else { +154 * @return the value of applicationName +155 * +156 * @deprecated use projectName instead. +157 */ +158 @Deprecated +159 public String getApplicationName() { +160 return applicationName; +161 } +162 +163 /** +164 * Set the value of applicationName. +165 * +166 * @param applicationName new value of applicationName +167 * @deprecated use projectName instead. +168 */ +169 @Deprecated +170 public void setApplicationName(String applicationName) { +171 this.applicationName = applicationName; +172 } +173 /** +174 * The name of the project being analyzed. +175 */ +176 private String projectName = "dependency-check"; +177 +178 /** +179 * Get the value of projectName. +180 * +181 * @return the value of projectName +182 */ +183 public String getProjectName() { +184 if (applicationName != null) { +185 log("Configuration 'applicationName' has been deprecated, please use 'projectName' instead", Project.MSG_WARN); +186 if ("dependency-check".equals(projectName)) { +187 projectName = applicationName; +188 } +189 } +190 return projectName; +191 } +192 +193 /** +194 * Set the value of projectName. +195 * +196 * @param projectName new value of projectName +197 */ +198 public void setProjectName(String projectName) { +199 this.projectName = projectName; +200 } +201 +202 /** +203 * Specifies the destination directory for the generated Dependency-Check +204 * report. +205 */ +206 private String reportOutputDirectory = "."; +207 +208 /** +209 * Get the value of reportOutputDirectory. +210 * +211 * @return the value of reportOutputDirectory +212 */ +213 public String getReportOutputDirectory() { +214 return reportOutputDirectory; +215 } +216 +217 /** +218 * Set the value of reportOutputDirectory. +219 * +220 * @param reportOutputDirectory new value of reportOutputDirectory +221 */ +222 public void setReportOutputDirectory(String reportOutputDirectory) { +223 this.reportOutputDirectory = reportOutputDirectory; +224 } +225 /** +226 * Specifies if the build should be failed if a CVSS score above a specified +227 * level is identified. The default is 11 which means since the CVSS scores +228 * are 0-10, by default the build will never fail and the CVSS score is set +229 * to 11. The valid range for the fail build on CVSS is 0 to 11, where +230 * anything above 10 will not cause the build to fail. +231 */ +232 private float failBuildOnCVSS = 11; +233 +234 /** +235 * Get the value of failBuildOnCVSS. +236 * +237 * @return the value of failBuildOnCVSS +238 */ +239 public float getFailBuildOnCVSS() { +240 return failBuildOnCVSS; +241 } +242 +243 /** +244 * Set the value of failBuildOnCVSS. +245 * +246 * @param failBuildOnCVSS new value of failBuildOnCVSS +247 */ +248 public void setFailBuildOnCVSS(float failBuildOnCVSS) { +249 this.failBuildOnCVSS = failBuildOnCVSS; +250 } +251 /** +252 * Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not +253 * recommended that this be turned to false. Default is true. +254 */ +255 private Boolean autoUpdate; +256 +257 /** +258 * Get the value of autoUpdate. +259 * +260 * @return the value of autoUpdate +261 */ +262 public Boolean isAutoUpdate() { +263 return autoUpdate; +264 } +265 +266 /** +267 * Set the value of autoUpdate. +268 * +269 * @param autoUpdate new value of autoUpdate +270 */ +271 public void setAutoUpdate(Boolean autoUpdate) { +272 this.autoUpdate = autoUpdate; +273 } +274 /** +275 * Whether only the update phase should be executed. +276 * +277 * @deprecated Use the update task instead +278 */ +279 @Deprecated +280 private boolean updateOnly = false; +281 +282 /** +283 * Get the value of updateOnly. +284 * +285 * @return the value of updateOnly +286 * @deprecated Use the update task instead +287 */ +288 @Deprecated +289 public boolean isUpdateOnly() { +290 return updateOnly; +291 } +292 +293 /** +294 * Set the value of updateOnly. +295 * +296 * @param updateOnly new value of updateOnly +297 * @deprecated Use the update task instead +298 */ +299 @Deprecated +300 public void setUpdateOnly(boolean updateOnly) { +301 this.updateOnly = updateOnly; +302 } +303 +304 /** +305 * The report format to be generated (HTML, XML, VULN, ALL). Default is +306 * HTML. +307 */ +308 private String reportFormat = "HTML"; +309 +310 /** +311 * Get the value of reportFormat. +312 * +313 * @return the value of reportFormat +314 */ +315 public String getReportFormat() { +316 return reportFormat; +317 } +318 +319 /** +320 * Set the value of reportFormat. +321 * +322 * @param reportFormat new value of reportFormat +323 */ +324 public void setReportFormat(ReportFormats reportFormat) { +325 this.reportFormat = reportFormat.getValue(); +326 } +327 /** +328 * The path to the suppression file. +329 */ +330 private String suppressionFile; +331 +332 /** +333 * Get the value of suppressionFile. +334 * +335 * @return the value of suppressionFile +336 */ +337 public String getSuppressionFile() { +338 return suppressionFile; +339 } +340 +341 /** +342 * Set the value of suppressionFile. +343 * +344 * @param suppressionFile new value of suppressionFile +345 */ +346 public void setSuppressionFile(String suppressionFile) { +347 this.suppressionFile = suppressionFile; +348 } +349 /** +350 * flag indicating whether or not to show a summary of findings. +351 */ +352 private boolean showSummary = true; +353 +354 /** +355 * Get the value of showSummary. +356 * +357 * @return the value of showSummary +358 */ +359 public boolean isShowSummary() { +360 return showSummary; +361 } +362 +363 /** +364 * Set the value of showSummary. +365 * +366 * @param showSummary new value of showSummary +367 */ +368 public void setShowSummary(boolean showSummary) { +369 this.showSummary = showSummary; +370 } +371 +372 /** +373 * Whether experimental analyzers are enabled. +374 */ +375 private Boolean enableExperimental; +376 +377 /** +378 * Get the value of enableExperimental. +379 * +380 * @return the value of enableExperimental +381 */ +382 public Boolean isEnableExperimental() { +383 return enableExperimental; +384 } +385 +386 /** +387 * Set the value of enableExperimental. +388 * +389 * @param enableExperimental new value of enableExperimental +390 */ +391 public void setEnableExperimental(Boolean enableExperimental) { +392 this.enableExperimental = enableExperimental; +393 } +394 +395 /** +396 * Whether or not the Jar Analyzer is enabled. +397 */ +398 private Boolean jarAnalyzerEnabled; +399 +400 /** +401 * Returns whether or not the analyzer is enabled. +402 * +403 * @return true if the analyzer is enabled +404 */ +405 public Boolean isJarAnalyzerEnabled() { +406 return jarAnalyzerEnabled; +407 } +408 +409 /** +410 * Sets whether or not the analyzer is enabled. +411 * +412 * @param jarAnalyzerEnabled the value of the new setting +413 */ +414 public void setJarAnalyzerEnabled(Boolean jarAnalyzerEnabled) { +415 this.jarAnalyzerEnabled = jarAnalyzerEnabled; +416 } +417 /** +418 * Whether or not the Archive Analyzer is enabled. +419 */ +420 private Boolean archiveAnalyzerEnabled; +421 +422 /** +423 * Returns whether or not the analyzer is enabled. +424 * +425 * @return true if the analyzer is enabled +426 */ +427 public Boolean isArchiveAnalyzerEnabled() { +428 return archiveAnalyzerEnabled; +429 } +430 /** +431 * Whether or not the .NET Assembly Analyzer is enabled. +432 */ +433 private Boolean assemblyAnalyzerEnabled; +434 +435 /** +436 * Sets whether or not the analyzer is enabled. +437 * +438 * @param archiveAnalyzerEnabled the value of the new setting +439 */ +440 public void setArchiveAnalyzerEnabled(Boolean archiveAnalyzerEnabled) { +441 this.archiveAnalyzerEnabled = archiveAnalyzerEnabled; +442 } +443 +444 /** +445 * Returns whether or not the analyzer is enabled. +446 * +447 * @return true if the analyzer is enabled +448 */ +449 public Boolean isAssemblyAnalyzerEnabled() { +450 return assemblyAnalyzerEnabled; +451 } +452 +453 /** +454 * Sets whether or not the analyzer is enabled. +455 * +456 * @param assemblyAnalyzerEnabled the value of the new setting +457 */ +458 public void setAssemblyAnalyzerEnabled(Boolean assemblyAnalyzerEnabled) { +459 this.assemblyAnalyzerEnabled = assemblyAnalyzerEnabled; +460 } +461 /** +462 * Whether or not the .NET Nuspec Analyzer is enabled. +463 */ +464 private Boolean nuspecAnalyzerEnabled; +465 +466 /** +467 * Returns whether or not the analyzer is enabled. +468 * +469 * @return true if the analyzer is enabled +470 */ +471 public Boolean isNuspecAnalyzerEnabled() { +472 return nuspecAnalyzerEnabled; +473 } +474 +475 /** +476 * Sets whether or not the analyzer is enabled. +477 * +478 * @param nuspecAnalyzerEnabled the value of the new setting +479 */ +480 public void setNuspecAnalyzerEnabled(Boolean nuspecAnalyzerEnabled) { +481 this.nuspecAnalyzerEnabled = nuspecAnalyzerEnabled; +482 } +483 /** +484 * Whether or not the PHP Composer Analyzer is enabled. +485 */ +486 private Boolean composerAnalyzerEnabled; +487 +488 /** +489 * Get the value of composerAnalyzerEnabled. +490 * +491 * @return the value of composerAnalyzerEnabled +492 */ +493 public Boolean isComposerAnalyzerEnabled() { +494 return composerAnalyzerEnabled; +495 } +496 +497 /** +498 * Set the value of composerAnalyzerEnabled. +499 * +500 * @param composerAnalyzerEnabled new value of composerAnalyzerEnabled +501 */ +502 public void setComposerAnalyzerEnabled(Boolean composerAnalyzerEnabled) { +503 this.composerAnalyzerEnabled = composerAnalyzerEnabled; +504 } +505 /** +506 * Whether the autoconf analyzer should be enabled. +507 */ +508 private Boolean autoconfAnalyzerEnabled; +509 +510 /** +511 * Get the value of autoconfAnalyzerEnabled. +512 * +513 * @return the value of autoconfAnalyzerEnabled +514 */ +515 public Boolean isAutoconfAnalyzerEnabled() { +516 return autoconfAnalyzerEnabled; +517 } +518 +519 /** +520 * Set the value of autoconfAnalyzerEnabled. +521 * +522 * @param autoconfAnalyzerEnabled new value of autoconfAnalyzerEnabled +523 */ +524 public void setAutoconfAnalyzerEnabled(Boolean autoconfAnalyzerEnabled) { +525 this.autoconfAnalyzerEnabled = autoconfAnalyzerEnabled; +526 } +527 /** +528 * Whether the CMake analyzer should be enabled. +529 */ +530 private Boolean cmakeAnalyzerEnabled; +531 +532 /** +533 * Get the value of cmakeAnalyzerEnabled. +534 * +535 * @return the value of cmakeAnalyzerEnabled +536 */ +537 public Boolean isCMakeAnalyzerEnabled() { +538 return cmakeAnalyzerEnabled; +539 } +540 +541 /** +542 * Set the value of cmakeAnalyzerEnabled. +543 * +544 * @param cmakeAnalyzerEnabled new value of cmakeAnalyzerEnabled +545 */ +546 public void setCMakeAnalyzerEnabled(Boolean cmakeAnalyzerEnabled) { +547 this.cmakeAnalyzerEnabled = cmakeAnalyzerEnabled; +548 } +549 /** +550 * Whether or not the openssl analyzer is enabled. +551 */ +552 private Boolean opensslAnalyzerEnabled; +553 +554 /** +555 * Get the value of opensslAnalyzerEnabled. +556 * +557 * @return the value of opensslAnalyzerEnabled +558 */ +559 public Boolean isOpensslAnalyzerEnabled() { +560 return opensslAnalyzerEnabled; +561 } +562 +563 /** +564 * Set the value of opensslAnalyzerEnabled. +565 * +566 * @param opensslAnalyzerEnabled new value of opensslAnalyzerEnabled +567 */ +568 public void setOpensslAnalyzerEnabled(Boolean opensslAnalyzerEnabled) { +569 this.opensslAnalyzerEnabled = opensslAnalyzerEnabled; +570 } +571 /** +572 * Whether or not the Node.js Analyzer is enabled. +573 */ +574 private Boolean nodeAnalyzerEnabled; +575 +576 /** +577 * Get the value of nodeAnalyzerEnabled. +578 * +579 * @return the value of nodeAnalyzerEnabled +580 */ +581 public Boolean isNodeAnalyzerEnabled() { +582 return nodeAnalyzerEnabled; +583 } +584 +585 /** +586 * Set the value of nodeAnalyzerEnabled. +587 * +588 * @param nodeAnalyzerEnabled new value of nodeAnalyzerEnabled +589 */ +590 public void setNodeAnalyzerEnabled(Boolean nodeAnalyzerEnabled) { +591 this.nodeAnalyzerEnabled = nodeAnalyzerEnabled; +592 } +593 /** +594 * Whether the ruby gemspec analyzer should be enabled. +595 */ +596 private Boolean rubygemsAnalyzerEnabled; +597 +598 /** +599 * Get the value of rubygemsAnalyzerEnabled. +600 * +601 * @return the value of rubygemsAnalyzerEnabled +602 */ +603 public Boolean isRubygemsAnalyzerEnabled() { +604 return rubygemsAnalyzerEnabled; +605 } +606 +607 /** +608 * Set the value of rubygemsAnalyzerEnabled. +609 * +610 * @param rubygemsAnalyzerEnabled new value of rubygemsAnalyzerEnabled +611 */ +612 public void setRubygemsAnalyzerEnabled(Boolean rubygemsAnalyzerEnabled) { +613 this.rubygemsAnalyzerEnabled = rubygemsAnalyzerEnabled; +614 } +615 /** +616 * Whether the python package analyzer should be enabled. +617 */ +618 private Boolean pyPackageAnalyzerEnabled; +619 +620 /** +621 * Get the value of pyPackageAnalyzerEnabled. +622 * +623 * @return the value of pyPackageAnalyzerEnabled +624 */ +625 public Boolean isPyPackageAnalyzerEnabled() { +626 return pyPackageAnalyzerEnabled; +627 } +628 +629 /** +630 * Set the value of pyPackageAnalyzerEnabled. +631 * +632 * @param pyPackageAnalyzerEnabled new value of pyPackageAnalyzerEnabled +633 */ +634 public void setPyPackageAnalyzerEnabled(Boolean pyPackageAnalyzerEnabled) { +635 this.pyPackageAnalyzerEnabled = pyPackageAnalyzerEnabled; +636 } +637 +638 /** +639 * Whether the python distribution analyzer should be enabled. +640 */ +641 private Boolean pyDistributionAnalyzerEnabled; +642 +643 /** +644 * Get the value of pyDistributionAnalyzerEnabled. +645 * +646 * @return the value of pyDistributionAnalyzerEnabled +647 */ +648 public Boolean isPyDistributionAnalyzerEnabled() { +649 return pyDistributionAnalyzerEnabled; +650 } +651 +652 /** +653 * Set the value of pyDistributionAnalyzerEnabled. +654 * +655 * @param pyDistributionAnalyzerEnabled new value of +656 * pyDistributionAnalyzerEnabled +657 */ +658 public void setPyDistributionAnalyzerEnabled(Boolean pyDistributionAnalyzerEnabled) { +659 this.pyDistributionAnalyzerEnabled = pyDistributionAnalyzerEnabled; +660 } +661 +662 /** +663 * Whether or not the central analyzer is enabled. +664 */ +665 private Boolean centralAnalyzerEnabled; +666 +667 /** +668 * Get the value of centralAnalyzerEnabled. +669 * +670 * @return the value of centralAnalyzerEnabled +671 */ +672 public Boolean isCentralAnalyzerEnabled() { +673 return centralAnalyzerEnabled; +674 } +675 +676 /** +677 * Set the value of centralAnalyzerEnabled. +678 * +679 * @param centralAnalyzerEnabled new value of centralAnalyzerEnabled +680 */ +681 public void setCentralAnalyzerEnabled(Boolean centralAnalyzerEnabled) { +682 this.centralAnalyzerEnabled = centralAnalyzerEnabled; +683 } +684 +685 /** +686 * Whether or not the nexus analyzer is enabled. +687 */ +688 private Boolean nexusAnalyzerEnabled; +689 +690 /** +691 * Get the value of nexusAnalyzerEnabled. +692 * +693 * @return the value of nexusAnalyzerEnabled +694 */ +695 public Boolean isNexusAnalyzerEnabled() { +696 return nexusAnalyzerEnabled; +697 } +698 +699 /** +700 * Set the value of nexusAnalyzerEnabled. +701 * +702 * @param nexusAnalyzerEnabled new value of nexusAnalyzerEnabled +703 */ +704 public void setNexusAnalyzerEnabled(Boolean nexusAnalyzerEnabled) { +705 this.nexusAnalyzerEnabled = nexusAnalyzerEnabled; +706 } +707 +708 /** +709 * The URL of a Nexus server's REST API end point +710 * (http://domain/nexus/service/local). +711 */ +712 private String nexusUrl; +713 +714 /** +715 * Get the value of nexusUrl. +716 * +717 * @return the value of nexusUrl +718 */ +719 public String getNexusUrl() { +720 return nexusUrl; +721 } +722 +723 /** +724 * Set the value of nexusUrl. +725 * +726 * @param nexusUrl new value of nexusUrl +727 */ +728 public void setNexusUrl(String nexusUrl) { +729 this.nexusUrl = nexusUrl; +730 } +731 /** +732 * Whether or not the defined proxy should be used when connecting to Nexus. +733 */ +734 private Boolean nexusUsesProxy; +735 +736 /** +737 * Get the value of nexusUsesProxy. +738 * +739 * @return the value of nexusUsesProxy +740 */ +741 public Boolean isNexusUsesProxy() { +742 return nexusUsesProxy; +743 } +744 +745 /** +746 * Set the value of nexusUsesProxy. +747 * +748 * @param nexusUsesProxy new value of nexusUsesProxy +749 */ +750 public void setNexusUsesProxy(Boolean nexusUsesProxy) { +751 this.nexusUsesProxy = nexusUsesProxy; +752 } +753 +754 /** +755 * Additional ZIP File extensions to add analyze. This should be a +756 * comma-separated list of file extensions to treat like ZIP files. +757 */ +758 private String zipExtensions; +759 +760 /** +761 * Get the value of zipExtensions. +762 * +763 * @return the value of zipExtensions +764 */ +765 public String getZipExtensions() { +766 return zipExtensions; +767 } +768 +769 /** +770 * Set the value of zipExtensions. +771 * +772 * @param zipExtensions new value of zipExtensions +773 */ +774 public void setZipExtensions(String zipExtensions) { +775 this.zipExtensions = zipExtensions; +776 } +777 +778 /** +779 * The path to Mono for .NET assembly analysis on non-windows systems. +780 */ +781 private String pathToMono; +782 +783 /** +784 * Get the value of pathToMono. +785 * +786 * @return the value of pathToMono +787 */ +788 public String getPathToMono() { +789 return pathToMono; +790 } +791 +792 /** +793 * Set the value of pathToMono. +794 * +795 * @param pathToMono new value of pathToMono +796 */ +797 public void setPathToMono(String pathToMono) { +798 this.pathToMono = pathToMono; +799 } +800 +801 @Override +802 public void execute() throws BuildException { +803 dealWithReferences(); +804 validateConfiguration(); +805 populateSettings(); +806 Engine engine = null; +807 try { +808 engine = new Engine(Check.class.getClassLoader()); +809 if (isUpdateOnly()) { +810 log("Deprecated 'UpdateOnly' property set; please use the UpdateTask instead", Project.MSG_WARN); 811 try { -812 for (Resource resource : path) { -813 final FileProvider provider = resource.as(FileProvider.class); -814 if (provider != null) { -815 final File file = provider.getFile(); -816 if (file != null && file.exists()) { -817 engine.scan(file); -818 } -819 } -820 } -821 -822 engine.analyzeDependencies(); -823 DatabaseProperties prop = null; -824 CveDB cve = null; -825 try { -826 cve = new CveDB(); -827 cve.open(); -828 prop = cve.getDatabaseProperties(); -829 } catch (DatabaseException ex) { -830 log("Unable to retrieve DB Properties", ex, Project.MSG_DEBUG); -831 } finally { -832 if (cve != null) { -833 cve.close(); -834 } +812 engine.doUpdates(); +813 } catch (UpdateException ex) { +814 if (this.isFailOnError()) { +815 throw new BuildException(ex); +816 } +817 log(ex.getMessage(), Project.MSG_ERR); +818 } +819 } else { +820 for (Resource resource : path) { +821 final FileProvider provider = resource.as(FileProvider.class); +822 if (provider != null) { +823 final File file = provider.getFile(); +824 if (file != null && file.exists()) { +825 engine.scan(file); +826 } +827 } +828 } +829 +830 try { +831 engine.analyzeDependencies(); +832 } catch (ExceptionCollection ex) { +833 if (this.isFailOnError()) { +834 throw new BuildException(ex); 835 } -836 final ReportGenerator reporter = new ReportGenerator(getProjectName(), engine.getDependencies(), engine.getAnalyzers(), prop); -837 reporter.generateReports(reportOutputDirectory, reportFormat); -838 -839 if (this.failBuildOnCVSS <= 10) { -840 checkForFailure(engine.getDependencies()); -841 } -842 if (this.showSummary) { -843 showSummary(engine.getDependencies()); -844 } -845 } catch (IOException ex) { -846 log("Unable to generate dependency-check report", ex, Project.MSG_DEBUG); -847 throw new BuildException("Unable to generate dependency-check report", ex); -848 } catch (Exception ex) { -849 log("An exception occurred; unable to continue task", ex, Project.MSG_DEBUG); -850 throw new BuildException("An exception occurred; unable to continue task", ex); -851 } -852 } -853 } catch (DatabaseException ex) { -854 log("Unable to connect to the dependency-check database; analysis has stopped", ex, Project.MSG_ERR); -855 } finally { -856 Settings.cleanup(true); -857 if (engine != null) { -858 engine.cleanup(); +836 } +837 DatabaseProperties prop = null; +838 CveDB cve = null; +839 try { +840 cve = new CveDB(); +841 cve.open(); +842 prop = cve.getDatabaseProperties(); +843 } catch (DatabaseException ex) { +844 log("Unable to retrieve DB Properties", ex, Project.MSG_DEBUG); +845 } finally { +846 if (cve != null) { +847 cve.close(); +848 } +849 } +850 final ReportGenerator reporter = new ReportGenerator(getProjectName(), engine.getDependencies(), engine.getAnalyzers(), prop); +851 reporter.generateReports(reportOutputDirectory, reportFormat); +852 +853 if (this.failBuildOnCVSS <= 10) { +854 checkForFailure(engine.getDependencies()); +855 } +856 if (this.showSummary) { +857 showSummary(engine.getDependencies()); +858 } 859 } -860 } -861 } -862 -863 /** -864 * Validate the configuration to ensure the parameters have been properly -865 * configured/initialized. -866 * -867 * @throws BuildException if the task was not configured correctly. -868 */ -869 private void validateConfiguration() throws BuildException { -870 if (path == null) { -871 throw new BuildException("No project dependencies have been defined to analyze."); -872 } -873 if (failBuildOnCVSS < 0 || failBuildOnCVSS > 11) { -874 throw new BuildException("Invalid configuration, failBuildOnCVSS must be between 0 and 11."); -875 } -876 } -877 -878 /** -879 * Takes the properties supplied and updates the dependency-check settings. -880 * Additionally, this sets the system properties required to change the -881 * proxy server, port, and connection timeout. -882 * -883 * @throws BuildException thrown when an invalid setting is configured. -884 */ -885 @Override -886 protected void populateSettings() throws BuildException { -887 super.populateSettings(); -888 Settings.setBooleanIfNotNull(Settings.KEYS.AUTO_UPDATE, autoUpdate); -889 Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile); -890 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, enableExperimental); -891 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_JAR_ENABLED, jarAnalyzerEnabled); -892 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, pyDistributionAnalyzerEnabled); -893 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, pyPackageAnalyzerEnabled); -894 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED, rubygemsAnalyzerEnabled); -895 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, opensslAnalyzerEnabled); -896 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CMAKE_ENABLED, cmakeAnalyzerEnabled); -897 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_AUTOCONF_ENABLED, autoconfAnalyzerEnabled); -898 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED, composerAnalyzerEnabled); -899 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED, nodeAnalyzerEnabled); -900 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, nuspecAnalyzerEnabled); -901 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, centralAnalyzerEnabled); -902 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled); -903 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, archiveAnalyzerEnabled); -904 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, assemblyAnalyzerEnabled); -905 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl); -906 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy); -907 Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions); -908 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono); -909 } -910 -911 /** -912 * Checks to see if a vulnerability has been identified with a CVSS score -913 * that is above the threshold set in the configuration. -914 * -915 * @param dependencies the list of dependency objects -916 * @throws BuildException thrown if a CVSS score is found that is higher -917 * then the threshold set -918 */ -919 private void checkForFailure(List<Dependency> dependencies) throws BuildException { -920 final StringBuilder ids = new StringBuilder(); -921 for (Dependency d : dependencies) { -922 for (Vulnerability v : d.getVulnerabilities()) { -923 if (v.getCvssScore() >= failBuildOnCVSS) { -924 if (ids.length() == 0) { -925 ids.append(v.getName()); -926 } else { -927 ids.append(", ").append(v.getName()); -928 } -929 } -930 } -931 } -932 if (ids.length() > 0) { -933 final String msg = String.format("%n%nDependency-Check Failure:%n" -934 + "One or more dependencies were identified with vulnerabilities that have a CVSS score greater then '%.1f': %s%n" -935 + "See the dependency-check report for more details.%n%n", failBuildOnCVSS, ids.toString()); -936 throw new BuildException(msg); -937 } -938 } -939 -940 /** -941 * Generates a warning message listing a summary of dependencies and their -942 * associated CPE and CVE entries. -943 * -944 * @param dependencies a list of dependency objects -945 */ -946 private void showSummary(List<Dependency> dependencies) { -947 final StringBuilder summary = new StringBuilder(); -948 for (Dependency d : dependencies) { -949 boolean firstEntry = true; -950 final StringBuilder ids = new StringBuilder(); -951 for (Vulnerability v : d.getVulnerabilities()) { -952 if (firstEntry) { -953 firstEntry = false; -954 } else { -955 ids.append(", "); -956 } -957 ids.append(v.getName()); -958 } -959 if (ids.length() > 0) { -960 summary.append(d.getFileName()).append(" ("); -961 firstEntry = true; -962 for (Identifier id : d.getIdentifiers()) { -963 if (firstEntry) { -964 firstEntry = false; -965 } else { -966 summary.append(", "); -967 } -968 summary.append(id.getValue()); -969 } -970 summary.append(") : ").append(ids).append(NEW_LINE); -971 } -972 } -973 if (summary.length() > 0) { -974 final String msg = String.format("%n%n" -975 + "One or more dependencies were identified with known vulnerabilities:%n%n%s" -976 + "%n%nSee the dependency-check report for more details.%n%n", summary.toString()); -977 log(msg, Project.MSG_WARN); -978 } -979 } -980 -981 /** -982 * An enumeration of supported report formats: "ALL", "HTML", "XML", "VULN", -983 * etc.. -984 */ -985 public static class ReportFormats extends EnumeratedAttribute { -986 -987 /** -988 * Returns the list of values for the report format. -989 * -990 * @return the list of values for the report format -991 */ -992 @Override -993 public String[] getValues() { -994 int i = 0; -995 final Format[] formats = Format.values(); -996 final String[] values = new String[formats.length]; -997 for (Format format : formats) { -998 values[i++] = format.name(); -999 } -1000 return values; -1001 } -1002 } -1003 } +860 } catch (DatabaseException ex) { +861 final String msg = "Unable to connect to the dependency-check database; analysis has stopped"; +862 if (this.isFailOnError()) { +863 throw new BuildException(msg, ex); +864 } +865 log(msg, ex, Project.MSG_ERR); +866 } catch (ReportException ex) { +867 final String msg = "Unable to generate the dependency-check report"; +868 if (this.isFailOnError()) { +869 throw new BuildException(msg, ex); +870 } +871 log(msg, ex, Project.MSG_ERR); +872 } finally { +873 Settings.cleanup(true); +874 if (engine != null) { +875 engine.cleanup(); +876 } +877 } +878 } +879 +880 /** +881 * Validate the configuration to ensure the parameters have been properly +882 * configured/initialized. +883 * +884 * @throws BuildException if the task was not configured correctly. +885 */ +886 private void validateConfiguration() throws BuildException { +887 if (path == null) { +888 throw new BuildException("No project dependencies have been defined to analyze."); +889 } +890 if (failBuildOnCVSS < 0 || failBuildOnCVSS > 11) { +891 throw new BuildException("Invalid configuration, failBuildOnCVSS must be between 0 and 11."); +892 } +893 } +894 +895 /** +896 * Takes the properties supplied and updates the dependency-check settings. +897 * Additionally, this sets the system properties required to change the +898 * proxy server, port, and connection timeout. +899 * +900 * @throws BuildException thrown when an invalid setting is configured. +901 */ +902 @Override +903 protected void populateSettings() throws BuildException { +904 super.populateSettings(); +905 Settings.setBooleanIfNotNull(Settings.KEYS.AUTO_UPDATE, autoUpdate); +906 Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile); +907 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, enableExperimental); +908 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_JAR_ENABLED, jarAnalyzerEnabled); +909 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, pyDistributionAnalyzerEnabled); +910 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, pyPackageAnalyzerEnabled); +911 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED, rubygemsAnalyzerEnabled); +912 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, opensslAnalyzerEnabled); +913 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CMAKE_ENABLED, cmakeAnalyzerEnabled); +914 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_AUTOCONF_ENABLED, autoconfAnalyzerEnabled); +915 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED, composerAnalyzerEnabled); +916 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED, nodeAnalyzerEnabled); +917 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, nuspecAnalyzerEnabled); +918 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, centralAnalyzerEnabled); +919 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled); +920 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, archiveAnalyzerEnabled); +921 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, assemblyAnalyzerEnabled); +922 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl); +923 Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy); +924 Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions); +925 Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono); +926 } +927 +928 /** +929 * Checks to see if a vulnerability has been identified with a CVSS score +930 * that is above the threshold set in the configuration. +931 * +932 * @param dependencies the list of dependency objects +933 * @throws BuildException thrown if a CVSS score is found that is higher +934 * then the threshold set +935 */ +936 private void checkForFailure(List<Dependency> dependencies) throws BuildException { +937 final StringBuilder ids = new StringBuilder(); +938 for (Dependency d : dependencies) { +939 for (Vulnerability v : d.getVulnerabilities()) { +940 if (v.getCvssScore() >= failBuildOnCVSS) { +941 if (ids.length() == 0) { +942 ids.append(v.getName()); +943 } else { +944 ids.append(", ").append(v.getName()); +945 } +946 } +947 } +948 } +949 if (ids.length() > 0) { +950 final String msg = String.format("%n%nDependency-Check Failure:%n" +951 + "One or more dependencies were identified with vulnerabilities that have a CVSS score greater then '%.1f': %s%n" +952 + "See the dependency-check report for more details.%n%n", failBuildOnCVSS, ids.toString()); +953 throw new BuildException(msg); +954 } +955 } +956 +957 /** +958 * Generates a warning message listing a summary of dependencies and their +959 * associated CPE and CVE entries. +960 * +961 * @param dependencies a list of dependency objects +962 */ +963 private void showSummary(List<Dependency> dependencies) { +964 final StringBuilder summary = new StringBuilder(); +965 for (Dependency d : dependencies) { +966 boolean firstEntry = true; +967 final StringBuilder ids = new StringBuilder(); +968 for (Vulnerability v : d.getVulnerabilities()) { +969 if (firstEntry) { +970 firstEntry = false; +971 } else { +972 ids.append(", "); +973 } +974 ids.append(v.getName()); +975 } +976 if (ids.length() > 0) { +977 summary.append(d.getFileName()).append(" ("); +978 firstEntry = true; +979 for (Identifier id : d.getIdentifiers()) { +980 if (firstEntry) { +981 firstEntry = false; +982 } else { +983 summary.append(", "); +984 } +985 summary.append(id.getValue()); +986 } +987 summary.append(") : ").append(ids).append(NEW_LINE); +988 } +989 } +990 if (summary.length() > 0) { +991 final String msg = String.format("%n%n" +992 + "One or more dependencies were identified with known vulnerabilities:%n%n%s" +993 + "%n%nSee the dependency-check report for more details.%n%n", summary.toString()); +994 log(msg, Project.MSG_WARN); +995 } +996 } +997 +998 /** +999 * An enumeration of supported report formats: "ALL", "HTML", "XML", "VULN", +1000 * etc.. +1001 */ +1002 public static class ReportFormats extends EnumeratedAttribute { +1003 +1004 /** +1005 * Returns the list of values for the report format. +1006 * +1007 * @return the list of values for the report format +1008 */ +1009 @Override +1010 public String[] getValues() { +1011 int i = 0; +1012 final Format[] formats = Format.values(); +1013 final String[] values = new String[formats.length]; +1014 for (Format format : formats) { +1015 values[i++] = format.name(); +1016 } +1017 return values; +1018 } +1019 } +1020 }
        diff --git a/xref/org/owasp/dependencycheck/taskdefs/Purge.html b/xref/org/owasp/dependencycheck/taskdefs/Purge.html index 35abcc910..967c6577a 100644 --- a/xref/org/owasp/dependencycheck/taskdefs/Purge.html +++ b/xref/org/owasp/dependencycheck/taskdefs/Purge.html @@ -79,60 +79,103 @@ 71 this.dataDirectory = dataDirectory; 72 } 73 -74 @Override -75 public void execute() throws BuildException { -76 populateSettings(); -77 File db; -78 try { -79 db = new File(Settings.getDataDirectory(), "dc.h2.db"); -80 if (db.exists()) { -81 if (db.delete()) { -82 log("Database file purged; local copy of the NVD has been removed", Project.MSG_INFO); -83 } else { -84 log(String.format("Unable to delete '%s'; please delete the file manually", db.getAbsolutePath()), Project.MSG_ERR); -85 } -86 } else { -87 log(String.format("Unable to purge database; the database file does not exists: %s", db.getAbsolutePath()), Project.MSG_ERR); -88 } -89 } catch (IOException ex) { -90 log("Unable to delete the database", Project.MSG_ERR); -91 } finally { -92 Settings.cleanup(true); -93 } -94 } -95 -96 /** -97 * Takes the properties supplied and updates the dependency-check settings. Additionally, this sets the system properties -98 * required to change the proxy server, port, and connection timeout. -99 */ -100 protected void populateSettings() { -101 Settings.initialize(); -102 InputStream taskProperties = null; -103 try { -104 taskProperties = this.getClass().getClassLoader().getResourceAsStream(PROPERTIES_FILE); -105 Settings.mergeProperties(taskProperties); -106 } catch (IOException ex) { -107 log("Unable to load the dependency-check ant task.properties file.", ex, Project.MSG_WARN); -108 } finally { -109 if (taskProperties != null) { -110 try { -111 taskProperties.close(); -112 } catch (IOException ex) { -113 log("", ex, Project.MSG_DEBUG); -114 } -115 } -116 } -117 if (dataDirectory != null) { -118 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory); -119 } else { -120 final File jarPath = new File(Purge.class.getProtectionDomain().getCodeSource().getLocation().getPath()); -121 final File base = jarPath.getParentFile(); -122 final String sub = Settings.getString(Settings.KEYS.DATA_DIRECTORY); -123 final File dataDir = new File(base, sub); -124 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath()); -125 } -126 } -127 } +74 /** +75 * Indicates if dependency-check should fail the build if an exception +76 * occurs. +77 */ +78 private boolean failOnError = true; +79 +80 /** +81 * Get the value of failOnError. +82 * +83 * @return the value of failOnError +84 */ +85 public boolean isFailOnError() { +86 return failOnError; +87 } +88 +89 /** +90 * Set the value of failOnError. +91 * +92 * @param failOnError new value of failOnError +93 */ +94 public void setFailOnError(boolean failOnError) { +95 this.failOnError = failOnError; +96 } +97 +98 @Override +99 public void execute() throws BuildException { +100 populateSettings(); +101 File db; +102 try { +103 db = new File(Settings.getDataDirectory(), "dc.h2.db"); +104 if (db.exists()) { +105 if (db.delete()) { +106 log("Database file purged; local copy of the NVD has been removed", Project.MSG_INFO); +107 } else { +108 final String msg = String.format("Unable to delete '%s'; please delete the file manually", db.getAbsolutePath()); +109 if (this.failOnError) { +110 throw new BuildException(msg); +111 } +112 log(msg, Project.MSG_ERR); +113 } +114 } else { +115 final String msg = String.format("Unable to purge database; the database file does not exists: %s", db.getAbsolutePath()); +116 if (this.failOnError) { +117 throw new BuildException(msg); +118 } +119 log(msg, Project.MSG_ERR); +120 } +121 } catch (IOException ex) { +122 final String msg = "Unable to delete the database"; +123 if (this.failOnError) { +124 throw new BuildException(msg); +125 } +126 log(msg, Project.MSG_ERR); +127 } finally { +128 Settings.cleanup(true); +129 } +130 } +131 +132 /** +133 * Takes the properties supplied and updates the dependency-check settings. +134 * Additionally, this sets the system properties required to change the +135 * proxy server, port, and connection timeout. +136 * +137 * @throws BuildException thrown if the properties file cannot be read. +138 */ +139 protected void populateSettings() throws BuildException { +140 Settings.initialize(); +141 InputStream taskProperties = null; +142 try { +143 taskProperties = this.getClass().getClassLoader().getResourceAsStream(PROPERTIES_FILE); +144 Settings.mergeProperties(taskProperties); +145 } catch (IOException ex) { +146 final String msg = "Unable to load the dependency-check ant task.properties file."; +147 if (this.failOnError) { +148 throw new BuildException(msg, ex); +149 } +150 log(msg, ex, Project.MSG_WARN); +151 } finally { +152 if (taskProperties != null) { +153 try { +154 taskProperties.close(); +155 } catch (IOException ex) { +156 log("", ex, Project.MSG_DEBUG); +157 } +158 } +159 } +160 if (dataDirectory != null) { +161 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory); +162 } else { +163 final File jarPath = new File(Purge.class.getProtectionDomain().getCodeSource().getLocation().getPath()); +164 final File base = jarPath.getParentFile(); +165 final String sub = Settings.getString(Settings.KEYS.DATA_DIRECTORY); +166 final File dataDir = new File(base, sub); +167 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath()); +168 } +169 } +170 }
        diff --git a/xref/org/owasp/dependencycheck/taskdefs/Update.html b/xref/org/owasp/dependencycheck/taskdefs/Update.html index 4e07e13da..18820b68a 100644 --- a/xref/org/owasp/dependencycheck/taskdefs/Update.html +++ b/xref/org/owasp/dependencycheck/taskdefs/Update.html @@ -26,423 +26,439 @@ 18 package org.owasp.dependencycheck.taskdefs; 19 20 import org.apache.tools.ant.BuildException; -21 import org.owasp.dependencycheck.Engine; -22 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; -23 import org.owasp.dependencycheck.utils.Settings; -24 import org.slf4j.impl.StaticLoggerBinder; -25 -26 /** -27 * An Ant task definition to execute dependency-check update. This will download the latest data from the National Vulnerability -28 * Database (NVD) and store a copy in the local database. -29 * -30 * @author Jeremy Long -31 */ -32 public class Update extends Purge { -33 -34 /** -35 * Construct a new UpdateTask. -36 */ -37 public Update() { -38 super(); -39 // Call this before Dependency Check Core starts logging anything - this way, all SLF4J messages from -40 // core end up coming through this tasks logger -41 StaticLoggerBinder.getSingleton().setTask(this); -42 } -43 -44 /** -45 * The Proxy Server. -46 */ -47 private String proxyServer; -48 -49 /** -50 * Get the value of proxyServer. -51 * -52 * @return the value of proxyServer -53 */ -54 public String getProxyServer() { -55 return proxyServer; -56 } -57 -58 /** -59 * Set the value of proxyServer. -60 * -61 * @param server new value of proxyServer -62 */ -63 public void setProxyServer(String server) { -64 this.proxyServer = server; -65 } -66 -67 /** -68 * The Proxy Port. -69 */ -70 private String proxyPort; -71 -72 /** -73 * Get the value of proxyPort. -74 * -75 * @return the value of proxyPort -76 */ -77 public String getProxyPort() { -78 return proxyPort; -79 } -80 -81 /** -82 * Set the value of proxyPort. -83 * -84 * @param proxyPort new value of proxyPort -85 */ -86 public void setProxyPort(String proxyPort) { -87 this.proxyPort = proxyPort; -88 } -89 /** -90 * The Proxy username. -91 */ -92 private String proxyUsername; -93 -94 /** -95 * Get the value of proxyUsername. -96 * -97 * @return the value of proxyUsername -98 */ -99 public String getProxyUsername() { -100 return proxyUsername; -101 } -102 -103 /** -104 * Set the value of proxyUsername. -105 * -106 * @param proxyUsername new value of proxyUsername -107 */ -108 public void setProxyUsername(String proxyUsername) { -109 this.proxyUsername = proxyUsername; -110 } -111 /** -112 * The Proxy password. -113 */ -114 private String proxyPassword; -115 -116 /** -117 * Get the value of proxyPassword. -118 * -119 * @return the value of proxyPassword -120 */ -121 public String getProxyPassword() { -122 return proxyPassword; -123 } -124 -125 /** -126 * Set the value of proxyPassword. -127 * -128 * @param proxyPassword new value of proxyPassword -129 */ -130 public void setProxyPassword(String proxyPassword) { -131 this.proxyPassword = proxyPassword; -132 } -133 /** -134 * The Connection Timeout. -135 */ -136 private String connectionTimeout; -137 -138 /** -139 * Get the value of connectionTimeout. -140 * -141 * @return the value of connectionTimeout -142 */ -143 public String getConnectionTimeout() { -144 return connectionTimeout; -145 } -146 -147 /** -148 * Set the value of connectionTimeout. -149 * -150 * @param connectionTimeout new value of connectionTimeout -151 */ -152 public void setConnectionTimeout(String connectionTimeout) { -153 this.connectionTimeout = connectionTimeout; -154 } -155 /** -156 * The database driver name; such as org.h2.Driver. -157 */ -158 private String databaseDriverName; -159 -160 /** -161 * Get the value of databaseDriverName. -162 * -163 * @return the value of databaseDriverName -164 */ -165 public String getDatabaseDriverName() { -166 return databaseDriverName; -167 } -168 -169 /** -170 * Set the value of databaseDriverName. -171 * -172 * @param databaseDriverName new value of databaseDriverName -173 */ -174 public void setDatabaseDriverName(String databaseDriverName) { -175 this.databaseDriverName = databaseDriverName; -176 } -177 -178 /** -179 * The path to the database driver JAR file if it is not on the class path. -180 */ -181 private String databaseDriverPath; -182 -183 /** -184 * Get the value of databaseDriverPath. -185 * -186 * @return the value of databaseDriverPath -187 */ -188 public String getDatabaseDriverPath() { -189 return databaseDriverPath; -190 } -191 -192 /** -193 * Set the value of databaseDriverPath. -194 * -195 * @param databaseDriverPath new value of databaseDriverPath -196 */ -197 public void setDatabaseDriverPath(String databaseDriverPath) { -198 this.databaseDriverPath = databaseDriverPath; -199 } -200 /** -201 * The database connection string. -202 */ -203 private String connectionString; -204 -205 /** -206 * Get the value of connectionString. -207 * -208 * @return the value of connectionString -209 */ -210 public String getConnectionString() { -211 return connectionString; -212 } -213 -214 /** -215 * Set the value of connectionString. -216 * -217 * @param connectionString new value of connectionString -218 */ -219 public void setConnectionString(String connectionString) { -220 this.connectionString = connectionString; -221 } -222 /** -223 * The user name for connecting to the database. -224 */ -225 private String databaseUser; -226 -227 /** -228 * Get the value of databaseUser. -229 * -230 * @return the value of databaseUser -231 */ -232 public String getDatabaseUser() { -233 return databaseUser; -234 } -235 -236 /** -237 * Set the value of databaseUser. -238 * -239 * @param databaseUser new value of databaseUser -240 */ -241 public void setDatabaseUser(String databaseUser) { -242 this.databaseUser = databaseUser; -243 } -244 -245 /** -246 * The password to use when connecting to the database. -247 */ -248 private String databasePassword; -249 -250 /** -251 * Get the value of databasePassword. -252 * -253 * @return the value of databasePassword -254 */ -255 public String getDatabasePassword() { -256 return databasePassword; -257 } -258 -259 /** -260 * Set the value of databasePassword. -261 * -262 * @param databasePassword new value of databasePassword -263 */ -264 public void setDatabasePassword(String databasePassword) { -265 this.databasePassword = databasePassword; -266 } -267 -268 /** -269 * The url for the modified NVD CVE (1.2 schema). -270 */ -271 private String cveUrl12Modified; -272 -273 /** -274 * Get the value of cveUrl12Modified. -275 * -276 * @return the value of cveUrl12Modified -277 */ -278 public String getCveUrl12Modified() { -279 return cveUrl12Modified; -280 } -281 -282 /** -283 * Set the value of cveUrl12Modified. -284 * -285 * @param cveUrl12Modified new value of cveUrl12Modified -286 */ -287 public void setCveUrl12Modified(String cveUrl12Modified) { -288 this.cveUrl12Modified = cveUrl12Modified; -289 } -290 -291 /** -292 * The url for the modified NVD CVE (2.0 schema). -293 */ -294 private String cveUrl20Modified; -295 -296 /** -297 * Get the value of cveUrl20Modified. -298 * -299 * @return the value of cveUrl20Modified -300 */ -301 public String getCveUrl20Modified() { -302 return cveUrl20Modified; -303 } -304 -305 /** -306 * Set the value of cveUrl20Modified. -307 * -308 * @param cveUrl20Modified new value of cveUrl20Modified -309 */ -310 public void setCveUrl20Modified(String cveUrl20Modified) { -311 this.cveUrl20Modified = cveUrl20Modified; -312 } -313 -314 /** -315 * Base Data Mirror URL for CVE 1.2. -316 */ -317 private String cveUrl12Base; -318 -319 /** -320 * Get the value of cveUrl12Base. -321 * -322 * @return the value of cveUrl12Base -323 */ -324 public String getCveUrl12Base() { -325 return cveUrl12Base; -326 } -327 -328 /** -329 * Set the value of cveUrl12Base. -330 * -331 * @param cveUrl12Base new value of cveUrl12Base -332 */ -333 public void setCveUrl12Base(String cveUrl12Base) { -334 this.cveUrl12Base = cveUrl12Base; -335 } -336 -337 /** -338 * Data Mirror URL for CVE 2.0. -339 */ -340 private String cveUrl20Base; -341 -342 /** -343 * Get the value of cveUrl20Base. -344 * -345 * @return the value of cveUrl20Base -346 */ -347 public String getCveUrl20Base() { -348 return cveUrl20Base; -349 } -350 -351 /** -352 * Set the value of cveUrl20Base. -353 * -354 * @param cveUrl20Base new value of cveUrl20Base -355 */ -356 public void setCveUrl20Base(String cveUrl20Base) { -357 this.cveUrl20Base = cveUrl20Base; -358 } -359 -360 /** -361 * The number of hours to wait before re-checking for updates. -362 */ -363 private Integer cveValidForHours; -364 -365 /** -366 * Get the value of cveValidForHours. -367 * -368 * @return the value of cveValidForHours -369 */ -370 public Integer getCveValidForHours() { -371 return cveValidForHours; -372 } -373 -374 /** -375 * Set the value of cveValidForHours. -376 * -377 * @param cveValidForHours new value of cveValidForHours -378 */ -379 public void setCveValidForHours(Integer cveValidForHours) { -380 this.cveValidForHours = cveValidForHours; -381 } -382 -383 /** -384 * Executes the update by initializing the settings, downloads the NVD XML data, and then processes the data storing it in the -385 * local database. -386 * -387 * @throws BuildException thrown if a connection to the local database cannot be made. -388 */ -389 @Override -390 public void execute() throws BuildException { -391 populateSettings(); -392 Engine engine = null; -393 try { -394 engine = new Engine(Update.class.getClassLoader()); -395 engine.doUpdates(); -396 } catch (DatabaseException ex) { -397 throw new BuildException("Unable to connect to the dependency-check database; unable to update the NVD data", ex); -398 } finally { -399 Settings.cleanup(true); -400 if (engine != null) { -401 engine.cleanup(); -402 } -403 } -404 } -405 -406 /** -407 * Takes the properties supplied and updates the dependency-check settings. Additionally, this sets the system properties -408 * required to change the proxy server, port, and connection timeout. -409 * -410 * @throws BuildException thrown when an invalid setting is configured. -411 */ -412 @Override -413 protected void populateSettings() throws BuildException { -414 super.populateSettings(); -415 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_SERVER, proxyServer); -416 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PORT, proxyPort); -417 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_USERNAME, proxyUsername); -418 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PASSWORD, proxyPassword); -419 Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout); -420 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName); -421 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath); -422 Settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString); -423 Settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser); -424 Settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword); -425 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_12_URL, cveUrl12Modified); -426 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_20_URL, cveUrl20Modified); -427 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_1_2, cveUrl12Base); -428 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_2_0, cveUrl20Base); -429 if (cveValidForHours != null) { -430 if (cveValidForHours >= 0) { -431 Settings.setInt(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, cveValidForHours); -432 } else { -433 throw new BuildException("Invalid setting: `cpeValidForHours` must be 0 or greater"); -434 } -435 } -436 } -437 } +21 import org.apache.tools.ant.Project; +22 import org.owasp.dependencycheck.Engine; +23 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; +24 import org.owasp.dependencycheck.data.update.exception.UpdateException; +25 import org.owasp.dependencycheck.utils.Settings; +26 import org.slf4j.impl.StaticLoggerBinder; +27 +28 /** +29 * An Ant task definition to execute dependency-check update. This will download +30 * the latest data from the National Vulnerability Database (NVD) and store a +31 * copy in the local database. +32 * +33 * @author Jeremy Long +34 */ +35 public class Update extends Purge { +36 +37 /** +38 * Construct a new UpdateTask. +39 */ +40 public Update() { +41 super(); +42 // Call this before Dependency Check Core starts logging anything - this way, all SLF4J messages from +43 // core end up coming through this tasks logger +44 StaticLoggerBinder.getSingleton().setTask(this); +45 } +46 +47 /** +48 * The Proxy Server. +49 */ +50 private String proxyServer; +51 +52 /** +53 * Get the value of proxyServer. +54 * +55 * @return the value of proxyServer +56 */ +57 public String getProxyServer() { +58 return proxyServer; +59 } +60 +61 /** +62 * Set the value of proxyServer. +63 * +64 * @param server new value of proxyServer +65 */ +66 public void setProxyServer(String server) { +67 this.proxyServer = server; +68 } +69 +70 /** +71 * The Proxy Port. +72 */ +73 private String proxyPort; +74 +75 /** +76 * Get the value of proxyPort. +77 * +78 * @return the value of proxyPort +79 */ +80 public String getProxyPort() { +81 return proxyPort; +82 } +83 +84 /** +85 * Set the value of proxyPort. +86 * +87 * @param proxyPort new value of proxyPort +88 */ +89 public void setProxyPort(String proxyPort) { +90 this.proxyPort = proxyPort; +91 } +92 /** +93 * The Proxy username. +94 */ +95 private String proxyUsername; +96 +97 /** +98 * Get the value of proxyUsername. +99 * +100 * @return the value of proxyUsername +101 */ +102 public String getProxyUsername() { +103 return proxyUsername; +104 } +105 +106 /** +107 * Set the value of proxyUsername. +108 * +109 * @param proxyUsername new value of proxyUsername +110 */ +111 public void setProxyUsername(String proxyUsername) { +112 this.proxyUsername = proxyUsername; +113 } +114 /** +115 * The Proxy password. +116 */ +117 private String proxyPassword; +118 +119 /** +120 * Get the value of proxyPassword. +121 * +122 * @return the value of proxyPassword +123 */ +124 public String getProxyPassword() { +125 return proxyPassword; +126 } +127 +128 /** +129 * Set the value of proxyPassword. +130 * +131 * @param proxyPassword new value of proxyPassword +132 */ +133 public void setProxyPassword(String proxyPassword) { +134 this.proxyPassword = proxyPassword; +135 } +136 /** +137 * The Connection Timeout. +138 */ +139 private String connectionTimeout; +140 +141 /** +142 * Get the value of connectionTimeout. +143 * +144 * @return the value of connectionTimeout +145 */ +146 public String getConnectionTimeout() { +147 return connectionTimeout; +148 } +149 +150 /** +151 * Set the value of connectionTimeout. +152 * +153 * @param connectionTimeout new value of connectionTimeout +154 */ +155 public void setConnectionTimeout(String connectionTimeout) { +156 this.connectionTimeout = connectionTimeout; +157 } +158 /** +159 * The database driver name; such as org.h2.Driver. +160 */ +161 private String databaseDriverName; +162 +163 /** +164 * Get the value of databaseDriverName. +165 * +166 * @return the value of databaseDriverName +167 */ +168 public String getDatabaseDriverName() { +169 return databaseDriverName; +170 } +171 +172 /** +173 * Set the value of databaseDriverName. +174 * +175 * @param databaseDriverName new value of databaseDriverName +176 */ +177 public void setDatabaseDriverName(String databaseDriverName) { +178 this.databaseDriverName = databaseDriverName; +179 } +180 +181 /** +182 * The path to the database driver JAR file if it is not on the class path. +183 */ +184 private String databaseDriverPath; +185 +186 /** +187 * Get the value of databaseDriverPath. +188 * +189 * @return the value of databaseDriverPath +190 */ +191 public String getDatabaseDriverPath() { +192 return databaseDriverPath; +193 } +194 +195 /** +196 * Set the value of databaseDriverPath. +197 * +198 * @param databaseDriverPath new value of databaseDriverPath +199 */ +200 public void setDatabaseDriverPath(String databaseDriverPath) { +201 this.databaseDriverPath = databaseDriverPath; +202 } +203 /** +204 * The database connection string. +205 */ +206 private String connectionString; +207 +208 /** +209 * Get the value of connectionString. +210 * +211 * @return the value of connectionString +212 */ +213 public String getConnectionString() { +214 return connectionString; +215 } +216 +217 /** +218 * Set the value of connectionString. +219 * +220 * @param connectionString new value of connectionString +221 */ +222 public void setConnectionString(String connectionString) { +223 this.connectionString = connectionString; +224 } +225 /** +226 * The user name for connecting to the database. +227 */ +228 private String databaseUser; +229 +230 /** +231 * Get the value of databaseUser. +232 * +233 * @return the value of databaseUser +234 */ +235 public String getDatabaseUser() { +236 return databaseUser; +237 } +238 +239 /** +240 * Set the value of databaseUser. +241 * +242 * @param databaseUser new value of databaseUser +243 */ +244 public void setDatabaseUser(String databaseUser) { +245 this.databaseUser = databaseUser; +246 } +247 +248 /** +249 * The password to use when connecting to the database. +250 */ +251 private String databasePassword; +252 +253 /** +254 * Get the value of databasePassword. +255 * +256 * @return the value of databasePassword +257 */ +258 public String getDatabasePassword() { +259 return databasePassword; +260 } +261 +262 /** +263 * Set the value of databasePassword. +264 * +265 * @param databasePassword new value of databasePassword +266 */ +267 public void setDatabasePassword(String databasePassword) { +268 this.databasePassword = databasePassword; +269 } +270 +271 /** +272 * The url for the modified NVD CVE (1.2 schema). +273 */ +274 private String cveUrl12Modified; +275 +276 /** +277 * Get the value of cveUrl12Modified. +278 * +279 * @return the value of cveUrl12Modified +280 */ +281 public String getCveUrl12Modified() { +282 return cveUrl12Modified; +283 } +284 +285 /** +286 * Set the value of cveUrl12Modified. +287 * +288 * @param cveUrl12Modified new value of cveUrl12Modified +289 */ +290 public void setCveUrl12Modified(String cveUrl12Modified) { +291 this.cveUrl12Modified = cveUrl12Modified; +292 } +293 +294 /** +295 * The url for the modified NVD CVE (2.0 schema). +296 */ +297 private String cveUrl20Modified; +298 +299 /** +300 * Get the value of cveUrl20Modified. +301 * +302 * @return the value of cveUrl20Modified +303 */ +304 public String getCveUrl20Modified() { +305 return cveUrl20Modified; +306 } +307 +308 /** +309 * Set the value of cveUrl20Modified. +310 * +311 * @param cveUrl20Modified new value of cveUrl20Modified +312 */ +313 public void setCveUrl20Modified(String cveUrl20Modified) { +314 this.cveUrl20Modified = cveUrl20Modified; +315 } +316 +317 /** +318 * Base Data Mirror URL for CVE 1.2. +319 */ +320 private String cveUrl12Base; +321 +322 /** +323 * Get the value of cveUrl12Base. +324 * +325 * @return the value of cveUrl12Base +326 */ +327 public String getCveUrl12Base() { +328 return cveUrl12Base; +329 } +330 +331 /** +332 * Set the value of cveUrl12Base. +333 * +334 * @param cveUrl12Base new value of cveUrl12Base +335 */ +336 public void setCveUrl12Base(String cveUrl12Base) { +337 this.cveUrl12Base = cveUrl12Base; +338 } +339 +340 /** +341 * Data Mirror URL for CVE 2.0. +342 */ +343 private String cveUrl20Base; +344 +345 /** +346 * Get the value of cveUrl20Base. +347 * +348 * @return the value of cveUrl20Base +349 */ +350 public String getCveUrl20Base() { +351 return cveUrl20Base; +352 } +353 +354 /** +355 * Set the value of cveUrl20Base. +356 * +357 * @param cveUrl20Base new value of cveUrl20Base +358 */ +359 public void setCveUrl20Base(String cveUrl20Base) { +360 this.cveUrl20Base = cveUrl20Base; +361 } +362 +363 /** +364 * The number of hours to wait before re-checking for updates. +365 */ +366 private Integer cveValidForHours; +367 +368 /** +369 * Get the value of cveValidForHours. +370 * +371 * @return the value of cveValidForHours +372 */ +373 public Integer getCveValidForHours() { +374 return cveValidForHours; +375 } +376 +377 /** +378 * Set the value of cveValidForHours. +379 * +380 * @param cveValidForHours new value of cveValidForHours +381 */ +382 public void setCveValidForHours(Integer cveValidForHours) { +383 this.cveValidForHours = cveValidForHours; +384 } +385 +386 /** +387 * Executes the update by initializing the settings, downloads the NVD XML +388 * data, and then processes the data storing it in the local database. +389 * +390 * @throws BuildException thrown if a connection to the local database +391 * cannot be made. +392 */ +393 @Override +394 public void execute() throws BuildException { +395 populateSettings(); +396 Engine engine = null; +397 try { +398 engine = new Engine(Update.class.getClassLoader()); +399 try { +400 engine.doUpdates(); +401 } catch (UpdateException ex) { +402 if (this.isFailOnError()) { +403 throw new BuildException(ex); +404 } +405 log(ex.getMessage(), Project.MSG_ERR); +406 } +407 } catch (DatabaseException ex) { +408 final String msg = "Unable to connect to the dependency-check database; unable to update the NVD data"; +409 if (this.isFailOnError()) { +410 throw new BuildException(msg, ex); +411 } +412 log(msg, Project.MSG_ERR); +413 } finally { +414 Settings.cleanup(true); +415 if (engine != null) { +416 engine.cleanup(); +417 } +418 } +419 } +420 +421 /** +422 * Takes the properties supplied and updates the dependency-check settings. +423 * Additionally, this sets the system properties required to change the +424 * proxy server, port, and connection timeout. +425 * +426 * @throws BuildException thrown when an invalid setting is configured. +427 */ +428 @Override +429 protected void populateSettings() throws BuildException { +430 super.populateSettings(); +431 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_SERVER, proxyServer); +432 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PORT, proxyPort); +433 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_USERNAME, proxyUsername); +434 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PASSWORD, proxyPassword); +435 Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout); +436 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName); +437 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath); +438 Settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString); +439 Settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser); +440 Settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword); +441 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_12_URL, cveUrl12Modified); +442 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_20_URL, cveUrl20Modified); +443 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_1_2, cveUrl12Base); +444 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_2_0, cveUrl20Base); +445 if (cveValidForHours != null) { +446 if (cveValidForHours >= 0) { +447 Settings.setInt(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, cveValidForHours); +448 } else { +449 throw new BuildException("Invalid setting: `cpeValidForHours` must be 0 or greater"); +450 } +451 } +452 } +453 }
        diff --git a/xref/org/owasp/dependencycheck/taskdefs/package-frame.html b/xref/org/owasp/dependencycheck/taskdefs/package-frame.html index 2d7877d35..fc4581800 100644 --- a/xref/org/owasp/dependencycheck/taskdefs/package-frame.html +++ b/xref/org/owasp/dependencycheck/taskdefs/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.taskdefs + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.taskdefs diff --git a/xref/org/owasp/dependencycheck/taskdefs/package-summary.html b/xref/org/owasp/dependencycheck/taskdefs/package-summary.html index 7a7886449..96369986f 100644 --- a/xref/org/owasp/dependencycheck/taskdefs/package-summary.html +++ b/xref/org/owasp/dependencycheck/taskdefs/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.taskdefs + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.taskdefs diff --git a/xref/org/owasp/dependencycheck/utils/Downloader.html b/xref/org/owasp/dependencycheck/utils/Downloader.html index 553877bdc..1b5a46416 100644 --- a/xref/org/owasp/dependencycheck/utils/Downloader.html +++ b/xref/org/owasp/dependencycheck/utils/Downloader.html @@ -39,22 +39,22 @@ 31 import java.security.InvalidAlgorithmParameterException; 32 import java.util.zip.GZIPInputStream; 33 import java.util.zip.InflaterInputStream; -34 -35 import static java.lang.String.format; -36 -37 /** -38 * A utility to download files from the Internet. -39 * -40 * @author Jeremy Long -41 */ -42 public final class Downloader { -43 -44 /** -45 * The logger. -46 */ -47 private static final Logger LOGGER = LoggerFactory.getLogger(Downloader.class); -48 /** -49 * The maximum number of redirects that will be followed when attempting to download a file. +34 import static java.lang.String.format; +35 +36 /** +37 * A utility to download files from the Internet. +38 * +39 * @author Jeremy Long +40 */ +41 public final class Downloader { +42 +43 /** +44 * The logger. +45 */ +46 private static final Logger LOGGER = LoggerFactory.getLogger(Downloader.class); +47 /** +48 * The maximum number of redirects that will be followed when attempting to +49 * download a file. 50 */ 51 private static final int MAX_REDIRECT_ATTEMPTS = 5; 52 @@ -79,250 +79,284 @@ 71 * 72 * @param url the URL of the file to download 73 * @param outputPath the path to the save the file to -74 * @throws DownloadFailedException is thrown if there is an error downloading the file -75 */ -76 public static void fetchFile(URL url, File outputPath) throws DownloadFailedException { -77 fetchFile(url, outputPath, true); -78 } -79 -80 /** -81 * Retrieves a file from a given URL and saves it to the outputPath. -82 * -83 * @param url the URL of the file to download -84 * @param outputPath the path to the save the file to -85 * @param useProxy whether to use the configured proxy when downloading files -86 * @throws DownloadFailedException is thrown if there is an error downloading the file -87 */ -88 public static void fetchFile(URL url, File outputPath, boolean useProxy) throws DownloadFailedException { -89 if ("file".equalsIgnoreCase(url.getProtocol())) { -90 File file; -91 try { -92 file = new File(url.toURI()); -93 } catch (URISyntaxException ex) { -94 final String msg = format("Download failed, unable to locate '%s'", url.toString()); -95 throw new DownloadFailedException(msg); -96 } -97 if (file.exists()) { -98 try { -99 org.apache.commons.io.FileUtils.copyFile(file, outputPath); -100 } catch (IOException ex) { -101 final String msg = format("Download failed, unable to copy '%s' to '%s'", url.toString(), outputPath.getAbsolutePath()); -102 throw new DownloadFailedException(msg); -103 } -104 } else { -105 final String msg = format("Download failed, file ('%s') does not exist", url.toString()); -106 throw new DownloadFailedException(msg); -107 } -108 } else { -109 HttpURLConnection conn = null; -110 try { -111 LOGGER.debug("Attempting download of {}", url.toString()); -112 conn = URLConnectionFactory.createHttpURLConnection(url, useProxy); -113 conn.setRequestProperty("Accept-Encoding", "gzip, deflate"); -114 conn.connect(); -115 int status = conn.getResponseCode(); -116 int redirectCount = 0; -117 while ((status == HttpURLConnection.HTTP_MOVED_TEMP -118 || status == HttpURLConnection.HTTP_MOVED_PERM -119 || status == HttpURLConnection.HTTP_SEE_OTHER) -120 && MAX_REDIRECT_ATTEMPTS > redirectCount++) { -121 final String location = conn.getHeaderField("Location"); -122 try { -123 conn.disconnect(); -124 } finally { -125 conn = null; -126 } -127 LOGGER.debug("Download is being redirected from {} to {}", url.toString(), location); -128 conn = URLConnectionFactory.createHttpURLConnection(new URL(location), useProxy); -129 conn.setRequestProperty("Accept-Encoding", "gzip, deflate"); -130 conn.connect(); -131 status = conn.getResponseCode(); -132 } -133 if (status != 200) { -134 try { -135 conn.disconnect(); -136 } finally { -137 conn = null; -138 } -139 final String msg = format("Error downloading file %s; received response code %s.", url.toString(), status); -140 throw new DownloadFailedException(msg); -141 -142 } -143 } catch (IOException ex) { -144 try { -145 if (conn != null) { -146 conn.disconnect(); -147 } -148 } finally { -149 conn = null; -150 } -151 final String msg = format("Error downloading file %s; unable to connect.", url.toString()); -152 throw new DownloadFailedException(msg, ex); -153 } -154 -155 final String encoding = conn.getContentEncoding(); -156 BufferedOutputStream writer = null; -157 InputStream reader = null; -158 try { -159 if (encoding != null && "gzip".equalsIgnoreCase(encoding)) { -160 reader = new GZIPInputStream(conn.getInputStream()); -161 } else if (encoding != null && "deflate".equalsIgnoreCase(encoding)) { -162 reader = new InflaterInputStream(conn.getInputStream()); -163 } else { -164 reader = conn.getInputStream(); -165 } -166 -167 writer = new BufferedOutputStream(new FileOutputStream(outputPath)); -168 final byte[] buffer = new byte[4096]; -169 int bytesRead; -170 while ((bytesRead = reader.read(buffer)) > 0) { -171 writer.write(buffer, 0, bytesRead); -172 } -173 LOGGER.debug("Download of {} complete", url.toString()); -174 } catch (IOException ex) { -175 analyzeException(ex); -176 final String msg = format("Error saving '%s' to file '%s'%nConnection Timeout: %d%nEncoding: %s%n", -177 url.toString(), outputPath.getAbsolutePath(), conn.getConnectTimeout(), encoding); -178 throw new DownloadFailedException(msg, ex); -179 } catch (Throwable ex) { -180 final String msg = format("Unexpected exception saving '%s' to file '%s'%nConnection Timeout: %d%nEncoding: %s%n", -181 url.toString(), outputPath.getAbsolutePath(), conn.getConnectTimeout(), encoding); -182 throw new DownloadFailedException(msg, ex); -183 } finally { -184 if (writer != null) { -185 try { -186 writer.close(); -187 } catch (IOException ex) { -188 LOGGER.trace("Error closing the writer in Downloader.", ex); -189 } -190 } -191 if (reader != null) { -192 try { -193 reader.close(); -194 } catch (IOException ex) { -195 LOGGER.trace("Error closing the reader in Downloader.", ex); -196 } -197 } -198 try { -199 conn.disconnect(); -200 } finally { -201 conn = null; -202 } -203 } -204 } -205 } -206 -207 /** -208 * Makes an HTTP Head request to retrieve the last modified date of the given URL. If the file:// protocol is specified, then -209 * the lastTimestamp of the file is returned. -210 * -211 * @param url the URL to retrieve the timestamp from -212 * @return an epoch timestamp -213 * @throws DownloadFailedException is thrown if an exception occurs making the HTTP request -214 */ -215 public static long getLastModified(URL url) throws DownloadFailedException { -216 long timestamp = 0; -217 //TODO add the FTP protocol? -218 if ("file".equalsIgnoreCase(url.getProtocol())) { -219 File lastModifiedFile; -220 try { -221 lastModifiedFile = new File(url.toURI()); -222 } catch (URISyntaxException ex) { -223 final String msg = format("Unable to locate '%s'", url.toString()); -224 throw new DownloadFailedException(msg); -225 } -226 timestamp = lastModifiedFile.lastModified(); -227 } else { -228 final String httpMethod = determineHttpMethod(); -229 HttpURLConnection conn = null; -230 try { -231 conn = URLConnectionFactory.createHttpURLConnection(url); -232 conn.setRequestMethod(httpMethod); -233 conn.connect(); -234 final int t = conn.getResponseCode(); -235 if (t >= 200 && t < 300) { -236 timestamp = conn.getLastModified(); -237 } else { -238 throw new DownloadFailedException(format("%s request returned a non-200 status code", httpMethod)); -239 } -240 } catch (URLConnectionFailureException ex) { -241 throw new DownloadFailedException(format("Error creating URL Connection for HTTP %s request.", httpMethod), ex); -242 } catch (IOException ex) { -243 analyzeException(ex); -244 try { -245 //retry -246 if (!Settings.getBoolean(Settings.KEYS.DOWNLOADER_QUICK_QUERY_TIMESTAMP)) { -247 Settings.setBoolean(Settings.KEYS.DOWNLOADER_QUICK_QUERY_TIMESTAMP, true); -248 return getLastModified(url); -249 } -250 } catch (InvalidSettingException ex1) { -251 LOGGER.debug("invalid setting?", ex); -252 } -253 -254 throw new DownloadFailedException(format("Error making HTTP %s request.", httpMethod), ex); -255 } finally { -256 if (conn != null) { -257 try { -258 conn.disconnect(); -259 } finally { -260 conn = null; -261 } -262 } -263 } -264 } -265 return timestamp; -266 } -267 -268 /** -269 * Analyzes the IOException, logs the appropriate information for debugging purposes, and then throws a -270 * DownloadFailedException that wraps the IO Exception. -271 * -272 * @param ex the original exception -273 * @throws DownloadFailedException a wrapper exception that contains the original exception as the cause -274 */ -275 protected static void analyzeException(IOException ex) throws DownloadFailedException { -276 Throwable cause = ex; -277 while (cause != null) { -278 if (cause instanceof InvalidAlgorithmParameterException) { -279 final String keystore = System.getProperty("javax.net.ssl.keyStore"); -280 final String version = System.getProperty("java.version"); -281 final String vendor = System.getProperty("java.vendor"); -282 LOGGER.info("Error making HTTPS request - InvalidAlgorithmParameterException"); -283 LOGGER.info("There appears to be an issue with the installation of Java and the cacerts." -284 + "See closed issue #177 here: https://github.com/jeremylong/DependencyCheck/issues/177"); -285 LOGGER.info("Java Info:\njavax.net.ssl.keyStore='{}'\njava.version='{}'\njava.vendor='{}'", -286 keystore, version, vendor); -287 throw new DownloadFailedException("Error making HTTPS request. Please see the log for more details."); +74 * @throws DownloadFailedException is thrown if there is an error +75 * downloading the file +76 */ +77 public static void fetchFile(URL url, File outputPath) throws DownloadFailedException { +78 fetchFile(url, outputPath, true); +79 } +80 +81 /** +82 * Retrieves a file from a given URL and saves it to the outputPath. +83 * +84 * @param url the URL of the file to download +85 * @param outputPath the path to the save the file to +86 * @param useProxy whether to use the configured proxy when downloading +87 * files +88 * @throws DownloadFailedException is thrown if there is an error +89 * downloading the file +90 */ +91 public static void fetchFile(URL url, File outputPath, boolean useProxy) throws DownloadFailedException { +92 if ("file".equalsIgnoreCase(url.getProtocol())) { +93 File file; +94 try { +95 file = new File(url.toURI()); +96 } catch (URISyntaxException ex) { +97 final String msg = format("Download failed, unable to locate '%s'", url.toString()); +98 throw new DownloadFailedException(msg); +99 } +100 if (file.exists()) { +101 try { +102 org.apache.commons.io.FileUtils.copyFile(file, outputPath); +103 } catch (IOException ex) { +104 final String msg = format("Download failed, unable to copy '%s' to '%s'", url.toString(), outputPath.getAbsolutePath()); +105 throw new DownloadFailedException(msg); +106 } +107 } else { +108 final String msg = format("Download failed, file ('%s') does not exist", url.toString()); +109 throw new DownloadFailedException(msg); +110 } +111 } else { +112 HttpURLConnection conn = null; +113 try { +114 LOGGER.debug("Attempting download of {}", url.toString()); +115 conn = URLConnectionFactory.createHttpURLConnection(url, useProxy); +116 conn.setRequestProperty("Accept-Encoding", "gzip, deflate"); +117 conn.connect(); +118 int status = conn.getResponseCode(); +119 int redirectCount = 0; +120 while ((status == HttpURLConnection.HTTP_MOVED_TEMP +121 || status == HttpURLConnection.HTTP_MOVED_PERM +122 || status == HttpURLConnection.HTTP_SEE_OTHER) +123 && MAX_REDIRECT_ATTEMPTS > redirectCount++) { +124 final String location = conn.getHeaderField("Location"); +125 try { +126 conn.disconnect(); +127 } finally { +128 conn = null; +129 } +130 LOGGER.debug("Download is being redirected from {} to {}", url.toString(), location); +131 conn = URLConnectionFactory.createHttpURLConnection(new URL(location), useProxy); +132 conn.setRequestProperty("Accept-Encoding", "gzip, deflate"); +133 conn.connect(); +134 status = conn.getResponseCode(); +135 } +136 if (status != 200) { +137 try { +138 conn.disconnect(); +139 } finally { +140 conn = null; +141 } +142 final String msg = format("Error downloading file %s; received response code %s.", url.toString(), status); +143 throw new DownloadFailedException(msg); +144 +145 } +146 } catch (IOException ex) { +147 try { +148 if (conn != null) { +149 conn.disconnect(); +150 } +151 } finally { +152 conn = null; +153 } +154 final String msg = format("Error downloading file %s; unable to connect.", url.toString()); +155 throw new DownloadFailedException(msg, ex); +156 } +157 +158 final String encoding = conn.getContentEncoding(); +159 BufferedOutputStream writer = null; +160 InputStream reader = null; +161 try { +162 if (encoding != null && "gzip".equalsIgnoreCase(encoding)) { +163 reader = new GZIPInputStream(conn.getInputStream()); +164 } else if (encoding != null && "deflate".equalsIgnoreCase(encoding)) { +165 reader = new InflaterInputStream(conn.getInputStream()); +166 } else { +167 reader = conn.getInputStream(); +168 } +169 +170 writer = new BufferedOutputStream(new FileOutputStream(outputPath)); +171 final byte[] buffer = new byte[4096]; +172 int bytesRead; +173 while ((bytesRead = reader.read(buffer)) > 0) { +174 writer.write(buffer, 0, bytesRead); +175 } +176 LOGGER.debug("Download of {} complete", url.toString()); +177 } catch (IOException ex) { +178 checkForCommonExceptionTypes(ex); +179 final String msg = format("Error saving '%s' to file '%s'%nConnection Timeout: %d%nEncoding: %s%n", +180 url.toString(), outputPath.getAbsolutePath(), conn.getConnectTimeout(), encoding); +181 throw new DownloadFailedException(msg, ex); +182 } catch (Throwable ex) { +183 final String msg = format("Unexpected exception saving '%s' to file '%s'%nConnection Timeout: %d%nEncoding: %s%n", +184 url.toString(), outputPath.getAbsolutePath(), conn.getConnectTimeout(), encoding); +185 throw new DownloadFailedException(msg, ex); +186 } finally { +187 if (writer != null) { +188 try { +189 writer.close(); +190 } catch (IOException ex) { +191 LOGGER.trace("Error closing the writer in Downloader.", ex); +192 } +193 } +194 if (reader != null) { +195 try { +196 reader.close(); +197 } catch (IOException ex) { +198 LOGGER.trace("Error closing the reader in Downloader.", ex); +199 } +200 } +201 try { +202 conn.disconnect(); +203 } finally { +204 conn = null; +205 } +206 } +207 } +208 } +209 +210 /** +211 * Makes an HTTP Head request to retrieve the last modified date of the +212 * given URL. If the file:// protocol is specified, then the lastTimestamp +213 * of the file is returned. +214 * +215 * @param url the URL to retrieve the timestamp from +216 * @return an epoch timestamp +217 * @throws DownloadFailedException is thrown if an exception occurs making +218 * the HTTP request +219 */ +220 public static long getLastModified(URL url) throws DownloadFailedException { +221 return getLastModified(url, false); +222 } +223 +224 /** +225 * Makes an HTTP Head request to retrieve the last modified date of the +226 * given URL. If the file:// protocol is specified, then the lastTimestamp +227 * of the file is returned. +228 * +229 * @param url the URL to retrieve the timestamp from +230 * @param isRetry indicates if this is a retry - to prevent endless loop and +231 * stack overflow +232 * @return an epoch timestamp +233 * @throws DownloadFailedException is thrown if an exception occurs making +234 * the HTTP request +235 */ +236 private static long getLastModified(URL url, boolean isRetry) throws DownloadFailedException { +237 long timestamp = 0; +238 //TODO add the FTP protocol? +239 if ("file".equalsIgnoreCase(url.getProtocol())) { +240 File lastModifiedFile; +241 try { +242 lastModifiedFile = new File(url.toURI()); +243 } catch (URISyntaxException ex) { +244 final String msg = format("Unable to locate '%s'", url.toString()); +245 throw new DownloadFailedException(msg); +246 } +247 timestamp = lastModifiedFile.lastModified(); +248 } else { +249 final String httpMethod = determineHttpMethod(); +250 HttpURLConnection conn = null; +251 try { +252 conn = URLConnectionFactory.createHttpURLConnection(url); +253 conn.setRequestMethod(httpMethod); +254 conn.connect(); +255 final int t = conn.getResponseCode(); +256 if (t >= 200 && t < 300) { +257 timestamp = conn.getLastModified(); +258 } else { +259 throw new DownloadFailedException(format("%s request returned a non-200 status code", httpMethod)); +260 } +261 } catch (URLConnectionFailureException ex) { +262 throw new DownloadFailedException(format("Error creating URL Connection for HTTP %s request.", httpMethod), ex); +263 } catch (IOException ex) { +264 checkForCommonExceptionTypes(ex); +265 LOGGER.error("IO Exception: " + ex.getMessage()); +266 LOGGER.debug("Exception details", ex); +267 if (ex.getCause() != null) { +268 LOGGER.debug("IO Exception cause: " + ex.getCause().getMessage(), ex.getCause()); +269 } +270 try { +271 //retry +272 if (!isRetry && Settings.getBoolean(Settings.KEYS.DOWNLOADER_QUICK_QUERY_TIMESTAMP)) { +273 Settings.setBoolean(Settings.KEYS.DOWNLOADER_QUICK_QUERY_TIMESTAMP, false); +274 return getLastModified(url, true); +275 } +276 } catch (InvalidSettingException ex1) { +277 LOGGER.debug("invalid setting?", ex); +278 } +279 throw new DownloadFailedException(format("Error making HTTP %s request.", httpMethod), ex); +280 } finally { +281 if (conn != null) { +282 try { +283 conn.disconnect(); +284 } finally { +285 conn = null; +286 } +287 } 288 } -289 cause = cause.getCause(); -290 } +289 } +290 return timestamp; 291 } 292 293 /** -294 * Returns the HEAD or GET HTTP method. HEAD is the default. -295 * -296 * @return the HTTP method to use -297 */ -298 private static String determineHttpMethod() { -299 return isQuickQuery() ? HEAD : GET; -300 } -301 -302 /** -303 * Determines if the HTTP method GET or HEAD should be used to check the timestamp on external resources. -304 * -305 * @return true if configured to use HEAD requests -306 */ -307 private static boolean isQuickQuery() { -308 boolean quickQuery; -309 -310 try { -311 quickQuery = Settings.getBoolean(Settings.KEYS.DOWNLOADER_QUICK_QUERY_TIMESTAMP, true); -312 } catch (InvalidSettingException e) { -313 quickQuery = true; -314 } -315 return quickQuery; -316 } -317 } +294 * Analyzes the IOException, logs the appropriate information for debugging +295 * purposes, and then throws a DownloadFailedException that wraps the IO +296 * Exception for common IO Exceptions. This is to provide additional details +297 * to assist in resolution of the exception. +298 * +299 * @param ex the original exception +300 * @throws DownloadFailedException a wrapper exception that contains the +301 * original exception as the cause +302 */ +303 protected static void checkForCommonExceptionTypes(IOException ex) throws DownloadFailedException { +304 Throwable cause = ex; +305 while (cause != null) { +306 if (cause instanceof java.net.UnknownHostException) { +307 final String msg = String.format("Unable to resolve domain '%s'", cause.getMessage()); +308 LOGGER.error(msg); +309 throw new DownloadFailedException(msg); +310 } +311 if (cause instanceof InvalidAlgorithmParameterException) { +312 final String keystore = System.getProperty("javax.net.ssl.keyStore"); +313 final String version = System.getProperty("java.version"); +314 final String vendor = System.getProperty("java.vendor"); +315 LOGGER.info("Error making HTTPS request - InvalidAlgorithmParameterException"); +316 LOGGER.info("There appears to be an issue with the installation of Java and the cacerts." +317 + "See closed issue #177 here: https://github.com/jeremylong/DependencyCheck/issues/177"); +318 LOGGER.info("Java Info:\njavax.net.ssl.keyStore='{}'\njava.version='{}'\njava.vendor='{}'", +319 keystore, version, vendor); +320 throw new DownloadFailedException("Error making HTTPS request. Please see the log for more details."); +321 } +322 cause = cause.getCause(); +323 } +324 } +325 +326 /** +327 * Returns the HEAD or GET HTTP method. HEAD is the default. +328 * +329 * @return the HTTP method to use +330 */ +331 private static String determineHttpMethod() { +332 return isQuickQuery() ? HEAD : GET; +333 } +334 +335 /** +336 * Determines if the HTTP method GET or HEAD should be used to check the +337 * timestamp on external resources. +338 * +339 * @return true if configured to use HEAD requests +340 */ +341 private static boolean isQuickQuery() { +342 boolean quickQuery; +343 +344 try { +345 quickQuery = Settings.getBoolean(Settings.KEYS.DOWNLOADER_QUICK_QUERY_TIMESTAMP, true); +346 } catch (InvalidSettingException e) { +347 quickQuery = true; +348 } +349 return quickQuery; +350 } +351 }
        diff --git a/xref/org/owasp/dependencycheck/utils/SSLSocketFactoryEx.html b/xref/org/owasp/dependencycheck/utils/SSLSocketFactoryEx.html new file mode 100644 index 000000000..0c780ffa3 --- /dev/null +++ b/xref/org/owasp/dependencycheck/utils/SSLSocketFactoryEx.html @@ -0,0 +1,398 @@ + + + +SSLSocketFactoryEx xref + + + +
        +1   package org.owasp.dependencycheck.utils;
        +2   
        +3   import java.io.IOException;
        +4   import java.net.InetAddress;
        +5   import java.net.Socket;
        +6   import java.security.KeyManagementException;
        +7   import java.security.NoSuchAlgorithmException;
        +8   import java.security.SecureRandom;
        +9   import java.util.ArrayList;
        +10  import java.util.Arrays;
        +11  import java.util.List;
        +12  import javax.net.ssl.KeyManager;
        +13  import javax.net.ssl.SSLContext;
        +14  import javax.net.ssl.SSLSocket;
        +15  import javax.net.ssl.SSLSocketFactory;
        +16  import javax.net.ssl.TrustManager;
        +17  import org.slf4j.Logger;
        +18  import org.slf4j.LoggerFactory;
        +19  
        +20  /**
        +21   * This class is used to enable additional ciphers used by the SSL Socket. This
        +22   * is specifically because the NVD stopped supporting TLS 1.0 and Java 6 and 7
        +23   * clients by default were unable to connect to download the NVD data feeds.
        +24   *
        +25   * The following code was copied from
        +26   * http://stackoverflow.com/questions/1037590/which-cipher-suites-to-enable-for-ssl-socket/23365536#23365536
        +27   *
        +28   * @author <a href="http://stackoverflow.com/users/608639/jww">jww</a>
        +29   */
        +30  public class SSLSocketFactoryEx extends SSLSocketFactory {
        +31  
        +32      /**
        +33       * The Logger for use throughout the class.
        +34       */
        +35      private static final Logger LOGGER = LoggerFactory.getLogger(SSLSocketFactoryEx.class);
        +36  
        +37      /**
        +38       * Constructs a new SSLSocketFactory.
        +39       *
        +40       * @throws NoSuchAlgorithmException thrown when an algorithm is not
        +41       * supported
        +42       * @throws KeyManagementException thrown if initialization fails
        +43       */
        +44      public SSLSocketFactoryEx() throws NoSuchAlgorithmException, KeyManagementException {
        +45          initSSLSocketFactoryEx(null, null, null);
        +46      }
        +47  
        +48      /**
        +49       * Constructs a new SSLSocketFactory.
        +50       *
        +51       * @param km the key manager
        +52       * @param tm the trust manager
        +53       * @param random secure random
        +54       * @throws NoSuchAlgorithmException thrown when an algorithm is not
        +55       * supported
        +56       * @throws KeyManagementException thrown if initialization fails
        +57       */
        +58      public SSLSocketFactoryEx(KeyManager[] km, TrustManager[] tm, SecureRandom random) throws NoSuchAlgorithmException, KeyManagementException {
        +59          initSSLSocketFactoryEx(km, tm, random);
        +60      }
        +61  
        +62      /**
        +63       * Constructs a new SSLSocketFactory.
        +64       *
        +65       * @param ctx the SSL context
        +66       * @throws NoSuchAlgorithmException thrown when an algorithm is not
        +67       * supported
        +68       * @throws KeyManagementException thrown if initialization fails
        +69       */
        +70      public SSLSocketFactoryEx(SSLContext ctx) throws NoSuchAlgorithmException, KeyManagementException {
        +71          initSSLSocketFactoryEx(ctx);
        +72      }
        +73  
        +74      /**
        +75       * Returns the default cipher suites.
        +76       *
        +77       * @return the default cipher suites
        +78       */
        +79      @Override
        +80      public String[] getDefaultCipherSuites() {
        +81          return Arrays.copyOf(ciphers, ciphers.length);
        +82      }
        +83  
        +84      /**
        +85       * Returns the supported cipher suites.
        +86       *
        +87       * @return the supported cipher suites
        +88       */
        +89      @Override
        +90      public String[] getSupportedCipherSuites() {
        +91          return Arrays.copyOf(ciphers, ciphers.length);
        +92      }
        +93  
        +94      /**
        +95       * Returns the default protocols.
        +96       *
        +97       * @return the default protocols
        +98       */
        +99      public String[] getDefaultProtocols() {
        +100         return Arrays.copyOf(protocols, protocols.length);
        +101     }
        +102 
        +103     /**
        +104      * Returns the supported protocols.
        +105      *
        +106      * @return the supported protocols
        +107      */
        +108     public String[] getSupportedProtocols() {
        +109         return Arrays.copyOf(protocols, protocols.length);
        +110     }
        +111 
        +112     /**
        +113      * Creates an SSL Socket.
        +114      *
        +115      * @param s the base socket
        +116      * @param host the host
        +117      * @param port the port
        +118      * @param autoClose if the socket should auto-close
        +119      * @return the SSL Socket
        +120      * @throws IOException thrown if the creation fails
        +121      */
        +122     @Override
        +123     public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
        +124         final SSLSocketFactory factory = sslCtxt.getSocketFactory();
        +125         final SSLSocket ss = (SSLSocket) factory.createSocket(s, host, port, autoClose);
        +126 
        +127         ss.setEnabledProtocols(protocols);
        +128         ss.setEnabledCipherSuites(ciphers);
        +129 
        +130         return ss;
        +131     }
        +132 
        +133     /**
        +134      * Creates a new SSL Socket.
        +135      *
        +136      * @param address the address to connect to
        +137      * @param port the port number
        +138      * @param localAddress the local address
        +139      * @param localPort the local port
        +140      * @return the SSL Socket
        +141      * @throws IOException thrown if the creation fails
        +142      */
        +143     @Override
        +144     public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
        +145         final SSLSocketFactory factory = sslCtxt.getSocketFactory();
        +146         final SSLSocket ss = (SSLSocket) factory.createSocket(address, port, localAddress, localPort);
        +147 
        +148         ss.setEnabledProtocols(protocols);
        +149         ss.setEnabledCipherSuites(ciphers);
        +150 
        +151         return ss;
        +152     }
        +153 
        +154     /**
        +155      * Creates a new SSL Socket.
        +156      *
        +157      * @param host the host to connect to
        +158      * @param port the port to connect to
        +159      * @param localHost the local host
        +160      * @param localPort the local port
        +161      * @return the SSL Socket
        +162      * @throws IOException thrown if the creation fails
        +163      */
        +164     @Override
        +165     public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException {
        +166         final SSLSocketFactory factory = sslCtxt.getSocketFactory();
        +167         final SSLSocket ss = (SSLSocket) factory.createSocket(host, port, localHost, localPort);
        +168 
        +169         ss.setEnabledProtocols(protocols);
        +170         ss.setEnabledCipherSuites(ciphers);
        +171 
        +172         return ss;
        +173     }
        +174 
        +175     /**
        +176      * Creates a new SSL Socket.
        +177      *
        +178      * @param host the host to connect to
        +179      * @param port the port to connect to
        +180      * @return the SSL Socket
        +181      * @throws IOException thrown if the creation fails
        +182      */
        +183     @Override
        +184     public Socket createSocket(InetAddress host, int port) throws IOException {
        +185         final SSLSocketFactory factory = sslCtxt.getSocketFactory();
        +186         final SSLSocket ss = (SSLSocket) factory.createSocket(host, port);
        +187 
        +188         ss.setEnabledProtocols(protocols);
        +189         ss.setEnabledCipherSuites(ciphers);
        +190 
        +191         return ss;
        +192     }
        +193 
        +194     /**
        +195      * Creates a new SSL Socket.
        +196      *
        +197      * @param host the host to connect to
        +198      * @param port the port to connect to
        +199      * @return the SSL Socket
        +200      * @throws IOException thrown if the creation fails
        +201      */
        +202     @Override
        +203     public Socket createSocket(String host, int port) throws IOException {
        +204         final SSLSocketFactory factory = sslCtxt.getSocketFactory();
        +205         final SSLSocket ss = (SSLSocket) factory.createSocket(host, port);
        +206 
        +207         ss.setEnabledProtocols(protocols);
        +208         ss.setEnabledCipherSuites(ciphers);
        +209 
        +210         return ss;
        +211     }
        +212 
        +213     /**
        +214      * Initializes the SSL Socket Factory Extension.
        +215      *
        +216      * @param km the key managers
        +217      * @param tm the trust managers
        +218      * @param random the secure random number generator
        +219      * @throws NoSuchAlgorithmException thrown when an algorithm is not
        +220      * supported
        +221      * @throws KeyManagementException thrown if initialization fails
        +222      */
        +223     private void initSSLSocketFactoryEx(KeyManager[] km, TrustManager[] tm, SecureRandom random)
        +224             throws NoSuchAlgorithmException, KeyManagementException {
        +225         sslCtxt = SSLContext.getInstance("TLS");
        +226         sslCtxt.init(km, tm, random);
        +227 
        +228         protocols = getProtocolList();
        +229         ciphers = getCipherList();
        +230     }
        +231 
        +232     /**
        +233      * Initializes the SSL Socket Factory Extension.
        +234      *
        +235      * @param ctx the SSL context
        +236      * @throws NoSuchAlgorithmException thrown when an algorithm is not
        +237      * supported
        +238      * @throws KeyManagementException thrown if initialization fails
        +239      */
        +240     private void initSSLSocketFactoryEx(SSLContext ctx)
        +241             throws NoSuchAlgorithmException, KeyManagementException {
        +242         sslCtxt = ctx;
        +243 
        +244         protocols = getProtocolList();
        +245         ciphers = getCipherList();
        +246     }
        +247 
        +248     /**
        +249      * Returns the protocol list.
        +250      *
        +251      * @return the protocol list
        +252      */
        +253     protected String[] getProtocolList() {
        +254         final String[] preferredProtocols = {"TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3"};
        +255         String[] availableProtocols = null;
        +256 
        +257         SSLSocket socket = null;
        +258 
        +259         try {
        +260             final SSLSocketFactory factory = sslCtxt.getSocketFactory();
        +261             socket = (SSLSocket) factory.createSocket();
        +262 
        +263             availableProtocols = socket.getSupportedProtocols();
        +264             Arrays.sort(availableProtocols);
        +265         } catch (Exception ex) {
        +266             LOGGER.debug("Error getting protocol list, using TLSv1", ex);
        +267             return new String[]{"TLSv1"};
        +268         } finally {
        +269             if (socket != null) {
        +270                 try {
        +271                     socket.close();
        +272                 } catch (IOException ex) {
        +273                     LOGGER.trace("Error closing socket", ex);
        +274                 }
        +275             }
        +276         }
        +277 
        +278         final List<String> aa = new ArrayList<String>();
        +279         for (String preferredProtocol : preferredProtocols) {
        +280             final int idx = Arrays.binarySearch(availableProtocols, preferredProtocol);
        +281             if (idx >= 0) {
        +282                 aa.add(preferredProtocol);
        +283             }
        +284         }
        +285 
        +286         return aa.toArray(new String[0]);
        +287     }
        +288 
        +289     /**
        +290      * Returns the cipher list.
        +291      *
        +292      * @return the cipher list
        +293      */
        +294     protected String[] getCipherList() {
        +295         final String[] preferredCiphers = {
        +296             // *_CHACHA20_POLY1305 are 3x to 4x faster than existing cipher suites.
        +297             //   http://googleonlinesecurity.blogspot.com/2014/04/speeding-up-and-strengthening-https.html
        +298             // Use them if available. Normative names can be found at (TLS spec depends on IPSec spec):
        +299             //   http://tools.ietf.org/html/draft-nir-ipsecme-chacha20-poly1305-01
        +300             //   http://tools.ietf.org/html/draft-mavrogiannopoulos-chacha-tls-02
        +301             "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305",
        +302             "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305",
        +303             "TLS_ECDHE_ECDSA_WITH_CHACHA20_SHA",
        +304             "TLS_ECDHE_RSA_WITH_CHACHA20_SHA",
        +305             "TLS_DHE_RSA_WITH_CHACHA20_POLY1305",
        +306             "TLS_RSA_WITH_CHACHA20_POLY1305",
        +307             "TLS_DHE_RSA_WITH_CHACHA20_SHA",
        +308             "TLS_RSA_WITH_CHACHA20_SHA",
        +309             // Done with bleeding edge, back to TLS v1.2 and below
        +310             "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384",
        +311             "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384",
        +312             "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
        +313             "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
        +314             "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
        +315             "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384",
        +316             "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
        +317             "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256",
        +318             // TLS v1.0 (with some SSLv3 interop)
        +319             "TLS_DHE_RSA_WITH_AES_256_CBC_SHA384",
        +320             "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256",
        +321             "TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
        +322             "TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
        +323             "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
        +324             "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA",
        +325             "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA",
        +326             "SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA",
        +327             // RSA key transport sucks, but they are needed as a fallback.
        +328             // For example, microsoft.com fails under all versions of TLS
        +329             // if they are not included. If only TLS 1.0 is available at
        +330             // the client, then google.com will fail too. TLS v1.3 is
        +331             // trying to deprecate them, so it will be interesteng to see
        +332             // what happens.
        +333             "TLS_RSA_WITH_AES_256_CBC_SHA256",
        +334             "TLS_RSA_WITH_AES_256_CBC_SHA",
        +335             "TLS_RSA_WITH_AES_128_CBC_SHA256",
        +336             "TLS_RSA_WITH_AES_128_CBC_SHA",
        +337         };
        +338 
        +339         String[] availableCiphers;
        +340 
        +341         try {
        +342             final SSLSocketFactory factory = sslCtxt.getSocketFactory();
        +343             availableCiphers = factory.getSupportedCipherSuites();
        +344             Arrays.sort(availableCiphers);
        +345         } catch (Exception e) {
        +346             LOGGER.debug("Error retrieving ciphers", e);
        +347             return new String[]{
        +348                 "TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
        +349                 "TLS_DHE_DSS_WITH_AES_256_CBC_SHA",
        +350                 "TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
        +351                 "TLS_DHE_RSA_WITH_AES_256_CBC_SHA",
        +352                 "TLS_RSA_WITH_AES_256_CBC_SHA256",
        +353                 "TLS_RSA_WITH_AES_256_CBC_SHA",
        +354                 "TLS_RSA_WITH_AES_128_CBC_SHA256",
        +355                 "TLS_RSA_WITH_AES_128_CBC_SHA",
        +356                 "TLS_EMPTY_RENEGOTIATION_INFO_SCSV",
        +357             };
        +358         }
        +359 
        +360         final List<String> aa = new ArrayList<String>();
        +361         for (String preferredCipher : preferredCiphers) {
        +362             final int idx = Arrays.binarySearch(availableCiphers, preferredCipher);
        +363             if (idx >= 0) {
        +364                 aa.add(preferredCipher);
        +365             }
        +366         }
        +367 
        +368         aa.add("TLS_EMPTY_RENEGOTIATION_INFO_SCSV");
        +369 
        +370         return aa.toArray(new String[0]);
        +371     }
        +372 
        +373     /**
        +374      * The SSL context.
        +375      */
        +376     private SSLContext sslCtxt;
        +377     /**
        +378      * The cipher suites.
        +379      */
        +380     private String[] ciphers;
        +381     /**
        +382      * The protocols.
        +383      */
        +384     private String[] protocols;
        +385 }
        +
        +
        + + + diff --git a/xref/org/owasp/dependencycheck/utils/Settings.html b/xref/org/owasp/dependencycheck/utils/Settings.html index f53fda40e..3dddd026c 100644 --- a/xref/org/owasp/dependencycheck/utils/Settings.html +++ b/xref/org/owasp/dependencycheck/utils/Settings.html @@ -54,815 +54,883 @@ 46 public static final class KEYS { 47 48 /** -49 * private constructor because this is a "utility" class containing constants -50 */ -51 private KEYS() { -52 //do nothing -53 } -54 /** -55 * The key to obtain the application name. -56 */ -57 public static final String APPLICATION_VAME = "application.name"; -58 /** -59 * The key to obtain the application version. -60 */ -61 public static final String APPLICATION_VERSION = "application.version"; -62 /** -63 * The key to obtain the URL to retrieve the current release version from. -64 */ -65 public static final String ENGINE_VERSION_CHECK_URL = "engine.version.url"; -66 /** -67 * The properties key indicating whether or not the cached data sources should be updated. -68 */ -69 public static final String AUTO_UPDATE = "autoupdate"; -70 /** -71 * The database driver class name. If this is not in the properties file the embedded database is used. -72 */ -73 public static final String DB_DRIVER_NAME = "data.driver_name"; -74 /** -75 * The database driver class name. If this is not in the properties file the embedded database is used. +49 * private constructor because this is a "utility" class containing +50 * constants +51 */ +52 private KEYS() { +53 //do nothing +54 } +55 /** +56 * The key to obtain the application name. +57 */ +58 public static final String APPLICATION_VAME = "application.name"; +59 /** +60 * The key to obtain the application version. +61 */ +62 public static final String APPLICATION_VERSION = "application.version"; +63 /** +64 * The key to obtain the URL to retrieve the current release version +65 * from. +66 */ +67 public static final String ENGINE_VERSION_CHECK_URL = "engine.version.url"; +68 /** +69 * The properties key indicating whether or not the cached data sources +70 * should be updated. +71 */ +72 public static final String AUTO_UPDATE = "autoupdate"; +73 /** +74 * The database driver class name. If this is not in the properties file +75 * the embedded database is used. 76 */ -77 public static final String DB_DRIVER_PATH = "data.driver_path"; +77 public static final String DB_DRIVER_NAME = "data.driver_name"; 78 /** -79 * The database connection string. If this is not in the properties file the embedded database is used. -80 */ -81 public static final String DB_CONNECTION_STRING = "data.connection_string"; -82 /** -83 * The username to use when connecting to the database. -84 */ -85 public static final String DB_USER = "data.user"; -86 /** -87 * The password to authenticate to the database. -88 */ -89 public static final String DB_PASSWORD = "data.password"; -90 /** -91 * The base path to use for the data directory (for embedded db). -92 */ -93 public static final String DATA_DIRECTORY = "data.directory"; -94 /** -95 * The database file name. -96 */ -97 public static final String DB_FILE_NAME = "data.file_name"; -98 /** -99 * The database schema version. -100 */ -101 public static final String DB_VERSION = "data.version"; -102 /** -103 * The properties key for the URL to retrieve the "meta" data from about the CVE entries. -104 */ -105 public static final String CVE_META_URL = "cve.url.meta"; -106 /** -107 * The properties key for the URL to retrieve the recently modified and added CVE entries (last 8 days) using the 2.0 -108 * schema. -109 */ -110 public static final String CVE_MODIFIED_20_URL = "cve.url-2.0.modified"; -111 /** -112 * The properties key for the URL to retrieve the recently modified and added CVE entries (last 8 days) using the 1.2 -113 * schema. +79 * The database driver class name. If this is not in the properties file +80 * the embedded database is used. +81 */ +82 public static final String DB_DRIVER_PATH = "data.driver_path"; +83 /** +84 * The database connection string. If this is not in the properties file +85 * the embedded database is used. +86 */ +87 public static final String DB_CONNECTION_STRING = "data.connection_string"; +88 /** +89 * The username to use when connecting to the database. +90 */ +91 public static final String DB_USER = "data.user"; +92 /** +93 * The password to authenticate to the database. +94 */ +95 public static final String DB_PASSWORD = "data.password"; +96 /** +97 * The base path to use for the data directory (for embedded db). +98 */ +99 public static final String DATA_DIRECTORY = "data.directory"; +100 /** +101 * The database file name. +102 */ +103 public static final String DB_FILE_NAME = "data.file_name"; +104 /** +105 * The database schema version. +106 */ +107 public static final String DB_VERSION = "data.version"; +108 /** +109 * The starts with filter used to exclude CVE entries from the database. +110 * By default this is set to 'cpe:/a:' which limits the CVEs imported to +111 * just those that are related to applications. If this were set to just +112 * 'cpe:' the OS, hardware, and application related CVEs would be +113 * imported. 114 */ -115 public static final String CVE_MODIFIED_12_URL = "cve.url-1.2.modified"; +115 public static final String CVE_CPE_STARTS_WITH_FILTER = "cve.cpe.startswith.filter"; 116 /** -117 * The properties key for the URL to retrieve the recently modified and added CVE entries (last 8 days). -118 */ -119 public static final String CVE_MODIFIED_VALID_FOR_DAYS = "cve.url.modified.validfordays"; -120 /** -121 * The properties key to control the skipping of the check for CVE updates. -122 */ -123 public static final String CVE_CHECK_VALID_FOR_HOURS = "cve.check.validforhours"; -124 /** -125 * The properties key for the telling us how many cve.url.* URLs exists. This is used in combination with CVE_BASE_URL to -126 * be able to retrieve the URLs for all of the files that make up the NVD CVE listing. -127 */ -128 public static final String CVE_START_YEAR = "cve.startyear"; -129 /** -130 * The properties key for the CVE schema version 1.2. -131 */ -132 public static final String CVE_SCHEMA_1_2 = "cve.url-1.2.base"; -133 /** -134 * The properties key for the CVE schema version 2.0. -135 */ -136 public static final String CVE_SCHEMA_2_0 = "cve.url-2.0.base"; -137 /** -138 * The properties key that indicates how often the CPE data needs to be updated. +117 * The properties key for the URL to retrieve the "meta" data from about +118 * the CVE entries. +119 */ +120 public static final String CVE_META_URL = "cve.url.meta"; +121 /** +122 * The properties key for the URL to retrieve the recently modified and +123 * added CVE entries (last 8 days) using the 2.0 schema. +124 */ +125 public static final String CVE_MODIFIED_20_URL = "cve.url-2.0.modified"; +126 /** +127 * The properties key for the URL to retrieve the recently modified and +128 * added CVE entries (last 8 days) using the 1.2 schema. +129 */ +130 public static final String CVE_MODIFIED_12_URL = "cve.url-1.2.modified"; +131 /** +132 * The properties key for the URL to retrieve the recently modified and +133 * added CVE entries (last 8 days). +134 */ +135 public static final String CVE_MODIFIED_VALID_FOR_DAYS = "cve.url.modified.validfordays"; +136 /** +137 * The properties key to control the skipping of the check for CVE +138 * updates. 139 */ -140 public static final String CPE_MODIFIED_VALID_FOR_DAYS = "cpe.validfordays"; +140 public static final String CVE_CHECK_VALID_FOR_HOURS = "cve.check.validforhours"; 141 /** -142 * The properties key for the URL to retrieve the CPE. -143 */ -144 public static final String CPE_URL = "cpe.url"; -145 /** -146 * The properties key for the proxy server. -147 * -148 * @deprecated use {@link org.owasp.dependencycheck.utils.Settings.KEYS#PROXY_SERVER} instead. +142 * The properties key for the telling us how many cve.url.* URLs exists. +143 * This is used in combination with CVE_BASE_URL to be able to retrieve +144 * the URLs for all of the files that make up the NVD CVE listing. +145 */ +146 public static final String CVE_START_YEAR = "cve.startyear"; +147 /** +148 * The properties key for the CVE schema version 1.2. 149 */ -150 @Deprecated -151 public static final String PROXY_URL = "proxy.server"; -152 /** -153 * The properties key for the proxy server. -154 */ -155 public static final String PROXY_SERVER = "proxy.server"; -156 /** -157 * The properties key for the proxy port - this must be an integer value. +150 public static final String CVE_SCHEMA_1_2 = "cve.url-1.2.base"; +151 /** +152 * The properties key for the CVE schema version 2.0. +153 */ +154 public static final String CVE_SCHEMA_2_0 = "cve.url-2.0.base"; +155 /** +156 * The properties key that indicates how often the CPE data needs to be +157 * updated. 158 */ -159 public static final String PROXY_PORT = "proxy.port"; +159 public static final String CPE_MODIFIED_VALID_FOR_DAYS = "cpe.validfordays"; 160 /** -161 * The properties key for the proxy username. +161 * The properties key for the URL to retrieve the CPE. 162 */ -163 public static final String PROXY_USERNAME = "proxy.username"; +163 public static final String CPE_URL = "cpe.url"; 164 /** -165 * The properties key for the proxy password. -166 */ -167 public static final String PROXY_PASSWORD = "proxy.password"; -168 /** -169 * The properties key for the non proxy hosts. +165 * The properties key for the proxy server. +166 * +167 * @deprecated use +168 * {@link org.owasp.dependencycheck.utils.Settings.KEYS#PROXY_SERVER} +169 * instead. 170 */ -171 public static final String PROXY_NON_PROXY_HOSTS = "proxy.nonproxyhosts"; -172 /** -173 * The properties key for the connection timeout. -174 */ -175 public static final String CONNECTION_TIMEOUT = "connection.timeout"; -176 /** -177 * The location of the temporary directory. -178 */ -179 public static final String TEMP_DIRECTORY = "temp.directory"; -180 /** -181 * The maximum number of threads to allocate when downloading files. -182 */ -183 public static final String MAX_DOWNLOAD_THREAD_POOL_SIZE = "max.download.threads"; -184 /** -185 * The key for a list of suppression files. -186 */ -187 public static final String SUPPRESSION_FILE = "suppression.file"; -188 /** -189 * The properties key for whether the Jar Analyzer is enabled. -190 */ -191 public static final String ANALYZER_JAR_ENABLED = "analyzer.jar.enabled"; -192 /** -193 * The properties key for whether experimental analyzers are loaded. -194 */ -195 public static final String ANALYZER_EXPERIMENTAL_ENABLED = "analyzer.experimental.enabled"; -196 /** -197 * The properties key for whether the Archive analyzer is enabled. -198 */ -199 public static final String ANALYZER_ARCHIVE_ENABLED = "analyzer.archive.enabled"; -200 /** -201 * The properties key for whether the node.js package analyzer is enabled. -202 */ -203 public static final String ANALYZER_NODE_PACKAGE_ENABLED = "analyzer.node.package.enabled"; -204 /** -205 * The properties key for whether the composer lock file analyzer is enabled. -206 */ -207 public static final String ANALYZER_COMPOSER_LOCK_ENABLED = "analyzer.composer.lock.enabled"; -208 /** -209 * The properties key for whether the Python Distribution analyzer is enabled. -210 */ -211 public static final String ANALYZER_PYTHON_DISTRIBUTION_ENABLED = "analyzer.python.distribution.enabled"; -212 /** -213 * The properties key for whether the Python Package analyzer is enabled. -214 */ -215 public static final String ANALYZER_PYTHON_PACKAGE_ENABLED = "analyzer.python.package.enabled"; -216 /** -217 * The properties key for whether the Ruby Gemspec Analyzer is enabled. -218 */ -219 public static final String ANALYZER_RUBY_GEMSPEC_ENABLED = "analyzer.ruby.gemspec.enabled"; -220 /** -221 * The properties key for whether the Autoconf analyzer is enabled. -222 */ -223 public static final String ANALYZER_AUTOCONF_ENABLED = "analyzer.autoconf.enabled"; -224 /** -225 * The properties key for whether the CMake analyzer is enabled. -226 */ -227 public static final String ANALYZER_CMAKE_ENABLED = "analyzer.cmake.enabled"; -228 /** -229 * The properties key for whether the Ruby Bundler Audit analyzer is enabled. -230 */ -231 public static final String ANALYZER_BUNDLE_AUDIT_ENABLED = "analyzer.bundle.audit.enabled"; -232 /** -233 * The properties key for whether the .NET Assembly analyzer is enabled. +171 @Deprecated +172 public static final String PROXY_URL = "proxy.server"; +173 /** +174 * The properties key for the proxy server. +175 */ +176 public static final String PROXY_SERVER = "proxy.server"; +177 /** +178 * The properties key for the proxy port - this must be an integer +179 * value. +180 */ +181 public static final String PROXY_PORT = "proxy.port"; +182 /** +183 * The properties key for the proxy username. +184 */ +185 public static final String PROXY_USERNAME = "proxy.username"; +186 /** +187 * The properties key for the proxy password. +188 */ +189 public static final String PROXY_PASSWORD = "proxy.password"; +190 /** +191 * The properties key for the non proxy hosts. +192 */ +193 public static final String PROXY_NON_PROXY_HOSTS = "proxy.nonproxyhosts"; +194 /** +195 * The properties key for the connection timeout. +196 */ +197 public static final String CONNECTION_TIMEOUT = "connection.timeout"; +198 /** +199 * The location of the temporary directory. +200 */ +201 public static final String TEMP_DIRECTORY = "temp.directory"; +202 /** +203 * The maximum number of threads to allocate when downloading files. +204 */ +205 public static final String MAX_DOWNLOAD_THREAD_POOL_SIZE = "max.download.threads"; +206 /** +207 * The key for the suppression file. +208 */ +209 public static final String SUPPRESSION_FILE = "suppression.file"; +210 /** +211 * The key for the hint file. +212 */ +213 public static final String HINTS_FILE = "hints.file"; +214 /** +215 * The properties key for whether the Jar Analyzer is enabled. +216 */ +217 public static final String ANALYZER_JAR_ENABLED = "analyzer.jar.enabled"; +218 /** +219 * The properties key for whether experimental analyzers are loaded. +220 */ +221 public static final String ANALYZER_EXPERIMENTAL_ENABLED = "analyzer.experimental.enabled"; +222 /** +223 * The properties key for whether the Archive analyzer is enabled. +224 */ +225 public static final String ANALYZER_ARCHIVE_ENABLED = "analyzer.archive.enabled"; +226 /** +227 * The properties key for whether the node.js package analyzer is +228 * enabled. +229 */ +230 public static final String ANALYZER_NODE_PACKAGE_ENABLED = "analyzer.node.package.enabled"; +231 /** +232 * The properties key for whether the composer lock file analyzer is +233 * enabled. 234 */ -235 public static final String ANALYZER_ASSEMBLY_ENABLED = "analyzer.assembly.enabled"; +235 public static final String ANALYZER_COMPOSER_LOCK_ENABLED = "analyzer.composer.lock.enabled"; 236 /** -237 * The properties key for whether the .NET Nuspec analyzer is enabled. -238 */ -239 public static final String ANALYZER_NUSPEC_ENABLED = "analyzer.nuspec.enabled"; -240 /** -241 * The properties key for whether the Nexus analyzer is enabled. -242 */ -243 public static final String ANALYZER_NEXUS_ENABLED = "analyzer.nexus.enabled"; -244 /** -245 * The properties key for the Nexus search URL. -246 */ -247 public static final String ANALYZER_NEXUS_URL = "analyzer.nexus.url"; -248 /** -249 * The properties key for using the proxy to reach Nexus. -250 */ -251 public static final String ANALYZER_NEXUS_USES_PROXY = "analyzer.nexus.proxy"; -252 /** -253 * The properties key for whether the Central analyzer is enabled. -254 */ -255 public static final String ANALYZER_CENTRAL_ENABLED = "analyzer.central.enabled"; -256 /** -257 * The properties key for whether the OpenSSL analyzer is enabled. -258 */ -259 public static final String ANALYZER_OPENSSL_ENABLED = "analyzer.openssl.enabled"; -260 /** -261 * The properties key for the Central search URL. -262 */ -263 public static final String ANALYZER_CENTRAL_URL = "analyzer.central.url"; -264 /** -265 * The path to mono, if available. -266 */ -267 public static final String ANALYZER_ASSEMBLY_MONO_PATH = "analyzer.assembly.mono.path"; -268 /** -269 * The path to bundle-audit, if available. -270 */ -271 public static final String ANALYZER_BUNDLE_AUDIT_PATH = "analyzer.bundle.audit.path"; -272 /** -273 * The additional configured zip file extensions, if available. -274 */ -275 public static final String ADDITIONAL_ZIP_EXTENSIONS = "extensions.zip"; -276 /** -277 * The key to obtain the path to the VFEED data file. -278 */ -279 public static final String VFEED_DATA_FILE = "vfeed.data_file"; -280 /** -281 * The key to obtain the VFEED connection string. -282 */ -283 public static final String VFEED_CONNECTION_STRING = "vfeed.connection_string"; -284 -285 /** -286 * The key to obtain the base download URL for the VFeed data file. -287 */ -288 public static final String VFEED_DOWNLOAD_URL = "vfeed.download_url"; -289 /** -290 * The key to obtain the download file name for the VFeed data. -291 */ -292 public static final String VFEED_DOWNLOAD_FILE = "vfeed.download_file"; -293 /** -294 * The key to obtain the VFeed update status. -295 */ -296 public static final String VFEED_UPDATE_STATUS = "vfeed.update_status"; -297 -298 /** -299 * The HTTP request method for query last modified date. -300 */ -301 public static final String DOWNLOADER_QUICK_QUERY_TIMESTAMP = "downloader.quick.query.timestamp"; -302 } -303 //</editor-fold> -304 -305 /** -306 * The logger. -307 */ -308 private static final Logger LOGGER = LoggerFactory.getLogger(Settings.class); -309 /** -310 * The properties file location. -311 */ -312 private static final String PROPERTIES_FILE = "dependencycheck.properties"; -313 /** -314 * Thread local settings. -315 */ -316 private static final ThreadLocal<Settings> LOCAL_SETTINGS = new ThreadLocal<Settings>(); -317 /** -318 * The properties. -319 */ -320 private Properties props = null; -321 -322 /** -323 * Private constructor for the Settings class. This class loads the properties files. -324 * -325 * @param propertiesFilePath the path to the base properties file to load -326 */ -327 private Settings(String propertiesFilePath) { -328 InputStream in = null; -329 props = new Properties(); -330 try { -331 in = this.getClass().getClassLoader().getResourceAsStream(propertiesFilePath); -332 props.load(in); -333 } catch (IOException ex) { -334 LOGGER.error("Unable to load default settings."); -335 LOGGER.debug("", ex); -336 } finally { -337 if (in != null) { -338 try { -339 in.close(); -340 } catch (IOException ex) { -341 LOGGER.trace("", ex); -342 } -343 } -344 } -345 logProperties("Properties loaded", props); -346 } -347 +237 * The properties key for whether the Python Distribution analyzer is +238 * enabled. +239 */ +240 public static final String ANALYZER_PYTHON_DISTRIBUTION_ENABLED = "analyzer.python.distribution.enabled"; +241 /** +242 * The properties key for whether the Python Package analyzer is +243 * enabled. +244 */ +245 public static final String ANALYZER_PYTHON_PACKAGE_ENABLED = "analyzer.python.package.enabled"; +246 /** +247 * The properties key for whether the Ruby Gemspec Analyzer is enabled. +248 */ +249 public static final String ANALYZER_RUBY_GEMSPEC_ENABLED = "analyzer.ruby.gemspec.enabled"; +250 /** +251 * The properties key for whether the Autoconf analyzer is enabled. +252 */ +253 public static final String ANALYZER_AUTOCONF_ENABLED = "analyzer.autoconf.enabled"; +254 /** +255 * The properties key for whether the CMake analyzer is enabled. +256 */ +257 public static final String ANALYZER_CMAKE_ENABLED = "analyzer.cmake.enabled"; +258 /** +259 * The properties key for whether the Ruby Bundler Audit analyzer is +260 * enabled. +261 */ +262 public static final String ANALYZER_BUNDLE_AUDIT_ENABLED = "analyzer.bundle.audit.enabled"; +263 /** +264 * The properties key for whether the .NET Assembly analyzer is enabled. +265 */ +266 public static final String ANALYZER_ASSEMBLY_ENABLED = "analyzer.assembly.enabled"; +267 /** +268 * The properties key for whether the .NET Nuspec analyzer is enabled. +269 */ +270 public static final String ANALYZER_NUSPEC_ENABLED = "analyzer.nuspec.enabled"; +271 /** +272 * The properties key for whether the Nexus analyzer is enabled. +273 */ +274 public static final String ANALYZER_NEXUS_ENABLED = "analyzer.nexus.enabled"; +275 /** +276 * The properties key for the Nexus search URL. +277 */ +278 public static final String ANALYZER_NEXUS_URL = "analyzer.nexus.url"; +279 /** +280 * The properties key for using the proxy to reach Nexus. +281 */ +282 public static final String ANALYZER_NEXUS_USES_PROXY = "analyzer.nexus.proxy"; +283 /** +284 * The properties key for whether the Central analyzer is enabled. +285 */ +286 public static final String ANALYZER_CENTRAL_ENABLED = "analyzer.central.enabled"; +287 /** +288 * The properties key for whether the OpenSSL analyzer is enabled. +289 */ +290 public static final String ANALYZER_OPENSSL_ENABLED = "analyzer.openssl.enabled"; +291 /** +292 * The properties key for the Central search URL. +293 */ +294 public static final String ANALYZER_CENTRAL_URL = "analyzer.central.url"; +295 /** +296 * The path to mono, if available. +297 */ +298 public static final String ANALYZER_ASSEMBLY_MONO_PATH = "analyzer.assembly.mono.path"; +299 /** +300 * The path to bundle-audit, if available. +301 */ +302 public static final String ANALYZER_BUNDLE_AUDIT_PATH = "analyzer.bundle.audit.path"; +303 /** +304 * The additional configured zip file extensions, if available. +305 */ +306 public static final String ADDITIONAL_ZIP_EXTENSIONS = "extensions.zip"; +307 /** +308 * The key to obtain the path to the VFEED data file. +309 */ +310 public static final String VFEED_DATA_FILE = "vfeed.data_file"; +311 /** +312 * The key to obtain the VFEED connection string. +313 */ +314 public static final String VFEED_CONNECTION_STRING = "vfeed.connection_string"; +315 +316 /** +317 * The key to obtain the base download URL for the VFeed data file. +318 */ +319 public static final String VFEED_DOWNLOAD_URL = "vfeed.download_url"; +320 /** +321 * The key to obtain the download file name for the VFeed data. +322 */ +323 public static final String VFEED_DOWNLOAD_FILE = "vfeed.download_file"; +324 /** +325 * The key to obtain the VFeed update status. +326 */ +327 public static final String VFEED_UPDATE_STATUS = "vfeed.update_status"; +328 +329 /** +330 * The HTTP request method for query last modified date. +331 */ +332 public static final String DOWNLOADER_QUICK_QUERY_TIMESTAMP = "downloader.quick.query.timestamp"; +333 } +334 //</editor-fold> +335 +336 /** +337 * The logger. +338 */ +339 private static final Logger LOGGER = LoggerFactory.getLogger(Settings.class); +340 /** +341 * The properties file location. +342 */ +343 private static final String PROPERTIES_FILE = "dependencycheck.properties"; +344 /** +345 * Thread local settings. +346 */ +347 private static final ThreadLocal<Settings> LOCAL_SETTINGS = new ThreadLocal<Settings>(); 348 /** -349 * Initializes the thread local settings object. Note, to use the settings object you must call this method. However, you must -350 * also call Settings.cleanup() to properly release resources. -351 */ -352 public static void initialize() { -353 LOCAL_SETTINGS.set(new Settings(PROPERTIES_FILE)); -354 } -355 -356 /** -357 * Initializes the thread local settings object. Note, to use the settings object you must call this method. However, you must -358 * also call Settings.cleanup() to properly release resources. -359 * -360 * @param propertiesFilePath the path to the base properties file to load -361 */ -362 public static void initialize(String propertiesFilePath) { -363 LOCAL_SETTINGS.set(new Settings(propertiesFilePath)); -364 } -365 -366 /** -367 * Cleans up resources to prevent memory leaks. -368 * -369 */ -370 public static void cleanup() { -371 cleanup(true); -372 } -373 -374 /** -375 * Cleans up resources to prevent memory leaks. -376 * -377 * @param deleteTemporary flag indicating whether any temporary directories generated should be removed -378 */ -379 public static void cleanup(boolean deleteTemporary) { -380 if (deleteTemporary && tempDirectory != null && tempDirectory.exists()) { -381 FileUtils.delete(tempDirectory); -382 if (tempDirectory.exists()) { -383 try { -384 Thread.sleep(2000); -385 } catch (InterruptedException ex) { -386 LOGGER.trace("ignore", ex); -387 } -388 FileUtils.delete(tempDirectory); -389 } -390 } -391 try { -392 LOCAL_SETTINGS.remove(); -393 } catch (Throwable ex) { -394 LOGGER.debug("Error cleaning up Settings", ex); -395 } -396 } -397 -398 /** -399 * Gets the underlying instance of the Settings object. -400 * -401 * @return the Settings object -402 */ -403 public static Settings getInstance() { -404 return LOCAL_SETTINGS.get(); -405 } -406 -407 /** -408 * Sets the instance of the Settings object to use in this thread. -409 * -410 * @param instance the instance of the settings object to use in this thread -411 */ -412 public static void setInstance(Settings instance) { -413 LOCAL_SETTINGS.set(instance); -414 } -415 -416 /** -417 * Logs the properties. This will not log any properties that contain 'password' in the key. -418 * -419 * @param header the header to print with the log message -420 * @param properties the properties to log -421 */ -422 private static void logProperties(String header, Properties properties) { -423 if (LOGGER.isDebugEnabled()) { -424 final StringWriter sw = new StringWriter(); -425 PrintWriter pw = null; -426 try { -427 pw = new PrintWriter(sw); -428 pw.format("%s:%n%n", header); -429 final Enumeration<?> e = properties.propertyNames(); -430 while (e.hasMoreElements()) { -431 final String key = (String) e.nextElement(); -432 if (key.contains("password")) { -433 pw.format("%s='*****'%n", key); -434 } else { -435 final String value = properties.getProperty(key); -436 if (value != null) { -437 pw.format("%s='%s'%n", key, value); -438 } -439 } -440 } -441 pw.flush(); -442 LOGGER.debug(sw.toString()); -443 } finally { -444 if (pw != null) { -445 pw.close(); -446 } -447 } -448 -449 } -450 } -451 -452 /** -453 * Sets a property value. +349 * The properties. +350 */ +351 private Properties props = null; +352 +353 /** +354 * Private constructor for the Settings class. This class loads the +355 * properties files. +356 * +357 * @param propertiesFilePath the path to the base properties file to load +358 */ +359 private Settings(String propertiesFilePath) { +360 InputStream in = null; +361 props = new Properties(); +362 try { +363 in = this.getClass().getClassLoader().getResourceAsStream(propertiesFilePath); +364 props.load(in); +365 } catch (IOException ex) { +366 LOGGER.error("Unable to load default settings."); +367 LOGGER.debug("", ex); +368 } finally { +369 if (in != null) { +370 try { +371 in.close(); +372 } catch (IOException ex) { +373 LOGGER.trace("", ex); +374 } +375 } +376 } +377 logProperties("Properties loaded", props); +378 } +379 +380 /** +381 * Initializes the thread local settings object. Note, to use the settings +382 * object you must call this method. However, you must also call +383 * Settings.cleanup() to properly release resources. +384 */ +385 public static void initialize() { +386 LOCAL_SETTINGS.set(new Settings(PROPERTIES_FILE)); +387 } +388 +389 /** +390 * Initializes the thread local settings object. Note, to use the settings +391 * object you must call this method. However, you must also call +392 * Settings.cleanup() to properly release resources. +393 * +394 * @param propertiesFilePath the path to the base properties file to load +395 */ +396 public static void initialize(String propertiesFilePath) { +397 LOCAL_SETTINGS.set(new Settings(propertiesFilePath)); +398 } +399 +400 /** +401 * Cleans up resources to prevent memory leaks. +402 * +403 */ +404 public static void cleanup() { +405 cleanup(true); +406 } +407 +408 /** +409 * Cleans up resources to prevent memory leaks. +410 * +411 * @param deleteTemporary flag indicating whether any temporary directories +412 * generated should be removed +413 */ +414 public static void cleanup(boolean deleteTemporary) { +415 if (deleteTemporary && tempDirectory != null && tempDirectory.exists()) { +416 FileUtils.delete(tempDirectory); +417 if (tempDirectory.exists()) { +418 try { +419 Thread.sleep(2000); +420 } catch (InterruptedException ex) { +421 LOGGER.trace("ignore", ex); +422 } +423 FileUtils.delete(tempDirectory); +424 } +425 } +426 try { +427 LOCAL_SETTINGS.remove(); +428 } catch (Throwable ex) { +429 LOGGER.debug("Error cleaning up Settings", ex); +430 } +431 } +432 +433 /** +434 * Gets the underlying instance of the Settings object. +435 * +436 * @return the Settings object +437 */ +438 public static Settings getInstance() { +439 return LOCAL_SETTINGS.get(); +440 } +441 +442 /** +443 * Sets the instance of the Settings object to use in this thread. +444 * +445 * @param instance the instance of the settings object to use in this thread +446 */ +447 public static void setInstance(Settings instance) { +448 LOCAL_SETTINGS.set(instance); +449 } +450 +451 /** +452 * Logs the properties. This will not log any properties that contain +453 * 'password' in the key. 454 * -455 * @param key the key for the property -456 * @param value the value for the property +455 * @param header the header to print with the log message +456 * @param properties the properties to log 457 */ -458 public static void setString(String key, String value) { -459 LOCAL_SETTINGS.get().props.setProperty(key, value); -460 LOGGER.debug("Setting: {}='{}'", key, value); -461 } -462 -463 /** -464 * Sets a property value only if the value is not null. -465 * -466 * @param key the key for the property -467 * @param value the value for the property -468 */ -469 public static void setStringIfNotNull(String key, String value) { -470 if (null != value) { -471 setString(key, value); -472 } -473 } -474 -475 /** -476 * Sets a property value only if the value is not null and not empty. -477 * -478 * @param key the key for the property -479 * @param value the value for the property -480 */ -481 public static void setStringIfNotEmpty(String key, String value) { -482 if (null != value && !value.isEmpty()) { -483 setString(key, value); -484 } -485 } -486 -487 /** -488 * Sets a property value. -489 * -490 * @param key the key for the property -491 * @param value the value for the property -492 */ -493 public static void setBoolean(String key, boolean value) { -494 setString(key, Boolean.toString(value)); -495 } -496 -497 /** -498 * Sets a property value only if the value is not null. -499 * -500 * @param key the key for the property -501 * @param value the value for the property -502 */ -503 public static void setBooleanIfNotNull(String key, Boolean value) { -504 if (null != value) { -505 setBoolean(key, value); -506 } -507 } -508 -509 /** -510 * Sets a property value. -511 * -512 * @param key the key for the property -513 * @param value the value for the property -514 */ -515 public static void setInt(String key, int value) { -516 LOCAL_SETTINGS.get().props.setProperty(key, String.valueOf(value)); -517 LOGGER.debug("Setting: {}='{}'", key, value); -518 } -519 -520 /** -521 * Sets a property value only if the value is not null. -522 * -523 * @param key the key for the property -524 * @param value the value for the property -525 */ -526 public static void setIntIfNotNull(String key, Integer value) { -527 if (null != value) { -528 setInt(key, value); -529 } -530 } -531 -532 /** -533 * Merges a new properties file into the current properties. This method allows for the loading of a user provided properties -534 * file.<br><br> -535 * <b>Note</b>: even if using this method - system properties will be loaded before properties loaded from files. -536 * -537 * @param filePath the path to the properties file to merge. -538 * @throws FileNotFoundException is thrown when the filePath points to a non-existent file -539 * @throws IOException is thrown when there is an exception loading/merging the properties -540 */ -541 public static void mergeProperties(File filePath) throws FileNotFoundException, IOException { -542 FileInputStream fis = null; -543 try { -544 fis = new FileInputStream(filePath); -545 mergeProperties(fis); -546 } finally { -547 if (fis != null) { -548 try { -549 fis.close(); -550 } catch (IOException ex) { -551 LOGGER.trace("close error", ex); -552 } -553 } -554 } -555 } -556 -557 /** -558 * Merges a new properties file into the current properties. This method allows for the loading of a user provided properties -559 * file.<br><br> -560 * Note: even if using this method - system properties will be loaded before properties loaded from files. -561 * -562 * @param filePath the path to the properties file to merge. -563 * @throws FileNotFoundException is thrown when the filePath points to a non-existent file -564 * @throws IOException is thrown when there is an exception loading/merging the properties -565 */ -566 public static void mergeProperties(String filePath) throws FileNotFoundException, IOException { -567 FileInputStream fis = null; -568 try { -569 fis = new FileInputStream(filePath); -570 mergeProperties(fis); -571 } finally { -572 if (fis != null) { -573 try { -574 fis.close(); -575 } catch (IOException ex) { -576 LOGGER.trace("close error", ex); -577 } -578 } -579 } -580 } -581 -582 /** -583 * Merges a new properties file into the current properties. This method allows for the loading of a user provided properties -584 * file.<br><br> -585 * <b>Note</b>: even if using this method - system properties will be loaded before properties loaded from files. -586 * -587 * @param stream an Input Stream pointing at a properties file to merge -588 * @throws IOException is thrown when there is an exception loading/merging the properties -589 */ -590 public static void mergeProperties(InputStream stream) throws IOException { -591 LOCAL_SETTINGS.get().props.load(stream); -592 logProperties("Properties updated via merge", LOCAL_SETTINGS.get().props); -593 } -594 -595 /** -596 * Returns a value from the properties file as a File object. If the value was specified as a system property or passed in via -597 * the -Dprop=value argument - this method will return the value from the system properties before the values in the contained -598 * configuration file. -599 * -600 * @param key the key to lookup within the properties file -601 * @return the property from the properties file converted to a File object -602 */ -603 public static File getFile(String key) { -604 final String file = getString(key); -605 if (file == null) { -606 return null; -607 } -608 return new File(file); -609 } -610 -611 /** -612 * Returns a value from the properties file as a File object. If the value was specified as a system property or passed in via -613 * the -Dprop=value argument - this method will return the value from the system properties before the values in the contained -614 * configuration file. -615 * -616 * This method will check the configured base directory and will use this as the base of the file path. Additionally, if the -617 * base directory begins with a leading "[JAR]\" sequence with the path to the folder containing the JAR file containing this -618 * class. -619 * -620 * @param key the key to lookup within the properties file -621 * @return the property from the properties file converted to a File object -622 */ -623 protected static File getDataFile(String key) { -624 final String file = getString(key); -625 LOGGER.debug("Settings.getDataFile() - file: '{}'", file); -626 if (file == null) { -627 return null; -628 } -629 if (file.startsWith("[JAR]")) { -630 LOGGER.debug("Settings.getDataFile() - transforming filename"); -631 final File jarPath = getJarPath(); -632 LOGGER.debug("Settings.getDataFile() - jar file: '{}'", jarPath.toString()); -633 final File retVal = new File(jarPath, file.substring(6)); -634 LOGGER.debug("Settings.getDataFile() - returning: '{}'", retVal.toString()); -635 return retVal; -636 } -637 return new File(file); -638 } -639 -640 /** -641 * Attempts to retrieve the folder containing the Jar file containing the Settings class. -642 * -643 * @return a File object -644 */ -645 private static File getJarPath() { -646 final String jarPath = Settings.class.getProtectionDomain().getCodeSource().getLocation().getPath(); -647 String decodedPath = "."; -648 try { -649 decodedPath = URLDecoder.decode(jarPath, "UTF-8"); -650 } catch (UnsupportedEncodingException ex) { -651 LOGGER.trace("", ex); +458 private static void logProperties(String header, Properties properties) { +459 if (LOGGER.isDebugEnabled()) { +460 final StringWriter sw = new StringWriter(); +461 PrintWriter pw = null; +462 try { +463 pw = new PrintWriter(sw); +464 pw.format("%s:%n%n", header); +465 final Enumeration<?> e = properties.propertyNames(); +466 while (e.hasMoreElements()) { +467 final String key = (String) e.nextElement(); +468 if (key.contains("password")) { +469 pw.format("%s='*****'%n", key); +470 } else { +471 final String value = properties.getProperty(key); +472 if (value != null) { +473 pw.format("%s='%s'%n", key, value); +474 } +475 } +476 } +477 pw.flush(); +478 LOGGER.debug(sw.toString()); +479 } finally { +480 if (pw != null) { +481 pw.close(); +482 } +483 } +484 +485 } +486 } +487 +488 /** +489 * Sets a property value. +490 * +491 * @param key the key for the property +492 * @param value the value for the property +493 */ +494 public static void setString(String key, String value) { +495 LOCAL_SETTINGS.get().props.setProperty(key, value); +496 LOGGER.debug("Setting: {}='{}'", key, value); +497 } +498 +499 /** +500 * Sets a property value only if the value is not null. +501 * +502 * @param key the key for the property +503 * @param value the value for the property +504 */ +505 public static void setStringIfNotNull(String key, String value) { +506 if (null != value) { +507 setString(key, value); +508 } +509 } +510 +511 /** +512 * Sets a property value only if the value is not null and not empty. +513 * +514 * @param key the key for the property +515 * @param value the value for the property +516 */ +517 public static void setStringIfNotEmpty(String key, String value) { +518 if (null != value && !value.isEmpty()) { +519 setString(key, value); +520 } +521 } +522 +523 /** +524 * Sets a property value. +525 * +526 * @param key the key for the property +527 * @param value the value for the property +528 */ +529 public static void setBoolean(String key, boolean value) { +530 setString(key, Boolean.toString(value)); +531 } +532 +533 /** +534 * Sets a property value only if the value is not null. +535 * +536 * @param key the key for the property +537 * @param value the value for the property +538 */ +539 public static void setBooleanIfNotNull(String key, Boolean value) { +540 if (null != value) { +541 setBoolean(key, value); +542 } +543 } +544 +545 /** +546 * Sets a property value. +547 * +548 * @param key the key for the property +549 * @param value the value for the property +550 */ +551 public static void setInt(String key, int value) { +552 LOCAL_SETTINGS.get().props.setProperty(key, String.valueOf(value)); +553 LOGGER.debug("Setting: {}='{}'", key, value); +554 } +555 +556 /** +557 * Sets a property value only if the value is not null. +558 * +559 * @param key the key for the property +560 * @param value the value for the property +561 */ +562 public static void setIntIfNotNull(String key, Integer value) { +563 if (null != value) { +564 setInt(key, value); +565 } +566 } +567 +568 /** +569 * Merges a new properties file into the current properties. This method +570 * allows for the loading of a user provided properties file.<br><br> +571 * <b>Note</b>: even if using this method - system properties will be loaded +572 * before properties loaded from files. +573 * +574 * @param filePath the path to the properties file to merge. +575 * @throws FileNotFoundException is thrown when the filePath points to a +576 * non-existent file +577 * @throws IOException is thrown when there is an exception loading/merging +578 * the properties +579 */ +580 public static void mergeProperties(File filePath) throws FileNotFoundException, IOException { +581 FileInputStream fis = null; +582 try { +583 fis = new FileInputStream(filePath); +584 mergeProperties(fis); +585 } finally { +586 if (fis != null) { +587 try { +588 fis.close(); +589 } catch (IOException ex) { +590 LOGGER.trace("close error", ex); +591 } +592 } +593 } +594 } +595 +596 /** +597 * Merges a new properties file into the current properties. This method +598 * allows for the loading of a user provided properties file.<br><br> +599 * Note: even if using this method - system properties will be loaded before +600 * properties loaded from files. +601 * +602 * @param filePath the path to the properties file to merge. +603 * @throws FileNotFoundException is thrown when the filePath points to a +604 * non-existent file +605 * @throws IOException is thrown when there is an exception loading/merging +606 * the properties +607 */ +608 public static void mergeProperties(String filePath) throws FileNotFoundException, IOException { +609 FileInputStream fis = null; +610 try { +611 fis = new FileInputStream(filePath); +612 mergeProperties(fis); +613 } finally { +614 if (fis != null) { +615 try { +616 fis.close(); +617 } catch (IOException ex) { +618 LOGGER.trace("close error", ex); +619 } +620 } +621 } +622 } +623 +624 /** +625 * Merges a new properties file into the current properties. This method +626 * allows for the loading of a user provided properties file.<br><br> +627 * <b>Note</b>: even if using this method - system properties will be loaded +628 * before properties loaded from files. +629 * +630 * @param stream an Input Stream pointing at a properties file to merge +631 * @throws IOException is thrown when there is an exception loading/merging +632 * the properties +633 */ +634 public static void mergeProperties(InputStream stream) throws IOException { +635 LOCAL_SETTINGS.get().props.load(stream); +636 logProperties("Properties updated via merge", LOCAL_SETTINGS.get().props); +637 } +638 +639 /** +640 * Returns a value from the properties file as a File object. If the value +641 * was specified as a system property or passed in via the -Dprop=value +642 * argument - this method will return the value from the system properties +643 * before the values in the contained configuration file. +644 * +645 * @param key the key to lookup within the properties file +646 * @return the property from the properties file converted to a File object +647 */ +648 public static File getFile(String key) { +649 final String file = getString(key); +650 if (file == null) { +651 return null; 652 } -653 -654 final File path = new File(decodedPath); -655 if (path.getName().toLowerCase().endsWith(".jar")) { -656 return path.getParentFile(); -657 } else { -658 return new File("."); -659 } -660 } -661 -662 /** -663 * Returns a value from the properties file. If the value was specified as a system property or passed in via the -Dprop=value -664 * argument - this method will return the value from the system properties before the values in the contained configuration -665 * file. +653 return new File(file); +654 } +655 +656 /** +657 * Returns a value from the properties file as a File object. If the value +658 * was specified as a system property or passed in via the -Dprop=value +659 * argument - this method will return the value from the system properties +660 * before the values in the contained configuration file. +661 * +662 * This method will check the configured base directory and will use this as +663 * the base of the file path. Additionally, if the base directory begins +664 * with a leading "[JAR]\" sequence with the path to the folder containing +665 * the JAR file containing this class. 666 * 667 * @param key the key to lookup within the properties file -668 * @param defaultValue the default value for the requested property -669 * @return the property from the properties file -670 */ -671 public static String getString(String key, String defaultValue) { -672 final String str = System.getProperty(key, LOCAL_SETTINGS.get().props.getProperty(key, defaultValue)); -673 return str; -674 } -675 -676 /** -677 * A reference to the temporary directory; used incase it needs to be deleted during cleanup. -678 */ -679 private static File tempDirectory = null; -680 -681 /** -682 * Returns the temporary directory. -683 * -684 * @return the temporary directory -685 * @throws java.io.IOException thrown if the temporary directory does not exist and cannot be created -686 */ -687 public static File getTempDirectory() throws IOException { -688 final File tmpDir = new File(Settings.getString(Settings.KEYS.TEMP_DIRECTORY, System.getProperty("java.io.tmpdir")), "dctemp"); -689 if (!tmpDir.exists() && !tmpDir.mkdirs()) { -690 final String msg = String.format("Unable to make a temporary folder '%s'", tmpDir.getPath()); -691 throw new IOException(msg); -692 } -693 tempDirectory = tmpDir; -694 return tmpDir; -695 } -696 -697 /** -698 * Returns a value from the properties file. If the value was specified as a system property or passed in via the -Dprop=value -699 * argument - this method will return the value from the system properties before the values in the contained configuration -700 * file. -701 * -702 * @param key the key to lookup within the properties file -703 * @return the property from the properties file -704 */ -705 public static String getString(String key) { -706 return System.getProperty(key, LOCAL_SETTINGS.get().props.getProperty(key)); -707 } -708 -709 /** -710 * Removes a property from the local properties collection. This is mainly used in test cases. -711 * -712 * @param key the property key to remove -713 */ -714 public static void removeProperty(String key) { -715 LOCAL_SETTINGS.get().props.remove(key); -716 } -717 -718 /** -719 * Returns an int value from the properties file. If the value was specified as a system property or passed in via the -720 * -Dprop=value argument - this method will return the value from the system properties before the values in the contained -721 * configuration file. -722 * -723 * @param key the key to lookup within the properties file -724 * @return the property from the properties file -725 * @throws InvalidSettingException is thrown if there is an error retrieving the setting -726 */ -727 public static int getInt(String key) throws InvalidSettingException { -728 try { -729 return Integer.parseInt(Settings.getString(key)); -730 } catch (NumberFormatException ex) { -731 throw new InvalidSettingException("Could not convert property '" + key + "' to an int.", ex); -732 } -733 } -734 -735 /** -736 * Returns an int value from the properties file. If the value was specified as a system property or passed in via the -737 * -Dprop=value argument - this method will return the value from the system properties before the values in the contained -738 * configuration file. -739 * -740 * @param key the key to lookup within the properties file -741 * @param defaultValue the default value to return -742 * @return the property from the properties file or the defaultValue if the property does not exist or cannot be converted to -743 * an integer -744 */ -745 public static int getInt(String key, int defaultValue) { -746 int value; -747 try { -748 value = Integer.parseInt(Settings.getString(key)); -749 } catch (NumberFormatException ex) { -750 if (!Settings.getString(key, "").isEmpty()) { -751 LOGGER.debug("Could not convert property '{}={}' to an int; using {} instead.", key, Settings.getString(key), defaultValue); -752 } -753 value = defaultValue; -754 } -755 return value; -756 } -757 -758 /** -759 * Returns a long value from the properties file. If the value was specified as a system property or passed in via the -760 * -Dprop=value argument - this method will return the value from the system properties before the values in the contained -761 * configuration file. -762 * -763 * @param key the key to lookup within the properties file -764 * @return the property from the properties file -765 * @throws InvalidSettingException is thrown if there is an error retrieving the setting +668 * @return the property from the properties file converted to a File object +669 */ +670 protected static File getDataFile(String key) { +671 final String file = getString(key); +672 LOGGER.debug("Settings.getDataFile() - file: '{}'", file); +673 if (file == null) { +674 return null; +675 } +676 if (file.startsWith("[JAR]")) { +677 LOGGER.debug("Settings.getDataFile() - transforming filename"); +678 final File jarPath = getJarPath(); +679 LOGGER.debug("Settings.getDataFile() - jar file: '{}'", jarPath.toString()); +680 final File retVal = new File(jarPath, file.substring(6)); +681 LOGGER.debug("Settings.getDataFile() - returning: '{}'", retVal.toString()); +682 return retVal; +683 } +684 return new File(file); +685 } +686 +687 /** +688 * Attempts to retrieve the folder containing the Jar file containing the +689 * Settings class. +690 * +691 * @return a File object +692 */ +693 private static File getJarPath() { +694 final String jarPath = Settings.class.getProtectionDomain().getCodeSource().getLocation().getPath(); +695 String decodedPath = "."; +696 try { +697 decodedPath = URLDecoder.decode(jarPath, "UTF-8"); +698 } catch (UnsupportedEncodingException ex) { +699 LOGGER.trace("", ex); +700 } +701 +702 final File path = new File(decodedPath); +703 if (path.getName().toLowerCase().endsWith(".jar")) { +704 return path.getParentFile(); +705 } else { +706 return new File("."); +707 } +708 } +709 +710 /** +711 * Returns a value from the properties file. If the value was specified as a +712 * system property or passed in via the -Dprop=value argument - this method +713 * will return the value from the system properties before the values in the +714 * contained configuration file. +715 * +716 * @param key the key to lookup within the properties file +717 * @param defaultValue the default value for the requested property +718 * @return the property from the properties file +719 */ +720 public static String getString(String key, String defaultValue) { +721 final String str = System.getProperty(key, LOCAL_SETTINGS.get().props.getProperty(key, defaultValue)); +722 return str; +723 } +724 +725 /** +726 * A reference to the temporary directory; used incase it needs to be +727 * deleted during cleanup. +728 */ +729 private static File tempDirectory = null; +730 +731 /** +732 * Returns the temporary directory. +733 * +734 * @return the temporary directory +735 * @throws java.io.IOException thrown if the temporary directory does not +736 * exist and cannot be created +737 */ +738 public static File getTempDirectory() throws IOException { +739 final File tmpDir = new File(Settings.getString(Settings.KEYS.TEMP_DIRECTORY, System.getProperty("java.io.tmpdir")), "dctemp"); +740 if (!tmpDir.exists() && !tmpDir.mkdirs()) { +741 final String msg = String.format("Unable to make a temporary folder '%s'", tmpDir.getPath()); +742 throw new IOException(msg); +743 } +744 tempDirectory = tmpDir; +745 return tmpDir; +746 } +747 +748 /** +749 * Returns a value from the properties file. If the value was specified as a +750 * system property or passed in via the -Dprop=value argument - this method +751 * will return the value from the system properties before the values in the +752 * contained configuration file. +753 * +754 * @param key the key to lookup within the properties file +755 * @return the property from the properties file +756 */ +757 public static String getString(String key) { +758 return System.getProperty(key, LOCAL_SETTINGS.get().props.getProperty(key)); +759 } +760 +761 /** +762 * Removes a property from the local properties collection. This is mainly +763 * used in test cases. +764 * +765 * @param key the property key to remove 766 */ -767 public static long getLong(String key) throws InvalidSettingException { -768 try { -769 return Long.parseLong(Settings.getString(key)); -770 } catch (NumberFormatException ex) { -771 throw new InvalidSettingException("Could not convert property '" + key + "' to a long.", ex); -772 } -773 } -774 -775 /** -776 * Returns a boolean value from the properties file. If the value was specified as a system property or passed in via the -777 * <code>-Dprop=value</code> argument this method will return the value from the system properties before the values in the -778 * contained configuration file. -779 * -780 * @param key the key to lookup within the properties file -781 * @return the property from the properties file -782 * @throws InvalidSettingException is thrown if there is an error retrieving the setting -783 */ -784 public static boolean getBoolean(String key) throws InvalidSettingException { -785 return Boolean.parseBoolean(Settings.getString(key)); -786 } -787 -788 /** -789 * Returns a boolean value from the properties file. If the value was specified as a system property or passed in via the -790 * <code>-Dprop=value</code> argument this method will return the value from the system properties before the values in the -791 * contained configuration file. -792 * -793 * @param key the key to lookup within the properties file -794 * @param defaultValue the default value to return if the setting does not exist -795 * @return the property from the properties file -796 * @throws InvalidSettingException is thrown if there is an error retrieving the setting -797 */ -798 public static boolean getBoolean(String key, boolean defaultValue) throws InvalidSettingException { -799 return Boolean.parseBoolean(Settings.getString(key, Boolean.toString(defaultValue))); -800 } -801 -802 /** -803 * Returns a connection string from the configured properties. If the connection string contains a %s, this method will -804 * determine the 'data' directory and replace the %s with the path to the data directory. If the data directory does not -805 * exists it will be created. -806 * -807 * @param connectionStringKey the property file key for the connection string -808 * @param dbFileNameKey the settings key for the db filename -809 * @return the connection string -810 * @throws IOException thrown the data directory cannot be created -811 * @throws InvalidSettingException thrown if there is an invalid setting -812 */ -813 public static String getConnectionString(String connectionStringKey, String dbFileNameKey) -814 throws IOException, InvalidSettingException { -815 final String connStr = Settings.getString(connectionStringKey); -816 if (connStr == null) { -817 final String msg = String.format("Invalid properties file; %s is missing.", connectionStringKey); -818 throw new InvalidSettingException(msg); -819 } -820 if (connStr.contains("%s")) { -821 final File directory = getDataDirectory(); -822 String fileName = null; -823 if (dbFileNameKey != null) { -824 fileName = Settings.getString(dbFileNameKey); -825 } -826 if (fileName == null) { -827 final String msg = String.format("Invalid properties file to get a file based connection string; '%s' must be defined.", -828 dbFileNameKey); -829 throw new InvalidSettingException(msg); -830 } -831 if (connStr.startsWith("jdbc:h2:file:") && fileName.endsWith(".h2.db")) { -832 fileName = fileName.substring(0, fileName.length() - 6); -833 } -834 // yes, for H2 this path won't actually exists - but this is sufficient to get the value needed -835 final File dbFile = new File(directory, fileName); -836 final String cString = String.format(connStr, dbFile.getCanonicalPath()); -837 LOGGER.debug("Connection String: '{}'", cString); -838 return cString; -839 } -840 return connStr; -841 } -842 -843 /** -844 * Retrieves the directory that the JAR file exists in so that we can ensure we always use a common data directory for the -845 * embedded H2 database. This is public solely for some unit tests; otherwise this should be private. -846 * -847 * @return the data directory to store data files -848 * @throws IOException is thrown if an IOException occurs of course... -849 */ -850 public static File getDataDirectory() throws IOException { -851 final File path = Settings.getDataFile(Settings.KEYS.DATA_DIRECTORY); -852 if (path.exists() || path.mkdirs()) { -853 return path; -854 } -855 throw new IOException(String.format("Unable to create the data directory '%s'", path.getAbsolutePath())); -856 } -857 } +767 public static void removeProperty(String key) { +768 LOCAL_SETTINGS.get().props.remove(key); +769 } +770 +771 /** +772 * Returns an int value from the properties file. If the value was specified +773 * as a system property or passed in via the -Dprop=value argument - this +774 * method will return the value from the system properties before the values +775 * in the contained configuration file. +776 * +777 * @param key the key to lookup within the properties file +778 * @return the property from the properties file +779 * @throws InvalidSettingException is thrown if there is an error retrieving +780 * the setting +781 */ +782 public static int getInt(String key) throws InvalidSettingException { +783 try { +784 return Integer.parseInt(Settings.getString(key)); +785 } catch (NumberFormatException ex) { +786 throw new InvalidSettingException("Could not convert property '" + key + "' to an int.", ex); +787 } +788 } +789 +790 /** +791 * Returns an int value from the properties file. If the value was specified +792 * as a system property or passed in via the -Dprop=value argument - this +793 * method will return the value from the system properties before the values +794 * in the contained configuration file. +795 * +796 * @param key the key to lookup within the properties file +797 * @param defaultValue the default value to return +798 * @return the property from the properties file or the defaultValue if the +799 * property does not exist or cannot be converted to an integer +800 */ +801 public static int getInt(String key, int defaultValue) { +802 int value; +803 try { +804 value = Integer.parseInt(Settings.getString(key)); +805 } catch (NumberFormatException ex) { +806 if (!Settings.getString(key, "").isEmpty()) { +807 LOGGER.debug("Could not convert property '{}={}' to an int; using {} instead.", key, Settings.getString(key), defaultValue); +808 } +809 value = defaultValue; +810 } +811 return value; +812 } +813 +814 /** +815 * Returns a long value from the properties file. If the value was specified +816 * as a system property or passed in via the -Dprop=value argument - this +817 * method will return the value from the system properties before the values +818 * in the contained configuration file. +819 * +820 * @param key the key to lookup within the properties file +821 * @return the property from the properties file +822 * @throws InvalidSettingException is thrown if there is an error retrieving +823 * the setting +824 */ +825 public static long getLong(String key) throws InvalidSettingException { +826 try { +827 return Long.parseLong(Settings.getString(key)); +828 } catch (NumberFormatException ex) { +829 throw new InvalidSettingException("Could not convert property '" + key + "' to a long.", ex); +830 } +831 } +832 +833 /** +834 * Returns a boolean value from the properties file. If the value was +835 * specified as a system property or passed in via the +836 * <code>-Dprop=value</code> argument this method will return the value from +837 * the system properties before the values in the contained configuration +838 * file. +839 * +840 * @param key the key to lookup within the properties file +841 * @return the property from the properties file +842 * @throws InvalidSettingException is thrown if there is an error retrieving +843 * the setting +844 */ +845 public static boolean getBoolean(String key) throws InvalidSettingException { +846 return Boolean.parseBoolean(Settings.getString(key)); +847 } +848 +849 /** +850 * Returns a boolean value from the properties file. If the value was +851 * specified as a system property or passed in via the +852 * <code>-Dprop=value</code> argument this method will return the value from +853 * the system properties before the values in the contained configuration +854 * file. +855 * +856 * @param key the key to lookup within the properties file +857 * @param defaultValue the default value to return if the setting does not +858 * exist +859 * @return the property from the properties file +860 * @throws InvalidSettingException is thrown if there is an error retrieving +861 * the setting +862 */ +863 public static boolean getBoolean(String key, boolean defaultValue) throws InvalidSettingException { +864 return Boolean.parseBoolean(Settings.getString(key, Boolean.toString(defaultValue))); +865 } +866 +867 /** +868 * Returns a connection string from the configured properties. If the +869 * connection string contains a %s, this method will determine the 'data' +870 * directory and replace the %s with the path to the data directory. If the +871 * data directory does not exists it will be created. +872 * +873 * @param connectionStringKey the property file key for the connection +874 * string +875 * @param dbFileNameKey the settings key for the db filename +876 * @return the connection string +877 * @throws IOException thrown the data directory cannot be created +878 * @throws InvalidSettingException thrown if there is an invalid setting +879 */ +880 public static String getConnectionString(String connectionStringKey, String dbFileNameKey) +881 throws IOException, InvalidSettingException { +882 final String connStr = Settings.getString(connectionStringKey); +883 if (connStr == null) { +884 final String msg = String.format("Invalid properties file; %s is missing.", connectionStringKey); +885 throw new InvalidSettingException(msg); +886 } +887 if (connStr.contains("%s")) { +888 final File directory = getDataDirectory(); +889 String fileName = null; +890 if (dbFileNameKey != null) { +891 fileName = Settings.getString(dbFileNameKey); +892 } +893 if (fileName == null) { +894 final String msg = String.format("Invalid properties file to get a file based connection string; '%s' must be defined.", +895 dbFileNameKey); +896 throw new InvalidSettingException(msg); +897 } +898 if (connStr.startsWith("jdbc:h2:file:") && fileName.endsWith(".h2.db")) { +899 fileName = fileName.substring(0, fileName.length() - 6); +900 } +901 // yes, for H2 this path won't actually exists - but this is sufficient to get the value needed +902 final File dbFile = new File(directory, fileName); +903 final String cString = String.format(connStr, dbFile.getCanonicalPath()); +904 LOGGER.debug("Connection String: '{}'", cString); +905 return cString; +906 } +907 return connStr; +908 } +909 +910 /** +911 * Retrieves the directory that the JAR file exists in so that we can ensure +912 * we always use a common data directory for the embedded H2 database. This +913 * is public solely for some unit tests; otherwise this should be private. +914 * +915 * @return the data directory to store data files +916 * @throws IOException is thrown if an IOException occurs of course... +917 */ +918 public static File getDataDirectory() throws IOException { +919 final File path = Settings.getDataFile(Settings.KEYS.DATA_DIRECTORY); +920 if (path.exists() || path.mkdirs()) { +921 return path; +922 } +923 throw new IOException(String.format("Unable to create the data directory '%s'", path.getAbsolutePath())); +924 } +925 }
        diff --git a/xref/org/owasp/dependencycheck/utils/URLConnectionFactory.html b/xref/org/owasp/dependencycheck/utils/URLConnectionFactory.html index 3271c74d6..f38bcbe57 100644 --- a/xref/org/owasp/dependencycheck/utils/URLConnectionFactory.html +++ b/xref/org/owasp/dependencycheck/utils/URLConnectionFactory.html @@ -36,142 +36,180 @@ 28 import java.net.Proxy; 29 import java.net.SocketAddress; 30 import java.net.URL; -31 -32 /** -33 * A URLConnection Factory to create new connections. This encapsulates several configuration checks to ensure that the connection -34 * uses the correct proxy settings. -35 * -36 * @author Jeremy Long -37 */ -38 public final class URLConnectionFactory { -39 -40 /** -41 * Private constructor for this factory. -42 */ -43 private URLConnectionFactory() { -44 } +31 import java.security.KeyManagementException; +32 import java.security.NoSuchAlgorithmException; +33 import javax.net.ssl.HttpsURLConnection; +34 import org.slf4j.Logger; +35 import org.slf4j.LoggerFactory; +36 +37 /** +38 * A URLConnection Factory to create new connections. This encapsulates several +39 * configuration checks to ensure that the connection uses the correct proxy +40 * settings. +41 * +42 * @author Jeremy Long +43 */ +44 public final class URLConnectionFactory { 45 46 /** -47 * Utility method to create an HttpURLConnection. If the application is configured to use a proxy this method will retrieve -48 * the proxy settings and use them when setting up the connection. -49 * -50 * @param url the url to connect to -51 * @return an HttpURLConnection -52 * @throws URLConnectionFailureException thrown if there is an exception +47 * The logger. +48 */ +49 private static final Logger LOGGER = LoggerFactory.getLogger(URLConnectionFactory.class); +50 +51 /** +52 * Private constructor for this factory. 53 */ -54 @SuppressFBWarnings(value = "RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE", justification = "Just being extra safe") -55 public static HttpURLConnection createHttpURLConnection(URL url) throws URLConnectionFailureException { -56 HttpURLConnection conn = null; -57 final String proxyUrl = Settings.getString(Settings.KEYS.PROXY_SERVER); -58 -59 try { -60 if (proxyUrl != null && !matchNonProxy(url)) { -61 final int proxyPort = Settings.getInt(Settings.KEYS.PROXY_PORT); -62 final SocketAddress address = new InetSocketAddress(proxyUrl, proxyPort); -63 -64 final String username = Settings.getString(Settings.KEYS.PROXY_USERNAME); -65 final String password = Settings.getString(Settings.KEYS.PROXY_PASSWORD); -66 -67 if (username != null && password != null) { -68 final Authenticator auth = new Authenticator() { -69 @Override -70 public PasswordAuthentication getPasswordAuthentication() { -71 if (getRequestorType().equals(Authenticator.RequestorType.PROXY)) { -72 return new PasswordAuthentication(username, password.toCharArray()); -73 } -74 return super.getPasswordAuthentication(); -75 } -76 }; -77 Authenticator.setDefault(auth); -78 } -79 -80 final Proxy proxy = new Proxy(Proxy.Type.HTTP, address); -81 conn = (HttpURLConnection) url.openConnection(proxy); -82 } else { -83 conn = (HttpURLConnection) url.openConnection(); -84 } -85 final int timeout = Settings.getInt(Settings.KEYS.CONNECTION_TIMEOUT, 10000); -86 conn.setConnectTimeout(timeout); -87 conn.setInstanceFollowRedirects(true); -88 } catch (IOException ex) { -89 if (conn != null) { -90 try { -91 conn.disconnect(); -92 } finally { -93 conn = null; -94 } -95 } -96 throw new URLConnectionFailureException("Error getting connection.", ex); -97 } -98 return conn; -99 } -100 -101 /** -102 * Check if hostname matches nonProxy settings -103 * -104 * @param url the url to connect to -105 * @return matching result. true: match nonProxy -106 */ -107 private static boolean matchNonProxy(final URL url) { -108 final String host = url.getHost(); -109 -110 // code partially from org.apache.maven.plugins.site.AbstractDeployMojo#getProxyInfo -111 final String nonProxyHosts = Settings.getString(Settings.KEYS.PROXY_NON_PROXY_HOSTS); -112 if (null != nonProxyHosts) { -113 final String[] nonProxies = nonProxyHosts.split("(,)|(;)|(\\|)"); -114 for (final String nonProxyHost : nonProxies) { -115 //if ( StringUtils.contains( nonProxyHost, "*" ) ) -116 if (null != nonProxyHost && nonProxyHost.contains("*")) { -117 // Handle wildcard at the end, beginning or middle of the nonProxyHost -118 final int pos = nonProxyHost.indexOf('*'); -119 final String nonProxyHostPrefix = nonProxyHost.substring(0, pos); -120 final String nonProxyHostSuffix = nonProxyHost.substring(pos + 1); -121 // prefix* -122 if (!StringUtils.isEmpty(nonProxyHostPrefix) && host.startsWith(nonProxyHostPrefix) && StringUtils.isEmpty(nonProxyHostSuffix)) { -123 return true; -124 } -125 // *suffix -126 if (StringUtils.isEmpty(nonProxyHostPrefix) && !StringUtils.isEmpty(nonProxyHostSuffix) && host.endsWith(nonProxyHostSuffix)) { -127 return true; -128 } -129 // prefix*suffix -130 if (!StringUtils.isEmpty(nonProxyHostPrefix) && host.startsWith(nonProxyHostPrefix) && !StringUtils.isEmpty(nonProxyHostSuffix) -131 && host.endsWith(nonProxyHostSuffix)) { -132 return true; -133 } -134 } else if (host.equals(nonProxyHost)) { -135 return true; -136 } -137 } -138 } -139 return false; -140 } -141 -142 /** -143 * Utility method to create an HttpURLConnection. The use of a proxy here is optional as there may be cases where a proxy is -144 * configured but we don't want to use it (for example, if there's an internal repository configured) -145 * -146 * @param url the URL to connect to -147 * @param proxy whether to use the proxy (if configured) -148 * @return a newly constructed HttpURLConnection -149 * @throws URLConnectionFailureException thrown if there is an exception -150 */ -151 public static HttpURLConnection createHttpURLConnection(URL url, boolean proxy) throws URLConnectionFailureException { -152 if (proxy) { -153 return createHttpURLConnection(url); -154 } -155 HttpURLConnection conn = null; -156 try { -157 conn = (HttpURLConnection) url.openConnection(); -158 final int timeout = Settings.getInt(Settings.KEYS.CONNECTION_TIMEOUT, 10000); -159 conn.setConnectTimeout(timeout); -160 conn.setInstanceFollowRedirects(true); -161 } catch (IOException ioe) { -162 throw new URLConnectionFailureException("Error getting connection.", ioe); -163 } -164 return conn; -165 } -166 } +54 private URLConnectionFactory() { +55 } +56 +57 /** +58 * Utility method to create an HttpURLConnection. If the application is +59 * configured to use a proxy this method will retrieve the proxy settings +60 * and use them when setting up the connection. +61 * +62 * @param url the url to connect to +63 * @return an HttpURLConnection +64 * @throws URLConnectionFailureException thrown if there is an exception +65 */ +66 @SuppressFBWarnings(value = "RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE", justification = "Just being extra safe") +67 public static HttpURLConnection createHttpURLConnection(URL url) throws URLConnectionFailureException { +68 HttpURLConnection conn = null; +69 final String proxyUrl = Settings.getString(Settings.KEYS.PROXY_SERVER); +70 +71 try { +72 if (proxyUrl != null && !matchNonProxy(url)) { +73 final int proxyPort = Settings.getInt(Settings.KEYS.PROXY_PORT); +74 final SocketAddress address = new InetSocketAddress(proxyUrl, proxyPort); +75 +76 final String username = Settings.getString(Settings.KEYS.PROXY_USERNAME); +77 final String password = Settings.getString(Settings.KEYS.PROXY_PASSWORD); +78 +79 if (username != null && password != null) { +80 final Authenticator auth = new Authenticator() { +81 @Override +82 public PasswordAuthentication getPasswordAuthentication() { +83 if (getRequestorType().equals(Authenticator.RequestorType.PROXY)) { +84 return new PasswordAuthentication(username, password.toCharArray()); +85 } +86 return super.getPasswordAuthentication(); +87 } +88 }; +89 Authenticator.setDefault(auth); +90 } +91 +92 final Proxy proxy = new Proxy(Proxy.Type.HTTP, address); +93 conn = (HttpURLConnection) url.openConnection(proxy); +94 } else { +95 conn = (HttpURLConnection) url.openConnection(); +96 } +97 final int timeout = Settings.getInt(Settings.KEYS.CONNECTION_TIMEOUT, 10000); +98 conn.setConnectTimeout(timeout); +99 conn.setInstanceFollowRedirects(true); +100 } catch (IOException ex) { +101 if (conn != null) { +102 try { +103 conn.disconnect(); +104 } finally { +105 conn = null; +106 } +107 } +108 throw new URLConnectionFailureException("Error getting connection.", ex); +109 } +110 configureTLS(url, conn); +111 return conn; +112 } +113 +114 /** +115 * Check if hostname matches nonProxy settings +116 * +117 * @param url the url to connect to +118 * @return matching result. true: match nonProxy +119 */ +120 private static boolean matchNonProxy(final URL url) { +121 final String host = url.getHost(); +122 +123 // code partially from org.apache.maven.plugins.site.AbstractDeployMojo#getProxyInfo +124 final String nonProxyHosts = Settings.getString(Settings.KEYS.PROXY_NON_PROXY_HOSTS); +125 if (null != nonProxyHosts) { +126 final String[] nonProxies = nonProxyHosts.split("(,)|(;)|(\\|)"); +127 for (final String nonProxyHost : nonProxies) { +128 //if ( StringUtils.contains( nonProxyHost, "*" ) ) +129 if (null != nonProxyHost && nonProxyHost.contains("*")) { +130 // Handle wildcard at the end, beginning or middle of the nonProxyHost +131 final int pos = nonProxyHost.indexOf('*'); +132 final String nonProxyHostPrefix = nonProxyHost.substring(0, pos); +133 final String nonProxyHostSuffix = nonProxyHost.substring(pos + 1); +134 // prefix* +135 if (!StringUtils.isEmpty(nonProxyHostPrefix) && host.startsWith(nonProxyHostPrefix) && StringUtils.isEmpty(nonProxyHostSuffix)) { +136 return true; +137 } +138 // *suffix +139 if (StringUtils.isEmpty(nonProxyHostPrefix) && !StringUtils.isEmpty(nonProxyHostSuffix) && host.endsWith(nonProxyHostSuffix)) { +140 return true; +141 } +142 // prefix*suffix +143 if (!StringUtils.isEmpty(nonProxyHostPrefix) && host.startsWith(nonProxyHostPrefix) && !StringUtils.isEmpty(nonProxyHostSuffix) +144 && host.endsWith(nonProxyHostSuffix)) { +145 return true; +146 } +147 } else if (host.equals(nonProxyHost)) { +148 return true; +149 } +150 } +151 } +152 return false; +153 } +154 +155 /** +156 * Utility method to create an HttpURLConnection. The use of a proxy here is +157 * optional as there may be cases where a proxy is configured but we don't +158 * want to use it (for example, if there's an internal repository +159 * configured) +160 * +161 * @param url the URL to connect to +162 * @param proxy whether to use the proxy (if configured) +163 * @return a newly constructed HttpURLConnection +164 * @throws URLConnectionFailureException thrown if there is an exception +165 */ +166 public static HttpURLConnection createHttpURLConnection(URL url, boolean proxy) throws URLConnectionFailureException { +167 if (proxy) { +168 return createHttpURLConnection(url); +169 } +170 HttpURLConnection conn = null; +171 try { +172 conn = (HttpURLConnection) url.openConnection(); +173 final int timeout = Settings.getInt(Settings.KEYS.CONNECTION_TIMEOUT, 10000); +174 conn.setConnectTimeout(timeout); +175 conn.setInstanceFollowRedirects(true); +176 } catch (IOException ioe) { +177 throw new URLConnectionFailureException("Error getting connection.", ioe); +178 } +179 configureTLS(url, conn); +180 return conn; +181 } +182 +183 /** +184 * If the protocol is HTTPS, this will configure the cipher suites so that +185 * connections can be made to the NVD, and others, using older versions of +186 * Java. +187 * +188 * @param url the URL +189 * @param conn the connection +190 */ +191 private static void configureTLS(URL url, HttpURLConnection conn) { +192 if ("https".equals(url.getProtocol())) { +193 try { +194 final HttpsURLConnection secCon = (HttpsURLConnection) conn; +195 final SSLSocketFactoryEx factory = new SSLSocketFactoryEx(); +196 secCon.setSSLSocketFactory(factory); +197 } catch (NoSuchAlgorithmException ex) { +198 LOGGER.debug("Unsupported algorithm in SSLSocketFactoryEx", ex); +199 } catch (KeyManagementException ex) { +200 LOGGER.debug("Key mnagement eception in SSLSocketFactoryEx", ex); +201 } +202 } +203 } +204 }
        diff --git a/xref/org/owasp/dependencycheck/utils/package-frame.html b/xref/org/owasp/dependencycheck/utils/package-frame.html index 821f495dd..99a1974d3 100644 --- a/xref/org/owasp/dependencycheck/utils/package-frame.html +++ b/xref/org/owasp/dependencycheck/utils/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.utils + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.utils @@ -65,6 +65,9 @@
      • Pair +
      • +
      • + SSLSocketFactoryEx
      • Settings diff --git a/xref/org/owasp/dependencycheck/utils/package-summary.html b/xref/org/owasp/dependencycheck/utils/package-summary.html index 62b71e100..2257c8530 100644 --- a/xref/org/owasp/dependencycheck/utils/package-summary.html +++ b/xref/org/owasp/dependencycheck/utils/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.utils + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.utils @@ -119,6 +119,11 @@ Pair + + + + SSLSocketFactoryEx + diff --git a/xref/org/owasp/dependencycheck/xml/hints/HintErrorHandler.html b/xref/org/owasp/dependencycheck/xml/hints/HintErrorHandler.html new file mode 100644 index 000000000..72211f4c7 --- /dev/null +++ b/xref/org/owasp/dependencycheck/xml/hints/HintErrorHandler.html @@ -0,0 +1,110 @@ + + + +HintErrorHandler xref + + + +
        +1   /*
        +2    * This file is part of dependency-check-core.
        +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) 2016 Jeremy Long. All Rights Reserved.
        +17   */
        +18  package org.owasp.dependencycheck.xml.hints;
        +19  
        +20  import org.slf4j.Logger;
        +21  import org.slf4j.LoggerFactory;
        +22  import org.xml.sax.ErrorHandler;
        +23  import org.xml.sax.SAXException;
        +24  import org.xml.sax.SAXParseException;
        +25  
        +26  /**
        +27   * An XML parsing error handler.
        +28   *
        +29   * @author Jeremy Long
        +30   */
        +31  public class HintErrorHandler implements ErrorHandler {
        +32  
        +33      /**
        +34       * The logger.
        +35       */
        +36      private static final Logger LOGGER = LoggerFactory.getLogger(HintErrorHandler.class);
        +37  
        +38      /**
        +39       * Builds a prettier exception message.
        +40       *
        +41       * @param ex the SAXParseException
        +42       * @return an easier to read exception message
        +43       */
        +44      private String getPrettyParseExceptionInfo(SAXParseException ex) {
        +45  
        +46          final StringBuilder sb = new StringBuilder();
        +47  
        +48          if (ex.getSystemId() != null) {
        +49              sb.append("systemId=").append(ex.getSystemId()).append(", ");
        +50          }
        +51          if (ex.getPublicId() != null) {
        +52              sb.append("publicId=").append(ex.getPublicId()).append(", ");
        +53          }
        +54          if (ex.getLineNumber() > 0) {
        +55              sb.append("Line=").append(ex.getLineNumber());
        +56          }
        +57          if (ex.getColumnNumber() > 0) {
        +58              sb.append(", Column=").append(ex.getColumnNumber());
        +59          }
        +60          sb.append(": ").append(ex.getMessage());
        +61  
        +62          return sb.toString();
        +63      }
        +64  
        +65      /**
        +66       * Logs warnings.
        +67       *
        +68       * @param ex the warning to log
        +69       * @throws SAXException is never thrown
        +70       */
        +71      @Override
        +72      public void warning(SAXParseException ex) throws SAXException {
        +73          LOGGER.debug("", ex);
        +74      }
        +75  
        +76      /**
        +77       * Handles errors.
        +78       *
        +79       * @param ex the error to handle
        +80       * @throws SAXException is always thrown
        +81       */
        +82      @Override
        +83      public void error(SAXParseException ex) throws SAXException {
        +84          throw new SAXException(getPrettyParseExceptionInfo(ex));
        +85      }
        +86  
        +87      /**
        +88       * Handles fatal exceptions.
        +89       *
        +90       * @param ex a fatal exception
        +91       * @throws SAXException is always
        +92       */
        +93      @Override
        +94      public void fatalError(SAXParseException ex) throws SAXException {
        +95          throw new SAXException(getPrettyParseExceptionInfo(ex));
        +96      }
        +97  }
        +
        +
        + + + diff --git a/xref/org/owasp/dependencycheck/xml/hints/HintHandler.html b/xref/org/owasp/dependencycheck/xml/hints/HintHandler.html new file mode 100644 index 000000000..f09cdc53b --- /dev/null +++ b/xref/org/owasp/dependencycheck/xml/hints/HintHandler.html @@ -0,0 +1,230 @@ + + + +HintHandler xref + + + +
        +1   /*
        +2    * This file is part of dependency-check-core.
        +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) 2016 Jeremy Long. All Rights Reserved.
        +17   */
        +18  package org.owasp.dependencycheck.xml.hints;
        +19  
        +20  import java.util.ArrayList;
        +21  import java.util.List;
        +22  import org.owasp.dependencycheck.dependency.Confidence;
        +23  import org.owasp.dependencycheck.xml.suppression.PropertyType;
        +24  import org.xml.sax.Attributes;
        +25  import org.xml.sax.SAXException;
        +26  import org.xml.sax.helpers.DefaultHandler;
        +27  
        +28  /**
        +29   * A handler to load hint rules.
        +30   *
        +31   * @author Jeremy Long
        +32   */
        +33  public class HintHandler extends DefaultHandler {
        +34  
        +35      //<editor-fold defaultstate="collapsed" desc="Element and attribute names">
        +36      /**
        +37       * Element name.
        +38       */
        +39      private static final String HINT = "hint";
        +40      /**
        +41       * Element name.
        +42       */
        +43      private static final String GIVEN = "given";
        +44      /**
        +45       * Element name.
        +46       */
        +47      private static final String ADD = "add";
        +48      /**
        +49       * Element name.
        +50       */
        +51      private static final String EVIDENCE = "evidence";
        +52      /**
        +53       * Element name.
        +54       */
        +55      private static final String FILE_NAME = "fileName";
        +56      /**
        +57       * Element name.
        +58       */
        +59      private static final String VENDOR_DUPLICATING_RULE = "vendorDuplicatingHint";
        +60      /**
        +61       * Attribute name.
        +62       */
        +63      private static final String DUPLICATE = "duplicate";
        +64      /**
        +65       * Attribute name.
        +66       */
        +67      private static final String VENDOR = "vendor";
        +68      /**
        +69       * Attribute name.
        +70       */
        +71      private static final String CONFIDENCE = "confidence";
        +72      /**
        +73       * Attribute name.
        +74       */
        +75      private static final String VALUE = "value";
        +76      /**
        +77       * Attribute name.
        +78       */
        +79      private static final String NAME = "name";
        +80      /**
        +81       * Attribute name.
        +82       */
        +83      private static final String SOURCE = "source";
        +84      /**
        +85       * Attribute name.
        +86       */
        +87      private static final String TYPE = "type";
        +88      /**
        +89       * Attribute name.
        +90       */
        +91      private static final String CASE_SENSITIVE = "caseSensitive";
        +92      /**
        +93       * Attribute name.
        +94       */
        +95      private static final String REGEX = "regex";
        +96      /**
        +97       * Attribute name.
        +98       */
        +99      private static final String CONTAINS = "contains";
        +100     //</editor-fold>
        +101 
        +102     /**
        +103      * The list of hint rules.
        +104      */
        +105     private final List<HintRule> hintRules = new ArrayList<HintRule>();
        +106 
        +107     /**
        +108      * Returns the list of hint rules.
        +109      *
        +110      * @return the value of hintRules
        +111      */
        +112     public List<HintRule> getHintRules() {
        +113         return hintRules;
        +114     }
        +115 
        +116     /**
        +117      * The list of vendor duplicating hint rules.
        +118      */
        +119     private final List<VendorDuplicatingHintRule> vendorDuplicatingHintRules = new ArrayList<VendorDuplicatingHintRule>();
        +120 
        +121     /**
        +122      * Returns the list of vendor duplicating hint rules.
        +123      *
        +124      * @return the list of vendor duplicating hint rules
        +125      */
        +126     public List<VendorDuplicatingHintRule> getVendorDuplicatingHintRules() {
        +127         return vendorDuplicatingHintRules;
        +128     }
        +129 
        +130     /**
        +131      * The current rule being read.
        +132      */
        +133     private HintRule rule;
        +134     /**
        +135      * The current state of the parent node (to differentiate between 'add' and
        +136      * 'given').
        +137      */
        +138     private boolean inAddNode = false;
        +139 
        +140     /**
        +141      * Handles the start element event.
        +142      *
        +143      * @param uri the uri of the element being processed
        +144      * @param localName the local name of the element being processed
        +145      * @param qName the qName of the element being processed
        +146      * @param attr the attributes of the element being processed
        +147      * @throws SAXException thrown if there is an exception processing
        +148      */
        +149     @Override
        +150     public void startElement(String uri, String localName, String qName, Attributes attr) throws SAXException {
        +151         if (HINT.equals(qName)) {
        +152             rule = new HintRule();
        +153         } else if (ADD.equals(qName)) {
        +154             inAddNode = true;
        +155         } else if (GIVEN.equals(qName)) {
        +156             inAddNode = false;
        +157         } else if (EVIDENCE.equals(qName)) {
        +158             final String hintType = attr.getValue(TYPE);
        +159             if (VENDOR.equals(hintType)) {
        +160                 if (inAddNode) {
        +161                     rule.addAddVendor(attr.getValue(SOURCE),
        +162                             attr.getValue(NAME),
        +163                             attr.getValue(VALUE),
        +164                             Confidence.valueOf(attr.getValue(CONFIDENCE)));
        +165                 } else {
        +166                     rule.addGivenVendor(attr.getValue(SOURCE),
        +167                             attr.getValue(NAME),
        +168                             attr.getValue(VALUE),
        +169                             Confidence.valueOf(attr.getValue(CONFIDENCE)));
        +170                 }
        +171             } else if (inAddNode) {
        +172                 rule.addAddProduct(attr.getValue(SOURCE),
        +173                         attr.getValue(NAME),
        +174                         attr.getValue(VALUE),
        +175                         Confidence.valueOf(attr.getValue(CONFIDENCE)));
        +176             } else {
        +177                 rule.addGivenProduct(attr.getValue(SOURCE),
        +178                         attr.getValue(NAME),
        +179                         attr.getValue(VALUE),
        +180                         Confidence.valueOf(attr.getValue(CONFIDENCE)));
        +181             }
        +182         } else if (FILE_NAME.equals(qName)) {
        +183             final PropertyType pt = new PropertyType();
        +184             pt.setValue(attr.getValue(CONTAINS));
        +185             if (attr.getLength() > 0) {
        +186                 final String regex = attr.getValue(REGEX);
        +187                 if (regex != null) {
        +188                     pt.setRegex(Boolean.parseBoolean(regex));
        +189                 }
        +190                 final String caseSensitive = attr.getValue(CASE_SENSITIVE);
        +191                 if (caseSensitive != null) {
        +192                     pt.setCaseSensitive(Boolean.parseBoolean(caseSensitive));
        +193                 }
        +194             }
        +195             rule.addFilename(pt);
        +196         } else if (VENDOR_DUPLICATING_RULE.equals(qName)) {
        +197             vendorDuplicatingHintRules.add(new VendorDuplicatingHintRule(attr.getValue(VALUE), attr.getValue(DUPLICATE)));
        +198         }
        +199     }
        +200 
        +201     /**
        +202      * Handles the end element event.
        +203      *
        +204      * @param uri the element's URI
        +205      * @param localName the local name
        +206      * @param qName the qualified name
        +207      * @throws SAXException thrown if there is an exception processing the
        +208      * element
        +209      */
        +210     @Override
        +211     public void endElement(String uri, String localName, String qName) throws SAXException {
        +212         if (HINT.equals(qName) && rule != null) {
        +213             hintRules.add(rule);
        +214             rule = null;
        +215         }
        +216     }
        +217 }
        +
        +
        + + + diff --git a/xref/org/owasp/dependencycheck/xml/hints/HintParseException.html b/xref/org/owasp/dependencycheck/xml/hints/HintParseException.html new file mode 100644 index 000000000..292a0fb7e --- /dev/null +++ b/xref/org/owasp/dependencycheck/xml/hints/HintParseException.html @@ -0,0 +1,81 @@ + + + +HintParseException xref + + + +
        +1   /*
        +2    * This file is part of dependency-check-core.
        +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) 2016 Jeremy Long. All Rights Reserved.
        +17   */
        +18  package org.owasp.dependencycheck.xml.hints;
        +19  
        +20  import java.io.IOException;
        +21  
        +22  /**
        +23   * An exception used when parsing a suppression rule file fails.
        +24   *
        +25   * @author Jeremy Long
        +26   */
        +27  public class HintParseException extends IOException {
        +28  
        +29      /**
        +30       * The serial version UID for serialization.
        +31       */
        +32      private static final long serialVersionUID = 1L;
        +33  
        +34      /**
        +35       * Creates a new SuppressionParseException.
        +36       */
        +37      public HintParseException() {
        +38          super();
        +39      }
        +40  
        +41      /**
        +42       * Creates a new SuppressionParseException.
        +43       *
        +44       * @param msg a message for the exception.
        +45       */
        +46      public HintParseException(String msg) {
        +47          super(msg);
        +48      }
        +49  
        +50      /**
        +51       * Creates a new SuppressionParseException.
        +52       *
        +53       * @param ex the cause of the parse exception
        +54       */
        +55      public HintParseException(Throwable ex) {
        +56          super(ex);
        +57      }
        +58  
        +59      /**
        +60       * Creates a new SuppressionParseException.
        +61       *
        +62       * @param msg a message for the exception.
        +63       * @param ex the cause of the parse exception
        +64       */
        +65      public HintParseException(String msg, Throwable ex) {
        +66          super(msg, ex);
        +67      }
        +68  }
        +
        +
        + + + diff --git a/xref/org/owasp/dependencycheck/xml/hints/HintParser.html b/xref/org/owasp/dependencycheck/xml/hints/HintParser.html new file mode 100644 index 000000000..ca18ae491 --- /dev/null +++ b/xref/org/owasp/dependencycheck/xml/hints/HintParser.html @@ -0,0 +1,159 @@ + + + +HintParser xref + + + +
        +1   /*
        +2    * This file is part of dependency-check-core.
        +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) 2016 Jeremy Long. All Rights Reserved.
        +17   */
        +18  package org.owasp.dependencycheck.xml.hints;
        +19  
        +20  import java.io.File;
        +21  import java.io.FileInputStream;
        +22  import java.io.FileNotFoundException;
        +23  import java.io.IOException;
        +24  import java.io.InputStream;
        +25  import java.io.InputStreamReader;
        +26  import java.io.Reader;
        +27  import javax.xml.parsers.ParserConfigurationException;
        +28  import javax.xml.parsers.SAXParser;
        +29  import javax.xml.parsers.SAXParserFactory;
        +30  
        +31  import org.slf4j.Logger;
        +32  import org.slf4j.LoggerFactory;
        +33  import org.xml.sax.InputSource;
        +34  import org.xml.sax.SAXException;
        +35  import org.xml.sax.XMLReader;
        +36  
        +37  /**
        +38   * A simple validating parser for XML Hint Rules.
        +39   *
        +40   * @author Jeremy Long
        +41   */
        +42  public class HintParser {
        +43  
        +44      /**
        +45       * The logger.
        +46       */
        +47      private static final Logger LOGGER = LoggerFactory.getLogger(HintParser.class);
        +48      /**
        +49       * JAXP Schema Language. Source:
        +50       * http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html
        +51       */
        +52      public static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
        +53      /**
        +54       * W3C XML Schema. Source:
        +55       * http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html
        +56       */
        +57      public static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";
        +58      /**
        +59       * JAXP Schema Source. Source:
        +60       * http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html
        +61       */
        +62      public static final String JAXP_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource";
        +63  
        +64      /**
        +65       * The schema for the hint XML files.
        +66       */
        +67      private static final String HINT_SCHEMA = "schema/dependency-hint.1.0.xsd";
        +68  
        +69      /**
        +70       * Parses the given XML file and returns a list of the hints contained.
        +71       *
        +72       * @param file an XML file containing hints
        +73       * @return a list of hint rules
        +74       * @throws HintParseException thrown if the XML file cannot be parsed
        +75       */
        +76      public Hints parseHints(File file) throws HintParseException {
        +77          FileInputStream fis = null;
        +78          try {
        +79              fis = new FileInputStream(file);
        +80              return parseHints(fis);
        +81          } catch (IOException ex) {
        +82              LOGGER.debug("", ex);
        +83              throw new HintParseException(ex);
        +84          } catch (SAXException ex) {
        +85              throw new HintParseException(ex);
        +86          } finally {
        +87              if (fis != null) {
        +88                  try {
        +89                      fis.close();
        +90                  } catch (IOException ex) {
        +91                      LOGGER.debug("Unable to close stream", ex);
        +92                  }
        +93              }
        +94          }
        +95      }
        +96  
        +97      /**
        +98       * Parses the given XML stream and returns a list of the hint rules
        +99       * contained.
        +100      *
        +101      * @param inputStream an InputStream containing hint rules
        +102      * @return a list of hint rules
        +103      * @throws HintParseException thrown if the XML cannot be parsed
        +104      * @throws SAXException thrown if the XML cannot be parsed
        +105      */
        +106     public Hints parseHints(InputStream inputStream) throws HintParseException, SAXException {
        +107         try {
        +108             final InputStream schemaStream = this.getClass().getClassLoader().getResourceAsStream(HINT_SCHEMA);
        +109             final HintHandler handler = new HintHandler();
        +110             final SAXParserFactory factory = SAXParserFactory.newInstance();
        +111             factory.setNamespaceAware(true);
        +112             factory.setValidating(true);
        +113             final SAXParser saxParser = factory.newSAXParser();
        +114             saxParser.setProperty(HintParser.JAXP_SCHEMA_LANGUAGE, HintParser.W3C_XML_SCHEMA);
        +115             saxParser.setProperty(HintParser.JAXP_SCHEMA_SOURCE, new InputSource(schemaStream));
        +116             final XMLReader xmlReader = saxParser.getXMLReader();
        +117             xmlReader.setErrorHandler(new HintErrorHandler());
        +118             xmlReader.setContentHandler(handler);
        +119 
        +120             final Reader reader = new InputStreamReader(inputStream, "UTF-8");
        +121             final InputSource in = new InputSource(reader);
        +122 
        +123             xmlReader.parse(in);
        +124             final Hints hints = new Hints();
        +125             hints.setHintRules(handler.getHintRules());
        +126             hints.setVendorDuplicatingHintRules(handler.getVendorDuplicatingHintRules());
        +127             return hints;
        +128         } catch (ParserConfigurationException ex) {
        +129             LOGGER.debug("", ex);
        +130             throw new HintParseException(ex);
        +131         } catch (SAXException ex) {
        +132             if (ex.getMessage().contains("Cannot find the declaration of element 'hints'.")) {
        +133                 throw ex;
        +134             } else {
        +135                 LOGGER.debug("", ex);
        +136                 throw new HintParseException(ex);
        +137             }
        +138         } catch (FileNotFoundException ex) {
        +139             LOGGER.debug("", ex);
        +140             throw new HintParseException(ex);
        +141         } catch (IOException ex) {
        +142             LOGGER.debug("", ex);
        +143             throw new HintParseException(ex);
        +144         }
        +145     }
        +146 }
        +
        +
        + + + diff --git a/xref/org/owasp/dependencycheck/xml/hints/HintRule.html b/xref/org/owasp/dependencycheck/xml/hints/HintRule.html new file mode 100644 index 000000000..c17ba93e9 --- /dev/null +++ b/xref/org/owasp/dependencycheck/xml/hints/HintRule.html @@ -0,0 +1,173 @@ + + + +HintRule xref + + + +
        +1   /*
        +2    * This file is part of dependency-check-core.
        +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) 2016 Jeremy Long. All Rights Reserved.
        +17   */
        +18  package org.owasp.dependencycheck.xml.hints;
        +19  
        +20  import java.util.ArrayList;
        +21  import java.util.List;
        +22  import org.owasp.dependencycheck.dependency.Confidence;
        +23  import org.owasp.dependencycheck.dependency.Evidence;
        +24  import org.owasp.dependencycheck.xml.suppression.PropertyType;
        +25  
        +26  /**
        +27   * A collection of product and vendor evidence to match; if any evidence is
        +28   * matched the addVendor and addProduct evidence should be added to the
        +29   * dependency.
        +30   *
        +31   * @author Jeremy Long
        +32   */
        +33  public class HintRule {
        +34  
        +35      /**
        +36       * The list of file names to match.
        +37       */
        +38      private final List<PropertyType> filenames = new ArrayList<PropertyType>();
        +39  
        +40      /**
        +41       * Adds the filename evidence to the collection.
        +42       *
        +43       * @param filename the filename to add
        +44       */
        +45      public void addFilename(PropertyType filename) {
        +46          this.filenames.add(filename);
        +47      }
        +48  
        +49      /**
        +50       * Returns the list of filename evidence to match against.
        +51       *
        +52       * @return the list of filename evidence to match against
        +53       */
        +54      public List<PropertyType> getFilenames() {
        +55          return filenames;
        +56      }
        +57      /**
        +58       * The list of product evidence that is being matched.
        +59       */
        +60      private final List<Evidence> givenProduct = new ArrayList<Evidence>();
        +61  
        +62      /**
        +63       * Adds a given product to the list of evidence to matched.
        +64       *
        +65       * @param source the source of the evidence
        +66       * @param name the name of the evidence
        +67       * @param value the value of the evidence
        +68       * @param confidence the confidence of the evidence
        +69       */
        +70      public void addGivenProduct(String source, String name, String value, Confidence confidence) {
        +71          givenProduct.add(new Evidence(source, name, value, confidence));
        +72      }
        +73  
        +74      /**
        +75       * Get the value of givenProduct.
        +76       *
        +77       * @return the value of givenProduct
        +78       */
        +79      public List<Evidence> getGivenProduct() {
        +80          return givenProduct;
        +81      }
        +82  
        +83      /**
        +84       * The list of vendor evidence that is being matched.
        +85       */
        +86      private final List<Evidence> givenVendor = new ArrayList<Evidence>();
        +87  
        +88      /**
        +89       * Adds a given vendors to the list of evidence to matched.
        +90       *
        +91       * @param source the source of the evidence
        +92       * @param name the name of the evidence
        +93       * @param value the value of the evidence
        +94       * @param confidence the confidence of the evidence
        +95       */
        +96      public void addGivenVendor(String source, String name, String value, Confidence confidence) {
        +97          givenVendor.add(new Evidence(source, name, value, confidence));
        +98      }
        +99  
        +100     /**
        +101      * Get the value of givenVendor.
        +102      *
        +103      * @return the value of givenVendor
        +104      */
        +105     public List<Evidence> getGivenVendor() {
        +106         return givenVendor;
        +107     }
        +108 
        +109     /**
        +110      * The list of product evidence to add.
        +111      */
        +112     private final List<Evidence> addProduct = new ArrayList<Evidence>();
        +113 
        +114     /**
        +115      * Adds a given product to the list of evidence to add when matched.
        +116      *
        +117      * @param source the source of the evidence
        +118      * @param name the name of the evidence
        +119      * @param value the value of the evidence
        +120      * @param confidence the confidence of the evidence
        +121      */
        +122     public void addAddProduct(String source, String name, String value, Confidence confidence) {
        +123         addProduct.add(new Evidence(source, name, value, confidence));
        +124     }
        +125 
        +126     /**
        +127      * Get the value of addProduct.
        +128      *
        +129      * @return the value of addProduct
        +130      */
        +131     public List<Evidence> getAddProduct() {
        +132         return addProduct;
        +133     }
        +134 
        +135     /**
        +136      * The list of vendor hints to add.
        +137      */
        +138     private final List<Evidence> addVendor = new ArrayList<Evidence>();
        +139 
        +140     /**
        +141      * Adds a given vendor to the list of evidence to add when matched.
        +142      *
        +143      * @param source the source of the evidence
        +144      * @param name the name of the evidence
        +145      * @param value the value of the evidence
        +146      * @param confidence the confidence of the evidence
        +147      */
        +148     public void addAddVendor(String source, String name, String value, Confidence confidence) {
        +149         addVendor.add(new Evidence(source, name, value, confidence));
        +150     }
        +151 
        +152     /**
        +153      * Get the value of addVendor.
        +154      *
        +155      * @return the value of addVendor
        +156      */
        +157     public List<Evidence> getAddVendor() {
        +158         return addVendor;
        +159     }
        +160 }
        +
        +
        + + + diff --git a/xref/org/owasp/dependencycheck/xml/hints/Hints.html b/xref/org/owasp/dependencycheck/xml/hints/Hints.html new file mode 100644 index 000000000..c8ee9e18d --- /dev/null +++ b/xref/org/owasp/dependencycheck/xml/hints/Hints.html @@ -0,0 +1,87 @@ + + + +Hints xref + + + +
        +1   /*
        +2    * This file is part of dependency-check-core.
        +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) 2016 Jeremy Long. All Rights Reserved.
        +17   */
        +18  package org.owasp.dependencycheck.xml.hints;
        +19  
        +20  import java.util.List;
        +21  
        +22  /**
        +23   * A collection of hint rules.
        +24   *
        +25   * @author Jeremy Long
        +26   */
        +27  public class Hints {
        +28  
        +29      /**
        +30       * The list of hint rules.
        +31       */
        +32      private List<HintRule> hintRules;
        +33  
        +34      /**
        +35       * Get the value of hintRules.
        +36       *
        +37       * @return the value of hintRules
        +38       */
        +39      public List<HintRule> getHintRules() {
        +40          return hintRules;
        +41      }
        +42  
        +43      /**
        +44       * Set the value of hintRules.
        +45       *
        +46       * @param hintRules new value of hintRules
        +47       */
        +48      public void setHintRules(List<HintRule> hintRules) {
        +49          this.hintRules = hintRules;
        +50      }
        +51  
        +52      /**
        +53       * The duplicating hint rules.
        +54       */
        +55      private List<VendorDuplicatingHintRule> vendorDuplicatingHintRules;
        +56  
        +57      /**
        +58       * Get the value of vendorDuplicatingHintRules.
        +59       *
        +60       * @return the value of vendorDuplicatingHintRules
        +61       */
        +62      public List<VendorDuplicatingHintRule> getVendorDuplicatingHintRules() {
        +63          return vendorDuplicatingHintRules;
        +64      }
        +65  
        +66      /**
        +67       * Set the value of vendorDuplicatingHintRules.
        +68       *
        +69       * @param vendorDuplicatingHintRules new value of vendorDuplicatingHintRules
        +70       */
        +71      public void setVendorDuplicatingHintRules(List<VendorDuplicatingHintRule> vendorDuplicatingHintRules) {
        +72          this.vendorDuplicatingHintRules = vendorDuplicatingHintRules;
        +73      }
        +74  }
        +
        +
        + + + diff --git a/xref/org/owasp/dependencycheck/xml/hints/VendorDuplicatingHintRule.html b/xref/org/owasp/dependencycheck/xml/hints/VendorDuplicatingHintRule.html new file mode 100644 index 000000000..23463a9a3 --- /dev/null +++ b/xref/org/owasp/dependencycheck/xml/hints/VendorDuplicatingHintRule.html @@ -0,0 +1,98 @@ + + + +VendorDuplicatingHintRule xref + + + +
        +1   /*
        +2    * This file is part of dependency-check-core.
        +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) 2016 Jeremy Long. All Rights Reserved.
        +17   */
        +18  package org.owasp.dependencycheck.xml.hints;
        +19  
        +20  /**
        +21   * Used to duplicate vendor evidence within a collection. The intent is if any evidence
        +22   * is found in a collection that matches the value given the evidence will be
        +23   * duplicated and the value replaced with the value indicated.
        +24   *
        +25   * @author Jeremy Long
        +26   */
        +27  public class VendorDuplicatingHintRule {
        +28  
        +29      /**
        +30       * Constructs a new duplicating rule.
        +31       *
        +32       * @param value the value to duplicate the evidence if found
        +33       * @param duplicate the value to replace within the duplicated evidence
        +34       */
        +35      public VendorDuplicatingHintRule(String value, String duplicate) {
        +36          this.value = value;
        +37          this.duplicate = duplicate;
        +38      }
        +39  
        +40      /**
        +41       * The evidence value to duplicate if found.
        +42       */
        +43      private String value;
        +44  
        +45      /**
        +46       * Get the value of value.
        +47       *
        +48       * @return the value of value
        +49       */
        +50      public String getValue() {
        +51          return value;
        +52      }
        +53  
        +54      /**
        +55       * Set the value of value.
        +56       *
        +57       * @param value new value of value
        +58       */
        +59      public void setValue(String value) {
        +60          this.value = value;
        +61      }
        +62  
        +63      /**
        +64       * The value to replace when duplicating the evidence.
        +65       */
        +66      private String duplicate;
        +67  
        +68      /**
        +69       * Get the value of duplicate.
        +70       *
        +71       * @return the value of duplicate
        +72       */
        +73      public String getDuplicate() {
        +74          return duplicate;
        +75      }
        +76  
        +77      /**
        +78       * Set the value of duplicate.
        +79       *
        +80       * @param duplicate new value of duplicate
        +81       */
        +82      public void setDuplicate(String duplicate) {
        +83          this.duplicate = duplicate;
        +84      }
        +85  }
        +
        +
        + + + diff --git a/xref/org/owasp/dependencycheck/xml/hints/package-frame.html b/xref/org/owasp/dependencycheck/xml/hints/package-frame.html new file mode 100644 index 000000000..b7634b0a1 --- /dev/null +++ b/xref/org/owasp/dependencycheck/xml/hints/package-frame.html @@ -0,0 +1,42 @@ + + + + + + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.xml.hints + + + + +

        + org.owasp.dependencycheck.xml.hints +

        + +

        Classes

        + + + + + \ No newline at end of file diff --git a/xref/org/owasp/dependencycheck/xml/hints/package-summary.html b/xref/org/owasp/dependencycheck/xml/hints/package-summary.html new file mode 100644 index 000000000..36b6cf5ed --- /dev/null +++ b/xref/org/owasp/dependencycheck/xml/hints/package-summary.html @@ -0,0 +1,99 @@ + + + + + + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.xml.hints + + + +
        + +
        +
        + +
        + +

        Package org.owasp.dependencycheck.xml.hints

        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        Class Summary
        + HintErrorHandler +
        + HintHandler +
        + HintParseException +
        + HintParser +
        + HintRule +
        + Hints +
        + VendorDuplicatingHintRule +
        + +
        + +
        +
        + +
        +
        + + + \ No newline at end of file diff --git a/xref/org/owasp/dependencycheck/xml/pom/package-frame.html b/xref/org/owasp/dependencycheck/xml/pom/package-frame.html index 3694b2a26..66d86d1f3 100644 --- a/xref/org/owasp/dependencycheck/xml/pom/package-frame.html +++ b/xref/org/owasp/dependencycheck/xml/pom/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.xml.pom + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.xml.pom diff --git a/xref/org/owasp/dependencycheck/xml/pom/package-summary.html b/xref/org/owasp/dependencycheck/xml/pom/package-summary.html index c10b5b094..fa4e8b2e9 100644 --- a/xref/org/owasp/dependencycheck/xml/pom/package-summary.html +++ b/xref/org/owasp/dependencycheck/xml/pom/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.owasp.dependencycheck.xml.pom + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.xml.pom diff --git a/xref/org/owasp/dependencycheck/xml/suppression/PropertyType.html b/xref/org/owasp/dependencycheck/xml/suppression/PropertyType.html new file mode 100644 index 000000000..d9f25138b --- /dev/null +++ b/xref/org/owasp/dependencycheck/xml/suppression/PropertyType.html @@ -0,0 +1,196 @@ + + + +PropertyType xref + + + +
        +1   /*
        +2    * This file is part of dependency-check-core.
        +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) 2013 Jeremy Long. All Rights Reserved.
        +17   */
        +18  package org.owasp.dependencycheck.xml.suppression;
        +19  
        +20  import java.util.regex.Pattern;
        +21  
        +22  /**
        +23   * A simple PropertyType used to represent a string value that could be used as a regular expression or could be case
        +24   * insensitive. The equals method has been over-ridden so that the object will correctly compare to strings.
        +25   *
        +26   * @author Jeremy Long
        +27   */
        +28  public class PropertyType {
        +29  
        +30      //<editor-fold defaultstate="collapsed" desc="properties">
        +31      /**
        +32       * The value.
        +33       */
        +34      private String value;
        +35  
        +36      /**
        +37       * Gets the value of the value property.
        +38       *
        +39       * @return the value of the value property
        +40       *
        +41       */
        +42      public String getValue() {
        +43          return value;
        +44      }
        +45  
        +46      /**
        +47       * Sets the value of the value property.
        +48       *
        +49       * @param value the value of the value property
        +50       */
        +51      public void setValue(String value) {
        +52          this.value = value;
        +53      }
        +54      /**
        +55       * Whether or not the expression is a regex.
        +56       */
        +57      private boolean regex = false;
        +58  
        +59      /**
        +60       * Returns whether or not the value is a regex.
        +61       *
        +62       * @return true if the value is a regex, otherwise false
        +63       *
        +64       */
        +65      public boolean isRegex() {
        +66          return regex;
        +67      }
        +68  
        +69      /**
        +70       * Sets whether the value property is a regex.
        +71       *
        +72       * @param value true if the value is a regex, otherwise false
        +73       *
        +74       */
        +75      public void setRegex(boolean value) {
        +76          this.regex = value;
        +77      }
        +78      /**
        +79       * Indicates case sensitivity.
        +80       */
        +81      private boolean caseSensitive = false;
        +82  
        +83      /**
        +84       * Gets the value of the caseSensitive property.
        +85       *
        +86       * @return true if the value is case sensitive
        +87       *
        +88       */
        +89      public boolean isCaseSensitive() {
        +90          return caseSensitive;
        +91      }
        +92  
        +93      /**
        +94       * Sets the value of the caseSensitive property.
        +95       *
        +96       * @param value whether the value is case sensitive
        +97       *
        +98       */
        +99      public void setCaseSensitive(boolean value) {
        +100         this.caseSensitive = value;
        +101     }
        +102     //</editor-fold>
        +103 
        +104     /**
        +105      * Uses the object's properties to determine if the supplied string matches the value of this property.
        +106      *
        +107      * @param text the String to validate
        +108      * @return whether the text supplied is matched by the value of the property
        +109      */
        +110     public boolean matches(String text) {
        +111         if (text == null) {
        +112             return false;
        +113         }
        +114         if (this.regex) {
        +115             Pattern rx;
        +116             if (this.caseSensitive) {
        +117                 rx = Pattern.compile(this.value);
        +118             } else {
        +119                 rx = Pattern.compile(this.value, Pattern.CASE_INSENSITIVE);
        +120             }
        +121             return rx.matcher(text).matches();
        +122         } else {
        +123             if (this.caseSensitive) {
        +124                 return value.equals(text);
        +125             } else {
        +126                 return value.equalsIgnoreCase(text);
        +127             }
        +128         }
        +129     }
        +130 
        +131     //<editor-fold defaultstate="collapsed" desc="standard implementations of hashCode, equals, and toString">
        +132     /**
        +133      * Default implementation of hashCode.
        +134      *
        +135      * @return the hash code
        +136      */
        +137     @Override
        +138     public int hashCode() {
        +139         int hash = 3;
        +140         hash = 59 * hash + (this.value != null ? this.value.hashCode() : 0);
        +141         hash = 59 * hash + (this.regex ? 1 : 0);
        +142         hash = 59 * hash + (this.caseSensitive ? 1 : 0);
        +143         return hash;
        +144     }
        +145 
        +146     /**
        +147      * Default implementation of equals.
        +148      *
        +149      * @param obj the object to compare
        +150      * @return whether the objects are equivalent
        +151      */
        +152     @Override
        +153     public boolean equals(Object obj) {
        +154         if (obj == null) {
        +155             return false;
        +156         }
        +157         if (getClass() != obj.getClass()) {
        +158             return false;
        +159         }
        +160         final PropertyType other = (PropertyType) obj;
        +161         if ((this.value == null) ? (other.value != null) : !this.value.equals(other.value)) {
        +162             return false;
        +163         }
        +164         if (this.regex != other.regex) {
        +165             return false;
        +166         }
        +167         if (this.caseSensitive != other.caseSensitive) {
        +168             return false;
        +169         }
        +170         return true;
        +171     }
        +172 
        +173     /**
        +174      * Default implementation of toString().
        +175      *
        +176      * @return the string representation of the object
        +177      */
        +178     @Override
        +179     public String toString() {
        +180         return "PropertyType{" + "value=" + value + ", regex=" + regex + ", caseSensitive=" + caseSensitive + '}';
        +181     }
        +182     //</editor-fold>
        +183 }
        +
        +
        + + + diff --git a/xref/org/owasp/dependencycheck/xml/suppression/SuppressionErrorHandler.html b/xref/org/owasp/dependencycheck/xml/suppression/SuppressionErrorHandler.html new file mode 100644 index 000000000..c9387de53 --- /dev/null +++ b/xref/org/owasp/dependencycheck/xml/suppression/SuppressionErrorHandler.html @@ -0,0 +1,110 @@ + + + +SuppressionErrorHandler xref + + + +
        +1   /*
        +2    * This file is part of dependency-check-core.
        +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) 2013 Jeremy Long. All Rights Reserved.
        +17   */
        +18  package org.owasp.dependencycheck.xml.suppression;
        +19  
        +20  import org.slf4j.Logger;
        +21  import org.slf4j.LoggerFactory;
        +22  import org.xml.sax.ErrorHandler;
        +23  import org.xml.sax.SAXException;
        +24  import org.xml.sax.SAXParseException;
        +25  
        +26  /**
        +27   * An XML parsing error handler.
        +28   *
        +29   * @author Jeremy Long
        +30   */
        +31  public class SuppressionErrorHandler implements ErrorHandler {
        +32  
        +33      /**
        +34       * The logger.
        +35       */
        +36      private static final Logger LOGGER = LoggerFactory.getLogger(SuppressionErrorHandler.class);
        +37  
        +38      /**
        +39       * Builds a prettier exception message.
        +40       *
        +41       * @param ex the SAXParseException
        +42       * @return an easier to read exception message
        +43       */
        +44      private String getPrettyParseExceptionInfo(SAXParseException ex) {
        +45  
        +46          final StringBuilder sb = new StringBuilder();
        +47  
        +48          if (ex.getSystemId() != null) {
        +49              sb.append("systemId=").append(ex.getSystemId()).append(", ");
        +50          }
        +51          if (ex.getPublicId() != null) {
        +52              sb.append("publicId=").append(ex.getPublicId()).append(", ");
        +53          }
        +54          if (ex.getLineNumber() > 0) {
        +55              sb.append("Line=").append(ex.getLineNumber());
        +56          }
        +57          if (ex.getColumnNumber() > 0) {
        +58              sb.append(", Column=").append(ex.getColumnNumber());
        +59          }
        +60          sb.append(": ").append(ex.getMessage());
        +61  
        +62          return sb.toString();
        +63      }
        +64  
        +65      /**
        +66       * Logs warnings.
        +67       *
        +68       * @param ex the warning to log
        +69       * @throws SAXException is never thrown
        +70       */
        +71      @Override
        +72      public void warning(SAXParseException ex) throws SAXException {
        +73          //LOGGER.debug("", ex);
        +74      }
        +75  
        +76      /**
        +77       * Handles errors.
        +78       *
        +79       * @param ex the error to handle
        +80       * @throws SAXException is always thrown
        +81       */
        +82      @Override
        +83      public void error(SAXParseException ex) throws SAXException {
        +84          throw new SAXException(getPrettyParseExceptionInfo(ex));
        +85      }
        +86  
        +87      /**
        +88       * Handles fatal exceptions.
        +89       *
        +90       * @param ex a fatal exception
        +91       * @throws SAXException is always
        +92       */
        +93      @Override
        +94      public void fatalError(SAXParseException ex) throws SAXException {
        +95          throw new SAXException(getPrettyParseExceptionInfo(ex));
        +96      }
        +97  }
        +
        +
        + + + diff --git a/xref/org/owasp/dependencycheck/xml/suppression/SuppressionHandler.html b/xref/org/owasp/dependencycheck/xml/suppression/SuppressionHandler.html new file mode 100644 index 000000000..bb048b6f2 --- /dev/null +++ b/xref/org/owasp/dependencycheck/xml/suppression/SuppressionHandler.html @@ -0,0 +1,196 @@ + + + +SuppressionHandler xref + + + +
        +1   /*
        +2    * This file is part of dependency-check-core.
        +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) 2013 Jeremy Long. All Rights Reserved.
        +17   */
        +18  package org.owasp.dependencycheck.xml.suppression;
        +19  
        +20  import java.util.ArrayList;
        +21  import java.util.List;
        +22  import org.xml.sax.Attributes;
        +23  import org.xml.sax.SAXException;
        +24  import org.xml.sax.helpers.DefaultHandler;
        +25  
        +26  /**
        +27   * A handler to load suppression rules.
        +28   *
        +29   * @author Jeremy Long
        +30   */
        +31  public class SuppressionHandler extends DefaultHandler {
        +32  
        +33      /**
        +34       * The suppress node, indicates the start of a new rule.
        +35       */
        +36      public static final String SUPPRESS = "suppress";
        +37      /**
        +38       * The file path element name.
        +39       */
        +40      public static final String FILE_PATH = "filePath";
        +41      /**
        +42       * The sha1 hash element name.
        +43       */
        +44      public static final String SHA1 = "sha1";
        +45      /**
        +46       * The CVE element name.
        +47       */
        +48      public static final String CVE = "cve";
        +49      /**
        +50       * The CPE element name.
        +51       */
        +52      public static final String CPE = "cpe";
        +53      /**
        +54       * The CWE element name.
        +55       */
        +56      public static final String CWE = "cwe";
        +57      /**
        +58       * The GAV element name.
        +59       */
        +60      public static final String GAV = "gav";
        +61      /**
        +62       * The cvssBelow element name.
        +63       */
        +64      public static final String CVSS_BELOW = "cvssBelow";
        +65      /**
        +66       * A list of suppression rules.
        +67       */
        +68      private final List<SuppressionRule> suppressionRules = new ArrayList<SuppressionRule>();
        +69  
        +70      /**
        +71       * Get the value of suppressionRules.
        +72       *
        +73       * @return the value of suppressionRules
        +74       */
        +75      public List<SuppressionRule> getSuppressionRules() {
        +76          return suppressionRules;
        +77      }
        +78      /**
        +79       * The current rule being read.
        +80       */
        +81      private SuppressionRule rule;
        +82      /**
        +83       * The attributes of the node being read.
        +84       */
        +85      private Attributes currentAttributes;
        +86      /**
        +87       * The current node text being extracted from the element.
        +88       */
        +89      private StringBuilder currentText;
        +90  
        +91      /**
        +92       * Handles the start element event.
        +93       *
        +94       * @param uri the uri of the element being processed
        +95       * @param localName the local name of the element being processed
        +96       * @param qName the qName of the element being processed
        +97       * @param attributes the attributes of the element being processed
        +98       * @throws SAXException thrown if there is an exception processing
        +99       */
        +100     @Override
        +101     public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        +102         currentAttributes = attributes;
        +103         currentText = new StringBuilder();
        +104         if (SUPPRESS.equals(qName)) {
        +105             rule = new SuppressionRule();
        +106             final String base = currentAttributes.getValue("base");
        +107             if (base != null) {
        +108                 rule.setBase(Boolean.parseBoolean(base));
        +109             } else {
        +110                 rule.setBase(false);
        +111             }
        +112         }
        +113     }
        +114 
        +115     /**
        +116      * Handles the end element event.
        +117      *
        +118      * @param uri the URI of the element
        +119      * @param localName the local name of the element
        +120      * @param qName the qName of the element
        +121      * @throws SAXException thrown if there is an exception processing
        +122      */
        +123     @Override
        +124     public void endElement(String uri, String localName, String qName) throws SAXException {
        +125         if (SUPPRESS.equals(qName)) {
        +126             suppressionRules.add(rule);
        +127             rule = null;
        +128         } else if (FILE_PATH.equals(qName)) {
        +129             final PropertyType pt = processPropertyType();
        +130             rule.setFilePath(pt);
        +131         } else if (SHA1.equals(qName)) {
        +132             rule.setSha1(currentText.toString());
        +133         } else if (GAV.equals(qName)) {
        +134             final PropertyType pt = processPropertyType();
        +135             rule.setGav(pt);
        +136         } else if (CPE.equals(qName)) {
        +137             final PropertyType pt = processPropertyType();
        +138             rule.addCpe(pt);
        +139         } else if (CWE.equals(qName)) {
        +140             rule.addCwe(currentText.toString());
        +141         } else if (CVE.equals(qName)) {
        +142             rule.addCve(currentText.toString());
        +143         } else if (CVSS_BELOW.equals(qName)) {
        +144             final float cvss = Float.parseFloat(currentText.toString());
        +145             rule.addCvssBelow(cvss);
        +146         }
        +147     }
        +148 
        +149     /**
        +150      * Collects the body text of the node being processed.
        +151      *
        +152      * @param ch the char array of text
        +153      * @param start the start position to copy text from in the char array
        +154      * @param length the number of characters to copy from the char array
        +155      * @throws SAXException thrown if there is a parsing exception
        +156      */
        +157     @Override
        +158     public void characters(char[] ch, int start, int length) throws SAXException {
        +159         currentText.append(ch, start, length);
        +160     }
        +161 
        +162     /**
        +163      * Processes field members that have been collected during the characters and startElement method to construct a
        +164      * PropertyType object.
        +165      *
        +166      * @return a PropertyType object
        +167      */
        +168     private PropertyType processPropertyType() {
        +169         final PropertyType pt = new PropertyType();
        +170         pt.setValue(currentText.toString());
        +171         if (currentAttributes != null && currentAttributes.getLength() > 0) {
        +172             final String regex = currentAttributes.getValue("regex");
        +173             if (regex != null) {
        +174                 pt.setRegex(Boolean.parseBoolean(regex));
        +175             }
        +176             final String caseSensitive = currentAttributes.getValue("caseSensitive");
        +177             if (caseSensitive != null) {
        +178                 pt.setCaseSensitive(Boolean.parseBoolean(caseSensitive));
        +179             }
        +180         }
        +181         return pt;
        +182     }
        +183 }
        +
        +
        + + + diff --git a/xref/org/owasp/dependencycheck/xml/suppression/SuppressionParseException.html b/xref/org/owasp/dependencycheck/xml/suppression/SuppressionParseException.html new file mode 100644 index 000000000..1bfa394ee --- /dev/null +++ b/xref/org/owasp/dependencycheck/xml/suppression/SuppressionParseException.html @@ -0,0 +1,81 @@ + + + +SuppressionParseException xref + + + +
        +1   /*
        +2    * This file is part of dependency-check-core.
        +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) 2013 Jeremy Long. All Rights Reserved.
        +17   */
        +18  package org.owasp.dependencycheck.xml.suppression;
        +19  
        +20  import java.io.IOException;
        +21  
        +22  /**
        +23   * An exception used when parsing a suppression rule file fails.
        +24   *
        +25   * @author Jeremy Long
        +26   */
        +27  public class SuppressionParseException extends IOException {
        +28  
        +29      /**
        +30       * The serial version UID for serialization.
        +31       */
        +32      private static final long serialVersionUID = 1L;
        +33  
        +34      /**
        +35       * Creates a new SuppressionParseException.
        +36       */
        +37      public SuppressionParseException() {
        +38          super();
        +39      }
        +40  
        +41      /**
        +42       * Creates a new SuppressionParseException.
        +43       *
        +44       * @param msg a message for the exception.
        +45       */
        +46      public SuppressionParseException(String msg) {
        +47          super(msg);
        +48      }
        +49  
        +50      /**
        +51       * Creates a new SuppressionParseException.
        +52       *
        +53       * @param ex the cause of the parse exception
        +54       */
        +55      public SuppressionParseException(Throwable ex) {
        +56          super(ex);
        +57      }
        +58  
        +59      /**
        +60       * Creates a new SuppressionParseException.
        +61       *
        +62       * @param msg a message for the exception.
        +63       * @param ex the cause of the parse exception
        +64       */
        +65      public SuppressionParseException(String msg, Throwable ex) {
        +66          super(msg, ex);
        +67      }
        +68  }
        +
        +
        + + + diff --git a/xref/org/owasp/dependencycheck/xml/suppression/SuppressionParser.html b/xref/org/owasp/dependencycheck/xml/suppression/SuppressionParser.html new file mode 100644 index 000000000..1981f2df2 --- /dev/null +++ b/xref/org/owasp/dependencycheck/xml/suppression/SuppressionParser.html @@ -0,0 +1,218 @@ + + + +SuppressionParser xref + + + +
        +1   /*
        +2    * This file is part of dependency-check-core.
        +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) 2013 Jeremy Long. All Rights Reserved.
        +17   */
        +18  package org.owasp.dependencycheck.xml.suppression;
        +19  
        +20  import java.io.File;
        +21  import java.io.FileInputStream;
        +22  import java.io.FileNotFoundException;
        +23  import java.io.IOException;
        +24  import java.io.InputStream;
        +25  import java.io.InputStreamReader;
        +26  import java.io.Reader;
        +27  import java.util.List;
        +28  import javax.xml.parsers.ParserConfigurationException;
        +29  import javax.xml.parsers.SAXParser;
        +30  import javax.xml.parsers.SAXParserFactory;
        +31  
        +32  import org.slf4j.Logger;
        +33  import org.slf4j.LoggerFactory;
        +34  import org.xml.sax.InputSource;
        +35  import org.xml.sax.SAXException;
        +36  import org.xml.sax.XMLReader;
        +37  
        +38  /**
        +39   * A simple validating parser for XML Suppression Rules.
        +40   *
        +41   * @author Jeremy Long
        +42   */
        +43  public class SuppressionParser {
        +44  
        +45      /**
        +46       * The logger.
        +47       */
        +48      private static final Logger LOGGER = LoggerFactory.getLogger(SuppressionParser.class);
        +49      /**
        +50       * JAXP Schema Language. Source:
        +51       * http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html
        +52       */
        +53      public static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
        +54      /**
        +55       * W3C XML Schema. Source:
        +56       * http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html
        +57       */
        +58      public static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";
        +59      /**
        +60       * JAXP Schema Source. Source:
        +61       * http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html
        +62       */
        +63      public static final String JAXP_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource";
        +64      /**
        +65       * The suppression schema file location.
        +66       */
        +67      private static final String SUPPRESSION_SCHEMA = "schema/dependency-suppression.1.1.xsd";
        +68      /**
        +69       * The old suppression schema file location.
        +70       */
        +71      private static final String OLD_SUPPRESSION_SCHEMA = "schema/suppression.xsd";
        +72  
        +73      /**
        +74       * Parses the given XML file and returns a list of the suppression rules
        +75       * contained.
        +76       *
        +77       * @param file an XML file containing suppression rules
        +78       * @return a list of suppression rules
        +79       * @throws SuppressionParseException thrown if the XML file cannot be parsed
        +80       */
        +81      public List<SuppressionRule> parseSuppressionRules(File file) throws SuppressionParseException {
        +82          FileInputStream fis = null;
        +83          try {
        +84              fis = new FileInputStream(file);
        +85              return parseSuppressionRules(fis);
        +86          } catch (IOException ex) {
        +87              LOGGER.debug("", ex);
        +88              throw new SuppressionParseException(ex);
        +89          } catch (SAXException ex) {
        +90              try {
        +91                  if (fis != null) {
        +92                      try {
        +93                          fis.close();
        +94                      } catch (IOException ex1) {
        +95                          LOGGER.debug("Unable to close stream", ex1);
        +96                      }
        +97                  }
        +98                  fis = new FileInputStream(file);
        +99              } catch (FileNotFoundException ex1) {
        +100                 throw new SuppressionParseException(ex);
        +101             }
        +102             return parseOldSuppressionRules(fis);
        +103         } finally {
        +104             if (fis != null) {
        +105                 try {
        +106                     fis.close();
        +107                 } catch (IOException ex) {
        +108                     LOGGER.debug("Unable to close stream", ex);
        +109                 }
        +110             }
        +111         }
        +112     }
        +113 
        +114     /**
        +115      * Parses the given XML stream and returns a list of the suppression rules
        +116      * contained.
        +117      *
        +118      * @param inputStream an InputStream containing suppression rules
        +119      * @return a list of suppression rules
        +120      * @throws SuppressionParseException thrown if the XML cannot be parsed
        +121      * @throws SAXException thrown if the XML cannot be parsed
        +122      */
        +123     public List<SuppressionRule> parseSuppressionRules(InputStream inputStream) throws SuppressionParseException, SAXException {
        +124         try {
        +125             final InputStream schemaStream = this.getClass().getClassLoader().getResourceAsStream(SUPPRESSION_SCHEMA);
        +126             final SuppressionHandler handler = new SuppressionHandler();
        +127             final SAXParserFactory factory = SAXParserFactory.newInstance();
        +128             factory.setNamespaceAware(true);
        +129             factory.setValidating(true);
        +130             final SAXParser saxParser = factory.newSAXParser();
        +131             saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_LANGUAGE, SuppressionParser.W3C_XML_SCHEMA);
        +132             saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_SOURCE, new InputSource(schemaStream));
        +133             final XMLReader xmlReader = saxParser.getXMLReader();
        +134             xmlReader.setErrorHandler(new SuppressionErrorHandler());
        +135             xmlReader.setContentHandler(handler);
        +136 
        +137             final Reader reader = new InputStreamReader(inputStream, "UTF-8");
        +138             final InputSource in = new InputSource(reader);
        +139             //in.setEncoding("UTF-8");
        +140 
        +141             xmlReader.parse(in);
        +142 
        +143             return handler.getSuppressionRules();
        +144         } catch (ParserConfigurationException ex) {
        +145             LOGGER.debug("", ex);
        +146             throw new SuppressionParseException(ex);
        +147         } catch (SAXException ex) {
        +148             if (ex.getMessage().contains("Cannot find the declaration of element 'suppressions'.")) {
        +149                 throw ex;
        +150             } else {
        +151                 LOGGER.debug("", ex);
        +152                 throw new SuppressionParseException(ex);
        +153             }
        +154         } catch (FileNotFoundException ex) {
        +155             LOGGER.debug("", ex);
        +156             throw new SuppressionParseException(ex);
        +157         } catch (IOException ex) {
        +158             LOGGER.debug("", ex);
        +159             throw new SuppressionParseException(ex);
        +160         }
        +161     }
        +162 
        +163     /**
        +164      * Parses the given XML stream and returns a list of the suppression rules
        +165      * contained.
        +166      *
        +167      * @param inputStream an InputStream containing suppression rues
        +168      * @return a list of suppression rules
        +169      * @throws SuppressionParseException if the XML cannot be parsed
        +170      */
        +171     private List<SuppressionRule> parseOldSuppressionRules(InputStream inputStream) throws SuppressionParseException {
        +172         try {
        +173             final InputStream schemaStream = this.getClass().getClassLoader().getResourceAsStream(OLD_SUPPRESSION_SCHEMA);
        +174             final SuppressionHandler handler = new SuppressionHandler();
        +175             final SAXParserFactory factory = SAXParserFactory.newInstance();
        +176             factory.setNamespaceAware(true);
        +177             factory.setValidating(true);
        +178             final SAXParser saxParser = factory.newSAXParser();
        +179             saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_LANGUAGE, SuppressionParser.W3C_XML_SCHEMA);
        +180             saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_SOURCE, new InputSource(schemaStream));
        +181             final XMLReader xmlReader = saxParser.getXMLReader();
        +182             xmlReader.setErrorHandler(new SuppressionErrorHandler());
        +183             xmlReader.setContentHandler(handler);
        +184 
        +185             final Reader reader = new InputStreamReader(inputStream, "UTF-8");
        +186             final InputSource in = new InputSource(reader);
        +187 
        +188             xmlReader.parse(in);
        +189 
        +190             return handler.getSuppressionRules();
        +191         } catch (ParserConfigurationException ex) {
        +192             LOGGER.debug("", ex);
        +193             throw new SuppressionParseException(ex);
        +194         } catch (SAXException ex) {
        +195             LOGGER.debug("", ex);
        +196             throw new SuppressionParseException(ex);
        +197         } catch (FileNotFoundException ex) {
        +198             LOGGER.debug("", ex);
        +199             throw new SuppressionParseException(ex);
        +200         } catch (IOException ex) {
        +201             LOGGER.debug("", ex);
        +202             throw new SuppressionParseException(ex);
        +203         }
        +204     }
        +205 }
        +
        +
        + + + diff --git a/xref/org/owasp/dependencycheck/xml/suppression/SuppressionRule.html b/xref/org/owasp/dependencycheck/xml/suppression/SuppressionRule.html new file mode 100644 index 000000000..bcaf686bf --- /dev/null +++ b/xref/org/owasp/dependencycheck/xml/suppression/SuppressionRule.html @@ -0,0 +1,491 @@ + + + +SuppressionRule xref + + + +
        +1   /*
        +2    * This file is part of dependency-check-core.
        +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) 2013 Jeremy Long. All Rights Reserved.
        +17   */
        +18  package org.owasp.dependencycheck.xml.suppression;
        +19  
        +20  import java.util.ArrayList;
        +21  import java.util.Iterator;
        +22  import java.util.List;
        +23  import org.owasp.dependencycheck.dependency.Dependency;
        +24  import org.owasp.dependencycheck.dependency.Identifier;
        +25  import org.owasp.dependencycheck.dependency.Vulnerability;
        +26  
        +27  /**
        +28   *
        +29   * @author Jeremy Long
        +30   */
        +31  public class SuppressionRule {
        +32  
        +33      /**
        +34       * The file path for the suppression.
        +35       */
        +36      private PropertyType filePath;
        +37  
        +38      /**
        +39       * Get the value of filePath.
        +40       *
        +41       * @return the value of filePath
        +42       */
        +43      public PropertyType getFilePath() {
        +44          return filePath;
        +45      }
        +46  
        +47      /**
        +48       * Set the value of filePath.
        +49       *
        +50       * @param filePath new value of filePath
        +51       */
        +52      public void setFilePath(PropertyType filePath) {
        +53          this.filePath = filePath;
        +54      }
        +55      /**
        +56       * The sha1 hash.
        +57       */
        +58      private String sha1;
        +59  
        +60      /**
        +61       * Get the value of sha1.
        +62       *
        +63       * @return the value of sha1
        +64       */
        +65      public String getSha1() {
        +66          return sha1;
        +67      }
        +68  
        +69      /**
        +70       * Set the value of sha1.
        +71       *
        +72       * @param sha1 new value of sha1
        +73       */
        +74      public void setSha1(String sha1) {
        +75          this.sha1 = sha1;
        +76      }
        +77      /**
        +78       * A list of CPEs to suppression
        +79       */
        +80      private List<PropertyType> cpe = new ArrayList<PropertyType>();
        +81  
        +82      /**
        +83       * Get the value of cpe.
        +84       *
        +85       * @return the value of cpe
        +86       */
        +87      public List<PropertyType> getCpe() {
        +88          return cpe;
        +89      }
        +90  
        +91      /**
        +92       * Set the value of cpe.
        +93       *
        +94       * @param cpe new value of cpe
        +95       */
        +96      public void setCpe(List<PropertyType> cpe) {
        +97          this.cpe = cpe;
        +98      }
        +99  
        +100     /**
        +101      * Adds the cpe to the cpe list.
        +102      *
        +103      * @param cpe the cpe to add
        +104      */
        +105     public void addCpe(PropertyType cpe) {
        +106         this.cpe.add(cpe);
        +107     }
        +108 
        +109     /**
        +110      * Returns whether or not this suppression rule as CPE entries.
        +111      *
        +112      * @return whether or not this suppression rule as CPE entries
        +113      */
        +114     public boolean hasCpe() {
        +115         return !cpe.isEmpty();
        +116     }
        +117     /**
        +118      * The list of cvssBelow scores.
        +119      */
        +120     private List<Float> cvssBelow = new ArrayList<Float>();
        +121 
        +122     /**
        +123      * Get the value of cvssBelow.
        +124      *
        +125      * @return the value of cvssBelow
        +126      */
        +127     public List<Float> getCvssBelow() {
        +128         return cvssBelow;
        +129     }
        +130 
        +131     /**
        +132      * Set the value of cvssBelow.
        +133      *
        +134      * @param cvssBelow new value of cvssBelow
        +135      */
        +136     public void setCvssBelow(List<Float> cvssBelow) {
        +137         this.cvssBelow = cvssBelow;
        +138     }
        +139 
        +140     /**
        +141      * Adds the cvss to the cvssBelow list.
        +142      *
        +143      * @param cvss the cvss to add
        +144      */
        +145     public void addCvssBelow(Float cvss) {
        +146         this.cvssBelow.add(cvss);
        +147     }
        +148 
        +149     /**
        +150      * Returns whether or not this suppression rule has cvss suppressions.
        +151      *
        +152      * @return whether or not this suppression rule has cvss suppressions
        +153      */
        +154     public boolean hasCvssBelow() {
        +155         return !cvssBelow.isEmpty();
        +156     }
        +157     /**
        +158      * The list of cwe entries to suppress.
        +159      */
        +160     private List<String> cwe = new ArrayList<String>();
        +161 
        +162     /**
        +163      * Get the value of cwe.
        +164      *
        +165      * @return the value of cwe
        +166      */
        +167     public List<String> getCwe() {
        +168         return cwe;
        +169     }
        +170 
        +171     /**
        +172      * Set the value of cwe.
        +173      *
        +174      * @param cwe new value of cwe
        +175      */
        +176     public void setCwe(List<String> cwe) {
        +177         this.cwe = cwe;
        +178     }
        +179 
        +180     /**
        +181      * Adds the cwe to the cwe list.
        +182      *
        +183      * @param cwe the cwe to add
        +184      */
        +185     public void addCwe(String cwe) {
        +186         this.cwe.add(cwe);
        +187     }
        +188 
        +189     /**
        +190      * Returns whether this suppression rule has CWE entries.
        +191      *
        +192      * @return whether this suppression rule has CWE entries
        +193      */
        +194     public boolean hasCwe() {
        +195         return !cwe.isEmpty();
        +196     }
        +197     /**
        +198      * The list of cve entries to suppress.
        +199      */
        +200     private List<String> cve = new ArrayList<String>();
        +201 
        +202     /**
        +203      * Get the value of cve.
        +204      *
        +205      * @return the value of cve
        +206      */
        +207     public List<String> getCve() {
        +208         return cve;
        +209     }
        +210 
        +211     /**
        +212      * Set the value of cve.
        +213      *
        +214      * @param cve new value of cve
        +215      */
        +216     public void setCve(List<String> cve) {
        +217         this.cve = cve;
        +218     }
        +219 
        +220     /**
        +221      * Adds the cve to the cve list.
        +222      *
        +223      * @param cve the cve to add
        +224      */
        +225     public void addCve(String cve) {
        +226         this.cve.add(cve);
        +227     }
        +228 
        +229     /**
        +230      * Returns whether this suppression rule has CVE entries.
        +231      *
        +232      * @return whether this suppression rule has CVE entries
        +233      */
        +234     public boolean hasCve() {
        +235         return !cve.isEmpty();
        +236     }
        +237     /**
        +238      * A Maven GAV to suppression.
        +239      */
        +240     private PropertyType gav = null;
        +241 
        +242     /**
        +243      * Get the value of Maven GAV.
        +244      *
        +245      * @return the value of gav
        +246      */
        +247     public PropertyType getGav() {
        +248         return gav;
        +249     }
        +250 
        +251     /**
        +252      * Set the value of Maven GAV.
        +253      *
        +254      * @param gav new value of Maven gav
        +255      */
        +256     public void setGav(PropertyType gav) {
        +257         this.gav = gav;
        +258     }
        +259 
        +260     /**
        +261      * Returns whether or not this suppression rule as GAV entries.
        +262      *
        +263      * @return whether or not this suppression rule as GAV entries
        +264      */
        +265     public boolean hasGav() {
        +266         return gav != null;
        +267     }
        +268 
        +269     /**
        +270      * A flag indicating whether or not the suppression rule is a core/base rule that should not be included in the resulting
        +271      * report in the "suppressed" section.
        +272      */
        +273     private boolean base;
        +274 
        +275     /**
        +276      * Get the value of base.
        +277      *
        +278      * @return the value of base
        +279      */
        +280     public boolean isBase() {
        +281         return base;
        +282     }
        +283 
        +284     /**
        +285      * Set the value of base.
        +286      *
        +287      * @param base new value of base
        +288      */
        +289     public void setBase(boolean base) {
        +290         this.base = base;
        +291     }
        +292 
        +293     /**
        +294      * Processes a given dependency to determine if any CPE, CVE, CWE, or CVSS scores should be suppressed. If any should be, they
        +295      * are removed from the dependency.
        +296      *
        +297      * @param dependency a project dependency to analyze
        +298      */
        +299     public void process(Dependency dependency) {
        +300         if (filePath != null && !filePath.matches(dependency.getFilePath())) {
        +301             return;
        +302         }
        +303         if (sha1 != null && !sha1.equalsIgnoreCase(dependency.getSha1sum())) {
        +304             return;
        +305         }
        +306         if (gav != null) {
        +307             final Iterator<Identifier> itr = dependency.getIdentifiers().iterator();
        +308             boolean gavFound = false;
        +309             while (itr.hasNext()) {
        +310                 final Identifier i = itr.next();
        +311                 if (identifierMatches("maven", this.gav, i)) {
        +312                     gavFound = true;
        +313                     break;
        +314                 }
        +315             }
        +316             if (!gavFound) {
        +317                 return;
        +318             }
        +319         }
        +320 
        +321         if (this.hasCpe()) {
        +322             final Iterator<Identifier> itr = dependency.getIdentifiers().iterator();
        +323             while (itr.hasNext()) {
        +324                 final Identifier i = itr.next();
        +325                 for (PropertyType c : this.cpe) {
        +326                     if (identifierMatches("cpe", c, i)) {
        +327                         if (!isBase()) {
        +328                             dependency.addSuppressedIdentifier(i);
        +329                         }
        +330                         itr.remove();
        +331                         break;
        +332                     }
        +333                 }
        +334             }
        +335         }
        +336         if (hasCve() || hasCwe() || hasCvssBelow()) {
        +337             final Iterator<Vulnerability> itr = dependency.getVulnerabilities().iterator();
        +338             while (itr.hasNext()) {
        +339                 boolean remove = false;
        +340                 final Vulnerability v = itr.next();
        +341                 for (String entry : this.cve) {
        +342                     if (entry.equalsIgnoreCase(v.getName())) {
        +343                         remove = true;
        +344                         break;
        +345                     }
        +346                 }
        +347                 if (!remove) {
        +348                     for (String entry : this.cwe) {
        +349                         if (v.getCwe() != null) {
        +350                             final String toMatch = String.format("CWE-%s ", entry);
        +351                             final String toTest = v.getCwe().substring(0, toMatch.length()).toUpperCase();
        +352                             if (toTest.equals(toMatch)) {
        +353                                 remove = true;
        +354                                 break;
        +355                             }
        +356                         }
        +357                     }
        +358                 }
        +359                 if (!remove) {
        +360                     for (float cvss : this.cvssBelow) {
        +361                         if (v.getCvssScore() < cvss) {
        +362                             remove = true;
        +363                             break;
        +364                         }
        +365                     }
        +366                 }
        +367                 if (remove) {
        +368                     if (!isBase()) {
        +369                         dependency.addSuppressedVulnerability(v);
        +370                     }
        +371                     itr.remove();
        +372                 }
        +373             }
        +374         }
        +375     }
        +376 
        +377     /**
        +378      * Identifies if the cpe specified by the cpe suppression rule does not specify a version.
        +379      *
        +380      * @param c a suppression rule identifier
        +381      * @return true if the property type does not specify a version; otherwise false
        +382      */
        +383     boolean cpeHasNoVersion(PropertyType c) {
        +384         return !c.isRegex() && countCharacter(c.getValue(), ':') <= 3;
        +385     }
        +386 
        +387     /**
        +388      * Counts the number of occurrences of the character found within the string.
        +389      *
        +390      * @param str the string to check
        +391      * @param c the character to count
        +392      * @return the number of times the character is found in the string
        +393      */
        +394     int countCharacter(String str, char c) {
        +395         int count = 0;
        +396         int pos = str.indexOf(c) + 1;
        +397         while (pos > 0) {
        +398             count += 1;
        +399             pos = str.indexOf(c, pos) + 1;
        +400         }
        +401         return count;
        +402     }
        +403 
        +404     /**
        +405      * Determines if the cpeEntry specified as a PropertyType matches the given Identifier.
        +406      *
        +407      * @param identifierType the type of identifier ("cpe", "maven", etc.)
        +408      * @param suppressionEntry a suppression rule entry
        +409      * @param identifier a CPE identifier to check
        +410      * @return true if the entry matches; otherwise false
        +411      */
        +412     boolean identifierMatches(String identifierType, PropertyType suppressionEntry, Identifier identifier) {
        +413         if (identifierType.equals(identifier.getType())) {
        +414             if (suppressionEntry.matches(identifier.getValue())) {
        +415                 return true;
        +416             } else if ("cpe".equals(identifierType) && cpeHasNoVersion(suppressionEntry)) {
        +417                 if (suppressionEntry.isCaseSensitive()) {
        +418                     return identifier.getValue().startsWith(suppressionEntry.getValue());
        +419                 } else {
        +420                     final String id = identifier.getValue().toLowerCase();
        +421                     final String check = suppressionEntry.getValue().toLowerCase();
        +422                     return id.startsWith(check);
        +423                 }
        +424             }
        +425         }
        +426         return false;
        +427     }
        +428 
        +429     /**
        +430      * Standard toString implementation.
        +431      *
        +432      * @return a string representation of this object
        +433      */
        +434     @Override
        +435     public String toString() {
        +436         final StringBuilder sb = new StringBuilder(64);
        +437         sb.append("SuppressionRule{");
        +438         if (filePath != null) {
        +439             sb.append("filePath=").append(filePath).append(',');
        +440         }
        +441         if (sha1 != null) {
        +442             sb.append("sha1=").append(sha1).append(',');
        +443         }
        +444         if (gav != null) {
        +445             sb.append("gav=").append(gav).append(',');
        +446         }
        +447         if (cpe != null && !cpe.isEmpty()) {
        +448             sb.append("cpe={");
        +449             for (PropertyType pt : cpe) {
        +450                 sb.append(pt).append(',');
        +451             }
        +452             sb.append('}');
        +453         }
        +454         if (cwe != null && !cwe.isEmpty()) {
        +455             sb.append("cwe={");
        +456             for (String s : cwe) {
        +457                 sb.append(s).append(',');
        +458             }
        +459             sb.append('}');
        +460         }
        +461         if (cve != null && !cve.isEmpty()) {
        +462             sb.append("cve={");
        +463             for (String s : cve) {
        +464                 sb.append(s).append(',');
        +465             }
        +466             sb.append('}');
        +467         }
        +468         if (cvssBelow != null && !cvssBelow.isEmpty()) {
        +469             sb.append("cvssBelow={");
        +470             for (Float s : cvssBelow) {
        +471                 sb.append(s).append(',');
        +472             }
        +473             sb.append('}');
        +474         }
        +475         sb.append('}');
        +476         return sb.toString();
        +477     }
        +478 }
        +
        +
        + + + diff --git a/xref/org/owasp/dependencycheck/xml/suppression/package-frame.html b/xref/org/owasp/dependencycheck/xml/suppression/package-frame.html new file mode 100644 index 000000000..c411073e4 --- /dev/null +++ b/xref/org/owasp/dependencycheck/xml/suppression/package-frame.html @@ -0,0 +1,39 @@ + + + + + + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.xml.suppression + + + + +

        + org.owasp.dependencycheck.xml.suppression +

        + +

        Classes

        + + + + + \ No newline at end of file diff --git a/xref/org/owasp/dependencycheck/xml/suppression/package-summary.html b/xref/org/owasp/dependencycheck/xml/suppression/package-summary.html new file mode 100644 index 000000000..01cf39d60 --- /dev/null +++ b/xref/org/owasp/dependencycheck/xml/suppression/package-summary.html @@ -0,0 +1,94 @@ + + + + + + Dependency-Check 1.4.2 Reference Package org.owasp.dependencycheck.xml.suppression + + + +
        + +
        +
        + +
        + +

        Package org.owasp.dependencycheck.xml.suppression

        + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        Class Summary
        + PropertyType +
        + SuppressionErrorHandler +
        + SuppressionHandler +
        + SuppressionParseException +
        + SuppressionParser +
        + SuppressionRule +
        + +
        + +
        +
        + +
        +
        + + + \ No newline at end of file diff --git a/xref/org/slf4j/impl/package-frame.html b/xref/org/slf4j/impl/package-frame.html index bc4c08e1f..1165df056 100644 --- a/xref/org/slf4j/impl/package-frame.html +++ b/xref/org/slf4j/impl/package-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.slf4j.impl + Dependency-Check 1.4.2 Reference Package org.slf4j.impl diff --git a/xref/org/slf4j/impl/package-summary.html b/xref/org/slf4j/impl/package-summary.html index bd259e1c0..44988dd58 100644 --- a/xref/org/slf4j/impl/package-summary.html +++ b/xref/org/slf4j/impl/package-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference Package org.slf4j.impl + Dependency-Check 1.4.2 Reference Package org.slf4j.impl diff --git a/xref/overview-frame.html b/xref/overview-frame.html index 1ca801587..b27fecb98 100644 --- a/xref/overview-frame.html +++ b/xref/overview-frame.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference + Dependency-Check 1.4.2 Reference @@ -80,18 +80,21 @@
      • org.owasp.dependencycheck.reporting -
      • -
      • - org.owasp.dependencycheck.suppression
      • org.owasp.dependencycheck.taskdefs
      • org.owasp.dependencycheck.utils +
      • +
      • + org.owasp.dependencycheck.xml.hints
      • org.owasp.dependencycheck.xml.pom +
      • +
      • + org.owasp.dependencycheck.xml.suppression
      • org.slf4j.impl diff --git a/xref/overview-summary.html b/xref/overview-summary.html index b5bac5318..479525040 100644 --- a/xref/overview-summary.html +++ b/xref/overview-summary.html @@ -3,7 +3,7 @@ - Dependency-Check 1.4.0 Reference + Dependency-Check 1.4.2 Reference @@ -24,7 +24,7 @@
      -

      Dependency-Check 1.4.0 Reference

      +

      Dependency-Check 1.4.2 Reference

      @@ -142,11 +142,6 @@ - - - + + + + + +
      org.owasp.dependencycheck.reporting
      - org.owasp.dependencycheck.suppression -
      @@ -157,11 +152,21 @@ org.owasp.dependencycheck.utils
      + org.owasp.dependencycheck.xml.hints +
      org.owasp.dependencycheck.xml.pom
      + org.owasp.dependencycheck.xml.suppression +