mirror of
https://github.com/ysoftdevs/DependencyCheck.git
synced 2026-01-14 15:53:36 +01:00
Compare commits
138 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6379bfb8b8 | ||
|
|
220539e51a | ||
|
|
95cd215e9e | ||
|
|
88c04714f8 | ||
|
|
6d47e32cac | ||
|
|
fc34b40c0a | ||
|
|
d95fa8a893 | ||
|
|
b48f83ff49 | ||
|
|
c189b258b4 | ||
|
|
06fc5e71c3 | ||
|
|
8093927579 | ||
|
|
d9eed4a460 | ||
|
|
9d609b6085 | ||
|
|
ef97f9c088 | ||
|
|
bb8aa0fe6f | ||
|
|
be441d2aa5 | ||
|
|
73e089d330 | ||
|
|
0a24fb57aa | ||
|
|
7f2c51f337 | ||
|
|
537e490f0f | ||
|
|
a85fb3a871 | ||
|
|
05a49ff5db | ||
|
|
0bec242b2e | ||
|
|
831624897b | ||
|
|
ca8a0e9a88 | ||
|
|
865ff7911a | ||
|
|
eefc6a5567 | ||
|
|
bf3bc83fd8 | ||
|
|
03b06eee67 | ||
|
|
3bc17e7b83 | ||
|
|
458297bf56 | ||
|
|
9673b2aa7c | ||
|
|
a55710df7b | ||
|
|
73edd3bc40 | ||
|
|
f2ee243628 | ||
|
|
88b1e668ee | ||
|
|
1c92a47d75 | ||
|
|
d2a9f0583a | ||
|
|
2621d2e1dc | ||
|
|
1ce683a95a | ||
|
|
3d5f725004 | ||
|
|
655bc4bee3 | ||
|
|
c67d372667 | ||
|
|
54e45dac51 | ||
|
|
5b0b594761 | ||
|
|
cdf6e3b456 | ||
|
|
cf46afea94 | ||
|
|
ea6cca588c | ||
|
|
1f9996fe62 | ||
|
|
e0be6c746c | ||
|
|
2b62bf0337 | ||
|
|
845825c0bf | ||
|
|
f9b09e5b61 | ||
|
|
1403aa18eb | ||
|
|
ba2fff249d | ||
|
|
17447d3cdc | ||
|
|
3f4c1e7029 | ||
|
|
543bbf34c2 | ||
|
|
5394151e42 | ||
|
|
9349e9cd99 | ||
|
|
594aa03c5a | ||
|
|
ff1328dbdd | ||
|
|
9ba44e32fb | ||
|
|
245becdc8c | ||
|
|
56f77e88a8 | ||
|
|
695e35634c | ||
|
|
1f408dd7a7 | ||
|
|
303a3ac376 | ||
|
|
221537601f | ||
|
|
f08919a829 | ||
|
|
cfb1f8c767 | ||
|
|
39d3e447ab | ||
|
|
bb76242632 | ||
|
|
6bfb709233 | ||
|
|
ab9ec7145d | ||
|
|
6ec931fcd7 | ||
|
|
ae76a7f7d4 | ||
|
|
2f20bf1bee | ||
|
|
f9d01d2fad | ||
|
|
1eb1329f68 | ||
|
|
51a3e60913 | ||
|
|
30c88a2fe7 | ||
|
|
4ffd336c72 | ||
|
|
7cbc047b41 | ||
|
|
adf4222b24 | ||
|
|
c095118e98 | ||
|
|
11d7d25037 | ||
|
|
c45ff40250 | ||
|
|
2f8c2b05bd | ||
|
|
a4c17bb308 | ||
|
|
75eff7f083 | ||
|
|
a5b9a707a4 | ||
|
|
1b013db312 | ||
|
|
158250e98d | ||
|
|
f9f4be181d | ||
|
|
3bea99c000 | ||
|
|
05e52ca236 | ||
|
|
f268a48a16 | ||
|
|
96bb9a2f8e | ||
|
|
f9b977d266 | ||
|
|
7fca2a9cc6 | ||
|
|
e473ef36b1 | ||
|
|
3b5b832bbc | ||
|
|
4cfb451755 | ||
|
|
368d1ad354 | ||
|
|
9a8f7ccba8 | ||
|
|
032c8e9fac | ||
|
|
20d1abd2e1 | ||
|
|
73903cbd1f | ||
|
|
bff22a4e4e | ||
|
|
daaaed4118 | ||
|
|
c2c9db66e2 | ||
|
|
09308083a9 | ||
|
|
cf492355b4 | ||
|
|
1cd1b1cb08 | ||
|
|
91a137ab95 | ||
|
|
efd4b8ec11 | ||
|
|
9803c75fbd | ||
|
|
509bbc7743 | ||
|
|
f7a2428ba9 | ||
|
|
c79a9f2ce3 | ||
|
|
685569e131 | ||
|
|
ca44e3062e | ||
|
|
3d919f1836 | ||
|
|
f4fa2150b5 | ||
|
|
0e28c8e0d5 | ||
|
|
cb25fc03f9 | ||
|
|
7a64b84c5f | ||
|
|
1cac8a857d | ||
|
|
f6e02aec2a | ||
|
|
78f7152f6c | ||
|
|
1f4746c90a | ||
|
|
c5f95e79d6 | ||
|
|
bd4cbc54fb | ||
|
|
17e3e51607 | ||
|
|
b9f5799c1b | ||
|
|
8b6e9b7f76 | ||
|
|
4a02c87c27 |
@@ -29,7 +29,7 @@ On Windows
|
||||
|
||||
### Maven Plugin
|
||||
|
||||
More detailed instructions can be found on the [dependency-check-maven github pages](http://jeremylong.github.io/DependencyCheck/dependency-check-maven/installation.html).
|
||||
More detailed instructions can be found on the [dependency-check-maven github pages](http://jeremylong.github.io/DependencyCheck/dependency-check-maven/usage.html).
|
||||
The plugin can be configured using the following:
|
||||
|
||||
```xml
|
||||
|
||||
@@ -21,7 +21,7 @@ Copyright (c) 2013 - Jeremy Long. All Rights Reserved.
|
||||
<parent>
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-parent</artifactId>
|
||||
<version>1.1.0</version>
|
||||
<version>1.1.2</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>dependency-check-ant</artifactId>
|
||||
@@ -237,8 +237,11 @@ Copyright (c) 2013 - Jeremy Long. All Rights Reserved.
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<version>2.5.2</version>
|
||||
<version>2.6</version>
|
||||
<configuration>
|
||||
<instrumentation>
|
||||
<ignoreTrivial>true</ignoreTrivial>
|
||||
</instrumentation>
|
||||
<check>
|
||||
<branchRate>85</branchRate>
|
||||
<lineRate>85</lineRate>
|
||||
@@ -270,11 +273,6 @@ Copyright (c) 2013 - Jeremy Long. All Rights Reserved.
|
||||
<version>2.16</version>
|
||||
<configuration>
|
||||
<systemProperties>
|
||||
<property>
|
||||
<name>net.sourceforge.cobertura.datafile</name>
|
||||
<value>${project.build.directory}/cobertura/cobertura.ser</value>
|
||||
<workingDirectory>target</workingDirectory>
|
||||
</property>
|
||||
<property>
|
||||
<name>data.directory</name>
|
||||
<value>${project.build.directory}/dependency-check-data</value>
|
||||
@@ -356,7 +354,7 @@ Copyright (c) 2013 - Jeremy Long. All Rights Reserved.
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<version>2.5.2</version>
|
||||
<version>2.6</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
|
||||
@@ -502,6 +502,28 @@ public class DependencyCheckTask extends Task {
|
||||
public void setNexusUrl(String nexusUrl) {
|
||||
this.nexusUrl = nexusUrl;
|
||||
}
|
||||
/**
|
||||
* Whether or not the defined proxy should be used when connecting to Nexus.
|
||||
*/
|
||||
private boolean nexusUsesProxy = true;
|
||||
|
||||
/**
|
||||
* Get the value of nexusUsesProxy.
|
||||
*
|
||||
* @return the value of nexusUsesProxy
|
||||
*/
|
||||
public boolean isNexusUsesProxy() {
|
||||
return nexusUsesProxy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of nexusUsesProxy.
|
||||
*
|
||||
* @param nexusUsesProxy new value of nexusUsesProxy
|
||||
*/
|
||||
public void setNexusUsesProxy(boolean nexusUsesProxy) {
|
||||
this.nexusUsesProxy = nexusUsesProxy;
|
||||
}
|
||||
|
||||
/**
|
||||
* The database driver name; such as org.h2.Driver.
|
||||
@@ -616,6 +638,122 @@ public class DependencyCheckTask extends Task {
|
||||
this.databasePassword = databasePassword;
|
||||
}
|
||||
|
||||
/**
|
||||
* Additional ZIP File extensions to add analyze. This should be a comma-separated list of file extensions to treat
|
||||
* like ZIP files.
|
||||
*/
|
||||
private String zipExtensions;
|
||||
|
||||
/**
|
||||
* Get the value of zipExtensions.
|
||||
*
|
||||
* @return the value of zipExtensions
|
||||
*/
|
||||
public String getZipExtensions() {
|
||||
return zipExtensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of zipExtensions.
|
||||
*
|
||||
* @param zipExtensions new value of zipExtensions
|
||||
*/
|
||||
public void setZipExtensions(String zipExtensions) {
|
||||
this.zipExtensions = zipExtensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* The url for the modified NVD CVE (1.2 schema).
|
||||
*/
|
||||
private String cveUrl12Modified;
|
||||
|
||||
/**
|
||||
* Get the value of cveUrl12Modified.
|
||||
*
|
||||
* @return the value of cveUrl12Modified
|
||||
*/
|
||||
public String getCveUrl12Modified() {
|
||||
return cveUrl12Modified;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of cveUrl12Modified.
|
||||
*
|
||||
* @param cveUrl12Modified new value of cveUrl12Modified
|
||||
*/
|
||||
public void setCveUrl12Modified(String cveUrl12Modified) {
|
||||
this.cveUrl12Modified = cveUrl12Modified;
|
||||
}
|
||||
|
||||
/**
|
||||
* The url for the modified NVD CVE (2.0 schema).
|
||||
*/
|
||||
private String cveUrl20Modified;
|
||||
|
||||
/**
|
||||
* Get the value of cveUrl20Modified.
|
||||
*
|
||||
* @return the value of cveUrl20Modified
|
||||
*/
|
||||
public String getCveUrl20Modified() {
|
||||
return cveUrl20Modified;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of cveUrl20Modified.
|
||||
*
|
||||
* @param cveUrl20Modified new value of cveUrl20Modified
|
||||
*/
|
||||
public void setCveUrl20Modified(String cveUrl20Modified) {
|
||||
this.cveUrl20Modified = cveUrl20Modified;
|
||||
}
|
||||
|
||||
/**
|
||||
* Base Data Mirror URL for CVE 1.2.
|
||||
*/
|
||||
private String cveUrl12Base;
|
||||
|
||||
/**
|
||||
* Get the value of cveUrl12Base.
|
||||
*
|
||||
* @return the value of cveUrl12Base
|
||||
*/
|
||||
public String getCveUrl12Base() {
|
||||
return cveUrl12Base;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of cveUrl12Base.
|
||||
*
|
||||
* @param cveUrl12Base new value of cveUrl12Base
|
||||
*/
|
||||
public void setCveUrl12Base(String cveUrl12Base) {
|
||||
this.cveUrl12Base = cveUrl12Base;
|
||||
}
|
||||
|
||||
/**
|
||||
* Data Mirror URL for CVE 2.0.
|
||||
*/
|
||||
private String cveUrl20Base;
|
||||
|
||||
/**
|
||||
* Get the value of cveUrl20Base.
|
||||
*
|
||||
* @return the value of cveUrl20Base
|
||||
*/
|
||||
public String getCveUrl20Base() {
|
||||
return cveUrl20Base;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of cveUrl20Base.
|
||||
*
|
||||
* @param cveUrl20Base new value of cveUrl20Base
|
||||
*/
|
||||
public void setCveUrl20Base(String cveUrl20Base) {
|
||||
this.cveUrl20Base = cveUrl20Base;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws BuildException {
|
||||
final InputStream in = DependencyCheckTask.class.getClassLoader().getResourceAsStream(LOG_PROPERTIES_FILE);
|
||||
@@ -625,46 +763,60 @@ public class DependencyCheckTask extends Task {
|
||||
validateConfiguration();
|
||||
populateSettings();
|
||||
|
||||
final Engine engine = new Engine();
|
||||
for (Resource resource : path) {
|
||||
final FileProvider provider = resource.as(FileProvider.class);
|
||||
if (provider != null) {
|
||||
final File file = provider.getFile();
|
||||
if (file != null && file.exists()) {
|
||||
engine.scan(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
Engine engine = null;
|
||||
try {
|
||||
engine.analyzeDependencies();
|
||||
DatabaseProperties prop = null;
|
||||
CveDB cve = null;
|
||||
try {
|
||||
cve = new CveDB();
|
||||
cve.open();
|
||||
prop = cve.getDatabaseProperties();
|
||||
} catch (DatabaseException ex) {
|
||||
Logger.getLogger(DependencyCheckTask.class.getName()).log(Level.FINE, "Unable to retrieve DB Properties", ex);
|
||||
} finally {
|
||||
if (cve != null) {
|
||||
cve.close();
|
||||
engine = new Engine();
|
||||
|
||||
for (Resource resource : path) {
|
||||
final FileProvider provider = resource.as(FileProvider.class);
|
||||
if (provider != null) {
|
||||
final File file = provider.getFile();
|
||||
if (file != null && file.exists()) {
|
||||
engine.scan(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
final ReportGenerator reporter = new ReportGenerator(applicationName, engine.getDependencies(), engine.getAnalyzers(), prop);
|
||||
reporter.generateReports(reportOutputDirectory, reportFormat);
|
||||
try {
|
||||
engine.analyzeDependencies();
|
||||
DatabaseProperties prop = null;
|
||||
CveDB cve = null;
|
||||
try {
|
||||
cve = new CveDB();
|
||||
cve.open();
|
||||
prop = cve.getDatabaseProperties();
|
||||
} catch (DatabaseException ex) {
|
||||
Logger.getLogger(DependencyCheckTask.class.getName()).log(Level.FINE, "Unable to retrieve DB Properties", ex);
|
||||
} finally {
|
||||
if (cve != null) {
|
||||
cve.close();
|
||||
}
|
||||
}
|
||||
final ReportGenerator reporter = new ReportGenerator(applicationName, engine.getDependencies(), engine.getAnalyzers(), prop);
|
||||
reporter.generateReports(reportOutputDirectory, reportFormat);
|
||||
|
||||
if (this.failBuildOnCVSS <= 10) {
|
||||
checkForFailure(engine.getDependencies());
|
||||
if (this.failBuildOnCVSS <= 10) {
|
||||
checkForFailure(engine.getDependencies());
|
||||
}
|
||||
if (this.showSummary) {
|
||||
showSummary(engine.getDependencies());
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(DependencyCheckTask.class.getName()).log(Level.FINE,
|
||||
"Unable to generate dependency-check report", ex);
|
||||
throw new BuildException("Unable to generate dependency-check report", ex);
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(DependencyCheckTask.class.getName()).log(Level.FINE,
|
||||
"An exception occurred; unable to continue task", ex);
|
||||
throw new BuildException("An exception occurred; unable to continue task", ex);
|
||||
}
|
||||
if (this.showSummary) {
|
||||
showSummary(engine.getDependencies());
|
||||
} catch (DatabaseException ex) {
|
||||
Logger.getLogger(DependencyCheckTask.class.getName()).log(Level.SEVERE,
|
||||
"Unable to connect to the dependency-check database; analysis has stopped");
|
||||
Logger.getLogger(DependencyCheckTask.class.getName()).log(Level.FINE, "", ex);
|
||||
} finally {
|
||||
if (engine != null) {
|
||||
engine.cleanup();
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(DependencyCheckTask.class.getName()).log(Level.FINE, "Unable to generate dependency-check report", ex);
|
||||
throw new BuildException("Unable to generate dependency-check report", ex);
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(DependencyCheckTask.class.getName()).log(Level.FINE, "An exception occurred; unable to continue task", ex);
|
||||
throw new BuildException("An exception occurred; unable to continue task", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -737,6 +889,7 @@ public class DependencyCheckTask extends Task {
|
||||
if (nexusUrl != null && !nexusUrl.isEmpty()) {
|
||||
Settings.setString(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl);
|
||||
}
|
||||
Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_PROXY, nexusUsesProxy);
|
||||
if (databaseDriverName != null && !databaseDriverName.isEmpty()) {
|
||||
Settings.setString(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName);
|
||||
}
|
||||
@@ -752,6 +905,21 @@ public class DependencyCheckTask extends Task {
|
||||
if (databasePassword != null && !databasePassword.isEmpty()) {
|
||||
Settings.setString(Settings.KEYS.DB_PASSWORD, databasePassword);
|
||||
}
|
||||
if (zipExtensions != null && !zipExtensions.isEmpty()) {
|
||||
Settings.setString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions);
|
||||
}
|
||||
if (cveUrl12Modified != null && !cveUrl12Modified.isEmpty()) {
|
||||
Settings.setString(Settings.KEYS.CVE_MODIFIED_12_URL, cveUrl12Modified);
|
||||
}
|
||||
if (cveUrl20Modified != null && !cveUrl20Modified.isEmpty()) {
|
||||
Settings.setString(Settings.KEYS.CVE_MODIFIED_20_URL, cveUrl20Modified);
|
||||
}
|
||||
if (cveUrl12Base != null && !cveUrl12Base.isEmpty()) {
|
||||
Settings.setString(Settings.KEYS.CVE_SCHEMA_1_2, cveUrl12Base);
|
||||
}
|
||||
if (cveUrl20Base != null && !cveUrl20Base.isEmpty()) {
|
||||
Settings.setString(Settings.KEYS.CVE_SCHEMA_2_0, cveUrl20Base);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,27 +20,31 @@ the project's dependencies.
|
||||
```
|
||||
The following table lists the configurable properties:
|
||||
|
||||
Property | Description | Requirement
|
||||
----------------------|-------------|---------
|
||||
ApplicationName | The name of the application to use in the generated report. | Required
|
||||
ReportFormat | The format of the report to be generated. Allowed values are: HTML, XML, VULN, or ALL. The default value is HTML.| Optional
|
||||
ReportOutputDirectory | The directory where dependency-check will store data used for analysis. Defaults to the current working directory. | Optional
|
||||
FailBuildOn | If set and a CVE is found that is greater then the specified value the build will fail. The default value is 11 which means that the build will not fail. Valid values are 0-11. | Optional
|
||||
AutoUpdate | If set to false the NVD CVE data is not automatically updated. Setting this to false could result in false negatives. However, this may be required in some environments. The default value is true. | Optional
|
||||
DataDirectory | The directory where dependency-check will store data used for analysis. Defaults to a folder called, called 'dependency-check-data', that is in the same directory as the dependency-check-ant jar file was installed in. *It is not recommended to change this.* | Optional
|
||||
LogFile | The file path to write verbose logging information. | Optional
|
||||
SuppressionFile | An XML file conforming to the suppression schema that suppresses findings; this is used to hide [false positives](../suppression.html). | Optional
|
||||
ProxyUrl | Defines the proxy used to connect to the Internet. | Optional
|
||||
ProxyPort | Defines the port for the proxy. | Optional
|
||||
ProxyUsername | Defines the proxy user name. | Optional
|
||||
ProxyPassword | Defines the proxy password. | Optional
|
||||
ConnectionTimeout | The connection timeout used when downloading data files from the Internet. | Optional
|
||||
nexusAnalyzerEnabled | The connection timeout used when downloading data files from the Internet. | Optional
|
||||
nexusUrl | The connection timeout used when downloading data files from the Internet. | Optional
|
||||
databaseDriverName | The name of the database driver. Example: org.h2.Driver. | Optional
|
||||
databaseDriverPath | The path to the database driver JAR file; only used if the driver is not in the class path. | Optional
|
||||
connectionString | The connection string used to connect to the database. | Optional
|
||||
databaseUser | The username used when connecting to the database. | Optional
|
||||
databasePassword | The password used when connecting to the database. | Optional
|
||||
|
||||
|
||||
Property | Description | Requirement | Default Value
|
||||
----------------------|-------------|-------------|------------
|
||||
applicationName | The name of the application to use in the generated report. | Required |
|
||||
reportFormat | The format of the report to be generated. Allowed values are: HTML, XML, VULN, or ALL. The default value is HTML.| Optional | HTML
|
||||
reportOutputDirectory | The directory where dependency-check will store data used for analysis. Defaults to the current working directory. | Optional |
|
||||
failBuildOn | If set and a CVE is found that is greater then the specified value the build will fail. The default value is 11 which means that the build will not fail. Valid values are 0-11. | Optional | 11
|
||||
autoUpdate | If set to false the NVD CVE data is not automatically updated. Setting this to false could result in false negatives. However, this may be required in some environments. | Optional | true
|
||||
dataDirectory | The directory where dependency-check will store data used for analysis. Defaults to a folder called, called 'dependency-check-data', that is in the same directory as the dependency-check-ant jar file was installed in. *It is not recommended to change this.* | Optional |
|
||||
logFile | The file path to write verbose logging information. | Optional |
|
||||
suppressionFile | An XML file conforming to the suppression schema that suppresses findings; this is used to hide [false positives](../suppression.html). | Optional |
|
||||
proxyUrl | Defines the proxy used to connect to the Internet. | Optional |
|
||||
proxyPort | Defines the port for the proxy. | Optional |
|
||||
proxyUsername | Defines the proxy user name. | Optional |
|
||||
proxyPassword | Defines the proxy password. | Optional |
|
||||
connectionTimeout | The connection timeout used when downloading data files from the Internet. | Optional |
|
||||
nexusAnalyzerEnabled | The connection timeout used when downloading data files from the Internet. | Optional |
|
||||
nexusUrl | The connection timeout used when downloading data files from the Internet. | Optional |
|
||||
nexusUsesProxy | Whether or not the defined proxy should be used when connecting to Nexus. | Optional | true
|
||||
databaseDriverName | The name of the database driver. Example: org.h2.Driver. | Optional |
|
||||
databaseDriverPath | The path to the database driver JAR file; only used if the driver is not in the class path. | Optional |
|
||||
connectionString | The connection string used to connect to the database. | Optional |
|
||||
databaseUser | The username used when connecting to the database. | Optional | dcuser
|
||||
databasePassword | The password used when connecting to the database. | Optional |
|
||||
zipExtensions | A comma-separated list of additional file extensions to be treated like a ZIP file, the contents will be extracted and analyzed. | Optional |
|
||||
cveUrl12Modified | URL for the modified CVE 1.2 | Optional | http://nvd.nist.gov/download/nvdcve-modified.xml
|
||||
cveUrl20Modified | URL for the modified CVE 2.0 | Optional | http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-modified.xml
|
||||
cveUrl12Base | Base URL for each year's CVE 1.2, the %d will be replaced with the year | Optional | http://nvd.nist.gov/download/nvdcve-%d.xml
|
||||
cveUrl20Base | Base URL for each year's CVE 2.0, the %d will be replaced with the year | Optional | http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-%d.xml
|
||||
|
||||
@@ -21,7 +21,7 @@ Copyright (c) 2012 - Jeremy Long. All Rights Reserved.
|
||||
<parent>
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-parent</artifactId>
|
||||
<version>1.1.0</version>
|
||||
<version>1.1.2</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>dependency-check-cli</artifactId>
|
||||
@@ -77,8 +77,11 @@ Copyright (c) 2012 - Jeremy Long. All Rights Reserved.
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<version>2.5.2</version>
|
||||
<version>2.6</version>
|
||||
<configuration>
|
||||
<instrumentation>
|
||||
<ignoreTrivial>true</ignoreTrivial>
|
||||
</instrumentation>
|
||||
<check>
|
||||
<branchRate>85</branchRate>
|
||||
<lineRate>85</lineRate>
|
||||
@@ -115,11 +118,6 @@ Copyright (c) 2012 - Jeremy Long. All Rights Reserved.
|
||||
<version>2.16</version>
|
||||
<configuration>
|
||||
<systemProperties>
|
||||
<property>
|
||||
<name>net.sourceforge.cobertura.datafile</name>
|
||||
<value>${project.build.directory}/cobertura/cobertura.ser</value>
|
||||
<workingDirectory>target</workingDirectory>
|
||||
</property>
|
||||
<property>
|
||||
<name>cpe</name>
|
||||
<value>data/cpe</value>
|
||||
@@ -206,7 +204,7 @@ Copyright (c) 2012 - Jeremy Long. All Rights Reserved.
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<version>2.5.2</version>
|
||||
<version>2.6</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
|
||||
@@ -98,36 +98,46 @@ public class App {
|
||||
* @param files the files/directories to scan
|
||||
*/
|
||||
private void runScan(String reportDirectory, String outputFormat, String applicationName, String[] files) {
|
||||
final Engine scanner = new Engine();
|
||||
|
||||
for (String file : files) {
|
||||
scanner.scan(file);
|
||||
}
|
||||
|
||||
scanner.analyzeDependencies();
|
||||
final List<Dependency> dependencies = scanner.getDependencies();
|
||||
DatabaseProperties prop = null;
|
||||
CveDB cve = null;
|
||||
Engine scanner = null;
|
||||
try {
|
||||
cve = new CveDB();
|
||||
cve.open();
|
||||
prop = cve.getDatabaseProperties();
|
||||
} catch (DatabaseException ex) {
|
||||
Logger.getLogger(App.class.getName()).log(Level.FINE, "Unable to retrieve DB Properties", ex);
|
||||
} finally {
|
||||
if (cve != null) {
|
||||
cve.close();
|
||||
scanner = new Engine();
|
||||
|
||||
for (String file : files) {
|
||||
scanner.scan(file);
|
||||
}
|
||||
|
||||
scanner.analyzeDependencies();
|
||||
final List<Dependency> dependencies = scanner.getDependencies();
|
||||
DatabaseProperties prop = null;
|
||||
CveDB cve = null;
|
||||
try {
|
||||
cve = new CveDB();
|
||||
cve.open();
|
||||
prop = cve.getDatabaseProperties();
|
||||
} catch (DatabaseException ex) {
|
||||
Logger.getLogger(App.class.getName()).log(Level.FINE, "Unable to retrieve DB Properties", ex);
|
||||
} finally {
|
||||
if (cve != null) {
|
||||
cve.close();
|
||||
}
|
||||
}
|
||||
final ReportGenerator report = new ReportGenerator(applicationName, dependencies, scanner.getAnalyzers(), prop);
|
||||
try {
|
||||
report.generateReports(reportDirectory, outputFormat);
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(App.class.getName()).log(Level.SEVERE, "There was an IO error while attempting to generate the report.");
|
||||
Logger.getLogger(App.class.getName()).log(Level.FINE, null, ex);
|
||||
} catch (Throwable ex) {
|
||||
Logger.getLogger(App.class.getName()).log(Level.SEVERE, "There was an error while attempting to generate the report.");
|
||||
Logger.getLogger(App.class.getName()).log(Level.FINE, null, ex);
|
||||
}
|
||||
} catch (DatabaseException ex) {
|
||||
Logger.getLogger(App.class.getName()).log(Level.SEVERE, "Unable to connect to the dependency-check database; analysis has stopped");
|
||||
Logger.getLogger(App.class.getName()).log(Level.FINE, "", ex);
|
||||
} finally {
|
||||
if (scanner != null) {
|
||||
scanner.cleanup();
|
||||
}
|
||||
}
|
||||
final ReportGenerator report = new ReportGenerator(applicationName, dependencies, scanner.getAnalyzers(), prop);
|
||||
try {
|
||||
report.generateReports(reportDirectory, outputFormat);
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(App.class.getName()).log(Level.SEVERE, "There was an IO error while attempting to generate the report.");
|
||||
Logger.getLogger(App.class.getName()).log(Level.INFO, null, ex);
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(App.class.getName()).log(Level.SEVERE, "There was an error while attempting to generate the report.");
|
||||
Logger.getLogger(App.class.getName()).log(Level.INFO, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,11 +160,13 @@ public class App {
|
||||
final String suppressionFile = cli.getSuppressionFile();
|
||||
final boolean nexusDisabled = cli.isNexusDisabled();
|
||||
final String nexusUrl = cli.getNexusUrl();
|
||||
final boolean nexusUsesProxy = cli.isNexusUsesProxy();
|
||||
final String databaseDriverName = cli.getDatabaseDriverName();
|
||||
final String databaseDriverPath = cli.getDatabaseDriverPath();
|
||||
final String connectionString = cli.getConnectionString();
|
||||
final String databaseUser = cli.getDatabaseUser();
|
||||
final String databasePassword = cli.getDatabasePassword();
|
||||
final String additionalZipExtensions = cli.getAdditionalZipExtensions();
|
||||
|
||||
if (propertiesFile != null) {
|
||||
try {
|
||||
@@ -204,7 +216,7 @@ public class App {
|
||||
if (nexusUrl != null && !nexusUrl.isEmpty()) {
|
||||
Settings.setString(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl);
|
||||
}
|
||||
|
||||
Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_PROXY, nexusUsesProxy);
|
||||
if (databaseDriverName != null && !databaseDriverName.isEmpty()) {
|
||||
Settings.setString(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName);
|
||||
}
|
||||
@@ -220,5 +232,8 @@ public class App {
|
||||
if (databasePassword != null && !databasePassword.isEmpty()) {
|
||||
Settings.setString(Settings.KEYS.DB_PASSWORD, databasePassword);
|
||||
}
|
||||
if (additionalZipExtensions != null && !additionalZipExtensions.isEmpty()) {
|
||||
Settings.setString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, additionalZipExtensions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,6 +204,16 @@ public final class CliParser {
|
||||
.withDescription("The url to the Nexus Server.")
|
||||
.create();
|
||||
|
||||
final Option nexusUsesProxy = OptionBuilder.withArgName("true/false").hasArg().withLongOpt(ArgumentName.NEXUS_USES_PROXY)
|
||||
.withDescription("Whether or not the configured proxy should be used when connecting to Nexus.")
|
||||
.create();
|
||||
|
||||
final Option additionalZipExtensions = OptionBuilder.withArgName("extensions").hasArg()
|
||||
.withLongOpt(ArgumentName.ADDITIONAL_ZIP_EXTENSIONS)
|
||||
.withDescription("A comma seperated list of additional extensions to be scanned as ZIP files "
|
||||
+ "(ZIP, EAR, WAR are already treated as zip files)")
|
||||
.create();
|
||||
|
||||
//This is an option group because it can be specified more then once.
|
||||
final OptionGroup og = new OptionGroup();
|
||||
og.addOption(path);
|
||||
@@ -220,7 +230,9 @@ public final class CliParser {
|
||||
.addOption(verboseLog)
|
||||
.addOption(suppressionFile)
|
||||
.addOption(disableNexusAnalyzer)
|
||||
.addOption(nexusUrl);
|
||||
.addOption(nexusUrl)
|
||||
.addOption(nexusUsesProxy)
|
||||
.addOption(additionalZipExtensions);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -335,6 +347,20 @@ public final class CliParser {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the Nexus Analyzer should use the configured proxy to connect to Nexus; otherwise false is
|
||||
* returned.
|
||||
*
|
||||
* @return true if the Nexus Analyzer should use the configured proxy to connect to Nexus; otherwise false
|
||||
*/
|
||||
public boolean isNexusUsesProxy() {
|
||||
if (line == null || !line.hasOption(ArgumentName.NEXUS_USES_PROXY)) {
|
||||
return true;
|
||||
} else {
|
||||
return Boolean.parseBoolean(line.getOptionValue(ArgumentName.NEXUS_USES_PROXY));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the command line help message to the standard output.
|
||||
*/
|
||||
@@ -548,6 +574,15 @@ public final class CliParser {
|
||||
return line.getOptionValue(ArgumentName.DB_PASSWORD);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the additional Extensions if specified; otherwise null is returned.
|
||||
*
|
||||
* @return the additional Extensions; otherwise null is returned
|
||||
*/
|
||||
public String getAdditionalZipExtensions() {
|
||||
return line.getOptionValue(ArgumentName.ADDITIONAL_ZIP_EXTENSIONS);
|
||||
}
|
||||
|
||||
/**
|
||||
* A collection of static final strings that represent the possible command line arguments.
|
||||
*/
|
||||
@@ -681,6 +716,10 @@ public final class CliParser {
|
||||
* The URL of the nexus server.
|
||||
*/
|
||||
public static final String NEXUS_URL = "nexus";
|
||||
/**
|
||||
* Whether or not the defined proxy should be used when connecting to Nexus.
|
||||
*/
|
||||
public static final String NEXUS_USES_PROXY = "nexusUsesProxy";
|
||||
/**
|
||||
* The CLI argument name for setting the connection string.
|
||||
*/
|
||||
@@ -701,5 +740,9 @@ public final class CliParser {
|
||||
* The CLI argument name for setting the path to the database driver; in case it is not on the class path.
|
||||
*/
|
||||
public static final String DB_DRIVER_PATH = "dbDriverPath";
|
||||
/**
|
||||
* The CLI argument name for setting extra extensions.
|
||||
*/
|
||||
public static final String ADDITIONAL_ZIP_EXTENSIONS = "zipExtensions";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,28 +3,30 @@ Command Line Arguments
|
||||
|
||||
The following table lists the command line arguments:
|
||||
|
||||
Short | Argument Name | Parameter | Description | Requirement
|
||||
-------|-----------------------|-------------|-------------|------------
|
||||
\-a | \-\-app | \<name\> | The name of the application being scanned. This is a required argument. |
|
||||
\-c | \-\-connectiontimeout | \<timeout\> | The connection timeout (in milliseconds) to use when downloading resources. | Optional
|
||||
\-d | \-\-data | \<path\> | The location of the data directory used to store persistent data. This option should generally not be set. | Optional
|
||||
\-f | \-\-format | \<format\> | The output format to write to (XML, HTML, VULN, ALL). The default is HTML. |
|
||||
\-h | \-\-help | | Print the help message. | Optional
|
||||
\-l | \-\-log | \<file\> | The file path to write verbose logging information. | Optional
|
||||
\-n | \-\-noupdate | | Disables the automatic updating of the CPE data. | Optional
|
||||
\-o | \-\-out | \<folder\> | The folder to write reports to. This defaults to the current directory. | Optional
|
||||
\-p | \-\-proxyport | \<port\> | The proxy port to use when downloading resources. | Optional
|
||||
| \-\-proxypass | \<pass\> | The proxy password to use when downloading resources. | Optional
|
||||
| \-\-proxyuser | \<user\> | The proxy username to use when downloading resources. | Optional
|
||||
\-s | \-\-scan | \<path\> | The path to scan \- this option can be specified multiple times. |
|
||||
| \-\-suppression | \<file\> | The file path to the suppression XML file; used to suppress [false positives](../suppression.html). | Optional
|
||||
\-u | \-\-proxyurl | \<url\> | The proxy url to use when downloading resources. | Optional
|
||||
\-v | \-\-version | | Print the version information. | Optional
|
||||
| \-\-advancedHelp | | Print the advanced help message. | Optional
|
||||
| \-\-connectionString | \<connStr\> | The connection string to the database. | Optional
|
||||
| \-\-dbDriverName | \<driver\> | The database driver name. | Optional
|
||||
| \-\-dbDriverPath | \<path\> | The path to the database driver; note, this does not need to be set unless the JAR is outside of the class path. | Optional
|
||||
| \-\-dbPassword | \<password\>| The password for connecting to the database. | Optional
|
||||
| \-\-dbUser | \<user\> | The username used to connect to the database. | Optional
|
||||
| \-\-disableNexus | | Disable the Nexus Analyzer. | Optional
|
||||
| \-\-nexus | \<url\> | The url to the Nexus Server. | Optional
|
||||
Short | Argument Name | Parameter | Description | Requirement
|
||||
-------|-----------------------|-----------------|-------------|------------
|
||||
\-a | \-\-app | \<name\> | The name of the application being scanned. This is a required argument. | Required
|
||||
\-c | \-\-connectiontimeout | \<timeout\> | The connection timeout (in milliseconds) to use when downloading resources. | Optional
|
||||
\-d | \-\-data | \<path\> | The location of the data directory used to store persistent data. This option should generally not be set. | Optional
|
||||
\-f | \-\-format | \<format\> | The output format to write to (XML, HTML, VULN, ALL). The default is HTML. | Required
|
||||
\-h | \-\-help | | Print the help message. | Optional
|
||||
\-l | \-\-log | \<file\> | The file path to write verbose logging information. | Optional
|
||||
\-n | \-\-noupdate | | Disables the automatic updating of the CPE data. | Optional
|
||||
\-o | \-\-out | \<folder\> | The folder to write reports to. This defaults to the current directory. | Optional
|
||||
\-p | \-\-proxyport | \<port\> | The proxy port to use when downloading resources. | Optional
|
||||
| \-\-proxypass | \<pass\> | The proxy password to use when downloading resources. | Optional
|
||||
| \-\-proxyuser | \<user\> | The proxy username to use when downloading resources. | Optional
|
||||
\-s | \-\-scan | \<path\> | The path to scan \- this option can be specified multiple times. | Required
|
||||
| \-\-suppression | \<file\> | The file path to the suppression XML file; used to suppress [false positives](../suppression.html). | Optional
|
||||
\-u | \-\-proxyurl | \<url\> | The proxy url to use when downloading resources. | Optional
|
||||
\-v | \-\-version | | Print the version information. | Optional
|
||||
| \-\-advancedHelp | | Print the advanced help message. | Optional
|
||||
| \-\-connectionString | \<connStr\> | The connection string to the database. | Optional
|
||||
| \-\-dbDriverName | \<driver\> | The database driver name. | Optional
|
||||
| \-\-dbDriverPath | \<path\> | The path to the database driver; note, this does not need to be set unless the JAR is outside of the class path. | Optional
|
||||
| \-\-dbPassword | \<password\> | The password for connecting to the database. | Optional
|
||||
| \-\-dbUser | \<user\> | The username used to connect to the database. | Optional
|
||||
| \-\-disableNexus | | Disable the Nexus Analyzer. | Optional
|
||||
| \-\-nexus | \<url\> | The url to the Nexus Server. | Optional
|
||||
| \-\-nexusUsesProxy | \<true\|false\> | Whether or not the defined proxy should be used when connecting to Nexus. | Optional
|
||||
| \-\-zipExtensions | \<strings\> | A comma-separated list of additional file extensions to be treated like a ZIP file, the contents will be extracted and analyzed. | Optional
|
||||
@@ -1,5 +1,5 @@
|
||||
Installation & Usage
|
||||
--------------------
|
||||
====================
|
||||
Download the dependency-check command line tool [here](http://dl.bintray.com/jeremy-long/owasp/dependency-check-${project.version}-release.zip).
|
||||
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
|
||||
@@ -9,15 +9,19 @@ script executable:
|
||||
|
||||
To scan a folder on the system you can run:
|
||||
|
||||
<h3>Windows</h3>
|
||||
Windows
|
||||
-------
|
||||
dependency-check.bat --app "My App Name" --scan "c:\java\application\lib"
|
||||
|
||||
<h3>\*nix</h3>
|
||||
\*nix
|
||||
-------
|
||||
dependency-check.sh --app "My App Name" --scan "/java/application/lib"
|
||||
|
||||
To view the command line arguments, see the <a href="arguments.html">arguments page</a>, or you can run:
|
||||
<h3>Windows</h3>
|
||||
Windows
|
||||
-------
|
||||
dependency-check.bat --help
|
||||
|
||||
<h3>\*nix</h3>
|
||||
\*nix
|
||||
-------
|
||||
dependency-check.sh --help
|
||||
@@ -21,7 +21,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||
<parent>
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-parent</artifactId>
|
||||
<version>1.1.0</version>
|
||||
<version>1.1.2</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>dependency-check-core</artifactId>
|
||||
@@ -144,6 +144,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||
<version>2.6</version>
|
||||
<configuration>
|
||||
<instrumentation>
|
||||
<ignoreTrivial>true</ignoreTrivial>
|
||||
<ignores>
|
||||
<ignore>.*\$KEYS\.class</ignore>
|
||||
<ignore>.*\$Element\.class</ignore>
|
||||
@@ -635,5 +636,40 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
<profile>
|
||||
<!-- The following profile adds additional
|
||||
dependencies that are only used during testing.
|
||||
Additionally, these are only added when using "allTests" to
|
||||
make the build slightly faster in most cases. -->
|
||||
<id>False Positive Tests</id>
|
||||
<!--activation>
|
||||
<property>
|
||||
<name>allTests</name>
|
||||
</property>
|
||||
</activation-->
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.xmlgraphics</groupId>
|
||||
<artifactId>batik-util</artifactId>
|
||||
<version>1.7</version>
|
||||
<scope>provided</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.thoughtworks.xstream</groupId>
|
||||
<artifactId>xstream</artifactId>
|
||||
<version>1.4.2</version>
|
||||
<scope>provided</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.ws.security</groupId>
|
||||
<artifactId>wss4j</artifactId>
|
||||
<version>1.5.7</version>
|
||||
<scope>provided</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
||||
|
||||
@@ -26,12 +26,13 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.owasp.dependencycheck.analyzer.AnalysisException;
|
||||
import org.owasp.dependencycheck.analyzer.AnalysisPhase;
|
||||
import org.owasp.dependencycheck.analyzer.Analyzer;
|
||||
import org.owasp.dependencycheck.analyzer.AnalyzerService;
|
||||
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||
import org.owasp.dependencycheck.data.cpe.CpeMemoryIndex;
|
||||
import org.owasp.dependencycheck.data.cpe.IndexException;
|
||||
import org.owasp.dependencycheck.data.nvdcve.ConnectionFactory;
|
||||
import org.owasp.dependencycheck.data.nvdcve.CveDB;
|
||||
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
|
||||
import org.owasp.dependencycheck.data.update.CachedWebDataSource;
|
||||
@@ -67,11 +68,14 @@ public class Engine {
|
||||
|
||||
/**
|
||||
* Creates a new Engine.
|
||||
*
|
||||
* @throws DatabaseException thrown if there is an error connecting to the database
|
||||
*/
|
||||
public Engine() {
|
||||
public Engine() throws DatabaseException {
|
||||
this.extensions = new HashSet<String>();
|
||||
this.dependencies = new ArrayList<Dependency>();
|
||||
this.analyzers = new EnumMap<AnalysisPhase, List<Analyzer>>(AnalysisPhase.class);
|
||||
ConnectionFactory.initialize();
|
||||
|
||||
boolean autoUpdate = true;
|
||||
try {
|
||||
@@ -85,6 +89,13 @@ public class Engine {
|
||||
loadAnalyzers();
|
||||
}
|
||||
|
||||
/**
|
||||
* Properly cleans up resources allocated during analysis.
|
||||
*/
|
||||
public void cleanup() {
|
||||
ConnectionFactory.cleanup();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the analyzers specified in the configuration file (or system properties).
|
||||
*/
|
||||
@@ -288,13 +299,13 @@ public class Engine {
|
||||
final String msg = String.format("Initializing %s", a.getName());
|
||||
Logger.getLogger(Engine.class.getName()).log(Level.FINE, msg);
|
||||
a.initialize();
|
||||
} catch (Exception ex) {
|
||||
} catch (Throwable ex) {
|
||||
final String msg = String.format("Exception occurred initializing %s.", a.getName());
|
||||
Logger.getLogger(Engine.class.getName()).log(Level.SEVERE, msg);
|
||||
Logger.getLogger(Engine.class.getName()).log(Level.INFO, null, ex);
|
||||
Logger.getLogger(Engine.class.getName()).log(Level.FINE, null, ex);
|
||||
try {
|
||||
a.close();
|
||||
} catch (Exception ex1) {
|
||||
} catch (Throwable ex1) {
|
||||
Logger.getLogger(Engine.class.getName()).log(Level.FINEST, null, ex1);
|
||||
}
|
||||
}
|
||||
@@ -321,13 +332,14 @@ public class Engine {
|
||||
try {
|
||||
a.analyze(d, this);
|
||||
} catch (AnalysisException ex) {
|
||||
d.addAnalysisException(ex);
|
||||
final String exMsg = String.format("An error occured while analyzing '%s'.", d.getActualFilePath());
|
||||
Logger.getLogger(Engine.class.getName()).log(Level.WARNING, exMsg);
|
||||
Logger.getLogger(Engine.class.getName()).log(Level.FINE, "", ex);
|
||||
} catch (Throwable ex) {
|
||||
final String axMsg = String.format("An unexpected error occurred during analysis of '%s'", d.getActualFilePath());
|
||||
final AnalysisException ax = new AnalysisException(axMsg, ex);
|
||||
d.addAnalysisException(ax);
|
||||
Logger.getLogger(Engine.class.getName()).log(Level.SEVERE, axMsg);
|
||||
Logger.getLogger(Engine.class.getName()).log(Level.FINE, axMsg, ex);
|
||||
//final AnalysisException ax = new AnalysisException(axMsg, ex);
|
||||
Logger.getLogger(Engine.class.getName()).log(Level.WARNING, axMsg);
|
||||
Logger.getLogger(Engine.class.getName()).log(Level.FINE, "", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -342,7 +354,7 @@ public class Engine {
|
||||
Logger.getLogger(Engine.class.getName()).log(Level.FINE, msg);
|
||||
try {
|
||||
a.close();
|
||||
} catch (Exception ex) {
|
||||
} catch (Throwable ex) {
|
||||
Logger.getLogger(Engine.class.getName()).log(Level.FINEST, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
package org.owasp.dependencycheck.analyzer;
|
||||
|
||||
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||
import java.util.Set;
|
||||
import org.owasp.dependencycheck.Engine;
|
||||
import org.owasp.dependencycheck.dependency.Dependency;
|
||||
|
||||
@@ -25,6 +25,7 @@ import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@@ -38,9 +39,11 @@ import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
|
||||
import org.apache.commons.compress.compressors.CompressorInputStream;
|
||||
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
|
||||
import org.apache.commons.compress.compressors.gzip.GzipUtils;
|
||||
import org.h2.store.fs.FileUtils;
|
||||
import org.owasp.dependencycheck.Engine;
|
||||
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||
import org.owasp.dependencycheck.analyzer.exception.ArchiveExtractionException;
|
||||
import org.owasp.dependencycheck.dependency.Dependency;
|
||||
import org.owasp.dependencycheck.utils.FileUtils;
|
||||
import org.owasp.dependencycheck.utils.Settings;
|
||||
|
||||
/**
|
||||
@@ -82,9 +85,23 @@ public class ArchiveAnalyzer extends AbstractAnalyzer implements Analyzer {
|
||||
*/
|
||||
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INITIAL;
|
||||
/**
|
||||
* The set of file extensions supported by this analyzer.
|
||||
* The set of things we can handle with Zip methods
|
||||
*/
|
||||
private static final Set<String> EXTENSIONS = newHashSet("zip", "ear", "war", "tar", "gz", "tgz");
|
||||
private static final Set<String> ZIPPABLES = newHashSet("zip", "ear", "war", "nupkg");
|
||||
/**
|
||||
* The set of file extensions supported by this analyzer. Note for developers, any additions to this list will need
|
||||
* to be explicitly handled in extractFiles().
|
||||
*/
|
||||
private static final Set<String> EXTENSIONS = newHashSet("tar", "gz", "tgz");
|
||||
|
||||
static {
|
||||
final String additionalZipExt = Settings.getString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS);
|
||||
if (additionalZipExt != null) {
|
||||
final HashSet ext = new HashSet<String>(Arrays.asList(additionalZipExt));
|
||||
ZIPPABLES.addAll(ext);
|
||||
}
|
||||
EXTENSIONS.addAll(ZIPPABLES);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of file EXTENSIONS supported by this analyzer.
|
||||
@@ -150,14 +167,19 @@ public class ArchiveAnalyzer extends AbstractAnalyzer implements Analyzer {
|
||||
}
|
||||
|
||||
/**
|
||||
* The close method does nothing for this Analyzer.
|
||||
* 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 {
|
||||
if (tempFileLocation != null && tempFileLocation.exists()) {
|
||||
FileUtils.deleteRecursive(tempFileLocation.getAbsolutePath(), true);
|
||||
Logger.getLogger(ArchiveAnalyzer.class.getName()).log(Level.FINE, "Attempting to delete temporary files");
|
||||
final boolean success = FileUtils.delete(tempFileLocation);
|
||||
if (!success) {
|
||||
Logger.getLogger(ArchiveAnalyzer.class.getName()).log(Level.WARNING,
|
||||
"Failed to delete some temporary files, see the log for more details");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,18 +268,18 @@ public class ArchiveAnalyzer extends AbstractAnalyzer implements Analyzer {
|
||||
try {
|
||||
fis = new FileInputStream(archive);
|
||||
} catch (FileNotFoundException ex) {
|
||||
Logger.getLogger(ArchiveAnalyzer.class.getName()).log(Level.INFO, null, ex);
|
||||
Logger.getLogger(ArchiveAnalyzer.class.getName()).log(Level.FINE, null, ex);
|
||||
throw new AnalysisException("Archive file was not found.", ex);
|
||||
}
|
||||
final String archiveExt = org.owasp.dependencycheck.utils.FileUtils.getFileExtension(archive.getName()).toLowerCase();
|
||||
final String archiveExt = FileUtils.getFileExtension(archive.getName()).toLowerCase();
|
||||
try {
|
||||
if ("zip".equals(archiveExt) || "war".equals(archiveExt) || "ear".equals(archiveExt)) {
|
||||
if (ZIPPABLES.contains(archiveExt)) {
|
||||
extractArchive(new ZipArchiveInputStream(new BufferedInputStream(fis)), destination, engine);
|
||||
} else if ("tar".equals(archiveExt)) {
|
||||
extractArchive(new TarArchiveInputStream(new BufferedInputStream(fis)), destination, engine);
|
||||
} else if ("gz".equals(archiveExt) || "tgz".equals(archiveExt)) {
|
||||
final String uncompressedName = GzipUtils.getUncompressedFilename(archive.getName());
|
||||
final String uncompressedExt = org.owasp.dependencycheck.utils.FileUtils.getFileExtension(uncompressedName).toLowerCase();
|
||||
final String uncompressedExt = FileUtils.getFileExtension(uncompressedName).toLowerCase();
|
||||
if (engine.supportsExtension(uncompressedExt)) {
|
||||
decompressFile(new GzipCompressorInputStream(new BufferedInputStream(fis)), new File(destination, uncompressedName));
|
||||
}
|
||||
@@ -301,7 +323,7 @@ public class ArchiveAnalyzer extends AbstractAnalyzer implements Analyzer {
|
||||
}
|
||||
} else {
|
||||
final File file = new File(destination, entry.getName());
|
||||
final String ext = org.owasp.dependencycheck.utils.FileUtils.getFileExtension(file.getName());
|
||||
final String ext = FileUtils.getFileExtension(file.getName());
|
||||
if (engine.supportsExtension(ext)) {
|
||||
BufferedOutputStream bos = null;
|
||||
FileOutputStream fos;
|
||||
|
||||
@@ -0,0 +1,269 @@
|
||||
/*
|
||||
* This file is part of dependency-check-core.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||
*/
|
||||
package org.owasp.dependencycheck.analyzer;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.xpath.XPath;
|
||||
import javax.xml.xpath.XPathExpressionException;
|
||||
import javax.xml.xpath.XPathFactory;
|
||||
import org.owasp.dependencycheck.Engine;
|
||||
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||
import org.owasp.dependencycheck.dependency.Confidence;
|
||||
import org.owasp.dependencycheck.dependency.Dependency;
|
||||
import org.owasp.dependencycheck.dependency.Evidence;
|
||||
import org.owasp.dependencycheck.utils.Settings;
|
||||
import org.w3c.dom.Document;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
/**
|
||||
* Analyzer for getting company, product, and version information from a .NET assembly.
|
||||
*
|
||||
* @author colezlaw
|
||||
*
|
||||
*/
|
||||
public class AssemblyAnalyzer extends AbstractAnalyzer {
|
||||
|
||||
/**
|
||||
* The analyzer name
|
||||
*/
|
||||
private static final String ANALYZER_NAME = "Assembly Analyzer";
|
||||
/**
|
||||
* The analysis phase
|
||||
*/
|
||||
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
|
||||
/**
|
||||
* The list of supported extensions
|
||||
*/
|
||||
private static final Set<String> SUPORTED_EXTENSIONS = newHashSet("dll", "exe");
|
||||
/**
|
||||
* The temp value for GrokAssembly.exe
|
||||
*/
|
||||
private File grokAssemblyExe;
|
||||
/**
|
||||
* The DocumentBuilder for parsing the XML
|
||||
*/
|
||||
private DocumentBuilder builder;
|
||||
/**
|
||||
* Logger
|
||||
*/
|
||||
private static final Logger LOG = Logger.getLogger(AbstractAnalyzer.class.getName());
|
||||
|
||||
/**
|
||||
* Builds the beginnings of a List for ProcessBuilder
|
||||
*
|
||||
* @return the list of arguments to begin populating the ProcessBuilder
|
||||
*/
|
||||
private List<String> buildArgumentList() {
|
||||
// Use file.separator as a wild guess as to whether this is Windows
|
||||
final List<String> args = new ArrayList<String>();
|
||||
if (!"\\".equals(System.getProperty("file.separator"))) {
|
||||
if (Settings.getString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH) != null) {
|
||||
args.add(Settings.getString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH));
|
||||
} else {
|
||||
args.add("mono");
|
||||
}
|
||||
}
|
||||
args.add(grokAssemblyExe.getPath());
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the analysis on a single Dependency.
|
||||
*
|
||||
* @param dependency the dependency to analyze
|
||||
* @param engine the engine to perform the analysis under
|
||||
* @throws AnalysisException if anything goes sideways
|
||||
*/
|
||||
@Override
|
||||
public void analyze(Dependency dependency, Engine engine)
|
||||
throws AnalysisException {
|
||||
if (grokAssemblyExe == null) {
|
||||
LOG.warning("GrokAssembly didn't get deployed");
|
||||
return;
|
||||
}
|
||||
|
||||
final List<String> args = buildArgumentList();
|
||||
args.add(dependency.getActualFilePath());
|
||||
final ProcessBuilder pb = new ProcessBuilder(args);
|
||||
try {
|
||||
final Process proc = pb.start();
|
||||
final Document doc = builder.parse(proc.getInputStream());
|
||||
final XPath xpath = XPathFactory.newInstance().newXPath();
|
||||
|
||||
// First, see if there was an error
|
||||
final String error = xpath.evaluate("/assembly/error", doc);
|
||||
if (error != null && !"".equals(error)) {
|
||||
throw new AnalysisException(error);
|
||||
}
|
||||
|
||||
final String version = xpath.evaluate("/assembly/version", doc);
|
||||
if (version != null) {
|
||||
dependency.getVersionEvidence().addEvidence(new Evidence("grokassembly", "version",
|
||||
version, Confidence.HIGHEST));
|
||||
}
|
||||
|
||||
final String vendor = xpath.evaluate("/assembly/company", doc);
|
||||
if (vendor != null) {
|
||||
dependency.getVendorEvidence().addEvidence(new Evidence("grokassembly", "vendor",
|
||||
vendor, Confidence.HIGH));
|
||||
}
|
||||
|
||||
final String product = xpath.evaluate("/assembly/product", doc);
|
||||
if (product != null) {
|
||||
dependency.getProductEvidence().addEvidence(new Evidence("grokassembly", "product",
|
||||
product, Confidence.HIGH));
|
||||
}
|
||||
|
||||
} catch (IOException ioe) {
|
||||
throw new AnalysisException(ioe);
|
||||
} catch (SAXException saxe) {
|
||||
throw new AnalysisException("Couldn't parse GrokAssembly result", saxe);
|
||||
} catch (XPathExpressionException xpe) {
|
||||
// This shouldn't happen
|
||||
throw new AnalysisException(xpe);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the analyzer. In this case, extract GrokAssembly.exe to a temporary location.
|
||||
*
|
||||
* @throws Exception if anything goes wrong
|
||||
*/
|
||||
@Override
|
||||
public void initialize() throws Exception {
|
||||
super.initialize();
|
||||
final File tempFile = File.createTempFile("GKA", ".exe");
|
||||
FileOutputStream fos = null;
|
||||
InputStream is = null;
|
||||
try {
|
||||
fos = new FileOutputStream(tempFile);
|
||||
is = AssemblyAnalyzer.class.getClassLoader().getResourceAsStream("GrokAssembly.exe");
|
||||
final byte[] buff = new byte[4096];
|
||||
int bread = -1;
|
||||
while ((bread = is.read(buff)) >= 0) {
|
||||
fos.write(buff, 0, bread);
|
||||
}
|
||||
grokAssemblyExe = tempFile;
|
||||
// Set the temp file to get deleted when we're done
|
||||
grokAssemblyExe.deleteOnExit();
|
||||
LOG.log(Level.FINE, "Extracted GrokAssembly.exe to {0}", grokAssemblyExe.getPath());
|
||||
} catch (IOException ioe) {
|
||||
LOG.log(Level.WARNING, "Could not extract GrokAssembly.exe: {0}", ioe.getMessage());
|
||||
throw new AnalysisException("Could not extract GrokAssembly.exe", ioe);
|
||||
} finally {
|
||||
if (fos != null) {
|
||||
try {
|
||||
fos.close();
|
||||
} catch (Throwable e) {
|
||||
LOG.fine("Error closing output stream");
|
||||
}
|
||||
}
|
||||
if (is != null) {
|
||||
try {
|
||||
is.close();
|
||||
} catch (Throwable e) {
|
||||
LOG.fine("Error closing input stream");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now, need to see if GrokAssembly actually runs from this location.
|
||||
final List<String> args = buildArgumentList();
|
||||
try {
|
||||
final Process p = new ProcessBuilder(args).start();
|
||||
final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(p.getInputStream());
|
||||
final XPath xpath = XPathFactory.newInstance().newXPath();
|
||||
final String error = xpath.evaluate("/assembly/error", doc);
|
||||
if (p.waitFor() != 1 || error == null || "".equals(error)) {
|
||||
LOG.warning("An error occured with the .NET AssemblyAnalyzer, please see the log for more details.");
|
||||
LOG.fine("GrokAssembly.exe is not working properly");
|
||||
grokAssemblyExe = null;
|
||||
throw new AnalysisException("Could not execute .NET AssemblyAnalyzer");
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
LOG.warning("An error occured with the .NET AssemblyAnalyzer; "
|
||||
+ "this can be ignored unless you are scanning .NET dlls. Please see the log for more details.");
|
||||
LOG.log(Level.FINE, "Could not execute GrokAssembly {0}", e.getMessage());
|
||||
throw new AnalysisException("An error occured with the .NET AssemblyAnalyzer", e);
|
||||
}
|
||||
|
||||
builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
super.close();
|
||||
try {
|
||||
grokAssemblyExe.delete();
|
||||
} catch (SecurityException se) {
|
||||
LOG.fine("Can't delete temporary GrokAssembly.exe");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the set of extensions supported by this analyzer.
|
||||
*
|
||||
* @return the list of supported extensions
|
||||
*/
|
||||
@Override
|
||||
public Set<String> getSupportedExtensions() {
|
||||
return SUPORTED_EXTENSIONS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this analyzer's name.
|
||||
*
|
||||
* @return the analyzer name
|
||||
*/
|
||||
@Override
|
||||
public String getName() {
|
||||
return ANALYZER_NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether the analyzer supports the provided extension.
|
||||
*
|
||||
* @param extension the extension to check
|
||||
* @return whether the analyzer supports the extension
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsExtension(String extension) {
|
||||
return SUPORTED_EXTENSIONS.contains(extension);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the phase this analyzer runs under.
|
||||
*
|
||||
* @return the phase this runs under
|
||||
*/
|
||||
@Override
|
||||
public AnalysisPhase getAnalysisPhase() {
|
||||
return ANALYSIS_PHASE;
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,7 @@ import org.apache.lucene.queryparser.classic.ParseException;
|
||||
import org.apache.lucene.search.ScoreDoc;
|
||||
import org.apache.lucene.search.TopDocs;
|
||||
import org.owasp.dependencycheck.Engine;
|
||||
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||
import org.owasp.dependencycheck.data.cpe.CpeMemoryIndex;
|
||||
import org.owasp.dependencycheck.data.cpe.Fields;
|
||||
import org.owasp.dependencycheck.data.cpe.IndexEntry;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
package org.owasp.dependencycheck.analyzer;
|
||||
|
||||
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||
import org.owasp.dependencycheck.Engine;
|
||||
import org.owasp.dependencycheck.dependency.Dependency;
|
||||
import org.owasp.dependencycheck.suppression.SuppressionRule;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
package org.owasp.dependencycheck.analyzer;
|
||||
|
||||
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||
import java.io.File;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
|
||||
@@ -30,6 +30,7 @@ import java.util.logging.Logger;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import org.owasp.dependencycheck.Engine;
|
||||
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||
import org.owasp.dependencycheck.dependency.Dependency;
|
||||
import org.owasp.dependencycheck.dependency.Identifier;
|
||||
import org.owasp.dependencycheck.dependency.VulnerableSoftware;
|
||||
@@ -281,6 +282,12 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
|
||||
} else if (i.getValue().startsWith("cpe:/a:apache:maven")
|
||||
&& !dependency.getFileName().toLowerCase().matches("maven-core-[\\d\\.]+\\.jar")) {
|
||||
itr.remove();
|
||||
} else if (i.getValue().startsWith("cpe:/a:m-core:m-core")
|
||||
&& !dependency.getEvidenceUsed().containsUsedString("m-core")) {
|
||||
itr.remove();
|
||||
} else if (i.getValue().startsWith("cpe:/a:jboss:jboss")
|
||||
&& !dependency.getFileName().toLowerCase().matches("jboss-[\\d\\.]+(GA)?\\.jar")) {
|
||||
itr.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
package org.owasp.dependencycheck.analyzer;
|
||||
|
||||
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||
import java.io.File;
|
||||
import java.util.Set;
|
||||
import org.owasp.dependencycheck.Engine;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
package org.owasp.dependencycheck.analyzer;
|
||||
|
||||
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -25,6 +25,7 @@ import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Reader;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
@@ -53,9 +54,9 @@ import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.parsers.SAXParser;
|
||||
import javax.xml.parsers.SAXParserFactory;
|
||||
import javax.xml.transform.sax.SAXSource;
|
||||
import org.h2.store.fs.FileUtils;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.owasp.dependencycheck.Engine;
|
||||
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||
import org.owasp.dependencycheck.dependency.Confidence;
|
||||
import org.owasp.dependencycheck.dependency.Dependency;
|
||||
import org.owasp.dependencycheck.dependency.EvidenceCollection;
|
||||
@@ -64,6 +65,7 @@ import org.owasp.dependencycheck.jaxb.pom.generated.License;
|
||||
import org.owasp.dependencycheck.jaxb.pom.generated.Model;
|
||||
import org.owasp.dependencycheck.jaxb.pom.generated.Organization;
|
||||
import org.owasp.dependencycheck.jaxb.pom.generated.Parent;
|
||||
import org.owasp.dependencycheck.utils.FileUtils;
|
||||
import org.owasp.dependencycheck.utils.NonClosingStream;
|
||||
import org.owasp.dependencycheck.utils.Settings;
|
||||
import org.xml.sax.InputSource;
|
||||
@@ -260,8 +262,7 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
|
||||
jar = new JarFile(dependency.getActualFilePath());
|
||||
} catch (IOException ex) {
|
||||
final String msg = String.format("Unable to read JarFile '%s'.", dependency.getActualFilePath());
|
||||
final AnalysisException ax = new AnalysisException(msg, ex);
|
||||
dependency.getAnalysisExceptions().add(ax);
|
||||
//final AnalysisException ax = new AnalysisException(msg, ex);
|
||||
Logger.getLogger(JarAnalyzer.class.getName()).log(Level.WARNING, msg);
|
||||
Logger.getLogger(JarAnalyzer.class.getName()).log(Level.FINE, null, ex);
|
||||
return false;
|
||||
@@ -271,10 +272,9 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
|
||||
pomEntries = retrievePomListing(jar);
|
||||
} catch (IOException ex) {
|
||||
final String msg = String.format("Unable to read Jar file entries in '%s'.", dependency.getActualFilePath());
|
||||
final AnalysisException ax = new AnalysisException(msg, ex);
|
||||
dependency.getAnalysisExceptions().add(ax);
|
||||
//final AnalysisException ax = new AnalysisException(msg, ex);
|
||||
Logger.getLogger(JarAnalyzer.class.getName()).log(Level.WARNING, msg);
|
||||
Logger.getLogger(JarAnalyzer.class.getName()).log(Level.INFO, msg, ex);
|
||||
Logger.getLogger(JarAnalyzer.class.getName()).log(Level.FINE, msg, ex);
|
||||
return false;
|
||||
}
|
||||
if (pomEntries.isEmpty()) {
|
||||
@@ -313,7 +313,9 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
|
||||
foundSomething |= setPomEvidence(dependency, pom, pomProperties, classes);
|
||||
}
|
||||
} catch (AnalysisException ex) {
|
||||
dependency.addAnalysisException(ex);
|
||||
final String msg = String.format("An error occured while analyzing '%s'.", dependency.getActualFilePath());
|
||||
Logger.getLogger(JarAnalyzer.class.getName()).log(Level.WARNING, msg);
|
||||
Logger.getLogger(JarAnalyzer.class.getName()).log(Level.FINE, "", ex);
|
||||
}
|
||||
}
|
||||
return foundSomething;
|
||||
@@ -392,11 +394,9 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(JarAnalyzer.class.getName()).log(Level.SEVERE, null, ex);
|
||||
} finally {
|
||||
try {
|
||||
input.close();
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(JarAnalyzer.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
closeStream(bos);
|
||||
closeStream(fos);
|
||||
closeStream(input);
|
||||
}
|
||||
Model model = null;
|
||||
FileInputStream fis = null;
|
||||
@@ -422,17 +422,41 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
|
||||
Logger.getLogger(JarAnalyzer.class.getName()).log(Level.FINE, null, ex);
|
||||
throw ex;
|
||||
} finally {
|
||||
if (fis != null) {
|
||||
try {
|
||||
fis.close();
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(JarAnalyzer.class.getName()).log(Level.FINEST, null, ex);
|
||||
}
|
||||
}
|
||||
closeStream(fis);
|
||||
}
|
||||
return model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Silently closes an input stream ignoring errors.
|
||||
*
|
||||
* @param stream an input stream to close
|
||||
*/
|
||||
private void closeStream(InputStream stream) {
|
||||
if (stream != null) {
|
||||
try {
|
||||
stream.close();
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(JarAnalyzer.class.getName()).log(Level.FINEST, null, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Silently closes an output stream ignoring errors.
|
||||
*
|
||||
* @param stream an output stream to close
|
||||
*/
|
||||
private void closeStream(OutputStream stream) {
|
||||
if (stream != null) {
|
||||
try {
|
||||
stream.close();
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(JarAnalyzer.class.getName()).log(Level.FINEST, null, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the specified POM from a jar file and converts it to a Model.
|
||||
*
|
||||
@@ -575,43 +599,12 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
|
||||
foundSomething = true;
|
||||
final String description = interpolateString(pom.getDescription(), pomProperties);
|
||||
if (description != null && !description.isEmpty()) {
|
||||
addDescription(dependency, description, "pom", "description");
|
||||
addMatchingValues(classes, description, dependency.getVendorEvidence());
|
||||
addMatchingValues(classes, description, dependency.getProductEvidence());
|
||||
}
|
||||
}
|
||||
|
||||
//license
|
||||
if (pom.getLicenses() != null) {
|
||||
String license = null;
|
||||
for (License lic : pom.getLicenses().getLicense()) {
|
||||
String tmp = null;
|
||||
if (lic.getName() != null) {
|
||||
tmp = interpolateString(lic.getName(), pomProperties);
|
||||
}
|
||||
if (lic.getUrl() != null) {
|
||||
if (tmp == null) {
|
||||
tmp = interpolateString(lic.getUrl(), pomProperties);
|
||||
} else {
|
||||
tmp += ": " + interpolateString(lic.getUrl(), pomProperties);
|
||||
}
|
||||
}
|
||||
if (tmp == null) {
|
||||
continue;
|
||||
}
|
||||
if (HTML_DETECTION_PATTERN.matcher(tmp).find()) {
|
||||
tmp = Jsoup.parse(tmp).text();
|
||||
}
|
||||
if (license == null) {
|
||||
license = tmp;
|
||||
} else {
|
||||
license += "\n" + tmp;
|
||||
}
|
||||
}
|
||||
if (license != null) {
|
||||
dependency.setLicense(license);
|
||||
final String trimmedDescription = addDescription(dependency, description, "pom", "description");
|
||||
addMatchingValues(classes, trimmedDescription, dependency.getVendorEvidence());
|
||||
addMatchingValues(classes, trimmedDescription, dependency.getProductEvidence());
|
||||
}
|
||||
}
|
||||
extractLicense(pom, pomProperties, dependency);
|
||||
return foundSomething;
|
||||
}
|
||||
|
||||
@@ -767,7 +760,16 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
|
||||
} else {
|
||||
versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
|
||||
}
|
||||
|
||||
} else if ("build-id".equals(key)) {
|
||||
int pos = value.indexOf('(');
|
||||
if (pos >= 0) {
|
||||
value = value.substring(0, pos - 1);
|
||||
}
|
||||
pos = value.indexOf('[');
|
||||
if (pos >= 0) {
|
||||
value = value.substring(0, pos - 1);
|
||||
}
|
||||
versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
|
||||
} else if (key.contains("title")) {
|
||||
productEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
|
||||
addMatchingValues(classInformation, value, productEvidence);
|
||||
@@ -816,14 +818,18 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a description to the given dependency.
|
||||
* Adds a description to the given dependency. If the description contains one of the following strings beyond 100
|
||||
* characters, then the description used will be trimmed to that position:
|
||||
* <ul><li>"such as"</li><li>"like "</li><li>"will use "</li><li>"* uses "</li></ul>
|
||||
*
|
||||
* @param dependency a dependency
|
||||
* @param description the description
|
||||
* @param source the source of the evidence
|
||||
* @param key the "name" of the evidence
|
||||
* @return if the description is trimmed, the trimmed version is returned; otherwise the original description is
|
||||
* returned
|
||||
*/
|
||||
private void addDescription(Dependency dependency, String description, String source, String key) {
|
||||
private String addDescription(Dependency dependency, String description, String source, String key) {
|
||||
if (dependency.getDescription() == null) {
|
||||
dependency.setDescription(description);
|
||||
}
|
||||
@@ -835,29 +841,42 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
|
||||
}
|
||||
dependency.setDescription(desc);
|
||||
if (desc.length() > 100) {
|
||||
desc = desc.replaceAll("\\s\\s+", " ");
|
||||
final int posSuchAs = desc.toLowerCase().indexOf("such as ", 100);
|
||||
final int posLike = desc.toLowerCase().indexOf("like ", 100);
|
||||
final int posWillUse = desc.toLowerCase().indexOf("will use ", 100);
|
||||
final int posUses = desc.toLowerCase().indexOf(" uses ", 100);
|
||||
int pos = -1;
|
||||
if (posLike > 0 && posSuchAs > 0) {
|
||||
pos = posLike > posSuchAs ? posLike : posSuchAs;
|
||||
} else if (posLike > 0) {
|
||||
pos = posLike;
|
||||
} else if (posSuchAs > 0) {
|
||||
pos = posSuchAs;
|
||||
pos = Math.max(pos, posSuchAs);
|
||||
if (pos >= 0 && posLike >= 0) {
|
||||
pos = Math.min(pos, posLike);
|
||||
} else {
|
||||
pos = Math.max(pos, posLike);
|
||||
}
|
||||
String descToUse = desc;
|
||||
if (pos >= 0 && posWillUse >= 0) {
|
||||
pos = Math.min(pos, posWillUse);
|
||||
} else {
|
||||
pos = Math.max(pos, posWillUse);
|
||||
}
|
||||
if (pos >= 0 && posUses >= 0) {
|
||||
pos = Math.min(pos, posUses);
|
||||
} else {
|
||||
pos = Math.max(pos, posUses);
|
||||
}
|
||||
|
||||
if (pos > 0) {
|
||||
final StringBuilder sb = new StringBuilder(pos + 3);
|
||||
sb.append(desc.substring(0, pos));
|
||||
sb.append("...");
|
||||
descToUse = sb.toString();
|
||||
desc = sb.toString();
|
||||
}
|
||||
dependency.getProductEvidence().addEvidence(source, key, descToUse, Confidence.LOW);
|
||||
dependency.getVendorEvidence().addEvidence(source, key, descToUse, Confidence.LOW);
|
||||
dependency.getProductEvidence().addEvidence(source, key, desc, Confidence.LOW);
|
||||
dependency.getVendorEvidence().addEvidence(source, key, desc, Confidence.LOW);
|
||||
} else {
|
||||
dependency.getProductEvidence().addEvidence(source, key, desc, Confidence.MEDIUM);
|
||||
dependency.getVendorEvidence().addEvidence(source, key, desc, Confidence.MEDIUM);
|
||||
}
|
||||
return desc;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -910,7 +929,12 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
|
||||
@Override
|
||||
public void close() {
|
||||
if (tempFileLocation != null && tempFileLocation.exists()) {
|
||||
FileUtils.deleteRecursive(tempFileLocation.getAbsolutePath(), true);
|
||||
Logger.getLogger(JarAnalyzer.class.getName()).log(Level.FINE, "Attempting to delete temporary files");
|
||||
final boolean success = FileUtils.delete(tempFileLocation);
|
||||
if (!success) {
|
||||
Logger.getLogger(JarAnalyzer.class.getName()).log(Level.WARNING,
|
||||
"Failed to delete some temporary files, see the log for more details");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1195,7 +1219,17 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
|
||||
addDescription(dependency, description, "pom", "description");
|
||||
}
|
||||
}
|
||||
extractLicense(pom, pomProperties, dependency);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the license information from the pom and adds it to the dependency.
|
||||
*
|
||||
* @param pom the pom object
|
||||
* @param pomProperties the properties, used for string interpolation
|
||||
* @param dependency the dependency to add license information too
|
||||
*/
|
||||
private void extractLicense(Model pom, Properties pomProperties, Dependency dependency) {
|
||||
//license
|
||||
if (pom.getLicenses() != null) {
|
||||
String license = null;
|
||||
|
||||
@@ -13,18 +13,26 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||
* Copyright (c) 2014 Jeremy Long. All Rights Reserved.
|
||||
*/
|
||||
package org.owasp.dependencycheck.analyzer;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Pattern;
|
||||
import org.owasp.dependencycheck.Engine;
|
||||
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||
import org.owasp.dependencycheck.dependency.Dependency;
|
||||
|
||||
/**
|
||||
*
|
||||
* Used to load a JAR file and collect information that can be used to determine the associated CPE.
|
||||
* Used to analyze a JavaScript file to gather information to aid in identification of a CPE identifier.
|
||||
*
|
||||
* @author Jeremy Long <jeremy.long@owasp.org>
|
||||
*/
|
||||
@@ -49,6 +57,7 @@ public class JavaScriptAnalyzer extends AbstractAnalyzer implements Analyzer {
|
||||
*
|
||||
* @return a list of file EXTENSIONS supported by this analyzer.
|
||||
*/
|
||||
@Override
|
||||
public Set<String> getSupportedExtensions() {
|
||||
return EXTENSIONS;
|
||||
}
|
||||
@@ -58,6 +67,7 @@ public class JavaScriptAnalyzer extends AbstractAnalyzer implements Analyzer {
|
||||
*
|
||||
* @return the name of the analyzer.
|
||||
*/
|
||||
@Override
|
||||
public String getName() {
|
||||
return ANALYZER_NAME;
|
||||
}
|
||||
@@ -68,6 +78,7 @@ public class JavaScriptAnalyzer extends AbstractAnalyzer implements Analyzer {
|
||||
* @param extension the file extension to test for support.
|
||||
* @return whether or not the specified file extension is supported by this analyzer.
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsExtension(String extension) {
|
||||
return EXTENSIONS.contains(extension);
|
||||
}
|
||||
@@ -77,42 +88,45 @@ public class JavaScriptAnalyzer extends AbstractAnalyzer implements Analyzer {
|
||||
*
|
||||
* @return the phase that the analyzer is intended to run in.
|
||||
*/
|
||||
@Override
|
||||
public AnalysisPhase getAnalysisPhase() {
|
||||
return ANALYSIS_PHASE;
|
||||
}
|
||||
//</editor-fold>
|
||||
|
||||
/**
|
||||
* Loads a specified JAR file and collects information from the manifest and checksums to identify the correct CPE
|
||||
* information.
|
||||
* Loads a specified JavaScript file and collects information from the copyright information contained within.
|
||||
*
|
||||
* @param dependency the dependency to analyze.
|
||||
* @param engine the engine that is scanning the dependencies
|
||||
* @throws AnalysisException is thrown if there is an error reading the JAR file.
|
||||
* @throws AnalysisException is thrown if there is an error reading the JavaScript file.
|
||||
*/
|
||||
@Override
|
||||
public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
|
||||
final Pattern extractComments = Pattern.compile("(/\\*([^*]|[\\r\\n]|(\\*+([^*/]|[\\r\\n])))*\\*+/)|(//.*)");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The initialize method does nothing for this Analyzer.
|
||||
*
|
||||
* @throws Exception thrown if there is an exception
|
||||
*/
|
||||
@Override
|
||||
public void initialize() throws Exception {
|
||||
//do nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* The close method does nothing for this Analyzer.
|
||||
*
|
||||
* @throws Exception thrown if there is an exception
|
||||
*/
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
//do nothing
|
||||
BufferedReader fin = null;;
|
||||
try {
|
||||
// /\*([^\*][^/]|[\r\n\f])+?\*/
|
||||
final Pattern extractComments = Pattern.compile("(/\\*([^*]|[\\r\\n]|(\\*+([^*/]|[\\r\\n])))*\\*+/)|(//.*)", Pattern.MULTILINE);
|
||||
File file = dependency.getActualFile();
|
||||
fin = new BufferedReader(new FileReader(file));
|
||||
StringBuilder sb = new StringBuilder(2000);
|
||||
String text;
|
||||
while ((text = fin.readLine()) != null) {
|
||||
sb.append(text);
|
||||
}
|
||||
} catch (FileNotFoundException ex) {
|
||||
final String msg = String.format("Dependency file not found: '%s'", dependency.getActualFilePath());
|
||||
throw new AnalysisException(msg, ex);
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(JavaScriptAnalyzer.class.getName()).log(Level.SEVERE, null, ex);
|
||||
} finally {
|
||||
if (fin != null) {
|
||||
try {
|
||||
fin.close();
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(JavaScriptAnalyzer.class.getName()).log(Level.FINEST, null, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.owasp.dependencycheck.Engine;
|
||||
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||
import org.owasp.dependencycheck.data.nexus.MavenArtifact;
|
||||
import org.owasp.dependencycheck.data.nexus.NexusSearch;
|
||||
import org.owasp.dependencycheck.dependency.Confidence;
|
||||
@@ -92,6 +93,10 @@ public class NexusAnalyzer extends AbstractAnalyzer {
|
||||
LOGGER.fine(String.format("Nexus Analyzer URL: %s", searchUrl));
|
||||
try {
|
||||
searcher = new NexusSearch(new URL(searchUrl));
|
||||
if (!searcher.preflightRequest()) {
|
||||
LOGGER.warning("There was an issue getting Nexus status. Disabling analyzer.");
|
||||
enabled = false;
|
||||
}
|
||||
} catch (MalformedURLException mue) {
|
||||
// I know that initialize can throw an exception, but we'll
|
||||
// just disable the analyzer if the URL isn't valid
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* This file is part of dependency-check-core.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Copyright (c) 2014 Jeremy Long. All Rights Reserved.
|
||||
*/
|
||||
package org.owasp.dependencycheck.analyzer;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.owasp.dependencycheck.Engine;
|
||||
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||
import org.owasp.dependencycheck.data.nuget.NugetPackage;
|
||||
import org.owasp.dependencycheck.data.nuget.NuspecParser;
|
||||
import org.owasp.dependencycheck.data.nuget.XPathNuspecParser;
|
||||
import org.owasp.dependencycheck.dependency.Confidence;
|
||||
import org.owasp.dependencycheck.dependency.Dependency;
|
||||
|
||||
/**
|
||||
* Analyzer which will parse a Nuspec file to gather module information.
|
||||
*
|
||||
* @author colezlaw
|
||||
*/
|
||||
public class NuspecAnalyzer extends AbstractAnalyzer {
|
||||
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private static final Logger LOGGER = Logger.getLogger(NuspecAnalyzer.class.getName());
|
||||
|
||||
/**
|
||||
* The name of the analyzer
|
||||
*/
|
||||
private static final String ANALYZER_NAME = "Nuspec Analyzer";
|
||||
|
||||
/**
|
||||
* The phase in which the analyzer runs
|
||||
*/
|
||||
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
|
||||
|
||||
/**
|
||||
* The types of files on which this will work.
|
||||
*/
|
||||
private static final Set<String> SUPPORTED_EXTENSIONS = newHashSet("nuspec");
|
||||
|
||||
/**
|
||||
* Initializes the analyzer once before any analysis is performed.
|
||||
*
|
||||
* @throws Exception if there's an error during initialization
|
||||
*/
|
||||
@Override
|
||||
public void initialize() throws Exception {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the analyzer's name.
|
||||
*
|
||||
* @return the name of the analyzer
|
||||
*/
|
||||
@Override
|
||||
public String getName() {
|
||||
return ANALYZER_NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the analysis phase under which the analyzer runs.
|
||||
*
|
||||
* @return the phase under which this analyzer runs
|
||||
*/
|
||||
@Override
|
||||
public AnalysisPhase getAnalysisPhase() {
|
||||
return ANALYSIS_PHASE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the extensions for which this Analyzer runs.
|
||||
*
|
||||
* @return the extensions for which this Analyzer runs
|
||||
*/
|
||||
@Override
|
||||
public Set<String> getSupportedExtensions() {
|
||||
return SUPPORTED_EXTENSIONS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the incoming extension is supported.
|
||||
*
|
||||
* @param extension the extension to check for support
|
||||
* @return whether the extension is supported
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsExtension(String extension) {
|
||||
return SUPPORTED_EXTENSIONS.contains(extension);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the analysis.
|
||||
*
|
||||
* @param dependency the dependency to analyze
|
||||
* @param engine the engine
|
||||
* @throws AnalysisException when there's an exception during analysis
|
||||
*/
|
||||
@Override
|
||||
public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
|
||||
LOGGER.log(Level.INFO, "Checking Nuspec file {0}", dependency.toString());
|
||||
try {
|
||||
final NuspecParser parser = new XPathNuspecParser();
|
||||
NugetPackage np = null;
|
||||
FileInputStream fis = null;
|
||||
try {
|
||||
fis = new FileInputStream(dependency.getActualFilePath());
|
||||
np = parser.parse(fis);
|
||||
} finally {
|
||||
if (fis != null) {
|
||||
try {
|
||||
fis.close();
|
||||
} catch (Throwable e) {
|
||||
LOGGER.fine("Error closing input stream");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (np.getOwners() != null) {
|
||||
dependency.getVendorEvidence().addEvidence("nuspec", "owners", np.getOwners(), Confidence.HIGHEST);
|
||||
}
|
||||
dependency.getVendorEvidence().addEvidence("nuspec", "authors", np.getAuthors(), Confidence.HIGH);
|
||||
dependency.getVersionEvidence().addEvidence("nuspec", "version", np.getVersion(), Confidence.HIGHEST);
|
||||
dependency.getProductEvidence().addEvidence("nuspec", "id", np.getId(), Confidence.HIGHEST);
|
||||
if (np.getTitle() != null) {
|
||||
dependency.getProductEvidence().addEvidence("nuspec", "title", np.getTitle(), Confidence.MEDIUM);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
throw new AnalysisException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// vim: cc=120:sw=4:ts=4:sts=4
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
package org.owasp.dependencycheck.analyzer;
|
||||
|
||||
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
package org.owasp.dependencycheck.analyzer;
|
||||
|
||||
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||
import org.owasp.dependencycheck.Engine;
|
||||
import org.owasp.dependencycheck.dependency.Dependency;
|
||||
import org.owasp.dependencycheck.suppression.SuppressionRule;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*
|
||||
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||
*/
|
||||
package org.owasp.dependencycheck.analyzer;
|
||||
package org.owasp.dependencycheck.analyzer.exception;
|
||||
|
||||
/**
|
||||
* An exception thrown when the analysis of a dependency fails.
|
||||
@@ -15,7 +15,7 @@
|
||||
*
|
||||
* Copyright (c) 2013 Jeremy Long. All Rights Reserved.
|
||||
*/
|
||||
package org.owasp.dependencycheck.analyzer;
|
||||
package org.owasp.dependencycheck.analyzer.exception;
|
||||
|
||||
/**
|
||||
* An exception thrown when files in an archive cannot be extracted.
|
||||
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* <html>
|
||||
* <head>
|
||||
* <title>org.owasp.dependencycheck.analyzer.exception</title>
|
||||
* </head>
|
||||
* <body>
|
||||
* <p>
|
||||
* A collection of exception classes used within the analyzers.</p>
|
||||
* </body>
|
||||
* </html>
|
||||
*/
|
||||
package org.owasp.dependencycheck.analyzer.exception;
|
||||
@@ -18,10 +18,9 @@
|
||||
package org.owasp.dependencycheck.data.cpe;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.apache.lucene.analysis.Analyzer;
|
||||
@@ -45,6 +44,8 @@ import org.owasp.dependencycheck.data.lucene.FieldAnalyzer;
|
||||
import org.owasp.dependencycheck.data.lucene.LuceneUtils;
|
||||
import org.owasp.dependencycheck.data.lucene.SearchFieldAnalyzer;
|
||||
import org.owasp.dependencycheck.data.nvdcve.CveDB;
|
||||
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
|
||||
import org.owasp.dependencycheck.utils.Pair;
|
||||
|
||||
/**
|
||||
* An in memory lucene index that contains the vendor/product combinations from the CPE (application) identifiers within
|
||||
@@ -210,7 +211,7 @@ public final class CpeMemoryIndex {
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the lucene index based off of the data within the CveDB.
|
||||
* Builds the CPE Lucene Index based off of the data within the CveDB.
|
||||
*
|
||||
* @param cve the data base containing the CPE data
|
||||
* @throws IndexException thrown if there is an issue creating the index
|
||||
@@ -222,15 +223,12 @@ public final class CpeMemoryIndex {
|
||||
analyzer = createIndexingAnalyzer();
|
||||
final IndexWriterConfig conf = new IndexWriterConfig(LuceneUtils.CURRENT_VERSION, analyzer);
|
||||
indexWriter = new IndexWriter(index, conf);
|
||||
final ResultSet rs = cve.getVendorProductList();
|
||||
if (rs == null) {
|
||||
throw new IndexException("No data exists");
|
||||
}
|
||||
try {
|
||||
while (rs.next()) {
|
||||
saveEntry(rs.getString(1), rs.getString(2), indexWriter);
|
||||
final Set<Pair<String, String>> data = cve.getVendorProductList();
|
||||
for (Pair<String, String> pair : data) {
|
||||
saveEntry(pair.getLeft(), pair.getRight(), indexWriter);
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
} catch (DatabaseException ex) {
|
||||
Logger.getLogger(CpeMemoryIndex.class.getName()).log(Level.FINE, null, ex);
|
||||
throw new IndexException("Error reading CPE data", ex);
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ public final class UrlTokenizingFilter extends AbstractTokenizingFilter {
|
||||
final List<String> data = UrlStringUtils.extractImportantUrlData(part);
|
||||
tokens.addAll(data);
|
||||
} catch (MalformedURLException ex) {
|
||||
Logger.getLogger(UrlTokenizingFilter.class.getName()).log(Level.INFO, "error parsing " + part, ex);
|
||||
Logger.getLogger(UrlTokenizingFilter.class.getName()).log(Level.FINE, "error parsing " + part, ex);
|
||||
tokens.add(part);
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -19,13 +19,18 @@ package org.owasp.dependencycheck.data.nexus;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.xpath.XPath;
|
||||
import javax.xml.xpath.XPathFactory;
|
||||
import org.owasp.dependencycheck.utils.InvalidSettingException;
|
||||
import org.owasp.dependencycheck.utils.Settings;
|
||||
import org.owasp.dependencycheck.utils.URLConnectionFactory;
|
||||
import org.w3c.dom.Document;
|
||||
|
||||
/**
|
||||
@@ -40,10 +45,16 @@ public class NexusSearch {
|
||||
*/
|
||||
private final URL rootURL;
|
||||
|
||||
/**
|
||||
* Whether to use the Proxy when making requests
|
||||
*/
|
||||
private boolean useProxy;
|
||||
|
||||
/**
|
||||
* Used for logging.
|
||||
*/
|
||||
private static final Logger LOGGER = Logger.getLogger(NexusSearch.class.getName());
|
||||
private static final Logger LOGGER = Logger.getLogger(NexusSearch.class
|
||||
.getName());
|
||||
|
||||
/**
|
||||
* Creates a NexusSearch for the given repository URL.
|
||||
@@ -53,6 +64,18 @@ public class NexusSearch {
|
||||
*/
|
||||
public NexusSearch(URL rootURL) {
|
||||
this.rootURL = rootURL;
|
||||
try {
|
||||
if (null != Settings.getString(Settings.KEYS.PROXY_URL)
|
||||
&& Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_PROXY)) {
|
||||
useProxy = true;
|
||||
LOGGER.fine("Using proxy");
|
||||
} else {
|
||||
useProxy = false;
|
||||
LOGGER.fine("Not using proxy");
|
||||
}
|
||||
} catch (InvalidSettingException ise) {
|
||||
useProxy = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -69,11 +92,19 @@ public class NexusSearch {
|
||||
throw new IllegalArgumentException("Invalid SHA1 format");
|
||||
}
|
||||
|
||||
final URL url = new URL(rootURL, String.format("identify/sha1/%s", sha1.toLowerCase()));
|
||||
final URL url = new URL(rootURL, String.format("identify/sha1/%s",
|
||||
sha1.toLowerCase()));
|
||||
|
||||
LOGGER.fine(String.format("Searching Nexus url %s", url.toString()));
|
||||
|
||||
final URLConnection conn = url.openConnection();
|
||||
// Determine if we need to use a proxy. The rules:
|
||||
// 1) If the proxy is set, AND the setting is set to true, use the proxy
|
||||
// 2) Otherwise, don't use the proxy (either the proxy isn't configured,
|
||||
// or proxy is specifically
|
||||
// set to false
|
||||
URLConnection conn = null;
|
||||
conn = URLConnectionFactory.createHttpURLConnection(url, useProxy);
|
||||
|
||||
conn.setDoOutput(true);
|
||||
|
||||
// JSON would be more elegant, but there's not currently a dependency
|
||||
@@ -82,23 +113,64 @@ public class NexusSearch {
|
||||
conn.connect();
|
||||
|
||||
try {
|
||||
final DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
|
||||
final DocumentBuilder builder = DocumentBuilderFactory
|
||||
.newInstance().newDocumentBuilder();
|
||||
final Document doc = builder.parse(conn.getInputStream());
|
||||
final XPath xpath = XPathFactory.newInstance().newXPath();
|
||||
final String groupId = xpath.evaluate("/org.sonatype.nexus.rest.model.NexusArtifact/groupId", doc);
|
||||
final String artifactId = xpath.evaluate("/org.sonatype.nexus.rest.model.NexusArtifact/artifactId", doc);
|
||||
final String version = xpath.evaluate("/org.sonatype.nexus.rest.model.NexusArtifact/version", doc);
|
||||
final String link = xpath.evaluate("/org.sonatype.nexus.rest.model.NexusArtifact/artifactLink", doc);
|
||||
final String groupId = xpath
|
||||
.evaluate(
|
||||
"/org.sonatype.nexus.rest.model.NexusArtifact/groupId",
|
||||
doc);
|
||||
final String artifactId = xpath.evaluate(
|
||||
"/org.sonatype.nexus.rest.model.NexusArtifact/artifactId",
|
||||
doc);
|
||||
final String version = xpath
|
||||
.evaluate(
|
||||
"/org.sonatype.nexus.rest.model.NexusArtifact/version",
|
||||
doc);
|
||||
final String link = xpath
|
||||
.evaluate(
|
||||
"/org.sonatype.nexus.rest.model.NexusArtifact/artifactLink",
|
||||
doc);
|
||||
return new MavenArtifact(groupId, artifactId, version, link);
|
||||
} catch (FileNotFoundException fnfe) {
|
||||
// This is what we get when the SHA1 they sent doesn't exist in Nexus. This
|
||||
// is useful upstream for recovery, so we just re-throw it
|
||||
/* This is what we get when the SHA1 they sent doesn't exist in
|
||||
* Nexus. This is useful upstream for recovery, so we just re-throw it
|
||||
*/
|
||||
throw fnfe;
|
||||
} catch (Exception e) {
|
||||
// Anything else is jacked-up XML stuff that we really can't recover from well
|
||||
} catch (Throwable e) {
|
||||
// Anything else is jacked-up XML stuff that we really can't recover
|
||||
// from well
|
||||
throw new IOException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Do a preflight request to see if the repository is actually working.
|
||||
*
|
||||
* @return whether the repository is listening and returns the /status URL correctly
|
||||
*/
|
||||
public boolean preflightRequest() {
|
||||
try {
|
||||
final HttpURLConnection conn = URLConnectionFactory.createHttpURLConnection(new URL(rootURL, "status"), useProxy);
|
||||
conn.addRequestProperty("Accept", "application/xml");
|
||||
conn.connect();
|
||||
if (conn.getResponseCode() != 200) {
|
||||
LOGGER.log(Level.WARNING, "Expected 200 result from Nexus, got {0}", conn.getResponseCode());
|
||||
return false;
|
||||
}
|
||||
final DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
|
||||
final Document doc = builder.parse(conn.getInputStream());
|
||||
if (!"status".equals(doc.getDocumentElement().getNodeName())) {
|
||||
LOGGER.log(Level.WARNING, "Expected root node name of status, got {0}", doc.getDocumentElement().getNodeName());
|
||||
return false;
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// vim: cc=120:sw=4:ts=4:sts=4
|
||||
|
||||
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* This file is part of dependency-check-core.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Copyright (c) 2014 Jeremy Long. All Rights Reserved.
|
||||
*/
|
||||
package org.owasp.dependencycheck.data.nuget;
|
||||
|
||||
/**
|
||||
* Represents the contents of a Nuspec manifest.
|
||||
*
|
||||
* @author colezlaw
|
||||
*/
|
||||
public class NugetPackage {
|
||||
/**
|
||||
* The id.
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* The version.
|
||||
*/
|
||||
private String version;
|
||||
|
||||
/**
|
||||
* The title.
|
||||
*/
|
||||
private String title;
|
||||
|
||||
/**
|
||||
* The authors.
|
||||
*/
|
||||
private String authors;
|
||||
|
||||
/**
|
||||
* The owners.
|
||||
*/
|
||||
private String owners;
|
||||
|
||||
/**
|
||||
* The licenseUrl.
|
||||
*/
|
||||
private String licenseUrl;
|
||||
|
||||
/**
|
||||
* Creates an empty NugetPackage.
|
||||
*/
|
||||
public NugetPackage() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the id.
|
||||
* @param id the id
|
||||
*/
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the id.
|
||||
* @return the id
|
||||
*/
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the version.
|
||||
* @param version the version
|
||||
*/
|
||||
public void setVersion(String version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the version.
|
||||
* @return the version
|
||||
*/
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the title.
|
||||
* @param title the title
|
||||
*/
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the title.
|
||||
* @return the title
|
||||
*/
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the authors.
|
||||
* @param authors the authors
|
||||
*/
|
||||
public void setAuthors(String authors) {
|
||||
this.authors = authors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the authors.
|
||||
* @return the authors
|
||||
*/
|
||||
public String getAuthors() {
|
||||
return authors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the owners.
|
||||
* @param owners the owners
|
||||
*/
|
||||
public void setOwners(String owners) {
|
||||
this.owners = owners;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the owners.
|
||||
* @return the owners
|
||||
*/
|
||||
public String getOwners() {
|
||||
return owners;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the licenseUrl.
|
||||
* @param licenseUrl the licenseUrl
|
||||
*/
|
||||
public void setLicenseUrl(String licenseUrl) {
|
||||
this.licenseUrl = licenseUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the licenseUrl.
|
||||
* @return the licenseUrl
|
||||
*/
|
||||
public String getLicenseUrl() {
|
||||
return licenseUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
if (other == null || other.getClass() != this.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final NugetPackage o = (NugetPackage) other;
|
||||
return o.getId().equals(id)
|
||||
&& o.getVersion().equals(version)
|
||||
&& o.getTitle().equals(title)
|
||||
&& o.getAuthors().equals(authors)
|
||||
&& o.getOwners().equals(owners)
|
||||
&& o.getLicenseUrl().equals(licenseUrl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 7;
|
||||
hash = 31 * hash + (null == id ? 0 : id.hashCode());
|
||||
hash = 31 * hash + (null == version ? 0 : version.hashCode());
|
||||
hash = 31 * hash + (null == title ? 0 : title.hashCode());
|
||||
hash = 31 * hash + (null == authors ? 0 : authors.hashCode());
|
||||
hash = 31 * hash + (null == owners ? 0 : owners.hashCode());
|
||||
hash = 31 * hash + (null == licenseUrl ? 0 : licenseUrl.hashCode());
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* This file is part of dependency-check-core.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Copyright (c) 2014 Jeremy Long. All Rights Reserved.
|
||||
*/
|
||||
package org.owasp.dependencycheck.data.nuget;
|
||||
|
||||
/**
|
||||
* Exception during the parsing of a Nuspec file.
|
||||
*
|
||||
* @author colezlaw
|
||||
*/
|
||||
public class NuspecParseException extends Exception {
|
||||
|
||||
/**
|
||||
* The serialVersionUID
|
||||
*/
|
||||
private static final long serialVersionUID = 1;
|
||||
|
||||
/**
|
||||
* Constructs a new exception with <code>null</code> as its detail message.
|
||||
*
|
||||
* The cause is not initialized, and may subsequently be initialized by a call to
|
||||
* {@link java.lang.Throwable#initCause(java.lang.Throwable)}.
|
||||
*/
|
||||
public NuspecParseException() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new exception with the specified detail message. The cause is not initialized, and may subsequently
|
||||
* be initialized by a call to {@link java.lang.Throwable#initCause(java.lang.Throwable)}.
|
||||
*
|
||||
* @param message the detail message. The detail message is saved for later retrieval by the
|
||||
* {@link java.lang.Throwable#getMessage()} method.
|
||||
*/
|
||||
public NuspecParseException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new exception with the specified detail message and cause.
|
||||
*
|
||||
* Note that the detail message associated with <code>cause</code> is <em>not</em>
|
||||
* automatically incorporated in this exception's detail message.
|
||||
*
|
||||
* @param message the detail message (whcih is saved for later retrieval by the
|
||||
* {@link java.lang.Throwable#getMessage()} method.
|
||||
* @param cause the cause (which is saved for later retrieval by the {@link java.lang.Throwable#getCause()} method).
|
||||
* (A <code>null</code> value is permitted, and indicates that the cause is nonexistent or unknown).
|
||||
*/
|
||||
public NuspecParseException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* This file is part of dependency-check-core.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Copyright (c) 2014 Jeremy Long. All Rights Reserved.
|
||||
*/
|
||||
package org.owasp.dependencycheck.data.nuget;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* Interface defining methods for parsing a Nuspec file.
|
||||
*
|
||||
* @author colezlaw
|
||||
*
|
||||
*/
|
||||
public interface NuspecParser {
|
||||
/**
|
||||
* Parse an input stream and return the resulting {@link NugetPackage}.
|
||||
*
|
||||
* @param stream the input stream to parse
|
||||
* @return the populated bean
|
||||
* @throws NuspecParseException when an exception occurs
|
||||
*/
|
||||
NugetPackage parse(InputStream stream) throws NuspecParseException;
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* This file is part of dependency-check-core.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Copyright (c) 2014 Jeremy Long. All Rights Reserved.
|
||||
*/
|
||||
package org.owasp.dependencycheck.data.nuget;
|
||||
|
||||
import java.io.InputStream;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.xpath.XPath;
|
||||
import javax.xml.xpath.XPathConstants;
|
||||
import javax.xml.xpath.XPathFactory;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
/**
|
||||
* Parse a Nuspec file using XPath.
|
||||
*
|
||||
* @author colezlaw
|
||||
*/
|
||||
public class XPathNuspecParser implements NuspecParser {
|
||||
|
||||
/**
|
||||
* Gets the string value of a node or null if it's not present
|
||||
*
|
||||
* @param n the node to test
|
||||
* @return the string content of the node, or null if the node itself is null
|
||||
*/
|
||||
private String getOrNull(Node n) {
|
||||
if (n != null) {
|
||||
return n.getTextContent();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an input stream and return the resulting {@link NugetPackage}.
|
||||
*
|
||||
* @param stream the input stream to parse
|
||||
* @return the populated bean
|
||||
* @throws NuspecParseException when an exception occurs
|
||||
*/
|
||||
@Override
|
||||
public NugetPackage parse(InputStream stream) throws NuspecParseException {
|
||||
try {
|
||||
final Document d = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(stream);
|
||||
final XPath xpath = XPathFactory.newInstance().newXPath();
|
||||
final NugetPackage nuspec = new NugetPackage();
|
||||
|
||||
if (xpath.evaluate("/package/metadata/id", d, XPathConstants.NODE) == null
|
||||
|| xpath.evaluate("/package/metadata/version", d, XPathConstants.NODE) == null
|
||||
|| xpath.evaluate("/package/metadata/authors", d, XPathConstants.NODE) == null
|
||||
|| xpath.evaluate("/package/metadata/description", d, XPathConstants.NODE) == null) {
|
||||
throw new NuspecParseException("Invalid Nuspec format");
|
||||
}
|
||||
|
||||
nuspec.setId(xpath.evaluate("/package/metadata/id", d));
|
||||
nuspec.setVersion(xpath.evaluate("/package/metadata/version", d));
|
||||
nuspec.setAuthors(xpath.evaluate("/package/metadata/authors", d));
|
||||
nuspec.setOwners(getOrNull((Node) xpath.evaluate("/package/metadata/owners", d, XPathConstants.NODE)));
|
||||
nuspec.setLicenseUrl(getOrNull((Node) xpath.evaluate("/package/metadata/licenseUrl", d, XPathConstants.NODE)));
|
||||
nuspec.setTitle(getOrNull((Node) xpath.evaluate("/package/metadata/title", d, XPathConstants.NODE)));
|
||||
return nuspec;
|
||||
} catch (Throwable e) {
|
||||
throw new NuspecParseException("Unable to parse nuspec", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* <html>
|
||||
* <head>
|
||||
* <title>org.owasp.dependencycheck.data.nuget</title>
|
||||
* </head>
|
||||
* <body>
|
||||
* <p>
|
||||
* Contains classes related to parsing Nuget related files</p>
|
||||
* <p>
|
||||
* These are used to abstract away Nuget-related handling from Dependency Check
|
||||
* so they can be used elsewhere.</p>
|
||||
* </body>
|
||||
* </html>
|
||||
*/
|
||||
package org.owasp.dependencycheck.data.nuget;
|
||||
@@ -24,6 +24,7 @@ import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.Connection;
|
||||
import java.sql.Driver;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
@@ -50,6 +51,22 @@ public final class ConnectionFactory {
|
||||
* Resource location for SQL file used to create the database schema.
|
||||
*/
|
||||
public static final String DB_STRUCTURE_RESOURCE = "data/initialize.sql";
|
||||
/**
|
||||
* The database driver used to connect to the database.
|
||||
*/
|
||||
private static Driver driver = null;
|
||||
/**
|
||||
* The database connection string.
|
||||
*/
|
||||
private static String connectionString = null;
|
||||
/**
|
||||
* The username to connect to the database.
|
||||
*/
|
||||
private static String userName = null;
|
||||
/**
|
||||
* The password for the database.
|
||||
*/
|
||||
private static String password = null;
|
||||
|
||||
/**
|
||||
* Private constructor for this factory class; no instance is ever needed.
|
||||
@@ -58,64 +75,135 @@ public final class ConnectionFactory {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new database connection object per the database configuration. This will load the appropriate
|
||||
* database driver, via the DriverManager, if configured.
|
||||
* Initializes the connection factory. Ensuring that the appropriate drivers are loaded and that a connection can be
|
||||
* made successfully.
|
||||
*
|
||||
* @return a database connection object
|
||||
* @throws DatabaseException thrown if there is an exception loading the database connection
|
||||
* @throws DatabaseException thrown if we are unable to connect to the database
|
||||
*/
|
||||
public static Connection getConnection() throws DatabaseException {
|
||||
public static synchronized void initialize() throws DatabaseException {
|
||||
//this only needs to be called once.
|
||||
if (connectionString != null) {
|
||||
return;
|
||||
}
|
||||
Connection conn = null;
|
||||
try {
|
||||
Logger.getLogger(CveDB.class.getName()).log(Level.FINE, "Loading database connection");
|
||||
|
||||
final String connStr = getConnectionString();
|
||||
final String user = Settings.getString(Settings.KEYS.DB_USER, "dcuser");
|
||||
//yes, yes - hard-coded password - only if there isn't one in the properties file.
|
||||
final String pass = Settings.getString(Settings.KEYS.DB_PASSWORD, "DC-Pass1337!");
|
||||
Logger.getLogger(CveDB.class.getName()).log(Level.FINE, "Connection String: {0}", connStr);
|
||||
Logger.getLogger(CveDB.class.getName()).log(Level.FINE, "Database User: {0}", user);
|
||||
boolean createTables = false;
|
||||
if (connStr.startsWith("jdbc:h2:file:")) { //H2
|
||||
createTables = needToCreateDatabaseStructure();
|
||||
Logger.getLogger(CveDB.class.getName()).log(Level.FINE, "Need to create DB Structure: {0}", createTables);
|
||||
}
|
||||
//load the driver if necessary
|
||||
final String driverName = Settings.getString(Settings.KEYS.DB_DRIVER_NAME, "");
|
||||
if (!driverName.isEmpty()) { //likely need to load the correct driver
|
||||
Logger.getLogger(CveDB.class.getName()).log(Level.FINE, "Loading driver: {0}", driverName);
|
||||
final String driverPath = Settings.getString(Settings.KEYS.DB_DRIVER_PATH, "");
|
||||
if (!driverPath.isEmpty()) { //ugh, driver is not on classpath?
|
||||
Logger.getLogger(CveDB.class.getName()).log(Level.FINE, "Loading driver from: {0}", driverPath);
|
||||
DriverLoader.load(driverName, driverPath);
|
||||
try {
|
||||
if (!driverPath.isEmpty()) {
|
||||
Logger.getLogger(CveDB.class.getName()).log(Level.FINE, "Loading driver from: {0}", driverPath);
|
||||
driver = DriverLoader.load(driverName, driverPath);
|
||||
} else {
|
||||
driver = DriverLoader.load(driverName);
|
||||
}
|
||||
} catch (DriverLoadException ex) {
|
||||
Logger.getLogger(ConnectionFactory.class.getName()).log(Level.FINE, "Unable to load database driver", ex);
|
||||
throw new DatabaseException("Unable to load database driver");
|
||||
}
|
||||
}
|
||||
userName = Settings.getString(Settings.KEYS.DB_USER, "dcuser");
|
||||
//yes, yes - hard-coded password - only if there isn't one in the properties file.
|
||||
password = Settings.getString(Settings.KEYS.DB_PASSWORD, "DC-Pass1337!");
|
||||
try {
|
||||
connectionString = getConnectionString();
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(ConnectionFactory.class.getName()).log(Level.FINE,
|
||||
"Unable to retrieve the database connection string", ex);
|
||||
throw new DatabaseException("Unable to retrieve the database connection string");
|
||||
}
|
||||
boolean shouldCreateSchema = false;
|
||||
try {
|
||||
if (connectionString.startsWith("jdbc:h2:file:")) { //H2
|
||||
shouldCreateSchema = !dbSchemaExists();
|
||||
Logger.getLogger(CveDB.class.getName()).log(Level.FINE, "Need to create DB Structure: {0}", shouldCreateSchema);
|
||||
}
|
||||
} catch (IOException ioex) {
|
||||
Logger.getLogger(ConnectionFactory.class.getName()).log(Level.FINE, "Unable to verify database exists", ioex);
|
||||
throw new DatabaseException("Unable to verify database exists");
|
||||
}
|
||||
Logger.getLogger(CveDB.class.getName()).log(Level.FINE, "Loading database connection");
|
||||
Logger.getLogger(CveDB.class.getName()).log(Level.FINE, "Connection String: {0}", connectionString);
|
||||
Logger.getLogger(CveDB.class.getName()).log(Level.FINE, "Database User: {0}", userName);
|
||||
|
||||
try {
|
||||
conn = DriverManager.getConnection(connectionString, userName, password);
|
||||
} catch (SQLException ex) {
|
||||
if (ex.getMessage().contains("java.net.UnknownHostException") && connectionString.contains("AUTO_SERVER=TRUE;")) {
|
||||
connectionString = connectionString.replace("AUTO_SERVER=TRUE;", "");
|
||||
try {
|
||||
conn = DriverManager.getConnection(connectionString, userName, password);
|
||||
Settings.setString(Settings.KEYS.DB_CONNECTION_STRING, connectionString);
|
||||
Logger.getLogger(ConnectionFactory.class.getName()).log(Level.FINE,
|
||||
"Unable to start the database in server mode; reverting to single user mode");
|
||||
} catch (SQLException sqlex) {
|
||||
Logger.getLogger(ConnectionFactory.class.getName()).log(Level.FINE, "Unable to connect to the database", ex);
|
||||
throw new DatabaseException("Unable to connect to the database");
|
||||
}
|
||||
} else {
|
||||
DriverLoader.load(driverName);
|
||||
Logger.getLogger(ConnectionFactory.class.getName()).log(Level.FINE, "Unable to connect to the database", ex);
|
||||
throw new DatabaseException("Unable to connect to the database");
|
||||
}
|
||||
}
|
||||
|
||||
//JDBC4 drivers don't need this call.
|
||||
//Class.forName("org.h2.Driver");
|
||||
conn = DriverManager.getConnection(connStr, user, pass);
|
||||
if (createTables) {
|
||||
if (shouldCreateSchema) {
|
||||
try {
|
||||
createTables(conn);
|
||||
} catch (DatabaseException ex) {
|
||||
Logger.getLogger(ConnectionFactory.class.getName()).log(Level.FINE, null, ex);
|
||||
} catch (DatabaseException dex) {
|
||||
Logger.getLogger(ConnectionFactory.class.getName()).log(Level.FINE, null, dex);
|
||||
throw new DatabaseException("Unable to create the database structure");
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
ensureSchemaVersion(conn);
|
||||
} catch (DatabaseException ex) {
|
||||
Logger.getLogger(ConnectionFactory.class.getName()).log(Level.FINE, null, ex);
|
||||
} catch (DatabaseException dex) {
|
||||
Logger.getLogger(ConnectionFactory.class.getName()).log(Level.FINE, null, dex);
|
||||
throw new DatabaseException("Database schema does not match this version of dependency-check");
|
||||
}
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(ConnectionFactory.class.getName()).log(Level.FINE, null, ex);
|
||||
throw new DatabaseException("Unable to load database");
|
||||
} catch (DriverLoadException ex) {
|
||||
Logger.getLogger(ConnectionFactory.class.getName()).log(Level.FINE, null, ex);
|
||||
throw new DatabaseException("Unable to load database driver");
|
||||
} finally {
|
||||
if (conn != null) {
|
||||
try {
|
||||
conn.close();
|
||||
} catch (SQLException ex) {
|
||||
Logger.getLogger(ConnectionFactory.class.getName()).log(Level.FINE, "An error occured closing the connection", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans up resources and unloads any registered database drivers. This needs to be called to ensure the driver is
|
||||
* unregistered prior to the finalize method being called as during shutdown the class loader used to load the
|
||||
* driver may be unloaded prior to the driver being de-registered.
|
||||
*/
|
||||
public static synchronized void cleanup() {
|
||||
if (driver != null) {
|
||||
try {
|
||||
DriverManager.deregisterDriver(driver);
|
||||
} catch (SQLException ex) {
|
||||
Logger.getLogger(ConnectionFactory.class.getName()).log(Level.FINE, "An error occured unloading the databse driver", ex);
|
||||
}
|
||||
driver = null;
|
||||
}
|
||||
connectionString = null;
|
||||
userName = null;
|
||||
password = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new database connection object per the database configuration.
|
||||
*
|
||||
* @return a database connection object
|
||||
* @throws DatabaseException thrown if there is an exception loading the database connection
|
||||
*/
|
||||
public static Connection getConnection() throws DatabaseException {
|
||||
initialize();
|
||||
Connection conn = null;
|
||||
try {
|
||||
conn = DriverManager.getConnection(connectionString, userName, password);
|
||||
} catch (SQLException ex) {
|
||||
Logger.getLogger(ConnectionFactory.class.getName()).log(Level.FINE, null, ex);
|
||||
throw new DatabaseException("Unable to connect to the database");
|
||||
@@ -164,11 +252,11 @@ public final class ConnectionFactory {
|
||||
* @return true if the H2 database file does not exist; otherwise false
|
||||
* @throws IOException thrown if the data directory does not exist and cannot be created
|
||||
*/
|
||||
private static boolean needToCreateDatabaseStructure() throws IOException {
|
||||
private static boolean dbSchemaExists() throws IOException {
|
||||
final File dir = getDataDirectory();
|
||||
final String name = String.format("cve.%s.h2.db", DB_SCHEMA_VERSION);
|
||||
final File file = new File(dir, name);
|
||||
return !file.exists();
|
||||
return file.exists();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -38,6 +38,7 @@ import org.owasp.dependencycheck.dependency.VulnerableSoftware;
|
||||
import org.owasp.dependencycheck.utils.DBUtils;
|
||||
import org.owasp.dependencycheck.utils.DependencyVersion;
|
||||
import org.owasp.dependencycheck.utils.DependencyVersionUtil;
|
||||
import org.owasp.dependencycheck.utils.Pair;
|
||||
|
||||
/**
|
||||
* The database holding information about the NVD CVE data.
|
||||
@@ -96,6 +97,10 @@ public class CveDB {
|
||||
final String msg = "There was an error attempting to close the CveDB, see the log for more details.";
|
||||
Logger.getLogger(DBUtils.class.getName()).log(Level.SEVERE, msg);
|
||||
Logger.getLogger(DBUtils.class.getName()).log(Level.FINE, null, ex);
|
||||
} catch (Throwable ex) {
|
||||
final String msg = "There was an exception attempting to close the CveDB, see the log for more details.";
|
||||
Logger.getLogger(DBUtils.class.getName()).log(Level.SEVERE, msg);
|
||||
Logger.getLogger(DBUtils.class.getName()).log(Level.FINE, null, ex);
|
||||
}
|
||||
conn = null;
|
||||
}
|
||||
@@ -128,7 +133,9 @@ public class CveDB {
|
||||
* @throws Throwable thrown if there is a problem
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("FinalizeDeclaration")
|
||||
protected void finalize() throws Throwable {
|
||||
Logger.getLogger(DBUtils.class.getName()).log(Level.FINE, "Entering finalize");
|
||||
close();
|
||||
super.finalize();
|
||||
}
|
||||
@@ -289,19 +296,27 @@ public class CveDB {
|
||||
/**
|
||||
* Returns the entire list of vendor/product combinations.
|
||||
*
|
||||
* @return the entire list of vendor/product combinations.
|
||||
* @return the entire list of vendor/product combinations
|
||||
* @throws DatabaseException thrown when there is an error retrieving the data from the DB
|
||||
*/
|
||||
public ResultSet getVendorProductList() {
|
||||
public Set<Pair<String, String>> getVendorProductList() throws DatabaseException {
|
||||
final HashSet data = new HashSet<Pair<String, String>>();
|
||||
ResultSet rs = null;
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
final PreparedStatement ps = getConnection().prepareStatement(SELECT_VENDOR_PRODUCT_LIST);
|
||||
ps = getConnection().prepareStatement(SELECT_VENDOR_PRODUCT_LIST);
|
||||
rs = ps.executeQuery();
|
||||
while (rs.next()) {
|
||||
data.add(new Pair(rs.getString(1), rs.getString(2)));
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
final String msg = "An unexpected SQL Exception occurred; please see the verbose log for more details.";
|
||||
Logger.getLogger(CveDB.class.getName()).log(Level.SEVERE, msg);
|
||||
Logger.getLogger(CveDB.class.getName()).log(Level.FINE, null, ex);
|
||||
} // can't close the statement in the PS as the resultset is returned, closing PS would close the resultset
|
||||
return rs;
|
||||
throw new DatabaseException(msg, ex);
|
||||
} finally {
|
||||
DBUtils.closeResultSet(rs);
|
||||
DBUtils.closeStatement(ps);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -47,11 +47,12 @@ public final class DriverLoader {
|
||||
* Loads the specified class using the system class loader and registers the driver with the driver manager.
|
||||
*
|
||||
* @param className the fully qualified name of the desired class
|
||||
* @return the loaded Driver
|
||||
* @throws DriverLoadException thrown if the driver cannot be loaded
|
||||
*/
|
||||
public static void load(String className) throws DriverLoadException {
|
||||
public static Driver load(String className) throws DriverLoadException {
|
||||
final ClassLoader loader = DriverLoader.class.getClassLoader(); //ClassLoader.getSystemClassLoader();
|
||||
load(className, loader);
|
||||
return load(className, loader);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -64,9 +65,10 @@ public final class DriverLoader {
|
||||
* @param className the fully qualified name of the desired class
|
||||
* @param pathToDriver the path to the JAR file containing the driver; note, this can be a semi-colon separated list
|
||||
* of paths
|
||||
* @return the loaded Driver
|
||||
* @throws DriverLoadException thrown if the driver cannot be loaded
|
||||
*/
|
||||
public static void load(String className, String pathToDriver) throws DriverLoadException {
|
||||
public static Driver load(String className, String pathToDriver) throws DriverLoadException {
|
||||
final URLClassLoader parent = (URLClassLoader) ClassLoader.getSystemClassLoader();
|
||||
final ArrayList<URL> urls = new ArrayList<URL>();
|
||||
final String[] paths = pathToDriver.split(File.pathSeparator);
|
||||
@@ -103,7 +105,7 @@ public final class DriverLoader {
|
||||
}
|
||||
});
|
||||
|
||||
load(className, loader);
|
||||
return load(className, loader);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -111,15 +113,18 @@ public final class DriverLoader {
|
||||
*
|
||||
* @param className the fully qualified name of the desired class
|
||||
* @param loader the class loader to use when loading the driver
|
||||
* @return the loaded Driver
|
||||
* @throws DriverLoadException thrown if the driver cannot be loaded
|
||||
*/
|
||||
private static void load(String className, ClassLoader loader) throws DriverLoadException {
|
||||
private static Driver load(String className, ClassLoader loader) throws DriverLoadException {
|
||||
try {
|
||||
final Class c = Class.forName(className, true, loader);
|
||||
//final Class c = loader.loadClass(className);
|
||||
final Driver driver = (Driver) c.newInstance();
|
||||
final Driver shim = new DriverShim(driver);
|
||||
//using the DriverShim to get around the fact that the DriverManager won't register a driver not in the base class path
|
||||
DriverManager.registerDriver(new DriverShim(driver));
|
||||
DriverManager.registerDriver(shim);
|
||||
return shim;
|
||||
} catch (ClassNotFoundException ex) {
|
||||
final String msg = String.format("Unable to load database driver '%s'", className);
|
||||
Logger.getLogger(DriverLoader.class.getName()).log(Level.FINE, msg, ex);
|
||||
|
||||
@@ -17,12 +17,15 @@
|
||||
*/
|
||||
package org.owasp.dependencycheck.data.nvdcve;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.sql.Connection;
|
||||
import java.sql.Driver;
|
||||
import java.sql.DriverPropertyInfo;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.SQLFeatureNotSupportedException;
|
||||
import java.util.Properties;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
@@ -64,6 +67,20 @@ class DriverShim implements Driver {
|
||||
return this.driver.acceptsURL(url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the call to the underlying driver's connect method.
|
||||
*
|
||||
* @param url the URL of the database
|
||||
* @param info a collection of string/value pairs
|
||||
* @return a Connection object
|
||||
* @throws SQLException thrown if there is an error connecting to the database
|
||||
* @see java.sql.Driver#connect(java.lang.String, java.util.Properties)
|
||||
*/
|
||||
@Override
|
||||
public Connection connect(String url, Properties info) throws SQLException {
|
||||
return this.driver.connect(url, info);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the wrapped driver's major version number.
|
||||
*
|
||||
@@ -87,28 +104,33 @@ class DriverShim implements Driver {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not the wrapped driver is jdbcCompliant.
|
||||
* Wraps the call to the underlying driver's getParentLogger method.
|
||||
*
|
||||
* @return true if the wrapped driver is JDBC compliant; otherwise false
|
||||
* @see java.sql.Driver#jdbcCompliant()
|
||||
* @return the parent's Logger
|
||||
* @throws SQLFeatureNotSupportedException thrown if the feature is not supported
|
||||
* @see java.sql.Driver#getParentLogger()
|
||||
*/
|
||||
@Override
|
||||
public boolean jdbcCompliant() {
|
||||
return this.driver.jdbcCompliant();
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the call to the underlying driver's connect method.
|
||||
*
|
||||
* @param url the URL of the database
|
||||
* @param info a collection of string/value pairs
|
||||
* @return a Connection object
|
||||
* @throws SQLException thrown if there is an error connecting to the database
|
||||
* @see java.sql.Driver#connect(java.lang.String, java.util.Properties)
|
||||
*/
|
||||
@Override
|
||||
public Connection connect(String url, Properties info) throws SQLException {
|
||||
return this.driver.connect(url, info);
|
||||
//@Override
|
||||
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
|
||||
//return driver.getParentLogger();
|
||||
Method m = null;
|
||||
try {
|
||||
m = driver.getClass().getMethod("getParentLogger");
|
||||
} catch (Throwable e) {
|
||||
throw new SQLFeatureNotSupportedException();
|
||||
}
|
||||
if (m != null) {
|
||||
try {
|
||||
return (Logger) m.invoke(m);
|
||||
} catch (IllegalAccessException ex) {
|
||||
Logger.getLogger(DriverShim.class.getName()).log(Level.FINER, null, ex);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
Logger.getLogger(DriverShim.class.getName()).log(Level.FINER, null, ex);
|
||||
} catch (InvocationTargetException ex) {
|
||||
Logger.getLogger(DriverShim.class.getName()).log(Level.FINER, null, ex);
|
||||
}
|
||||
}
|
||||
throw new SQLFeatureNotSupportedException();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -126,15 +148,14 @@ class DriverShim implements Driver {
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the call to the underlying driver's getParentLogger method.
|
||||
* Returns whether or not the wrapped driver is jdbcCompliant.
|
||||
*
|
||||
* @return the parent's Logger
|
||||
* @throws SQLFeatureNotSupportedException thrown if the feature is not supported
|
||||
* @see java.sql.Driver#getParentLogger()
|
||||
* @return true if the wrapped driver is JDBC compliant; otherwise false
|
||||
* @see java.sql.Driver#jdbcCompliant()
|
||||
*/
|
||||
@Override
|
||||
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
|
||||
return this.driver.getParentLogger();
|
||||
public boolean jdbcCompliant() {
|
||||
return this.driver.jdbcCompliant();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -134,20 +134,20 @@ public class StandardUpdate {
|
||||
downloadExecutors.shutdownNow();
|
||||
processExecutor.shutdownNow();
|
||||
|
||||
Logger.getLogger(StandardUpdate.class.getName()).log(Level.FINE, "Thread was interupted during download", ex);
|
||||
throw new UpdateException("The download was interupted", ex);
|
||||
Logger.getLogger(StandardUpdate.class.getName()).log(Level.FINE, "Thread was interrupted during download", ex);
|
||||
throw new UpdateException("The download was interrupted", ex);
|
||||
} catch (ExecutionException ex) {
|
||||
downloadExecutors.shutdownNow();
|
||||
processExecutor.shutdownNow();
|
||||
|
||||
Logger.getLogger(StandardUpdate.class.getName()).log(Level.FINE, "Thread was interupted during download execution", ex);
|
||||
throw new UpdateException("The execution of the download was interupted", ex);
|
||||
Logger.getLogger(StandardUpdate.class.getName()).log(Level.FINE, "Thread was interrupted during download execution", ex);
|
||||
throw new UpdateException("The execution of the download was interrupted", ex);
|
||||
}
|
||||
if (task == null) {
|
||||
downloadExecutors.shutdownNow();
|
||||
processExecutor.shutdownNow();
|
||||
Logger.getLogger(StandardUpdate.class.getName()).log(Level.FINE, "Thread was interupted during download");
|
||||
throw new UpdateException("The download was interupted; unable to complete the update");
|
||||
Logger.getLogger(StandardUpdate.class.getName()).log(Level.FINE, "Thread was interrupted during download");
|
||||
throw new UpdateException("The download was interrupted; unable to complete the update");
|
||||
} else {
|
||||
processFutures.add(task);
|
||||
}
|
||||
@@ -161,7 +161,7 @@ public class StandardUpdate {
|
||||
}
|
||||
} catch (InterruptedException ex) {
|
||||
processExecutor.shutdownNow();
|
||||
Logger.getLogger(StandardUpdate.class.getName()).log(Level.FINE, "Thread was interupted during processing", ex);
|
||||
Logger.getLogger(StandardUpdate.class.getName()).log(Level.FINE, "Thread was interrupted during processing", ex);
|
||||
throw new UpdateException(ex);
|
||||
} catch (ExecutionException ex) {
|
||||
processExecutor.shutdownNow();
|
||||
@@ -245,11 +245,8 @@ public class StandardUpdate {
|
||||
}
|
||||
} catch (NumberFormatException ex) {
|
||||
final String msg = "An invalid schema version or timestamp exists in the data.properties file.";
|
||||
Logger
|
||||
.getLogger(StandardUpdate.class
|
||||
.getName()).log(Level.WARNING, msg);
|
||||
Logger.getLogger(StandardUpdate.class
|
||||
.getName()).log(Level.FINE, null, ex);
|
||||
Logger.getLogger(StandardUpdate.class.getName()).log(Level.WARNING, msg);
|
||||
Logger.getLogger(StandardUpdate.class.getName()).log(Level.FINE, "", ex);
|
||||
}
|
||||
}
|
||||
return updates;
|
||||
@@ -292,7 +289,7 @@ public class StandardUpdate {
|
||||
if (cveDB != null) {
|
||||
try {
|
||||
cveDB.close();
|
||||
} catch (Exception ignore) {
|
||||
} catch (Throwable ignore) {
|
||||
Logger.getLogger(StandardUpdate.class.getName()).log(Level.FINEST, "Error closing the cveDB", ignore);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,8 +20,6 @@ package org.owasp.dependencycheck.dependency;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
@@ -145,6 +143,15 @@ public class Dependency implements Comparable<Dependency> {
|
||||
return this.actualFilePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a reference to the File object.
|
||||
*
|
||||
* @return the File object.
|
||||
*/
|
||||
public File getActualFile() {
|
||||
return new File(this.actualFilePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the file path of the dependency.
|
||||
*
|
||||
@@ -318,37 +325,6 @@ public class Dependency implements Comparable<Dependency> {
|
||||
public EvidenceCollection getVersionEvidence() {
|
||||
return this.versionEvidence;
|
||||
}
|
||||
/**
|
||||
* A list of exceptions that occurred during analysis of this dependency.
|
||||
*/
|
||||
private List<Exception> analysisExceptions = new ArrayList<Exception>();
|
||||
|
||||
/**
|
||||
* Get the value of analysisExceptions.
|
||||
*
|
||||
* @return the value of analysisExceptions
|
||||
*/
|
||||
public List<Exception> getAnalysisExceptions() {
|
||||
return analysisExceptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of analysisExceptions.
|
||||
*
|
||||
* @param analysisExceptions new value of analysisExceptions
|
||||
*/
|
||||
public void setAnalysisExceptions(List<Exception> analysisExceptions) {
|
||||
this.analysisExceptions = analysisExceptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an exception to the analysis exceptions collection.
|
||||
*
|
||||
* @param ex an exception.
|
||||
*/
|
||||
public void addAnalysisException(Exception ex) {
|
||||
this.analysisExceptions.add(ex);
|
||||
}
|
||||
/**
|
||||
* The description of the JAR file.
|
||||
*/
|
||||
@@ -535,10 +511,6 @@ public class Dependency implements Comparable<Dependency> {
|
||||
if (this.versionEvidence != other.versionEvidence && (this.versionEvidence == null || !this.versionEvidence.equals(other.versionEvidence))) {
|
||||
return false;
|
||||
}
|
||||
if (this.analysisExceptions != other.analysisExceptions
|
||||
&& (this.analysisExceptions == null || !this.analysisExceptions.equals(other.analysisExceptions))) {
|
||||
return false;
|
||||
}
|
||||
if ((this.description == null) ? (other.description != null) : !this.description.equals(other.description)) {
|
||||
return false;
|
||||
}
|
||||
@@ -573,7 +545,6 @@ public class Dependency implements Comparable<Dependency> {
|
||||
hash = 47 * hash + (this.vendorEvidence != null ? this.vendorEvidence.hashCode() : 0);
|
||||
hash = 47 * hash + (this.productEvidence != null ? this.productEvidence.hashCode() : 0);
|
||||
hash = 47 * hash + (this.versionEvidence != null ? this.versionEvidence.hashCode() : 0);
|
||||
hash = 47 * hash + (this.analysisExceptions != null ? this.analysisExceptions.hashCode() : 0);
|
||||
hash = 47 * hash + (this.description != null ? this.description.hashCode() : 0);
|
||||
hash = 47 * hash + (this.license != null ? this.license.hashCode() : 0);
|
||||
hash = 47 * hash + (this.vulnerabilities != null ? this.vulnerabilities.hashCode() : 0);
|
||||
|
||||
@@ -360,7 +360,7 @@ public class EvidenceCollection implements Iterable<Evidence> {
|
||||
final List<String> data = UrlStringUtils.extractImportantUrlData(part);
|
||||
sb.append(' ').append(StringUtils.join(data, ' '));
|
||||
} catch (MalformedURLException ex) {
|
||||
Logger.getLogger(EvidenceCollection.class.getName()).log(Level.INFO, "error parsing " + part, ex);
|
||||
Logger.getLogger(EvidenceCollection.class.getName()).log(Level.FINE, "error parsing " + part, ex);
|
||||
sb.append(' ').append(part);
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -184,13 +184,21 @@ public class VulnerableSoftware extends IndexEntry implements Serializable, Comp
|
||||
if (subMax > 0) {
|
||||
for (int x = 0; result == 0 && x < subMax; x++) {
|
||||
if (isPositiveInteger(subLeft[x]) && isPositiveInteger(subRight[x])) {
|
||||
final int iLeft = Integer.parseInt(subLeft[x]);
|
||||
final int iRight = Integer.parseInt(subRight[x]);
|
||||
if (iLeft != iRight) {
|
||||
if (iLeft > iRight) {
|
||||
result = 2;
|
||||
} else {
|
||||
result = -2;
|
||||
try {
|
||||
result = Long.valueOf(subLeft[x]).compareTo(Long.valueOf(subRight[x]));
|
||||
// final long iLeft = Long.parseLong(subLeft[x]);
|
||||
// final long iRight = Long.parseLong(subRight[x]);
|
||||
// if (iLeft != iRight) {
|
||||
// if (iLeft > iRight) {
|
||||
// result = 2;
|
||||
// } else {
|
||||
// result = -2;
|
||||
// }
|
||||
// }
|
||||
} catch (NumberFormatException ex) {
|
||||
//ignore the exception - they obviously aren't numbers
|
||||
if (!subLeft[x].equalsIgnoreCase(subRight[x])) {
|
||||
result = subLeft[x].compareToIgnoreCase(subRight[x]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -22,12 +22,7 @@ import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.Authenticator;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.PasswordAuthentication;
|
||||
import java.net.Proxy;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.util.logging.Level;
|
||||
@@ -58,7 +53,7 @@ public final class Downloader {
|
||||
public static void fetchFile(URL url, File outputPath) throws DownloadFailedException {
|
||||
HttpURLConnection conn = null;
|
||||
try {
|
||||
conn = Downloader.getConnection(url);
|
||||
conn = URLConnectionFactory.createHttpURLConnection(url);
|
||||
conn.setRequestProperty("Accept-Encoding", "gzip, deflate");
|
||||
conn.connect();
|
||||
} catch (IOException ex) {
|
||||
@@ -90,13 +85,13 @@ public final class Downloader {
|
||||
while ((bytesRead = reader.read(buffer)) > 0) {
|
||||
writer.write(buffer, 0, bytesRead);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
} catch (Throwable ex) {
|
||||
throw new DownloadFailedException("Error saving downloaded file.", ex);
|
||||
} finally {
|
||||
if (writer != null) {
|
||||
try {
|
||||
writer.close();
|
||||
} catch (Exception ex) {
|
||||
} catch (Throwable ex) {
|
||||
Logger.getLogger(Downloader.class.getName()).log(Level.FINEST,
|
||||
"Error closing the writer in Downloader.", ex);
|
||||
}
|
||||
@@ -104,7 +99,7 @@ public final class Downloader {
|
||||
if (reader != null) {
|
||||
try {
|
||||
reader.close();
|
||||
} catch (Exception ex) {
|
||||
} catch (Throwable ex) {
|
||||
Logger.getLogger(Downloader.class.getName()).log(Level.FINEST,
|
||||
"Error closing the reader in Downloader.", ex);
|
||||
}
|
||||
@@ -149,11 +144,13 @@ public final class Downloader {
|
||||
} else {
|
||||
HttpURLConnection conn = null;
|
||||
try {
|
||||
conn = Downloader.getConnection(url);
|
||||
conn = URLConnectionFactory.createHttpURLConnection(url);
|
||||
conn.setRequestMethod("HEAD");
|
||||
conn.connect();
|
||||
timestamp = conn.getLastModified();
|
||||
} catch (Exception ex) {
|
||||
} catch (URLConnectionFailureException ex) {
|
||||
throw new DownloadFailedException("Error creating URL Connection for HTTP HEAD request.", ex);
|
||||
} catch (IOException ex) {
|
||||
throw new DownloadFailedException("Error making HTTP HEAD request.", ex);
|
||||
} finally {
|
||||
if (conn != null) {
|
||||
@@ -167,56 +164,4 @@ public final class Downloader {
|
||||
}
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to get an HttpURLConnection. If the app is configured to use a proxy this method will retrieve the
|
||||
* proxy settings and use them when setting up the connection.
|
||||
*
|
||||
* @param url the url to connect to
|
||||
* @return an HttpURLConnection
|
||||
* @throws DownloadFailedException thrown if there is an exception
|
||||
*/
|
||||
private static HttpURLConnection getConnection(URL url) throws DownloadFailedException {
|
||||
HttpURLConnection conn = null;
|
||||
Proxy proxy = null;
|
||||
final String proxyUrl = Settings.getString(Settings.KEYS.PROXY_URL);
|
||||
try {
|
||||
if (proxyUrl != null) {
|
||||
final int proxyPort = Settings.getInt(Settings.KEYS.PROXY_PORT);
|
||||
final SocketAddress addr = new InetSocketAddress(proxyUrl, proxyPort);
|
||||
|
||||
final String username = Settings.getString(Settings.KEYS.PROXY_USERNAME);
|
||||
final String password = Settings.getString(Settings.KEYS.PROXY_PASSWORD);
|
||||
if (username != null && password != null) {
|
||||
final Authenticator auth = new Authenticator() {
|
||||
@Override
|
||||
public PasswordAuthentication getPasswordAuthentication() {
|
||||
if (getRequestorType().equals(RequestorType.PROXY)) {
|
||||
return new PasswordAuthentication(username, password.toCharArray());
|
||||
}
|
||||
return super.getPasswordAuthentication();
|
||||
}
|
||||
};
|
||||
Authenticator.setDefault(auth);
|
||||
}
|
||||
|
||||
proxy = new Proxy(Proxy.Type.HTTP, addr);
|
||||
conn = (HttpURLConnection) url.openConnection(proxy);
|
||||
} else {
|
||||
conn = (HttpURLConnection) url.openConnection();
|
||||
}
|
||||
final int timeout = Settings.getInt(Settings.KEYS.CONNECTION_TIMEOUT, 60000);
|
||||
conn.setConnectTimeout(timeout);
|
||||
} catch (IOException ex) {
|
||||
if (conn != null) {
|
||||
try {
|
||||
conn.disconnect();
|
||||
} finally {
|
||||
conn = null;
|
||||
}
|
||||
}
|
||||
throw new DownloadFailedException("Error getting connection.", ex);
|
||||
}
|
||||
return conn;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,23 +69,21 @@ public final class FileUtils {
|
||||
* Deletes a file. If the File is a directory it will recursively delete the contents.
|
||||
*
|
||||
* @param file the File to delete
|
||||
* @throws IOException is thrown if the file could not be deleted
|
||||
* @return true if the file was deleted successfully, otherwise false
|
||||
*/
|
||||
public static void delete(File file) throws IOException {
|
||||
if (file.isDirectory()) {
|
||||
for (File c : file.listFiles()) {
|
||||
delete(c);
|
||||
public static boolean delete(File file) {
|
||||
boolean success = true;
|
||||
if (file.isDirectory()) { //some of this may duplicative of deleteQuietly....
|
||||
for (File f : file.listFiles()) {
|
||||
success &= delete(f);
|
||||
}
|
||||
}
|
||||
if (!org.apache.commons.io.FileUtils.deleteQuietly(file)) {
|
||||
throw new FileNotFoundException("Failed to delete file: " + file);
|
||||
success = false;
|
||||
final String msg = String.format("Failed to delete file: %s", file.getPath());
|
||||
Logger.getLogger(FileUtils.class.getName()).log(Level.FINE, msg);
|
||||
}
|
||||
/* else {
|
||||
//delete on exit was a bad idea. if for some reason the file can't be deleted
|
||||
// this will cause a newly constructed file to be deleted and a subsequent run may fail.
|
||||
// still not sure why a file fails to be deleted, but can be overwritten... odd.
|
||||
file.deleteOnExit();
|
||||
}*/
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -160,7 +158,7 @@ public final class FileUtils {
|
||||
try {
|
||||
fis = new FileInputStream(archive);
|
||||
} catch (FileNotFoundException ex) {
|
||||
Logger.getLogger(FileUtils.class.getName()).log(Level.INFO, null, ex);
|
||||
Logger.getLogger(FileUtils.class.getName()).log(Level.FINE, null, ex);
|
||||
throw new ExtractionException("Archive file was not found.", ex);
|
||||
}
|
||||
zis = new ZipInputStream(new BufferedInputStream(fis));
|
||||
|
||||
@@ -66,7 +66,7 @@ public final class LogUtils {
|
||||
if (in != null) {
|
||||
try {
|
||||
in.close();
|
||||
} catch (Exception ex) {
|
||||
} catch (Throwable ex) {
|
||||
Logger.getLogger(LogUtils.class.getName()).log(Level.FINEST, "Error closing resource stream", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* This file is part of dependency-check-core.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Copyright (c) 2014 Jeremy Long. All Rights Reserved.
|
||||
*/
|
||||
package org.owasp.dependencycheck.utils;
|
||||
|
||||
/**
|
||||
* A generic pair of elements.
|
||||
*
|
||||
* @param <L> the type for the left element in the pair
|
||||
* @param <R> the type for the right element in the pair
|
||||
*
|
||||
* @author Jeremy Long <jeremy.long@owasp.org>
|
||||
*/
|
||||
public class Pair<L, R> {
|
||||
|
||||
/**
|
||||
* Constructs a new empty pair.
|
||||
*/
|
||||
public Pair() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new Pair with the given left and right values.
|
||||
*
|
||||
* @param left the value for the left pair
|
||||
* @param right the value for the right pair
|
||||
*/
|
||||
public Pair(L left, R right) {
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
}
|
||||
/**
|
||||
* The left element of the pair.
|
||||
*/
|
||||
private L left = null;
|
||||
|
||||
/**
|
||||
* Get the value of left.
|
||||
*
|
||||
* @return the value of left
|
||||
*/
|
||||
public L getLeft() {
|
||||
return left;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of left.
|
||||
*
|
||||
* @param left new value of left
|
||||
*/
|
||||
public void setLeft(L left) {
|
||||
this.left = left;
|
||||
}
|
||||
/**
|
||||
* The right element of the pair.
|
||||
*/
|
||||
private R right = null;
|
||||
|
||||
/**
|
||||
* Get the value of right.
|
||||
*
|
||||
* @return the value of right
|
||||
*/
|
||||
public R getRight() {
|
||||
return right;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of right.
|
||||
*
|
||||
* @param right new value of right
|
||||
*/
|
||||
public void setRight(R right) {
|
||||
this.right = right;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the hash code using the hash codes from the contained objects.
|
||||
*
|
||||
* @return the hash code of the Pair
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 3;
|
||||
hash = 53 * hash + (this.left != null ? this.left.hashCode() : 0);
|
||||
hash = 53 * hash + (this.right != null ? this.right.hashCode() : 0);
|
||||
return hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the equality of this and the provided object.
|
||||
*
|
||||
* @param obj the {@link Object} to check for equality to this
|
||||
* @return true if this and the provided {@link Object} are equal; otherwise false
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final Pair<?, ?> other = (Pair<?, ?>) obj;
|
||||
if (this.left != other.left && (this.left == null || !this.left.equals(other.left))) {
|
||||
return false;
|
||||
}
|
||||
if (this.right != other.right && (this.right == null || !this.right.equals(other.right))) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -22,8 +22,11 @@ import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Properties;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
@@ -35,6 +38,11 @@ import java.util.logging.Logger;
|
||||
*/
|
||||
public final class Settings {
|
||||
|
||||
/**
|
||||
* The logger.
|
||||
*/
|
||||
private static final Logger LOGGER = Logger.getLogger(Settings.class.getName());
|
||||
|
||||
/**
|
||||
* The collection of keys used within the properties file.
|
||||
*/
|
||||
@@ -145,6 +153,30 @@ public final class Settings {
|
||||
* The properties key for the Nexus search URL.
|
||||
*/
|
||||
public static final String ANALYZER_NEXUS_URL = "analyzer.nexus.url";
|
||||
/**
|
||||
* The properties key for using the proxy to reach Nexus.
|
||||
*/
|
||||
public static final String ANALYZER_NEXUS_PROXY = "analyzer.nexus.proxy";
|
||||
/**
|
||||
* The path to mono, if available.
|
||||
*/
|
||||
public static final String ANALYZER_ASSEMBLY_MONO_PATH = "analyzer.assembly.mono.path";
|
||||
/**
|
||||
* The additional configured zip file extensions, if available.
|
||||
*/
|
||||
public static final String ADDITIONAL_ZIP_EXTENSIONS = "extensions.zip";
|
||||
/**
|
||||
* The properties key for whether Test Scope dependencies should be skipped.
|
||||
*/
|
||||
public static final String SKIP_TEST_SCOPE = "skip.test.scope";
|
||||
/**
|
||||
* The properties key for whether Runtime Scope dependencies should be skipped.
|
||||
*/
|
||||
public static final String SKIP_RUNTIME_SCOPE = "skip.runtime.scope";
|
||||
/**
|
||||
* The properties key for whether Provided Scope dependencies should be skipped.
|
||||
*/
|
||||
public static final String SKIP_PROVIDED_SCOPE = "skip.provided.scope";
|
||||
}
|
||||
/**
|
||||
* The properties file location.
|
||||
@@ -180,6 +212,43 @@ public final class Settings {
|
||||
}
|
||||
}
|
||||
}
|
||||
logProperties("Properties loaded", props);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs the properties. This will not log any properties that contain 'password' in the key.
|
||||
*
|
||||
* @param header the header to print with the log message
|
||||
* @param properties the properties to log
|
||||
*/
|
||||
private static void logProperties(String header, Properties properties) {
|
||||
if (LOGGER.isLoggable(Level.FINE)) {
|
||||
final StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = null;
|
||||
try {
|
||||
pw = new PrintWriter(sw);
|
||||
pw.format("%s:%n%n", header);
|
||||
final Enumeration e = properties.propertyNames();
|
||||
while (e.hasMoreElements()) {
|
||||
final String key = (String) e.nextElement();
|
||||
if (key.contains("password")) {
|
||||
pw.format("%s='*****'%n", key);
|
||||
} else {
|
||||
final String value = properties.getProperty(key);
|
||||
if (value != null) {
|
||||
pw.format("%s='%s'%n", key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
pw.flush();
|
||||
LOGGER.fine(sw.toString());
|
||||
} finally {
|
||||
if (pw != null) {
|
||||
pw.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -190,6 +259,9 @@ public final class Settings {
|
||||
*/
|
||||
public static void setString(String key, String value) {
|
||||
INSTANCE.props.setProperty(key, value);
|
||||
if (LOGGER.isLoggable(Level.FINE)) {
|
||||
LOGGER.fine(String.format("Setting: %s='%s'", key, value));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -204,6 +276,9 @@ public final class Settings {
|
||||
} else {
|
||||
INSTANCE.props.setProperty(key, Boolean.FALSE.toString());
|
||||
}
|
||||
if (LOGGER.isLoggable(Level.FINE)) {
|
||||
LOGGER.fine(String.format("Setting: %s='%b'", key, value));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -244,6 +319,7 @@ public final class Settings {
|
||||
*/
|
||||
public static void mergeProperties(InputStream stream) throws IOException {
|
||||
INSTANCE.props.load(stream);
|
||||
logProperties("Properties updated via merge", INSTANCE.props);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* This file is part of dependency-check-core.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Copyright (c) 2014 Jeremy Long. All Rights Reserved.
|
||||
*/
|
||||
package org.owasp.dependencycheck.utils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Authenticator;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.PasswordAuthentication;
|
||||
import java.net.Proxy;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* A URLConnection Factory to create new connections. This encapsulates several configuration checks to ensure that the
|
||||
* connection uses the correct proxy settings.
|
||||
*
|
||||
* @author Jeremy Long <jeremy.long@owasp.org>
|
||||
*/
|
||||
public final class URLConnectionFactory {
|
||||
|
||||
/**
|
||||
* Private constructor for this factory.
|
||||
*/
|
||||
private URLConnectionFactory() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to create an HttpURLConnection. If the application is configured to use a proxy this method will
|
||||
* retrieve the proxy settings and use them when setting up the connection.
|
||||
*
|
||||
* @param url the url to connect to
|
||||
* @return an HttpURLConnection
|
||||
* @throws URLConnectionFailureException thrown if there is an exception
|
||||
*/
|
||||
public static HttpURLConnection createHttpURLConnection(URL url) throws URLConnectionFailureException {
|
||||
HttpURLConnection conn = null;
|
||||
Proxy proxy = null;
|
||||
final String proxyUrl = Settings.getString(Settings.KEYS.PROXY_URL);
|
||||
try {
|
||||
if (proxyUrl != null) {
|
||||
final int proxyPort = Settings.getInt(Settings.KEYS.PROXY_PORT);
|
||||
final SocketAddress addr = new InetSocketAddress(proxyUrl, proxyPort);
|
||||
|
||||
final String username = Settings.getString(Settings.KEYS.PROXY_USERNAME);
|
||||
final String password = Settings.getString(Settings.KEYS.PROXY_PASSWORD);
|
||||
if (username != null && password != null) {
|
||||
final Authenticator auth = new Authenticator() {
|
||||
@Override
|
||||
public PasswordAuthentication getPasswordAuthentication() {
|
||||
if (getRequestorType().equals(Authenticator.RequestorType.PROXY)) {
|
||||
return new PasswordAuthentication(username, password.toCharArray());
|
||||
}
|
||||
return super.getPasswordAuthentication();
|
||||
}
|
||||
};
|
||||
Authenticator.setDefault(auth);
|
||||
}
|
||||
|
||||
proxy = new Proxy(Proxy.Type.HTTP, addr);
|
||||
conn = (HttpURLConnection) url.openConnection(proxy);
|
||||
} else {
|
||||
conn = (HttpURLConnection) url.openConnection();
|
||||
}
|
||||
final int timeout = Settings.getInt(Settings.KEYS.CONNECTION_TIMEOUT, 60000);
|
||||
conn.setConnectTimeout(timeout);
|
||||
} catch (IOException ex) {
|
||||
if (conn != null) {
|
||||
try {
|
||||
conn.disconnect();
|
||||
} finally {
|
||||
conn = null;
|
||||
}
|
||||
}
|
||||
throw new URLConnectionFailureException("Error getting connection.", ex);
|
||||
}
|
||||
return conn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to create an HttpURLConnection. The use of a proxy here is optional as there may be cases where a
|
||||
* proxy is configured but we don't want to use it (for example, if there's an internal repository configured)
|
||||
*
|
||||
* @param url the url to connect to
|
||||
* @param proxy whether to use the proxy (if configured)
|
||||
* @return a newly constructed HttpURLConnection
|
||||
* @throws URLConnectionFailureException thrown if there is an exception
|
||||
*/
|
||||
public static HttpURLConnection createHttpURLConnection(URL url, boolean proxy) throws URLConnectionFailureException {
|
||||
if (proxy) {
|
||||
return createHttpURLConnection(url);
|
||||
}
|
||||
HttpURLConnection conn = null;
|
||||
try {
|
||||
conn = (HttpURLConnection) url.openConnection();
|
||||
final int timeout = Settings.getInt(Settings.KEYS.CONNECTION_TIMEOUT, 60000);
|
||||
conn.setConnectTimeout(timeout);
|
||||
} catch (IOException ioe) {
|
||||
throw new URLConnectionFailureException("Error getting connection.", ioe);
|
||||
}
|
||||
return conn;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* This file is part of dependency-check-core.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Copyright (c) 2014 Jeremy Long. All Rights Reserved.
|
||||
*/
|
||||
package org.owasp.dependencycheck.utils;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* An exception used when the creation of an URLConnection fails.
|
||||
*
|
||||
* @author Jeremy Long <jeremy.long@owasp.org>
|
||||
*/
|
||||
public class URLConnectionFailureException extends IOException {
|
||||
|
||||
/**
|
||||
* The serial version UID.
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Creates a new URLConnectionFailureException.
|
||||
*/
|
||||
public URLConnectionFailureException() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new URLConnectionFailureException.
|
||||
*
|
||||
* @param msg a message for the exception.
|
||||
*/
|
||||
public URLConnectionFailureException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new URLConnectionFailureException.
|
||||
*
|
||||
* @param ex the cause of the download failure.
|
||||
*/
|
||||
public URLConnectionFailureException(Throwable ex) {
|
||||
super(ex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new URLConnectionFailureException.
|
||||
*
|
||||
* @param msg a message for the exception.
|
||||
* @param ex the cause of the download failure.
|
||||
*/
|
||||
public URLConnectionFailureException(String msg, Throwable ex) {
|
||||
super(msg, ex);
|
||||
}
|
||||
}
|
||||
BIN
dependency-check-core/src/main/resources/GrokAssembly.exe
Executable file
BIN
dependency-check-core/src/main/resources/GrokAssembly.exe
Executable file
Binary file not shown.
@@ -9,3 +9,5 @@ org.owasp.dependencycheck.analyzer.DependencyBundlingAnalyzer
|
||||
org.owasp.dependencycheck.analyzer.NvdCveAnalyzer
|
||||
org.owasp.dependencycheck.analyzer.VulnerabilitySuppressionAnalyzer
|
||||
org.owasp.dependencycheck.analyzer.NexusAnalyzer
|
||||
org.owasp.dependencycheck.analyzer.NuspecAnalyzer
|
||||
org.owasp.dependencycheck.analyzer.AssemblyAnalyzer
|
||||
Binary file not shown.
@@ -30,11 +30,6 @@ data.password=DC-Pass1337!
|
||||
data.driver_name=org.h2.Driver
|
||||
data.driver_path=
|
||||
|
||||
# the path to the cpe xml file
|
||||
cpe.url=http://static.nvd.nist.gov/feeds/xml/cpe/dictionary/official-cpe-dictionary_v2.2.xml.gz
|
||||
# the path to the cpe meta data file.
|
||||
cpe.meta.url=http://static.nvd.nist.gov/feeds/xml/cpe/dictionary/official-cpe-dictionary_v2.2.meta
|
||||
|
||||
# the number of days that the modified nvd cve data holds data for. We don't need
|
||||
# to update the other files if we are within this timespan. Per NIST this file
|
||||
# holds 8 days of updates, we are using 7 just to be safe.
|
||||
@@ -50,4 +45,6 @@ cve.url-1.2.base=http://nvd.nist.gov/download/nvdcve-%d.xml
|
||||
# the URL for searching Nexus for SHA-1 hashes and whether it's enabled
|
||||
analyzer.nexus.enabled=true
|
||||
analyzer.nexus.url=http://repository.sonatype.org/service/local/
|
||||
|
||||
# If set to true, the proxy will still ONLY be used if the proxy properties (proxy.url, proxy.port)
|
||||
# are configured
|
||||
analyzer.nexus.proxy=true
|
||||
|
||||
@@ -69,5 +69,6 @@ public class EngineIntegrationTest {
|
||||
ReportGenerator rg = new ReportGenerator("DependencyCheck",
|
||||
instance.getDependencies(), instance.getAnalyzers(), dbProp);
|
||||
rg.generateReports("./target/", "ALL");
|
||||
instance.cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,6 +69,7 @@ public class ArchiveAnalyzerTest extends BaseIndexTestCase {
|
||||
expResult.add("zip");
|
||||
expResult.add("war");
|
||||
expResult.add("ear");
|
||||
expResult.add("nupkg");
|
||||
expResult.add("tar");
|
||||
expResult.add("gz");
|
||||
expResult.add("tgz");
|
||||
@@ -110,6 +111,10 @@ public class ArchiveAnalyzerTest extends BaseIndexTestCase {
|
||||
extension = "zip"; //supported
|
||||
result = instance.supportsExtension(extension);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
extension = "nupkg"; //supported
|
||||
result = instance.supportsExtension(extension);
|
||||
assertEquals(expResult, result);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -148,12 +153,15 @@ public class ArchiveAnalyzerTest extends BaseIndexTestCase {
|
||||
File file = new File(this.getClass().getClassLoader().getResource("daytrader-ear-2.1.7.ear").getPath());
|
||||
Dependency dependency = new Dependency(file);
|
||||
Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false);
|
||||
Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false);
|
||||
Engine engine = new Engine();
|
||||
|
||||
int initial_size = engine.getDependencies().size();
|
||||
instance.analyze(dependency, engine);
|
||||
int ending_size = engine.getDependencies().size();
|
||||
|
||||
engine.cleanup();
|
||||
|
||||
assertTrue(initial_size < ending_size);
|
||||
|
||||
} finally {
|
||||
@@ -174,11 +182,13 @@ public class ArchiveAnalyzerTest extends BaseIndexTestCase {
|
||||
File file = new File(this.getClass().getClassLoader().getResource("stagedhttp-modified.tar").getPath());
|
||||
Dependency dependency = new Dependency(file);
|
||||
Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false);
|
||||
Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false);
|
||||
Engine engine = new Engine();
|
||||
|
||||
int initial_size = engine.getDependencies().size();
|
||||
instance.analyze(dependency, engine);
|
||||
int ending_size = engine.getDependencies().size();
|
||||
engine.cleanup();
|
||||
|
||||
assertTrue(initial_size < ending_size);
|
||||
|
||||
@@ -199,6 +209,7 @@ public class ArchiveAnalyzerTest extends BaseIndexTestCase {
|
||||
File file = new File(this.getClass().getClassLoader().getResource("file.tar.gz").getPath());
|
||||
//Dependency dependency = new Dependency(file);
|
||||
Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false);
|
||||
Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false);
|
||||
Engine engine = new Engine();
|
||||
|
||||
int initial_size = engine.getDependencies().size();
|
||||
@@ -206,7 +217,7 @@ public class ArchiveAnalyzerTest extends BaseIndexTestCase {
|
||||
engine.scan(file);
|
||||
engine.analyzeDependencies();
|
||||
int ending_size = engine.getDependencies().size();
|
||||
|
||||
engine.cleanup();
|
||||
assertTrue(initial_size < ending_size);
|
||||
|
||||
} finally {
|
||||
@@ -214,6 +225,27 @@ public class ArchiveAnalyzerTest extends BaseIndexTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Test of analyze method, of class ArchiveAnalyzer.
|
||||
// */
|
||||
// @Test
|
||||
// public void testNestedZipFolder() throws Exception {
|
||||
// ArchiveAnalyzer instance = new ArchiveAnalyzer();
|
||||
// try {
|
||||
// instance.initialize();
|
||||
//
|
||||
// File file = new File(this.getClass().getClassLoader().getResource("nested.zip").getPath());
|
||||
// Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false);
|
||||
// Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false);
|
||||
// Engine engine = new Engine();
|
||||
//
|
||||
// engine.scan(file);
|
||||
// engine.analyzeDependencies();
|
||||
//
|
||||
// } finally {
|
||||
// instance.close();
|
||||
// }
|
||||
// }
|
||||
/**
|
||||
* Test of analyze method, of class ArchiveAnalyzer.
|
||||
*/
|
||||
@@ -225,13 +257,14 @@ public class ArchiveAnalyzerTest extends BaseIndexTestCase {
|
||||
|
||||
File file = new File(this.getClass().getClassLoader().getResource("file.tgz").getPath());
|
||||
Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false);
|
||||
Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false);
|
||||
Engine engine = new Engine();
|
||||
|
||||
int initial_size = engine.getDependencies().size();
|
||||
engine.scan(file);
|
||||
engine.analyzeDependencies();
|
||||
int ending_size = engine.getDependencies().size();
|
||||
|
||||
engine.cleanup();
|
||||
assertTrue(initial_size < ending_size);
|
||||
|
||||
} finally {
|
||||
@@ -251,6 +284,7 @@ public class ArchiveAnalyzerTest extends BaseIndexTestCase {
|
||||
File file = new File(this.getClass().getClassLoader().getResource("test.zip").getPath());
|
||||
Dependency dependency = new Dependency(file);
|
||||
Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false);
|
||||
Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false);
|
||||
Engine engine = new Engine();
|
||||
int initial_size = engine.getDependencies().size();
|
||||
// boolean failed = false;
|
||||
@@ -261,6 +295,7 @@ public class ArchiveAnalyzerTest extends BaseIndexTestCase {
|
||||
// }
|
||||
// assertTrue(failed);
|
||||
int ending_size = engine.getDependencies().size();
|
||||
engine.cleanup();
|
||||
assertEquals(initial_size, ending_size);
|
||||
} finally {
|
||||
instance.close();
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* This file is part of dependency-check-core.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||
*/
|
||||
package org.owasp.dependencycheck.analyzer;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.junit.After;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import org.junit.Assume;
|
||||
import static org.junit.Assume.assumeFalse;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||
import org.owasp.dependencycheck.dependency.Confidence;
|
||||
import org.owasp.dependencycheck.dependency.Dependency;
|
||||
import org.owasp.dependencycheck.dependency.Evidence;
|
||||
import org.owasp.dependencycheck.utils.Settings;
|
||||
|
||||
/**
|
||||
* Tests for the AssemblyAnalyzer.
|
||||
*
|
||||
* @author colezlaw
|
||||
*
|
||||
*/
|
||||
public class AssemblyAnalyzerTest {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(AssemblyAnalyzerTest.class.getName());
|
||||
|
||||
AssemblyAnalyzer analyzer;
|
||||
|
||||
/**
|
||||
* Sets up the analyzer.
|
||||
*
|
||||
* @throws Exception if anything goes sideways
|
||||
*/
|
||||
@Before
|
||||
public void setUp() {
|
||||
try {
|
||||
analyzer = new AssemblyAnalyzer();
|
||||
analyzer.initialize();
|
||||
} catch (Exception e) {
|
||||
LOGGER.log(Level.WARNING, "Exception setting up AssemblyAnalyzer. Tests will be incomplete", e);
|
||||
Assume.assumeNoException("Is mono installed? TESTS WILL BE INCOMPLETE", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests to make sure the name is correct.
|
||||
*/
|
||||
@Test
|
||||
public void testGetName() {
|
||||
assertEquals("Assembly Analyzer", analyzer.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnalysis() throws Exception {
|
||||
File f = new File(AssemblyAnalyzerTest.class.getClassLoader().getResource("GrokAssembly.exe").getPath());
|
||||
Dependency d = new Dependency(f);
|
||||
analyzer.analyze(d, null);
|
||||
assertTrue(d.getVersionEvidence().getEvidence().contains(new Evidence("grokassembly", "version", "1.0.5140.29700", Confidence.HIGHEST)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLog4Net() throws Exception {
|
||||
File f = new File(AssemblyAnalyzerTest.class.getClassLoader().getResource("log4net.dll").getPath());
|
||||
Dependency d = new Dependency(f);
|
||||
analyzer.analyze(d, null);
|
||||
assertTrue(d.getVersionEvidence().getEvidence().contains(new Evidence("grokassembly", "version", "1.2.13.0", Confidence.HIGHEST)));
|
||||
assertTrue(d.getVendorEvidence().getEvidence().contains(new Evidence("grokassembly", "vendor", "The Apache Software Foundation", Confidence.HIGH)));
|
||||
assertTrue(d.getProductEvidence().getEvidence().contains(new Evidence("grokassembly", "product", "log4net", Confidence.HIGH)));
|
||||
}
|
||||
|
||||
@Test(expected = AnalysisException.class)
|
||||
public void testNonexistent() throws Exception {
|
||||
File f = new File(AssemblyAnalyzerTest.class.getClassLoader().getResource("log4net.dll").getPath());
|
||||
File test = new File(f.getParent(), "nonexistent.dll");
|
||||
Dependency d = new Dependency(test);
|
||||
analyzer.analyze(d, null);
|
||||
}
|
||||
|
||||
@Test(expected = AnalysisException.class)
|
||||
public void testWithSettingMono() throws Exception {
|
||||
|
||||
//This test doesn't work on Windows.
|
||||
assumeFalse(System.getProperty("os.name").startsWith("Windows"));
|
||||
|
||||
String oldValue = Settings.getString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH);
|
||||
// if oldValue is null, that means that neither the system property nor the setting has
|
||||
// been set. If that's the case, then we have to make it such that when we recover,
|
||||
// null still comes back. But you can't put a null value in a HashMap, so we have to set
|
||||
// the system property rather than the setting.
|
||||
if (oldValue == null) {
|
||||
System.setProperty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, "/yooser/bine/mono");
|
||||
} else {
|
||||
Settings.setString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, "/yooser/bine/mono");
|
||||
}
|
||||
|
||||
try {
|
||||
// Have to make a NEW analyzer because during setUp, it would have gotten the correct one
|
||||
AssemblyAnalyzer aanalyzer = new AssemblyAnalyzer();
|
||||
aanalyzer.initialize();
|
||||
} finally {
|
||||
// Now recover the way we came in. If we had to set a System property, delete it. Otherwise,
|
||||
// reset the old value
|
||||
if (oldValue == null) {
|
||||
System.getProperties().remove(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH);
|
||||
} else {
|
||||
Settings.setString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, oldValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
analyzer.close();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* This file is part of dependency-check-core.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Copyright (c) 2014 Jeremy Long. All Rights Reserved.
|
||||
*/
|
||||
package org.owasp.dependencycheck.analyzer;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.owasp.dependencycheck.Engine;
|
||||
import org.owasp.dependencycheck.dependency.Dependency;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jeremy Long <jeremy.long@owasp.org>
|
||||
*/
|
||||
public class JavaScriptAnalyzerTest {
|
||||
|
||||
public JavaScriptAnalyzerTest() {
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpClass() {
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void tearDownClass() {
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of getSupportedExtensions method, of class JavaScriptAnalyzer.
|
||||
*/
|
||||
@Test
|
||||
public void testGetSupportedExtensions() {
|
||||
JavaScriptAnalyzer instance = new JavaScriptAnalyzer();
|
||||
Set expResult = new HashSet<String>();
|
||||
expResult.add("js");
|
||||
Set result = instance.getSupportedExtensions();
|
||||
assertEquals(expResult, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of getName method, of class JavaScriptAnalyzer.
|
||||
*/
|
||||
@Test
|
||||
public void testGetName() {
|
||||
System.out.println("getName");
|
||||
JavaScriptAnalyzer instance = new JavaScriptAnalyzer();
|
||||
String expResult = "JavaScript Analyzer";
|
||||
String result = instance.getName();
|
||||
assertEquals(expResult, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of supportsExtension method, of class JavaScriptAnalyzer.
|
||||
*/
|
||||
@Test
|
||||
public void testSupportsExtension() {
|
||||
String extension = "js";
|
||||
JavaScriptAnalyzer instance = new JavaScriptAnalyzer();
|
||||
boolean expResult = true;
|
||||
boolean result = instance.supportsExtension(extension);
|
||||
assertEquals(expResult, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of getAnalysisPhase method, of class JavaScriptAnalyzer.
|
||||
*/
|
||||
@Test
|
||||
public void testGetAnalysisPhase() {
|
||||
JavaScriptAnalyzer instance = new JavaScriptAnalyzer();
|
||||
AnalysisPhase expResult = AnalysisPhase.INFORMATION_COLLECTION;
|
||||
AnalysisPhase result = instance.getAnalysisPhase();
|
||||
assertEquals(expResult, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of analyze method, of class JavaScriptAnalyzer.
|
||||
*/
|
||||
@Test
|
||||
public void testAnalyze() throws Exception {
|
||||
File jq6 = new File(this.getClass().getClassLoader().getResource("jquery-1.6.2.min.js").getPath());
|
||||
File jq10 = new File(this.getClass().getClassLoader().getResource("jquery-1.10.2.js").getPath());
|
||||
File jq10min = new File(this.getClass().getClassLoader().getResource("jquery-1.10.2.min.js").getPath());
|
||||
Dependency depJQ6 = new Dependency(jq6);
|
||||
Dependency depJQ10 = new Dependency(jq10);
|
||||
Dependency depJQ10min = new Dependency(jq10min);
|
||||
Engine engine = null;
|
||||
JavaScriptAnalyzer instance = new JavaScriptAnalyzer();
|
||||
|
||||
// assertTrue(depJQ6.getEvidence().size() == 0);
|
||||
// assertTrue(depJQ10.getEvidence().size() == 0);
|
||||
// assertTrue(depJQ10min.getEvidence().size() == 0);
|
||||
//
|
||||
// instance.analyze(depJQ6, engine);
|
||||
// instance.analyze(depJQ10, engine);
|
||||
// instance.analyze(depJQ10min, engine);
|
||||
// //TODO improve the assertions
|
||||
// assertTrue(depJQ6.getEvidence().size() > 0);
|
||||
// assertTrue(depJQ10.getEvidence().size() > 0);
|
||||
// assertTrue(depJQ10min.getEvidence().size() > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of initialize method, of class JavaScriptAnalyzer.
|
||||
*/
|
||||
@Test
|
||||
public void testInitialize() throws Exception {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of close method, of class JavaScriptAnalyzer.
|
||||
*/
|
||||
@Test
|
||||
public void testClose() throws Exception {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* This file is part of dependency-check-core.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Copyright (c) 2013 Jeremy Long. All Rights Reserved.
|
||||
*/
|
||||
package org.owasp.dependencycheck.analyzer;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class NuspecAnalyzerTest {
|
||||
private NuspecAnalyzer instance;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
instance = new NuspecAnalyzer();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAnalyzerName() {
|
||||
assertEquals("Nuspec Analyzer", instance.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSupportedExtensions() {
|
||||
assertTrue(instance.getSupportedExtensions().contains("nuspec"));
|
||||
assertFalse(instance.getSupportedExtensions().contains("nupkg"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSupportsExtension() {
|
||||
assertTrue(instance.supportsExtension("nuspec"));
|
||||
assertFalse(instance.supportsExtension("nupkg"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAnalysisPhaze() {
|
||||
assertEquals(AnalysisPhase.INFORMATION_COLLECTION, instance.getAnalysisPhase());
|
||||
}
|
||||
}
|
||||
|
||||
// vim: cc=120:sw=4:ts=4:sts=4
|
||||
@@ -59,11 +59,26 @@ public class CweDBTest {
|
||||
// SAXParser saxParser = factory.newSAXParser();
|
||||
//
|
||||
// CweHandler handler = new CweHandler();
|
||||
// File file = new File(this.getClass().getClassLoader().getResource("cwe.2000.xml").getPath());
|
||||
// //File file = new File(this.getClass().getClassLoader().getResource("cwe.2000.xml").getPath());
|
||||
// File file = new File(this.getClass().getClassLoader().getResource("cwec_v2.5.xml").getPath());
|
||||
//
|
||||
// saxParser.parse(file, handler);
|
||||
// System.out.println("Found " + handler.getCwe().size() + " cwe entries.");
|
||||
// Map<String,String> cwe = handler.getCwe();
|
||||
// Map<String, String> cwe = handler.getCwe();
|
||||
//// FileOutputStream fout = new FileOutputStream("target/current.csv");
|
||||
//// //FileOutputStream fout = new FileOutputStream("target/new.csv");
|
||||
//// PrintWriter writer = new PrintWriter(fout);
|
||||
//// for (Map.Entry<String, String> entry : cwe.entrySet()) {
|
||||
//// writer.print('"');
|
||||
//// writer.print(entry.getKey());
|
||||
//// writer.print('"');
|
||||
//// writer.print(',');
|
||||
//// writer.print('"');
|
||||
//// writer.print(entry.getValue());
|
||||
//// writer.println('"');
|
||||
//// }
|
||||
//// writer.close();
|
||||
//
|
||||
// FileOutputStream fout = new FileOutputStream("src/main/resources/data/cwe.hashmap.serialized");
|
||||
// ObjectOutputStream objOut = new ObjectOutputStream(fout);
|
||||
// objOut.writeObject(cwe);
|
||||
|
||||
@@ -17,13 +17,15 @@
|
||||
*/
|
||||
package org.owasp.dependencycheck.data.nexus;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.net.URL;
|
||||
import java.util.logging.Logger;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import org.junit.Assume;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.owasp.dependencycheck.utils.Settings;
|
||||
|
||||
@@ -37,6 +39,7 @@ public class NexusSearchTest {
|
||||
String nexusUrl = Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL);
|
||||
LOGGER.fine(nexusUrl);
|
||||
searcher = new NexusSearch(new URL(nexusUrl));
|
||||
Assume.assumeTrue(searcher.preflightRequest());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
@@ -52,7 +55,6 @@ public class NexusSearchTest {
|
||||
// This test does generate network traffic and communicates with a host
|
||||
// you may not be able to reach. Remove the @Ignore annotation if you want to
|
||||
// test it anyway
|
||||
@Ignore
|
||||
@Test
|
||||
public void testValidSha1() throws Exception {
|
||||
MavenArtifact ma = searcher.searchSha1("9977a8d04e75609cf01badc4eb6a9c7198c4c5ea");
|
||||
@@ -65,7 +67,6 @@ public class NexusSearchTest {
|
||||
// This test does generate network traffic and communicates with a host
|
||||
// you may not be able to reach. Remove the @Ignore annotation if you want to
|
||||
// test it anyway
|
||||
@Ignore
|
||||
@Test(expected = FileNotFoundException.class)
|
||||
public void testMissingSha1() throws Exception {
|
||||
searcher.searchSha1("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* This file is part of dependency-check-core.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Copyright (c) 2014 Jeremy Long. All Rights Reserved.
|
||||
*/
|
||||
package org.owasp.dependencycheck.data.nuget;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author colezlaw
|
||||
*
|
||||
*/
|
||||
public class XPathNuspecParserTest {
|
||||
/**
|
||||
* Test all the valid components.
|
||||
*
|
||||
* @throws Exception if anything goes sideways.
|
||||
*/
|
||||
@Test
|
||||
public void testGoodDocument() throws Exception {
|
||||
NuspecParser parser = new XPathNuspecParser();
|
||||
InputStream is = XPathNuspecParserTest.class.getClassLoader().getResourceAsStream("log4net.2.0.3.nuspec");
|
||||
NugetPackage np = parser.parse(is);
|
||||
assertEquals("log4net", np.getId());
|
||||
assertEquals("2.0.3", np.getVersion());
|
||||
assertEquals("log4net [1.2.13]", np.getTitle());
|
||||
assertEquals("Apache Software Foundation", np.getAuthors());
|
||||
assertEquals("Apache Software Foundation", np.getOwners());
|
||||
assertEquals("http://logging.apache.org/log4net/license.html", np.getLicenseUrl());
|
||||
}
|
||||
|
||||
/**
|
||||
* Expect a NuspecParseException when what we pass isn't even XML.
|
||||
*
|
||||
* @throws Exception we expect this.
|
||||
*/
|
||||
@Test(expected=NuspecParseException.class)
|
||||
public void testMissingDocument() throws Exception {
|
||||
NuspecParser parser = new XPathNuspecParser();
|
||||
InputStream is = XPathNuspecParserTest.class.getClassLoader().getResourceAsStream("dependencycheck.properties");
|
||||
NugetPackage np = parser.parse(is);
|
||||
}
|
||||
|
||||
/**
|
||||
* Expect a NuspecParseException when it's valid XML, but not a Nuspec.
|
||||
*
|
||||
* @throws Exception we expect this.
|
||||
*/
|
||||
@Test(expected=NuspecParseException.class)
|
||||
public void testNotNuspec() throws Exception {
|
||||
NuspecParser parser = new XPathNuspecParser();
|
||||
InputStream is = XPathNuspecParserTest.class.getClassLoader().getResourceAsStream("suppressions.xml");
|
||||
NugetPackage np = parser.parse(is);
|
||||
}
|
||||
}
|
||||
@@ -73,7 +73,7 @@ public abstract class BaseDBTestCase extends TestCase {
|
||||
while ((count = zin.read(data, 0, BUFFER_SIZE)) != -1) {
|
||||
dest.write(data, 0, count);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
} catch (Throwable ex) {
|
||||
Logger.getLogger(BaseDBTestCase.class.getName()).log(Level.SEVERE, null, ex);
|
||||
} finally {
|
||||
try {
|
||||
|
||||
@@ -59,7 +59,14 @@ public class DriverLoaderTest {
|
||||
@Test
|
||||
public void testLoad_String() throws Exception {
|
||||
String className = "org.h2.Driver";
|
||||
DriverLoader.load(className);
|
||||
Driver d = null;
|
||||
try {
|
||||
d = DriverLoader.load(className);
|
||||
} finally {
|
||||
if (d != null) {
|
||||
DriverManager.deregisterDriver(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -68,7 +75,7 @@ public class DriverLoaderTest {
|
||||
@Test(expected = DriverLoadException.class)
|
||||
public void testLoad_String_ex() throws Exception {
|
||||
String className = "bad.Driver";
|
||||
DriverLoader.load(className);
|
||||
Driver d = DriverLoader.load(className);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -82,9 +89,16 @@ public class DriverLoaderTest {
|
||||
File driver = new File(testClassPath, "../../src/test/resources/mysql-connector-java-5.1.27-bin.jar");
|
||||
assertTrue("MySQL Driver JAR file not found in src/test/resources?", driver.isFile());
|
||||
|
||||
DriverLoader.load(className, driver.getAbsolutePath());
|
||||
Driver d = DriverManager.getDriver("jdbc:mysql://localhost:3306/dependencycheck");
|
||||
assertNotNull(d);
|
||||
Driver d = null;
|
||||
try {
|
||||
d = DriverLoader.load(className, driver.getAbsolutePath());
|
||||
d = DriverManager.getDriver("jdbc:mysql://localhost:3306/dependencycheck");
|
||||
assertNotNull(d);
|
||||
} finally {
|
||||
if (d != null) {
|
||||
DriverManager.deregisterDriver(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -99,7 +113,14 @@ public class DriverLoaderTest {
|
||||
final File dir2 = new File(testClassPath, "../../src/test/resources/");
|
||||
final String paths = String.format("%s" + File.pathSeparator + "%s", dir1.getAbsolutePath(), dir2.getAbsolutePath());
|
||||
|
||||
DriverLoader.load(className, paths);
|
||||
Driver d = null;
|
||||
try {
|
||||
d = DriverLoader.load(className, paths);
|
||||
} finally {
|
||||
if (d != null) {
|
||||
DriverManager.deregisterDriver(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -113,7 +134,7 @@ public class DriverLoaderTest {
|
||||
File driver = new File(testClassPath, "../../src/test/resources/mysql-connector-java-5.1.27-bin.jar");
|
||||
assertTrue("MySQL Driver JAR file not found in src/test/resources?", driver.isFile());
|
||||
|
||||
DriverLoader.load(className, driver.getAbsolutePath());
|
||||
Driver d = DriverLoader.load(className, driver.getAbsolutePath());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -125,6 +146,6 @@ public class DriverLoaderTest {
|
||||
//we know this is in target/test-classes
|
||||
File testClassPath = (new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath())).getParentFile();
|
||||
File driver = new File(testClassPath, "../../src/test/bad/mysql-connector-java-5.1.27-bin.jar");
|
||||
DriverLoader.load(className, driver.getAbsolutePath());
|
||||
Driver d = DriverLoader.load(className, driver.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ public class NvdCve_2_0_HandlerTest {
|
||||
|
||||
@Test
|
||||
public void testParse() {
|
||||
Exception results = null;
|
||||
Throwable results = null;
|
||||
try {
|
||||
SAXParserFactory factory = SAXParserFactory.newInstance();
|
||||
SAXParser saxParser = factory.newSAXParser();
|
||||
@@ -64,7 +64,7 @@ public class NvdCve_2_0_HandlerTest {
|
||||
NvdCve20Handler instance = new NvdCve20Handler();
|
||||
|
||||
saxParser.parse(file, instance);
|
||||
} catch (Exception ex) {
|
||||
} catch (Throwable ex) {
|
||||
results = ex;
|
||||
}
|
||||
assertTrue("Exception thrown during parse of 2012 CVE version 2.0?", results == null);
|
||||
|
||||
@@ -87,5 +87,13 @@ public class VulnerableSoftwareTest {
|
||||
int expResult = -2;
|
||||
int result = instance.compareTo(vs);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
vs = new VulnerableSoftware();
|
||||
vs.setCpe("cpe:/a:yahoo:toolbar:3.1.0.20130813024103");
|
||||
instance = new VulnerableSoftware();
|
||||
instance.setCpe("cpe:/a:yahoo:toolbar:3.1.0.20130813024104");
|
||||
expResult = 1;
|
||||
result = instance.compareTo(vs);
|
||||
assertEquals(expResult, result);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,6 +150,8 @@ public class ReportGeneratorTest {
|
||||
ReportGenerator generator = new ReportGenerator("Test Report", engine.getDependencies(), engine.getAnalyzers(), dbProp);
|
||||
generator.generateReport(templateName, writeTo);
|
||||
|
||||
engine.cleanup();
|
||||
|
||||
InputStream xsdStream = ReportGenerator.class.getClassLoader().getResourceAsStream("schema/DependencyCheck.xsd");
|
||||
StreamSource xsdSource = new StreamSource(xsdStream);
|
||||
StreamSource xmlSource = new StreamSource(new File(writeTo));
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
@@ -76,7 +77,8 @@ public class FileUtilsTest {
|
||||
if (!file.exists()) {
|
||||
fail("Unable to create a temporary file.");
|
||||
}
|
||||
FileUtils.delete(file);
|
||||
boolean status = FileUtils.delete(file);
|
||||
assertTrue("delete returned a failed status", status);
|
||||
assertFalse("Temporary file exists after attempting deletion", file.exists());
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -50,3 +50,6 @@ cve.url-1.2.base=http://nvd.nist.gov/download/nvdcve-%d.xml
|
||||
# the URL for searching Nexus for SHA-1 hashes and whether it's enabled
|
||||
analyzer.nexus.enabled=true
|
||||
analyzer.nexus.url=http://repository.sonatype.org/service/local/
|
||||
# If set to true, the proxy will still ONLY be used if the proxy properties (proxy.url, proxy.port)
|
||||
# are configured
|
||||
analyzer.nexus.proxy=true
|
||||
|
||||
9789
dependency-check-core/src/test/resources/jquery-1.10.2.js
vendored
Normal file
9789
dependency-check-core/src/test/resources/jquery-1.10.2.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
6
dependency-check-core/src/test/resources/jquery-1.10.2.min.js
vendored
Normal file
6
dependency-check-core/src/test/resources/jquery-1.10.2.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
18
dependency-check-core/src/test/resources/jquery-1.6.2.min.js
vendored
Normal file
18
dependency-check-core/src/test/resources/jquery-1.6.2.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
911
dependency-check-core/src/test/resources/jquery.prettyPhoto.js
Normal file
911
dependency-check-core/src/test/resources/jquery.prettyPhoto.js
Normal file
@@ -0,0 +1,911 @@
|
||||
/* ------------------------------------------------------------------------
|
||||
Class: prettyPhoto
|
||||
Use: Lightbox clone for jQuery
|
||||
Author: Stephane Caron (http://www.no-margin-for-errors.com)
|
||||
Version: 3.1.5
|
||||
------------------------------------------------------------------------- */
|
||||
(function($) {
|
||||
$.prettyPhoto = {version: '3.1.5'};
|
||||
|
||||
$.fn.prettyPhoto = function(pp_settings) {
|
||||
pp_settings = jQuery.extend({
|
||||
hook: 'rel', /* the attribute tag to use for prettyPhoto hooks. default: 'rel'. For HTML5, use "data-rel" or similar. */
|
||||
animation_speed: 'fast', /* fast/slow/normal */
|
||||
ajaxcallback: function() {},
|
||||
slideshow: 5000, /* false OR interval time in ms */
|
||||
autoplay_slideshow: false, /* true/false */
|
||||
opacity: 0.80, /* Value between 0 and 1 */
|
||||
show_title: true, /* true/false */
|
||||
allow_resize: true, /* Resize the photos bigger than viewport. true/false */
|
||||
allow_expand: true, /* Allow the user to expand a resized image. true/false */
|
||||
default_width: 500,
|
||||
default_height: 344,
|
||||
counter_separator_label: '/', /* The separator for the gallery counter 1 "of" 2 */
|
||||
theme: 'pp_default', /* light_rounded / dark_rounded / light_square / dark_square / facebook */
|
||||
horizontal_padding: 20, /* The padding on each side of the picture */
|
||||
hideflash: false, /* Hides all the flash object on a page, set to TRUE if flash appears over prettyPhoto */
|
||||
wmode: 'opaque', /* Set the flash wmode attribute */
|
||||
autoplay: true, /* Automatically start videos: True/False */
|
||||
modal: false, /* If set to true, only the close button will close the window */
|
||||
deeplinking: true, /* Allow prettyPhoto to update the url to enable deeplinking. */
|
||||
overlay_gallery: true, /* If set to true, a gallery will overlay the fullscreen image on mouse over */
|
||||
overlay_gallery_max: 30, /* Maximum number of pictures in the overlay gallery */
|
||||
keyboard_shortcuts: true, /* Set to false if you open forms inside prettyPhoto */
|
||||
changepicturecallback: function(){}, /* Called everytime an item is shown/changed */
|
||||
callback: function(){}, /* Called when prettyPhoto is closed */
|
||||
ie6_fallback: true,
|
||||
markup: '<div class="pp_pic_holder"> \
|
||||
<div class="ppt"> </div> \
|
||||
<div class="pp_top"> \
|
||||
<div class="pp_left"></div> \
|
||||
<div class="pp_middle"></div> \
|
||||
<div class="pp_right"></div> \
|
||||
</div> \
|
||||
<div class="pp_content_container"> \
|
||||
<div class="pp_left"> \
|
||||
<div class="pp_right"> \
|
||||
<div class="pp_content"> \
|
||||
<div class="pp_loaderIcon"></div> \
|
||||
<div class="pp_fade"> \
|
||||
<a href="#" class="pp_expand" title="Expand the image">Expand</a> \
|
||||
<div class="pp_hoverContainer"> \
|
||||
<a class="pp_next" href="#">next</a> \
|
||||
<a class="pp_previous" href="#">previous</a> \
|
||||
</div> \
|
||||
<div id="pp_full_res"></div> \
|
||||
<div class="pp_details"> \
|
||||
<div class="pp_nav"> \
|
||||
<a href="#" class="pp_arrow_previous">Previous</a> \
|
||||
<p class="currentTextHolder">0/0</p> \
|
||||
<a href="#" class="pp_arrow_next">Next</a> \
|
||||
</div> \
|
||||
<p class="pp_description"></p> \
|
||||
<div class="pp_social">{pp_social}</div> \
|
||||
<a class="pp_close" href="#">Close</a> \
|
||||
</div> \
|
||||
</div> \
|
||||
</div> \
|
||||
</div> \
|
||||
</div> \
|
||||
</div> \
|
||||
<div class="pp_bottom"> \
|
||||
<div class="pp_left"></div> \
|
||||
<div class="pp_middle"></div> \
|
||||
<div class="pp_right"></div> \
|
||||
</div> \
|
||||
</div> \
|
||||
<div class="pp_overlay"></div>',
|
||||
gallery_markup: '<div class="pp_gallery"> \
|
||||
<a href="#" class="pp_arrow_previous">Previous</a> \
|
||||
<div> \
|
||||
<ul> \
|
||||
{gallery} \
|
||||
</ul> \
|
||||
</div> \
|
||||
<a href="#" class="pp_arrow_next">Next</a> \
|
||||
</div>',
|
||||
image_markup: '<img id="fullResImage" src="{path}" />',
|
||||
flash_markup: '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="{width}" height="{height}"><param name="wmode" value="{wmode}" /><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="{path}" /><embed src="{path}" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="{width}" height="{height}" wmode="{wmode}"></embed></object>',
|
||||
quicktime_markup: '<object classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" codebase="http://www.apple.com/qtactivex/qtplugin.cab" height="{height}" width="{width}"><param name="src" value="{path}"><param name="autoplay" value="{autoplay}"><param name="type" value="video/quicktime"><embed src="{path}" height="{height}" width="{width}" autoplay="{autoplay}" type="video/quicktime" pluginspage="http://www.apple.com/quicktime/download/"></embed></object>',
|
||||
iframe_markup: '<iframe src ="{path}" width="{width}" height="{height}" frameborder="no"></iframe>',
|
||||
inline_markup: '<div class="pp_inline">{content}</div>',
|
||||
custom_markup: '',
|
||||
social_tools: '<div class="twitter"><a href="http://twitter.com/share" class="twitter-share-button" data-count="none">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div><div class="facebook"><iframe src="//www.facebook.com/plugins/like.php?locale=en_US&href={location_href}&layout=button_count&show_faces=true&width=500&action=like&font&colorscheme=light&height=23" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:500px; height:23px;" allowTransparency="true"></iframe></div>' /* html or false to disable */
|
||||
}, pp_settings);
|
||||
|
||||
// Global variables accessible only by prettyPhoto
|
||||
var matchedObjects = this, percentBased = false, pp_dimensions, pp_open,
|
||||
|
||||
// prettyPhoto container specific
|
||||
pp_contentHeight, pp_contentWidth, pp_containerHeight, pp_containerWidth,
|
||||
|
||||
// Window size
|
||||
windowHeight = $(window).height(), windowWidth = $(window).width(),
|
||||
|
||||
// Global elements
|
||||
pp_slideshow;
|
||||
|
||||
doresize = true, scroll_pos = _get_scroll();
|
||||
|
||||
// Window/Keyboard events
|
||||
$(window).unbind('resize.prettyphoto').bind('resize.prettyphoto',function(){ _center_overlay(); _resize_overlay(); });
|
||||
|
||||
if(pp_settings.keyboard_shortcuts) {
|
||||
$(document).unbind('keydown.prettyphoto').bind('keydown.prettyphoto',function(e){
|
||||
if(typeof $pp_pic_holder != 'undefined'){
|
||||
if($pp_pic_holder.is(':visible')){
|
||||
switch(e.keyCode){
|
||||
case 37:
|
||||
$.prettyPhoto.changePage('previous');
|
||||
e.preventDefault();
|
||||
break;
|
||||
case 39:
|
||||
$.prettyPhoto.changePage('next');
|
||||
e.preventDefault();
|
||||
break;
|
||||
case 27:
|
||||
if(!settings.modal)
|
||||
$.prettyPhoto.close();
|
||||
e.preventDefault();
|
||||
break;
|
||||
};
|
||||
// return false;
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize prettyPhoto.
|
||||
*/
|
||||
$.prettyPhoto.initialize = function() {
|
||||
|
||||
settings = pp_settings;
|
||||
|
||||
if(settings.theme == 'pp_default') settings.horizontal_padding = 16;
|
||||
|
||||
// Find out if the picture is part of a set
|
||||
theRel = $(this).attr(settings.hook);
|
||||
galleryRegExp = /\[(?:.*)\]/;
|
||||
isSet = (galleryRegExp.exec(theRel)) ? true : false;
|
||||
|
||||
// Put the SRCs, TITLEs, ALTs into an array.
|
||||
pp_images = (isSet) ? jQuery.map(matchedObjects, function(n, i){ if($(n).attr(settings.hook).indexOf(theRel) != -1) return $(n).attr('href'); }) : $.makeArray($(this).attr('href'));
|
||||
pp_titles = (isSet) ? jQuery.map(matchedObjects, function(n, i){ if($(n).attr(settings.hook).indexOf(theRel) != -1) return ($(n).find('img').attr('alt')) ? $(n).find('img').attr('alt') : ""; }) : $.makeArray($(this).find('img').attr('alt'));
|
||||
pp_descriptions = (isSet) ? jQuery.map(matchedObjects, function(n, i){ if($(n).attr(settings.hook).indexOf(theRel) != -1) return ($(n).attr('title')) ? $(n).attr('title') : ""; }) : $.makeArray($(this).attr('title'));
|
||||
|
||||
if(pp_images.length > settings.overlay_gallery_max) settings.overlay_gallery = false;
|
||||
|
||||
set_position = jQuery.inArray($(this).attr('href'), pp_images); // Define where in the array the clicked item is positionned
|
||||
rel_index = (isSet) ? set_position : $("a["+settings.hook+"^='"+theRel+"']").index($(this));
|
||||
|
||||
_build_overlay(this); // Build the overlay {this} being the caller
|
||||
|
||||
if(settings.allow_resize)
|
||||
$(window).bind('scroll.prettyphoto',function(){ _center_overlay(); });
|
||||
|
||||
|
||||
$.prettyPhoto.open();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Opens the prettyPhoto modal box.
|
||||
* @param image {String,Array} Full path to the image to be open, can also be an array containing full images paths.
|
||||
* @param title {String,Array} The title to be displayed with the picture, can also be an array containing all the titles.
|
||||
* @param description {String,Array} The description to be displayed with the picture, can also be an array containing all the descriptions.
|
||||
*/
|
||||
$.prettyPhoto.open = function(event) {
|
||||
if(typeof settings == "undefined"){ // Means it's an API call, need to manually get the settings and set the variables
|
||||
settings = pp_settings;
|
||||
pp_images = $.makeArray(arguments[0]);
|
||||
pp_titles = (arguments[1]) ? $.makeArray(arguments[1]) : $.makeArray("");
|
||||
pp_descriptions = (arguments[2]) ? $.makeArray(arguments[2]) : $.makeArray("");
|
||||
isSet = (pp_images.length > 1) ? true : false;
|
||||
set_position = (arguments[3])? arguments[3]: 0;
|
||||
_build_overlay(event.target); // Build the overlay {this} being the caller
|
||||
}
|
||||
|
||||
if(settings.hideflash) $('object,embed,iframe[src*=youtube],iframe[src*=vimeo]').css('visibility','hidden'); // Hide the flash
|
||||
|
||||
_checkPosition($(pp_images).size()); // Hide the next/previous links if on first or last images.
|
||||
|
||||
$('.pp_loaderIcon').show();
|
||||
|
||||
if(settings.deeplinking)
|
||||
setHashtag();
|
||||
|
||||
// Rebuild Facebook Like Button with updated href
|
||||
if(settings.social_tools){
|
||||
facebook_like_link = settings.social_tools.replace('{location_href}', encodeURIComponent(location.href));
|
||||
$pp_pic_holder.find('.pp_social').html(facebook_like_link);
|
||||
}
|
||||
|
||||
// Fade the content in
|
||||
if($ppt.is(':hidden')) $ppt.css('opacity',0).show();
|
||||
$pp_overlay.show().fadeTo(settings.animation_speed,settings.opacity);
|
||||
|
||||
// Display the current position
|
||||
$pp_pic_holder.find('.currentTextHolder').text((set_position+1) + settings.counter_separator_label + $(pp_images).size());
|
||||
|
||||
// Set the description
|
||||
if(typeof pp_descriptions[set_position] != 'undefined' && pp_descriptions[set_position] != ""){
|
||||
$pp_pic_holder.find('.pp_description').show().html(unescape(pp_descriptions[set_position]));
|
||||
}else{
|
||||
$pp_pic_holder.find('.pp_description').hide();
|
||||
}
|
||||
|
||||
// Get the dimensions
|
||||
movie_width = ( parseFloat(getParam('width',pp_images[set_position])) ) ? getParam('width',pp_images[set_position]) : settings.default_width.toString();
|
||||
movie_height = ( parseFloat(getParam('height',pp_images[set_position])) ) ? getParam('height',pp_images[set_position]) : settings.default_height.toString();
|
||||
|
||||
// If the size is % based, calculate according to window dimensions
|
||||
percentBased=false;
|
||||
if(movie_height.indexOf('%') != -1) { movie_height = parseFloat(($(window).height() * parseFloat(movie_height) / 100) - 150); percentBased = true; }
|
||||
if(movie_width.indexOf('%') != -1) { movie_width = parseFloat(($(window).width() * parseFloat(movie_width) / 100) - 150); percentBased = true; }
|
||||
|
||||
// Fade the holder
|
||||
$pp_pic_holder.fadeIn(function(){
|
||||
// Set the title
|
||||
(settings.show_title && pp_titles[set_position] != "" && typeof pp_titles[set_position] != "undefined") ? $ppt.html(unescape(pp_titles[set_position])) : $ppt.html(' ');
|
||||
|
||||
imgPreloader = "";
|
||||
skipInjection = false;
|
||||
|
||||
// Inject the proper content
|
||||
switch(_getFileType(pp_images[set_position])){
|
||||
case 'image':
|
||||
imgPreloader = new Image();
|
||||
|
||||
// Preload the neighbour images
|
||||
nextImage = new Image();
|
||||
if(isSet && set_position < $(pp_images).size() -1) nextImage.src = pp_images[set_position + 1];
|
||||
prevImage = new Image();
|
||||
if(isSet && pp_images[set_position - 1]) prevImage.src = pp_images[set_position - 1];
|
||||
|
||||
$pp_pic_holder.find('#pp_full_res')[0].innerHTML = settings.image_markup.replace(/{path}/g,pp_images[set_position]);
|
||||
|
||||
imgPreloader.onload = function(){
|
||||
// Fit item to viewport
|
||||
pp_dimensions = _fitToViewport(imgPreloader.width,imgPreloader.height);
|
||||
|
||||
_showContent();
|
||||
};
|
||||
|
||||
imgPreloader.onerror = function(){
|
||||
alert('Image cannot be loaded. Make sure the path is correct and image exist.');
|
||||
$.prettyPhoto.close();
|
||||
};
|
||||
|
||||
imgPreloader.src = pp_images[set_position];
|
||||
break;
|
||||
|
||||
case 'youtube':
|
||||
pp_dimensions = _fitToViewport(movie_width,movie_height); // Fit item to viewport
|
||||
|
||||
// Regular youtube link
|
||||
movie_id = getParam('v',pp_images[set_position]);
|
||||
|
||||
// youtu.be link
|
||||
if(movie_id == ""){
|
||||
movie_id = pp_images[set_position].split('youtu.be/');
|
||||
movie_id = movie_id[1];
|
||||
if(movie_id.indexOf('?') > 0)
|
||||
movie_id = movie_id.substr(0,movie_id.indexOf('?')); // Strip anything after the ?
|
||||
|
||||
if(movie_id.indexOf('&') > 0)
|
||||
movie_id = movie_id.substr(0,movie_id.indexOf('&')); // Strip anything after the &
|
||||
}
|
||||
|
||||
movie = 'http://www.youtube.com/embed/'+movie_id;
|
||||
(getParam('rel',pp_images[set_position])) ? movie+="?rel="+getParam('rel',pp_images[set_position]) : movie+="?rel=1";
|
||||
|
||||
if(settings.autoplay) movie += "&autoplay=1";
|
||||
|
||||
toInject = settings.iframe_markup.replace(/{width}/g,pp_dimensions['width']).replace(/{height}/g,pp_dimensions['height']).replace(/{wmode}/g,settings.wmode).replace(/{path}/g,movie);
|
||||
break;
|
||||
|
||||
case 'vimeo':
|
||||
pp_dimensions = _fitToViewport(movie_width,movie_height); // Fit item to viewport
|
||||
|
||||
movie_id = pp_images[set_position];
|
||||
var regExp = /http(s?):\/\/(www\.)?vimeo.com\/(\d+)/;
|
||||
var match = movie_id.match(regExp);
|
||||
|
||||
movie = 'http://player.vimeo.com/video/'+ match[3] +'?title=0&byline=0&portrait=0';
|
||||
if(settings.autoplay) movie += "&autoplay=1;";
|
||||
|
||||
vimeo_width = pp_dimensions['width'] + '/embed/?moog_width='+ pp_dimensions['width'];
|
||||
|
||||
toInject = settings.iframe_markup.replace(/{width}/g,vimeo_width).replace(/{height}/g,pp_dimensions['height']).replace(/{path}/g,movie);
|
||||
break;
|
||||
|
||||
case 'quicktime':
|
||||
pp_dimensions = _fitToViewport(movie_width,movie_height); // Fit item to viewport
|
||||
pp_dimensions['height']+=15; pp_dimensions['contentHeight']+=15; pp_dimensions['containerHeight']+=15; // Add space for the control bar
|
||||
|
||||
toInject = settings.quicktime_markup.replace(/{width}/g,pp_dimensions['width']).replace(/{height}/g,pp_dimensions['height']).replace(/{wmode}/g,settings.wmode).replace(/{path}/g,pp_images[set_position]).replace(/{autoplay}/g,settings.autoplay);
|
||||
break;
|
||||
|
||||
case 'flash':
|
||||
pp_dimensions = _fitToViewport(movie_width,movie_height); // Fit item to viewport
|
||||
|
||||
flash_vars = pp_images[set_position];
|
||||
flash_vars = flash_vars.substring(pp_images[set_position].indexOf('flashvars') + 10,pp_images[set_position].length);
|
||||
|
||||
filename = pp_images[set_position];
|
||||
filename = filename.substring(0,filename.indexOf('?'));
|
||||
|
||||
toInject = settings.flash_markup.replace(/{width}/g,pp_dimensions['width']).replace(/{height}/g,pp_dimensions['height']).replace(/{wmode}/g,settings.wmode).replace(/{path}/g,filename+'?'+flash_vars);
|
||||
break;
|
||||
|
||||
case 'iframe':
|
||||
pp_dimensions = _fitToViewport(movie_width,movie_height); // Fit item to viewport
|
||||
|
||||
frame_url = pp_images[set_position];
|
||||
frame_url = frame_url.substr(0,frame_url.indexOf('iframe')-1);
|
||||
|
||||
toInject = settings.iframe_markup.replace(/{width}/g,pp_dimensions['width']).replace(/{height}/g,pp_dimensions['height']).replace(/{path}/g,frame_url);
|
||||
break;
|
||||
|
||||
case 'ajax':
|
||||
doresize = false; // Make sure the dimensions are not resized.
|
||||
pp_dimensions = _fitToViewport(movie_width,movie_height);
|
||||
doresize = true; // Reset the dimensions
|
||||
|
||||
skipInjection = true;
|
||||
$.get(pp_images[set_position],function(responseHTML){
|
||||
toInject = settings.inline_markup.replace(/{content}/g,responseHTML);
|
||||
$pp_pic_holder.find('#pp_full_res')[0].innerHTML = toInject;
|
||||
_showContent();
|
||||
});
|
||||
|
||||
break;
|
||||
|
||||
case 'custom':
|
||||
pp_dimensions = _fitToViewport(movie_width,movie_height); // Fit item to viewport
|
||||
|
||||
toInject = settings.custom_markup;
|
||||
break;
|
||||
|
||||
case 'inline':
|
||||
// to get the item height clone it, apply default width, wrap it in the prettyPhoto containers , then delete
|
||||
myClone = $(pp_images[set_position]).clone().append('<br clear="all" />').css({'width':settings.default_width}).wrapInner('<div id="pp_full_res"><div class="pp_inline"></div></div>').appendTo($('body')).show();
|
||||
doresize = false; // Make sure the dimensions are not resized.
|
||||
pp_dimensions = _fitToViewport($(myClone).width(),$(myClone).height());
|
||||
doresize = true; // Reset the dimensions
|
||||
$(myClone).remove();
|
||||
toInject = settings.inline_markup.replace(/{content}/g,$(pp_images[set_position]).html());
|
||||
break;
|
||||
};
|
||||
|
||||
if(!imgPreloader && !skipInjection){
|
||||
$pp_pic_holder.find('#pp_full_res')[0].innerHTML = toInject;
|
||||
|
||||
// Show content
|
||||
_showContent();
|
||||
};
|
||||
});
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Change page in the prettyPhoto modal box
|
||||
* @param direction {String} Direction of the paging, previous or next.
|
||||
*/
|
||||
$.prettyPhoto.changePage = function(direction){
|
||||
currentGalleryPage = 0;
|
||||
|
||||
if(direction == 'previous') {
|
||||
set_position--;
|
||||
if (set_position < 0) set_position = $(pp_images).size()-1;
|
||||
}else if(direction == 'next'){
|
||||
set_position++;
|
||||
if(set_position > $(pp_images).size()-1) set_position = 0;
|
||||
}else{
|
||||
set_position=direction;
|
||||
};
|
||||
|
||||
rel_index = set_position;
|
||||
|
||||
if(!doresize) doresize = true; // Allow the resizing of the images
|
||||
if(settings.allow_expand) {
|
||||
$('.pp_contract').removeClass('pp_contract').addClass('pp_expand');
|
||||
}
|
||||
|
||||
_hideContent(function(){ $.prettyPhoto.open(); });
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Change gallery page in the prettyPhoto modal box
|
||||
* @param direction {String} Direction of the paging, previous or next.
|
||||
*/
|
||||
$.prettyPhoto.changeGalleryPage = function(direction){
|
||||
if(direction=='next'){
|
||||
currentGalleryPage ++;
|
||||
|
||||
if(currentGalleryPage > totalPage) currentGalleryPage = 0;
|
||||
}else if(direction=='previous'){
|
||||
currentGalleryPage --;
|
||||
|
||||
if(currentGalleryPage < 0) currentGalleryPage = totalPage;
|
||||
}else{
|
||||
currentGalleryPage = direction;
|
||||
};
|
||||
|
||||
slide_speed = (direction == 'next' || direction == 'previous') ? settings.animation_speed : 0;
|
||||
|
||||
slide_to = currentGalleryPage * (itemsPerPage * itemWidth);
|
||||
|
||||
$pp_gallery.find('ul').animate({left:-slide_to},slide_speed);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Start the slideshow...
|
||||
*/
|
||||
$.prettyPhoto.startSlideshow = function(){
|
||||
if(typeof pp_slideshow == 'undefined'){
|
||||
$pp_pic_holder.find('.pp_play').unbind('click').removeClass('pp_play').addClass('pp_pause').click(function(){
|
||||
$.prettyPhoto.stopSlideshow();
|
||||
return false;
|
||||
});
|
||||
pp_slideshow = setInterval($.prettyPhoto.startSlideshow,settings.slideshow);
|
||||
}else{
|
||||
$.prettyPhoto.changePage('next');
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Stop the slideshow...
|
||||
*/
|
||||
$.prettyPhoto.stopSlideshow = function(){
|
||||
$pp_pic_holder.find('.pp_pause').unbind('click').removeClass('pp_pause').addClass('pp_play').click(function(){
|
||||
$.prettyPhoto.startSlideshow();
|
||||
return false;
|
||||
});
|
||||
clearInterval(pp_slideshow);
|
||||
pp_slideshow=undefined;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Closes prettyPhoto.
|
||||
*/
|
||||
$.prettyPhoto.close = function(){
|
||||
if($pp_overlay.is(":animated")) return;
|
||||
|
||||
$.prettyPhoto.stopSlideshow();
|
||||
|
||||
$pp_pic_holder.stop().find('object,embed').css('visibility','hidden');
|
||||
|
||||
$('div.pp_pic_holder,div.ppt,.pp_fade').fadeOut(settings.animation_speed,function(){ $(this).remove(); });
|
||||
|
||||
$pp_overlay.fadeOut(settings.animation_speed, function(){
|
||||
|
||||
if(settings.hideflash) $('object,embed,iframe[src*=youtube],iframe[src*=vimeo]').css('visibility','visible'); // Show the flash
|
||||
|
||||
$(this).remove(); // No more need for the prettyPhoto markup
|
||||
|
||||
$(window).unbind('scroll.prettyphoto');
|
||||
|
||||
clearHashtag();
|
||||
|
||||
settings.callback();
|
||||
|
||||
doresize = true;
|
||||
|
||||
pp_open = false;
|
||||
|
||||
delete settings;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the proper sizes on the containers and animate the content in.
|
||||
*/
|
||||
function _showContent(){
|
||||
$('.pp_loaderIcon').hide();
|
||||
|
||||
// Calculate the opened top position of the pic holder
|
||||
projectedTop = scroll_pos['scrollTop'] + ((windowHeight/2) - (pp_dimensions['containerHeight']/2));
|
||||
if(projectedTop < 0) projectedTop = 0;
|
||||
|
||||
$ppt.fadeTo(settings.animation_speed,1);
|
||||
|
||||
// Resize the content holder
|
||||
$pp_pic_holder.find('.pp_content')
|
||||
.animate({
|
||||
height:pp_dimensions['contentHeight'],
|
||||
width:pp_dimensions['contentWidth']
|
||||
},settings.animation_speed);
|
||||
|
||||
// Resize picture the holder
|
||||
$pp_pic_holder.animate({
|
||||
'top': projectedTop,
|
||||
'left': ((windowWidth/2) - (pp_dimensions['containerWidth']/2) < 0) ? 0 : (windowWidth/2) - (pp_dimensions['containerWidth']/2),
|
||||
width:pp_dimensions['containerWidth']
|
||||
},settings.animation_speed,function(){
|
||||
$pp_pic_holder.find('.pp_hoverContainer,#fullResImage').height(pp_dimensions['height']).width(pp_dimensions['width']);
|
||||
|
||||
$pp_pic_holder.find('.pp_fade').fadeIn(settings.animation_speed); // Fade the new content
|
||||
|
||||
// Show the nav
|
||||
if(isSet && _getFileType(pp_images[set_position])=="image") { $pp_pic_holder.find('.pp_hoverContainer').show(); }else{ $pp_pic_holder.find('.pp_hoverContainer').hide(); }
|
||||
|
||||
if(settings.allow_expand) {
|
||||
if(pp_dimensions['resized']){ // Fade the resizing link if the image is resized
|
||||
$('a.pp_expand,a.pp_contract').show();
|
||||
}else{
|
||||
$('a.pp_expand').hide();
|
||||
}
|
||||
}
|
||||
|
||||
if(settings.autoplay_slideshow && !pp_slideshow && !pp_open) $.prettyPhoto.startSlideshow();
|
||||
|
||||
settings.changepicturecallback(); // Callback!
|
||||
|
||||
pp_open = true;
|
||||
});
|
||||
|
||||
_insert_gallery();
|
||||
pp_settings.ajaxcallback();
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide the content...DUH!
|
||||
*/
|
||||
function _hideContent(callback){
|
||||
// Fade out the current picture
|
||||
$pp_pic_holder.find('#pp_full_res object,#pp_full_res embed').css('visibility','hidden');
|
||||
$pp_pic_holder.find('.pp_fade').fadeOut(settings.animation_speed,function(){
|
||||
$('.pp_loaderIcon').show();
|
||||
|
||||
callback();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Check the item position in the gallery array, hide or show the navigation links
|
||||
* @param setCount {integer} The total number of items in the set
|
||||
*/
|
||||
function _checkPosition(setCount){
|
||||
(setCount > 1) ? $('.pp_nav').show() : $('.pp_nav').hide(); // Hide the bottom nav if it's not a set.
|
||||
};
|
||||
|
||||
/**
|
||||
* Resize the item dimensions if it's bigger than the viewport
|
||||
* @param width {integer} Width of the item to be opened
|
||||
* @param height {integer} Height of the item to be opened
|
||||
* @return An array containin the "fitted" dimensions
|
||||
*/
|
||||
function _fitToViewport(width,height){
|
||||
resized = false;
|
||||
|
||||
_getDimensions(width,height);
|
||||
|
||||
// Define them in case there's no resize needed
|
||||
imageWidth = width, imageHeight = height;
|
||||
|
||||
if( ((pp_containerWidth > windowWidth) || (pp_containerHeight > windowHeight)) && doresize && settings.allow_resize && !percentBased) {
|
||||
resized = true, fitting = false;
|
||||
|
||||
while (!fitting){
|
||||
if((pp_containerWidth > windowWidth)){
|
||||
imageWidth = (windowWidth - 200);
|
||||
imageHeight = (height/width) * imageWidth;
|
||||
}else if((pp_containerHeight > windowHeight)){
|
||||
imageHeight = (windowHeight - 200);
|
||||
imageWidth = (width/height) * imageHeight;
|
||||
}else{
|
||||
fitting = true;
|
||||
};
|
||||
|
||||
pp_containerHeight = imageHeight, pp_containerWidth = imageWidth;
|
||||
};
|
||||
|
||||
|
||||
|
||||
if((pp_containerWidth > windowWidth) || (pp_containerHeight > windowHeight)){
|
||||
_fitToViewport(pp_containerWidth,pp_containerHeight)
|
||||
};
|
||||
|
||||
_getDimensions(imageWidth,imageHeight);
|
||||
};
|
||||
|
||||
return {
|
||||
width:Math.floor(imageWidth),
|
||||
height:Math.floor(imageHeight),
|
||||
containerHeight:Math.floor(pp_containerHeight),
|
||||
containerWidth:Math.floor(pp_containerWidth) + (settings.horizontal_padding * 2),
|
||||
contentHeight:Math.floor(pp_contentHeight),
|
||||
contentWidth:Math.floor(pp_contentWidth),
|
||||
resized:resized
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the containers dimensions according to the item size
|
||||
* @param width {integer} Width of the item to be opened
|
||||
* @param height {integer} Height of the item to be opened
|
||||
*/
|
||||
function _getDimensions(width,height){
|
||||
width = parseFloat(width);
|
||||
height = parseFloat(height);
|
||||
|
||||
// Get the details height, to do so, I need to clone it since it's invisible
|
||||
$pp_details = $pp_pic_holder.find('.pp_details');
|
||||
$pp_details.width(width);
|
||||
detailsHeight = parseFloat($pp_details.css('marginTop')) + parseFloat($pp_details.css('marginBottom'));
|
||||
|
||||
$pp_details = $pp_details.clone().addClass(settings.theme).width(width).appendTo($('body')).css({
|
||||
'position':'absolute',
|
||||
'top':-10000
|
||||
});
|
||||
detailsHeight += $pp_details.height();
|
||||
detailsHeight = (detailsHeight <= 34) ? 36 : detailsHeight; // Min-height for the details
|
||||
$pp_details.remove();
|
||||
|
||||
// Get the titles height, to do so, I need to clone it since it's invisible
|
||||
$pp_title = $pp_pic_holder.find('.ppt');
|
||||
$pp_title.width(width);
|
||||
titleHeight = parseFloat($pp_title.css('marginTop')) + parseFloat($pp_title.css('marginBottom'));
|
||||
$pp_title = $pp_title.clone().appendTo($('body')).css({
|
||||
'position':'absolute',
|
||||
'top':-10000
|
||||
});
|
||||
titleHeight += $pp_title.height();
|
||||
$pp_title.remove();
|
||||
|
||||
// Get the container size, to resize the holder to the right dimensions
|
||||
pp_contentHeight = height + detailsHeight;
|
||||
pp_contentWidth = width;
|
||||
pp_containerHeight = pp_contentHeight + titleHeight + $pp_pic_holder.find('.pp_top').height() + $pp_pic_holder.find('.pp_bottom').height();
|
||||
pp_containerWidth = width;
|
||||
}
|
||||
|
||||
function _getFileType(itemSrc){
|
||||
if (itemSrc.match(/youtube\.com\/watch/i) || itemSrc.match(/youtu\.be/i)) {
|
||||
return 'youtube';
|
||||
}else if (itemSrc.match(/vimeo\.com/i)) {
|
||||
return 'vimeo';
|
||||
}else if(itemSrc.match(/\b.mov\b/i)){
|
||||
return 'quicktime';
|
||||
}else if(itemSrc.match(/\b.swf\b/i)){
|
||||
return 'flash';
|
||||
}else if(itemSrc.match(/\biframe=true\b/i)){
|
||||
return 'iframe';
|
||||
}else if(itemSrc.match(/\bajax=true\b/i)){
|
||||
return 'ajax';
|
||||
}else if(itemSrc.match(/\bcustom=true\b/i)){
|
||||
return 'custom';
|
||||
}else if(itemSrc.substr(0,1) == '#'){
|
||||
return 'inline';
|
||||
}else{
|
||||
return 'image';
|
||||
};
|
||||
};
|
||||
|
||||
function _center_overlay(){
|
||||
if(doresize && typeof $pp_pic_holder != 'undefined') {
|
||||
scroll_pos = _get_scroll();
|
||||
contentHeight = $pp_pic_holder.height(), contentwidth = $pp_pic_holder.width();
|
||||
|
||||
projectedTop = (windowHeight/2) + scroll_pos['scrollTop'] - (contentHeight/2);
|
||||
if(projectedTop < 0) projectedTop = 0;
|
||||
|
||||
if(contentHeight > windowHeight)
|
||||
return;
|
||||
|
||||
$pp_pic_holder.css({
|
||||
'top': projectedTop,
|
||||
'left': (windowWidth/2) + scroll_pos['scrollLeft'] - (contentwidth/2)
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
function _get_scroll(){
|
||||
if (self.pageYOffset) {
|
||||
return {scrollTop:self.pageYOffset,scrollLeft:self.pageXOffset};
|
||||
} else if (document.documentElement && document.documentElement.scrollTop) { // Explorer 6 Strict
|
||||
return {scrollTop:document.documentElement.scrollTop,scrollLeft:document.documentElement.scrollLeft};
|
||||
} else if (document.body) {// all other Explorers
|
||||
return {scrollTop:document.body.scrollTop,scrollLeft:document.body.scrollLeft};
|
||||
};
|
||||
};
|
||||
|
||||
function _resize_overlay() {
|
||||
windowHeight = $(window).height(), windowWidth = $(window).width();
|
||||
|
||||
if(typeof $pp_overlay != "undefined") $pp_overlay.height($(document).height()).width(windowWidth);
|
||||
};
|
||||
|
||||
function _insert_gallery(){
|
||||
if(isSet && settings.overlay_gallery && _getFileType(pp_images[set_position])=="image") {
|
||||
itemWidth = 52+5; // 52 beign the thumb width, 5 being the right margin.
|
||||
navWidth = (settings.theme == "facebook" || settings.theme == "pp_default") ? 50 : 30; // Define the arrow width depending on the theme
|
||||
|
||||
itemsPerPage = Math.floor((pp_dimensions['containerWidth'] - 100 - navWidth) / itemWidth);
|
||||
itemsPerPage = (itemsPerPage < pp_images.length) ? itemsPerPage : pp_images.length;
|
||||
totalPage = Math.ceil(pp_images.length / itemsPerPage) - 1;
|
||||
|
||||
// Hide the nav in the case there's no need for links
|
||||
if(totalPage == 0){
|
||||
navWidth = 0; // No nav means no width!
|
||||
$pp_gallery.find('.pp_arrow_next,.pp_arrow_previous').hide();
|
||||
}else{
|
||||
$pp_gallery.find('.pp_arrow_next,.pp_arrow_previous').show();
|
||||
};
|
||||
|
||||
galleryWidth = itemsPerPage * itemWidth;
|
||||
fullGalleryWidth = pp_images.length * itemWidth;
|
||||
|
||||
// Set the proper width to the gallery items
|
||||
$pp_gallery
|
||||
.css('margin-left',-((galleryWidth/2) + (navWidth/2)))
|
||||
.find('div:first').width(galleryWidth+5)
|
||||
.find('ul').width(fullGalleryWidth)
|
||||
.find('li.selected').removeClass('selected');
|
||||
|
||||
goToPage = (Math.floor(set_position/itemsPerPage) < totalPage) ? Math.floor(set_position/itemsPerPage) : totalPage;
|
||||
|
||||
$.prettyPhoto.changeGalleryPage(goToPage);
|
||||
|
||||
$pp_gallery_li.filter(':eq('+set_position+')').addClass('selected');
|
||||
}else{
|
||||
$pp_pic_holder.find('.pp_content').unbind('mouseenter mouseleave');
|
||||
// $pp_gallery.hide();
|
||||
}
|
||||
}
|
||||
|
||||
function _build_overlay(caller){
|
||||
// Inject Social Tool markup into General markup
|
||||
if(settings.social_tools)
|
||||
facebook_like_link = settings.social_tools.replace('{location_href}', encodeURIComponent(location.href));
|
||||
|
||||
settings.markup = settings.markup.replace('{pp_social}','');
|
||||
|
||||
$('body').append(settings.markup); // Inject the markup
|
||||
|
||||
$pp_pic_holder = $('.pp_pic_holder') , $ppt = $('.ppt'), $pp_overlay = $('div.pp_overlay'); // Set my global selectors
|
||||
|
||||
// Inject the inline gallery!
|
||||
if(isSet && settings.overlay_gallery) {
|
||||
currentGalleryPage = 0;
|
||||
toInject = "";
|
||||
for (var i=0; i < pp_images.length; i++) {
|
||||
if(!pp_images[i].match(/\b(jpg|jpeg|png|gif)\b/gi)){
|
||||
classname = 'default';
|
||||
img_src = '';
|
||||
}else{
|
||||
classname = '';
|
||||
img_src = pp_images[i];
|
||||
}
|
||||
toInject += "<li class='"+classname+"'><a href='#'><img src='" + img_src + "' width='50' alt='' /></a></li>";
|
||||
};
|
||||
|
||||
toInject = settings.gallery_markup.replace(/{gallery}/g,toInject);
|
||||
|
||||
$pp_pic_holder.find('#pp_full_res').after(toInject);
|
||||
|
||||
$pp_gallery = $('.pp_pic_holder .pp_gallery'), $pp_gallery_li = $pp_gallery.find('li'); // Set the gallery selectors
|
||||
|
||||
$pp_gallery.find('.pp_arrow_next').click(function(){
|
||||
$.prettyPhoto.changeGalleryPage('next');
|
||||
$.prettyPhoto.stopSlideshow();
|
||||
return false;
|
||||
});
|
||||
|
||||
$pp_gallery.find('.pp_arrow_previous').click(function(){
|
||||
$.prettyPhoto.changeGalleryPage('previous');
|
||||
$.prettyPhoto.stopSlideshow();
|
||||
return false;
|
||||
});
|
||||
|
||||
$pp_pic_holder.find('.pp_content').hover(
|
||||
function(){
|
||||
$pp_pic_holder.find('.pp_gallery:not(.disabled)').fadeIn();
|
||||
},
|
||||
function(){
|
||||
$pp_pic_holder.find('.pp_gallery:not(.disabled)').fadeOut();
|
||||
});
|
||||
|
||||
itemWidth = 52+5; // 52 beign the thumb width, 5 being the right margin.
|
||||
$pp_gallery_li.each(function(i){
|
||||
$(this)
|
||||
.find('a')
|
||||
.click(function(){
|
||||
$.prettyPhoto.changePage(i);
|
||||
$.prettyPhoto.stopSlideshow();
|
||||
return false;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// Inject the play/pause if it's a slideshow
|
||||
if(settings.slideshow){
|
||||
$pp_pic_holder.find('.pp_nav').prepend('<a href="#" class="pp_play">Play</a>')
|
||||
$pp_pic_holder.find('.pp_nav .pp_play').click(function(){
|
||||
$.prettyPhoto.startSlideshow();
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
$pp_pic_holder.attr('class','pp_pic_holder ' + settings.theme); // Set the proper theme
|
||||
|
||||
$pp_overlay
|
||||
.css({
|
||||
'opacity':0,
|
||||
'height':$(document).height(),
|
||||
'width':$(window).width()
|
||||
})
|
||||
.bind('click',function(){
|
||||
if(!settings.modal) $.prettyPhoto.close();
|
||||
});
|
||||
|
||||
$('a.pp_close').bind('click',function(){ $.prettyPhoto.close(); return false; });
|
||||
|
||||
|
||||
if(settings.allow_expand) {
|
||||
$('a.pp_expand').bind('click',function(e){
|
||||
// Expand the image
|
||||
if($(this).hasClass('pp_expand')){
|
||||
$(this).removeClass('pp_expand').addClass('pp_contract');
|
||||
doresize = false;
|
||||
}else{
|
||||
$(this).removeClass('pp_contract').addClass('pp_expand');
|
||||
doresize = true;
|
||||
};
|
||||
|
||||
_hideContent(function(){ $.prettyPhoto.open(); });
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
$pp_pic_holder.find('.pp_previous, .pp_nav .pp_arrow_previous').bind('click',function(){
|
||||
$.prettyPhoto.changePage('previous');
|
||||
$.prettyPhoto.stopSlideshow();
|
||||
return false;
|
||||
});
|
||||
|
||||
$pp_pic_holder.find('.pp_next, .pp_nav .pp_arrow_next').bind('click',function(){
|
||||
$.prettyPhoto.changePage('next');
|
||||
$.prettyPhoto.stopSlideshow();
|
||||
return false;
|
||||
});
|
||||
|
||||
_center_overlay(); // Center it
|
||||
};
|
||||
|
||||
if(!pp_alreadyInitialized && getHashtag()){
|
||||
pp_alreadyInitialized = true;
|
||||
|
||||
// Grab the rel index to trigger the click on the correct element
|
||||
hashIndex = getHashtag();
|
||||
hashRel = hashIndex;
|
||||
hashIndex = hashIndex.substring(hashIndex.indexOf('/')+1,hashIndex.length-1);
|
||||
hashRel = hashRel.substring(0,hashRel.indexOf('/'));
|
||||
|
||||
// Little timeout to make sure all the prettyPhoto initialize scripts has been run.
|
||||
// Useful in the event the page contain several init scripts.
|
||||
setTimeout(function(){ $("a["+pp_settings.hook+"^='"+hashRel+"']:eq("+hashIndex+")").trigger('click'); },50);
|
||||
}
|
||||
|
||||
return this.unbind('click.prettyphoto').bind('click.prettyphoto',$.prettyPhoto.initialize); // Return the jQuery object for chaining. The unbind method is used to avoid click conflict when the plugin is called more than once
|
||||
};
|
||||
|
||||
function getHashtag(){
|
||||
var url = location.href;
|
||||
hashtag = (url.indexOf('#prettyPhoto') !== -1) ? decodeURI(url.substring(url.indexOf('#prettyPhoto')+1,url.length)) : false;
|
||||
|
||||
return hashtag;
|
||||
};
|
||||
|
||||
function setHashtag(){
|
||||
if(typeof theRel == 'undefined') return; // theRel is set on normal calls, it's impossible to deeplink using the API
|
||||
location.hash = theRel + '/'+rel_index+'/';
|
||||
};
|
||||
|
||||
function clearHashtag(){
|
||||
if ( location.href.indexOf('#prettyPhoto') !== -1 ) location.hash = "prettyPhoto";
|
||||
}
|
||||
|
||||
function getParam(name,url){
|
||||
name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
|
||||
var regexS = "[\\?&]"+name+"=([^&#]*)";
|
||||
var regex = new RegExp( regexS );
|
||||
var results = regex.exec( url );
|
||||
return ( results == null ) ? "" : results[1];
|
||||
}
|
||||
|
||||
})(jQuery);
|
||||
|
||||
var pp_alreadyInitialized = false; // Used for the deep linking to make sure not to call the same function several times.
|
||||
905
dependency-check-core/src/test/resources/jquery.prettyPhoto_.js
Normal file
905
dependency-check-core/src/test/resources/jquery.prettyPhoto_.js
Normal file
@@ -0,0 +1,905 @@
|
||||
/* ------------------------------------------------------------------------
|
||||
Class: prettyPhoto
|
||||
Use: Lightbox clone for jQuery
|
||||
Author: Stephane Caron (http://www.no-margin-for-errors.com)
|
||||
Version: 3.1.3
|
||||
------------------------------------------------------------------------- */
|
||||
(function($) {
|
||||
$.prettyPhoto = {version: '3.1.3'};
|
||||
|
||||
$.fn.prettyPhoto = function(pp_settings) {
|
||||
pp_settings = jQuery.extend({
|
||||
animation_speed: 'fast', /* fast/slow/normal */
|
||||
slideshow: 5000, /* false OR interval time in ms */
|
||||
autoplay_slideshow: false, /* true/false */
|
||||
opacity: 0.80, /* Value between 0 and 1 */
|
||||
show_title: true, /* true/false */
|
||||
allow_resize: true, /* Resize the photos bigger than viewport. true/false */
|
||||
default_width: 500,
|
||||
default_height: 344,
|
||||
counter_separator_label: '/', /* The separator for the gallery counter 1 "of" 2 */
|
||||
theme: 'pp_default', /* light_rounded / dark_rounded / light_square / dark_square / facebook */
|
||||
horizontal_padding: 20, /* The padding on each side of the picture */
|
||||
hideflash: false, /* Hides all the flash object on a page, set to TRUE if flash appears over prettyPhoto */
|
||||
wmode: 'opaque', /* Set the flash wmode attribute */
|
||||
autoplay: true, /* Automatically start videos: True/False */
|
||||
modal: false, /* If set to true, only the close button will close the window */
|
||||
deeplinking: true, /* Allow prettyPhoto to update the url to enable deeplinking. */
|
||||
overlay_gallery: true, /* If set to true, a gallery will overlay the fullscreen image on mouse over */
|
||||
keyboard_shortcuts: true, /* Set to false if you open forms inside prettyPhoto */
|
||||
changepicturecallback: function(){}, /* Called everytime an item is shown/changed */
|
||||
callback: function(){}, /* Called when prettyPhoto is closed */
|
||||
ie6_fallback: true,
|
||||
markup: '<div class="pp_pic_holder"> \
|
||||
<div class="ppt"> </div> \
|
||||
<div class="pp_top"> \
|
||||
<div class="pp_left"></div> \
|
||||
<div class="pp_middle"></div> \
|
||||
<div class="pp_right"></div> \
|
||||
</div> \
|
||||
<div class="pp_content_container"> \
|
||||
<div class="pp_left"> \
|
||||
<div class="pp_right"> \
|
||||
<div class="pp_content"> \
|
||||
<div class="pp_loaderIcon"></div> \
|
||||
<div class="pp_fade"> \
|
||||
<a href="#" class="pp_expand" title="Expand the image">Expand</a> \
|
||||
<div class="pp_hoverContainer"> \
|
||||
<a class="pp_next" href="#">next</a> \
|
||||
<a class="pp_previous" href="#">previous</a> \
|
||||
</div> \
|
||||
<div id="pp_full_res"></div> \
|
||||
<div class="pp_details"> \
|
||||
<div class="pp_nav"> \
|
||||
<a href="#" class="pp_arrow_previous">Previous</a> \
|
||||
<p class="currentTextHolder">0/0</p> \
|
||||
<a href="#" class="pp_arrow_next">Next</a> \
|
||||
</div> \
|
||||
<p class="pp_description"></p> \
|
||||
<div class="pp_social">{pp_social}</div> \
|
||||
<a class="pp_close" href="#">Close</a> \
|
||||
</div> \
|
||||
</div> \
|
||||
</div> \
|
||||
</div> \
|
||||
</div> \
|
||||
</div> \
|
||||
<div class="pp_bottom"> \
|
||||
<div class="pp_left"></div> \
|
||||
<div class="pp_middle"></div> \
|
||||
<div class="pp_right"></div> \
|
||||
</div> \
|
||||
</div> \
|
||||
<div class="pp_overlay"></div>',
|
||||
gallery_markup: '<div class="pp_gallery"> \
|
||||
<a href="#" class="pp_arrow_previous">Previous</a> \
|
||||
<div> \
|
||||
<ul> \
|
||||
{gallery} \
|
||||
</ul> \
|
||||
</div> \
|
||||
<a href="#" class="pp_arrow_next">Next</a> \
|
||||
</div>',
|
||||
image_markup: '<img id="fullResImage" src="{path}" />',
|
||||
flash_markup: '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="{width}" height="{height}"><param name="wmode" value="{wmode}" /><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="{path}" /><embed src="{path}" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="{width}" height="{height}" wmode="{wmode}"></embed></object>',
|
||||
quicktime_markup: '<object classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" codebase="http://www.apple.com/qtactivex/qtplugin.cab" height="{height}" width="{width}"><param name="src" value="{path}"><param name="autoplay" value="{autoplay}"><param name="type" value="video/quicktime"><embed src="{path}" height="{height}" width="{width}" autoplay="{autoplay}" type="video/quicktime" pluginspage="http://www.apple.com/quicktime/download/"></embed></object>',
|
||||
iframe_markup: '<iframe src ="{path}" width="{width}" height="{height}" frameborder="no"></iframe>',
|
||||
inline_markup: '<div class="pp_inline">{content}</div>',
|
||||
custom_markup: '',
|
||||
social_tools: '<div class="twitter"><a href="http://twitter.com/share" class="twitter-share-button" data-count="none">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div><div class="facebook"><iframe src="http://www.facebook.com/plugins/like.php?locale=en_US&href={location_href}&layout=button_count&show_faces=true&width=500&action=like&font&colorscheme=light&height=23" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:500px; height:23px;" allowTransparency="true"></iframe></div>' /* html or false to disable */
|
||||
}, pp_settings);
|
||||
|
||||
// Global variables accessible only by prettyPhoto
|
||||
var matchedObjects = this, percentBased = false, pp_dimensions, pp_open,
|
||||
|
||||
// prettyPhoto container specific
|
||||
pp_contentHeight, pp_contentWidth, pp_containerHeight, pp_containerWidth,
|
||||
|
||||
// Window size
|
||||
windowHeight = $(window).height(), windowWidth = $(window).width(),
|
||||
|
||||
// Global elements
|
||||
pp_slideshow;
|
||||
|
||||
doresize = true, scroll_pos = _get_scroll();
|
||||
|
||||
// Window/Keyboard events
|
||||
$(window).unbind('resize.prettyphoto').bind('resize.prettyphoto',function(){ _center_overlay(); _resize_overlay(); });
|
||||
|
||||
if(pp_settings.keyboard_shortcuts) {
|
||||
$(document).unbind('keydown.prettyphoto').bind('keydown.prettyphoto',function(e){
|
||||
if(typeof $pp_pic_holder != 'undefined'){
|
||||
if($pp_pic_holder.is(':visible')){
|
||||
switch(e.keyCode){
|
||||
case 37:
|
||||
$.prettyPhoto.changePage('previous');
|
||||
e.preventDefault();
|
||||
break;
|
||||
case 39:
|
||||
$.prettyPhoto.changePage('next');
|
||||
e.preventDefault();
|
||||
break;
|
||||
case 27:
|
||||
if(!settings.modal)
|
||||
$.prettyPhoto.close();
|
||||
e.preventDefault();
|
||||
break;
|
||||
};
|
||||
// return false;
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize prettyPhoto.
|
||||
*/
|
||||
$.prettyPhoto.initialize = function() {
|
||||
|
||||
settings = pp_settings;
|
||||
|
||||
if(settings.theme == 'pp_default') settings.horizontal_padding = 16;
|
||||
if(settings.ie6_fallback && $.browser.msie && parseInt($.browser.version) == 6) settings.theme = "light_square"; // Fallback to a supported theme for IE6
|
||||
|
||||
// Find out if the picture is part of a set
|
||||
theRel = $(this).attr('rel');
|
||||
galleryRegExp = /\[(?:.*)\]/;
|
||||
isSet = (galleryRegExp.exec(theRel)) ? true : false;
|
||||
|
||||
// Put the SRCs, TITLEs, ALTs into an array.
|
||||
pp_images = (isSet) ? jQuery.map(matchedObjects, function(n, i){ if($(n).attr('rel').indexOf(theRel) != -1) return $(n).attr('href'); }) : $.makeArray($(this).attr('href'));
|
||||
pp_titles = (isSet) ? jQuery.map(matchedObjects, function(n, i){ if($(n).attr('rel').indexOf(theRel) != -1) return ($(n).find('img').attr('alt')) ? $(n).find('img').attr('alt') : ""; }) : $.makeArray($(this).find('img').attr('alt'));
|
||||
pp_descriptions = (isSet) ? jQuery.map(matchedObjects, function(n, i){ if($(n).attr('rel').indexOf(theRel) != -1) return ($(n).attr('title')) ? $(n).attr('title') : ""; }) : $.makeArray($(this).attr('title'));
|
||||
|
||||
if(pp_images.length > 30) settings.overlay_gallery = false;
|
||||
|
||||
set_position = jQuery.inArray($(this).attr('href'), pp_images); // Define where in the array the clicked item is positionned
|
||||
rel_index = (isSet) ? set_position : $("a[rel^='"+theRel+"']").index($(this));
|
||||
|
||||
_build_overlay(this); // Build the overlay {this} being the caller
|
||||
|
||||
if(settings.allow_resize)
|
||||
$(window).bind('scroll.prettyphoto',function(){ _center_overlay(); });
|
||||
|
||||
|
||||
$.prettyPhoto.open();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Opens the prettyPhoto modal box.
|
||||
* @param image {String,Array} Full path to the image to be open, can also be an array containing full images paths.
|
||||
* @param title {String,Array} The title to be displayed with the picture, can also be an array containing all the titles.
|
||||
* @param description {String,Array} The description to be displayed with the picture, can also be an array containing all the descriptions.
|
||||
*/
|
||||
$.prettyPhoto.open = function(event) {
|
||||
if(typeof settings == "undefined"){ // Means it's an API call, need to manually get the settings and set the variables
|
||||
settings = pp_settings;
|
||||
if($.browser.msie && $.browser.version == 6) settings.theme = "light_square"; // Fallback to a supported theme for IE6
|
||||
pp_images = $.makeArray(arguments[0]);
|
||||
pp_titles = (arguments[1]) ? $.makeArray(arguments[1]) : $.makeArray("");
|
||||
pp_descriptions = (arguments[2]) ? $.makeArray(arguments[2]) : $.makeArray("");
|
||||
isSet = (pp_images.length > 1) ? true : false;
|
||||
set_position = 0;
|
||||
_build_overlay(event.target); // Build the overlay {this} being the caller
|
||||
}
|
||||
|
||||
if($.browser.msie && $.browser.version == 6) $('select').css('visibility','hidden'); // To fix the bug with IE select boxes
|
||||
|
||||
if(settings.hideflash) $('object,embed,iframe[src*=youtube],iframe[src*=vimeo]').css('visibility','hidden'); // Hide the flash
|
||||
|
||||
_checkPosition($(pp_images).size()); // Hide the next/previous links if on first or last images.
|
||||
|
||||
$('.pp_loaderIcon').show();
|
||||
|
||||
if(settings.deeplinking)
|
||||
setHashtag();
|
||||
|
||||
// Rebuild Facebook Like Button with updated href
|
||||
if(settings.social_tools){
|
||||
facebook_like_link = settings.social_tools.replace('{location_href}', encodeURIComponent(location.href));
|
||||
$pp_pic_holder.find('.pp_social').html(facebook_like_link);
|
||||
}
|
||||
|
||||
// Fade the content in
|
||||
if($ppt.is(':hidden')) $ppt.css('opacity',0).show();
|
||||
$pp_overlay.show().fadeTo(settings.animation_speed,settings.opacity);
|
||||
|
||||
// Display the current position
|
||||
$pp_pic_holder.find('.currentTextHolder').text((set_position+1) + settings.counter_separator_label + $(pp_images).size());
|
||||
|
||||
// Set the description
|
||||
if(pp_descriptions[set_position] != ""){
|
||||
$pp_pic_holder.find('.pp_description').show().html(unescape(pp_descriptions[set_position]));
|
||||
}else{
|
||||
$pp_pic_holder.find('.pp_description').hide();
|
||||
}
|
||||
|
||||
// Get the dimensions
|
||||
movie_width = ( parseFloat(getParam('width',pp_images[set_position])) ) ? getParam('width',pp_images[set_position]) : settings.default_width.toString();
|
||||
movie_height = ( parseFloat(getParam('height',pp_images[set_position])) ) ? getParam('height',pp_images[set_position]) : settings.default_height.toString();
|
||||
|
||||
// If the size is % based, calculate according to window dimensions
|
||||
percentBased=false;
|
||||
if(movie_height.indexOf('%') != -1) { movie_height = parseFloat(($(window).height() * parseFloat(movie_height) / 100) - 150); percentBased = true; }
|
||||
if(movie_width.indexOf('%') != -1) { movie_width = parseFloat(($(window).width() * parseFloat(movie_width) / 100) - 150); percentBased = true; }
|
||||
|
||||
// Fade the holder
|
||||
$pp_pic_holder.fadeIn(function(){
|
||||
// Set the title
|
||||
(settings.show_title && pp_titles[set_position] != "" && typeof pp_titles[set_position] != "undefined") ? $ppt.html(unescape(pp_titles[set_position])) : $ppt.html(' ');
|
||||
|
||||
imgPreloader = "";
|
||||
skipInjection = false;
|
||||
|
||||
// Inject the proper content
|
||||
switch(_getFileType(pp_images[set_position])){
|
||||
case 'image':
|
||||
imgPreloader = new Image();
|
||||
|
||||
// Preload the neighbour images
|
||||
nextImage = new Image();
|
||||
if(isSet && set_position < $(pp_images).size() -1) nextImage.src = pp_images[set_position + 1];
|
||||
prevImage = new Image();
|
||||
if(isSet && pp_images[set_position - 1]) prevImage.src = pp_images[set_position - 1];
|
||||
|
||||
$pp_pic_holder.find('#pp_full_res')[0].innerHTML = settings.image_markup.replace(/{path}/g,pp_images[set_position]);
|
||||
|
||||
imgPreloader.onload = function(){
|
||||
// Fit item to viewport
|
||||
pp_dimensions = _fitToViewport(imgPreloader.width,imgPreloader.height);
|
||||
|
||||
_showContent();
|
||||
};
|
||||
|
||||
imgPreloader.onerror = function(){
|
||||
alert('Image cannot be loaded. Make sure the path is correct and image exist.');
|
||||
$.prettyPhoto.close();
|
||||
};
|
||||
|
||||
imgPreloader.src = pp_images[set_position];
|
||||
break;
|
||||
|
||||
case 'youtube':
|
||||
pp_dimensions = _fitToViewport(movie_width,movie_height); // Fit item to viewport
|
||||
|
||||
// Regular youtube link
|
||||
movie_id = getParam('v',pp_images[set_position]);
|
||||
|
||||
// youtu.be link
|
||||
if(movie_id == ""){
|
||||
movie_id = pp_images[set_position].split('youtu.be/');
|
||||
movie_id = movie_id[1];
|
||||
if(movie_id.indexOf('?') > 0)
|
||||
movie_id = movie_id.substr(0,movie_id.indexOf('?')); // Strip anything after the ?
|
||||
|
||||
if(movie_id.indexOf('&') > 0)
|
||||
movie_id = movie_id.substr(0,movie_id.indexOf('&')); // Strip anything after the &
|
||||
}
|
||||
|
||||
movie = 'http://www.youtube.com/embed/'+movie_id;
|
||||
(getParam('rel',pp_images[set_position])) ? movie+="?rel="+getParam('rel',pp_images[set_position]) : movie+="?rel=1";
|
||||
|
||||
if(settings.autoplay) movie += "&autoplay=1";
|
||||
|
||||
toInject = settings.iframe_markup.replace(/{width}/g,pp_dimensions['width']).replace(/{height}/g,pp_dimensions['height']).replace(/{wmode}/g,settings.wmode).replace(/{path}/g,movie);
|
||||
break;
|
||||
|
||||
case 'vimeo':
|
||||
pp_dimensions = _fitToViewport(movie_width,movie_height); // Fit item to viewport
|
||||
|
||||
movie_id = pp_images[set_position];
|
||||
var regExp = /http:\/\/(www\.)?vimeo.com\/(\d+)/;
|
||||
var match = movie_id.match(regExp);
|
||||
|
||||
movie = 'http://player.vimeo.com/video/'+ match[2] +'?title=0&byline=0&portrait=0';
|
||||
if(settings.autoplay) movie += "&autoplay=1;";
|
||||
|
||||
vimeo_width = pp_dimensions['width'] + '/embed/?moog_width='+ pp_dimensions['width'];
|
||||
|
||||
toInject = settings.iframe_markup.replace(/{width}/g,vimeo_width).replace(/{height}/g,pp_dimensions['height']).replace(/{path}/g,movie);
|
||||
break;
|
||||
|
||||
case 'quicktime':
|
||||
pp_dimensions = _fitToViewport(movie_width,movie_height); // Fit item to viewport
|
||||
pp_dimensions['height']+=15; pp_dimensions['contentHeight']+=15; pp_dimensions['containerHeight']+=15; // Add space for the control bar
|
||||
|
||||
toInject = settings.quicktime_markup.replace(/{width}/g,pp_dimensions['width']).replace(/{height}/g,pp_dimensions['height']).replace(/{wmode}/g,settings.wmode).replace(/{path}/g,pp_images[set_position]).replace(/{autoplay}/g,settings.autoplay);
|
||||
break;
|
||||
|
||||
case 'flash':
|
||||
pp_dimensions = _fitToViewport(movie_width,movie_height); // Fit item to viewport
|
||||
|
||||
flash_vars = pp_images[set_position];
|
||||
flash_vars = flash_vars.substring(pp_images[set_position].indexOf('flashvars') + 10,pp_images[set_position].length);
|
||||
|
||||
filename = pp_images[set_position];
|
||||
filename = filename.substring(0,filename.indexOf('?'));
|
||||
|
||||
toInject = settings.flash_markup.replace(/{width}/g,pp_dimensions['width']).replace(/{height}/g,pp_dimensions['height']).replace(/{wmode}/g,settings.wmode).replace(/{path}/g,filename+'?'+flash_vars);
|
||||
break;
|
||||
|
||||
case 'iframe':
|
||||
pp_dimensions = _fitToViewport(movie_width,movie_height); // Fit item to viewport
|
||||
|
||||
frame_url = pp_images[set_position];
|
||||
frame_url = frame_url.substr(0,frame_url.indexOf('iframe')-1);
|
||||
|
||||
toInject = settings.iframe_markup.replace(/{width}/g,pp_dimensions['width']).replace(/{height}/g,pp_dimensions['height']).replace(/{path}/g,frame_url);
|
||||
break;
|
||||
|
||||
case 'ajax':
|
||||
doresize = false; // Make sure the dimensions are not resized.
|
||||
pp_dimensions = _fitToViewport(movie_width,movie_height);
|
||||
doresize = true; // Reset the dimensions
|
||||
|
||||
skipInjection = true;
|
||||
$.get(pp_images[set_position],function(responseHTML){
|
||||
toInject = settings.inline_markup.replace(/{content}/g,responseHTML);
|
||||
$pp_pic_holder.find('#pp_full_res')[0].innerHTML = toInject;
|
||||
_showContent();
|
||||
});
|
||||
|
||||
break;
|
||||
|
||||
case 'custom':
|
||||
pp_dimensions = _fitToViewport(movie_width,movie_height); // Fit item to viewport
|
||||
|
||||
toInject = settings.custom_markup;
|
||||
break;
|
||||
|
||||
case 'inline':
|
||||
// to get the item height clone it, apply default width, wrap it in the prettyPhoto containers , then delete
|
||||
myClone = $(pp_images[set_position]).clone().append('<br clear="all" />').css({'width':settings.default_width}).wrapInner('<div id="pp_full_res"><div class="pp_inline"></div></div>').appendTo($('body')).show();
|
||||
doresize = false; // Make sure the dimensions are not resized.
|
||||
pp_dimensions = _fitToViewport($(myClone).width(),$(myClone).height());
|
||||
doresize = true; // Reset the dimensions
|
||||
$(myClone).remove();
|
||||
toInject = settings.inline_markup.replace(/{content}/g,$(pp_images[set_position]).html());
|
||||
break;
|
||||
};
|
||||
|
||||
if(!imgPreloader && !skipInjection){
|
||||
$pp_pic_holder.find('#pp_full_res')[0].innerHTML = toInject;
|
||||
|
||||
// Show content
|
||||
_showContent();
|
||||
};
|
||||
});
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Change page in the prettyPhoto modal box
|
||||
* @param direction {String} Direction of the paging, previous or next.
|
||||
*/
|
||||
$.prettyPhoto.changePage = function(direction){
|
||||
currentGalleryPage = 0;
|
||||
|
||||
if(direction == 'previous') {
|
||||
set_position--;
|
||||
if (set_position < 0) set_position = $(pp_images).size()-1;
|
||||
}else if(direction == 'next'){
|
||||
set_position++;
|
||||
if(set_position > $(pp_images).size()-1) set_position = 0;
|
||||
}else{
|
||||
set_position=direction;
|
||||
};
|
||||
|
||||
rel_index = set_position;
|
||||
|
||||
if(!doresize) doresize = true; // Allow the resizing of the images
|
||||
$('.pp_contract').removeClass('pp_contract').addClass('pp_expand');
|
||||
|
||||
_hideContent(function(){ $.prettyPhoto.open(); });
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Change gallery page in the prettyPhoto modal box
|
||||
* @param direction {String} Direction of the paging, previous or next.
|
||||
*/
|
||||
$.prettyPhoto.changeGalleryPage = function(direction){
|
||||
if(direction=='next'){
|
||||
currentGalleryPage ++;
|
||||
|
||||
if(currentGalleryPage > totalPage) currentGalleryPage = 0;
|
||||
}else if(direction=='previous'){
|
||||
currentGalleryPage --;
|
||||
|
||||
if(currentGalleryPage < 0) currentGalleryPage = totalPage;
|
||||
}else{
|
||||
currentGalleryPage = direction;
|
||||
};
|
||||
|
||||
slide_speed = (direction == 'next' || direction == 'previous') ? settings.animation_speed : 0;
|
||||
|
||||
slide_to = currentGalleryPage * (itemsPerPage * itemWidth);
|
||||
|
||||
$pp_gallery.find('ul').animate({left:-slide_to},slide_speed);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Start the slideshow...
|
||||
*/
|
||||
$.prettyPhoto.startSlideshow = function(){
|
||||
if(typeof pp_slideshow == 'undefined'){
|
||||
$pp_pic_holder.find('.pp_play').unbind('click').removeClass('pp_play').addClass('pp_pause').click(function(){
|
||||
$.prettyPhoto.stopSlideshow();
|
||||
return false;
|
||||
});
|
||||
pp_slideshow = setInterval($.prettyPhoto.startSlideshow,settings.slideshow);
|
||||
}else{
|
||||
$.prettyPhoto.changePage('next');
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Stop the slideshow...
|
||||
*/
|
||||
$.prettyPhoto.stopSlideshow = function(){
|
||||
$pp_pic_holder.find('.pp_pause').unbind('click').removeClass('pp_pause').addClass('pp_play').click(function(){
|
||||
$.prettyPhoto.startSlideshow();
|
||||
return false;
|
||||
});
|
||||
clearInterval(pp_slideshow);
|
||||
pp_slideshow=undefined;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Closes prettyPhoto.
|
||||
*/
|
||||
$.prettyPhoto.close = function(){
|
||||
if($pp_overlay.is(":animated")) return;
|
||||
|
||||
$.prettyPhoto.stopSlideshow();
|
||||
|
||||
$pp_pic_holder.stop().find('object,embed').css('visibility','hidden');
|
||||
|
||||
$('div.pp_pic_holder,div.ppt,.pp_fade').fadeOut(settings.animation_speed,function(){ $(this).remove(); });
|
||||
|
||||
$pp_overlay.fadeOut(settings.animation_speed, function(){
|
||||
if($.browser.msie && $.browser.version == 6) $('select').css('visibility','visible'); // To fix the bug with IE select boxes
|
||||
|
||||
if(settings.hideflash) $('object,embed,iframe[src*=youtube],iframe[src*=vimeo]').css('visibility','visible'); // Show the flash
|
||||
|
||||
$(this).remove(); // No more need for the prettyPhoto markup
|
||||
|
||||
$(window).unbind('scroll.prettyphoto');
|
||||
|
||||
clearHashtag();
|
||||
|
||||
settings.callback();
|
||||
|
||||
doresize = true;
|
||||
|
||||
pp_open = false;
|
||||
|
||||
delete settings;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the proper sizes on the containers and animate the content in.
|
||||
*/
|
||||
function _showContent(){
|
||||
$('.pp_loaderIcon').hide();
|
||||
|
||||
// Calculate the opened top position of the pic holder
|
||||
projectedTop = scroll_pos['scrollTop'] + ((windowHeight/2) - (pp_dimensions['containerHeight']/2));
|
||||
if(projectedTop < 0) projectedTop = 0;
|
||||
|
||||
$ppt.fadeTo(settings.animation_speed,1);
|
||||
|
||||
// Resize the content holder
|
||||
$pp_pic_holder.find('.pp_content')
|
||||
.animate({
|
||||
height:pp_dimensions['contentHeight'],
|
||||
width:pp_dimensions['contentWidth']
|
||||
},settings.animation_speed);
|
||||
|
||||
// Resize picture the holder
|
||||
$pp_pic_holder.animate({
|
||||
'top': projectedTop,
|
||||
'left': (windowWidth/2) - (pp_dimensions['containerWidth']/2),
|
||||
width:pp_dimensions['containerWidth']
|
||||
},settings.animation_speed,function(){
|
||||
$pp_pic_holder.find('.pp_hoverContainer,#fullResImage').height(pp_dimensions['height']).width(pp_dimensions['width']);
|
||||
|
||||
$pp_pic_holder.find('.pp_fade').fadeIn(settings.animation_speed); // Fade the new content
|
||||
|
||||
// Show the nav
|
||||
if(isSet && _getFileType(pp_images[set_position])=="image") { $pp_pic_holder.find('.pp_hoverContainer').show(); }else{ $pp_pic_holder.find('.pp_hoverContainer').hide(); }
|
||||
|
||||
if(pp_dimensions['resized']){ // Fade the resizing link if the image is resized
|
||||
$('a.pp_expand,a.pp_contract').show();
|
||||
}else{
|
||||
$('a.pp_expand').hide();
|
||||
}
|
||||
|
||||
if(settings.autoplay_slideshow && !pp_slideshow && !pp_open) $.prettyPhoto.startSlideshow();
|
||||
|
||||
settings.changepicturecallback(); // Callback!
|
||||
|
||||
pp_open = true;
|
||||
});
|
||||
|
||||
_insert_gallery();
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide the content...DUH!
|
||||
*/
|
||||
function _hideContent(callback){
|
||||
// Fade out the current picture
|
||||
$pp_pic_holder.find('#pp_full_res object,#pp_full_res embed').css('visibility','hidden');
|
||||
$pp_pic_holder.find('.pp_fade').fadeOut(settings.animation_speed,function(){
|
||||
$('.pp_loaderIcon').show();
|
||||
|
||||
callback();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Check the item position in the gallery array, hide or show the navigation links
|
||||
* @param setCount {integer} The total number of items in the set
|
||||
*/
|
||||
function _checkPosition(setCount){
|
||||
(setCount > 1) ? $('.pp_nav').show() : $('.pp_nav').hide(); // Hide the bottom nav if it's not a set.
|
||||
};
|
||||
|
||||
/**
|
||||
* Resize the item dimensions if it's bigger than the viewport
|
||||
* @param width {integer} Width of the item to be opened
|
||||
* @param height {integer} Height of the item to be opened
|
||||
* @return An array containin the "fitted" dimensions
|
||||
*/
|
||||
function _fitToViewport(width,height){
|
||||
resized = false;
|
||||
|
||||
_getDimensions(width,height);
|
||||
|
||||
// Define them in case there's no resize needed
|
||||
imageWidth = width, imageHeight = height;
|
||||
|
||||
if( ((pp_containerWidth > windowWidth) || (pp_containerHeight > windowHeight)) && doresize && settings.allow_resize && !percentBased) {
|
||||
resized = true, fitting = false;
|
||||
|
||||
while (!fitting){
|
||||
if((pp_containerWidth > windowWidth)){
|
||||
imageWidth = (windowWidth - 200);
|
||||
imageHeight = (height/width) * imageWidth;
|
||||
}else if((pp_containerHeight > windowHeight)){
|
||||
imageHeight = (windowHeight - 200);
|
||||
imageWidth = (width/height) * imageHeight;
|
||||
}else{
|
||||
fitting = true;
|
||||
};
|
||||
|
||||
pp_containerHeight = imageHeight, pp_containerWidth = imageWidth;
|
||||
};
|
||||
|
||||
_getDimensions(imageWidth,imageHeight);
|
||||
|
||||
if((pp_containerWidth > windowWidth) || (pp_containerHeight > windowHeight)){
|
||||
_fitToViewport(pp_containerWidth,pp_containerHeight)
|
||||
};
|
||||
};
|
||||
|
||||
return {
|
||||
width:Math.floor(imageWidth),
|
||||
height:Math.floor(imageHeight),
|
||||
containerHeight:Math.floor(pp_containerHeight),
|
||||
containerWidth:Math.floor(pp_containerWidth) + (settings.horizontal_padding * 2),
|
||||
contentHeight:Math.floor(pp_contentHeight),
|
||||
contentWidth:Math.floor(pp_contentWidth),
|
||||
resized:resized
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the containers dimensions according to the item size
|
||||
* @param width {integer} Width of the item to be opened
|
||||
* @param height {integer} Height of the item to be opened
|
||||
*/
|
||||
function _getDimensions(width,height){
|
||||
width = parseFloat(width);
|
||||
height = parseFloat(height);
|
||||
|
||||
// Get the details height, to do so, I need to clone it since it's invisible
|
||||
$pp_details = $pp_pic_holder.find('.pp_details');
|
||||
$pp_details.width(width);
|
||||
detailsHeight = parseFloat($pp_details.css('marginTop')) + parseFloat($pp_details.css('marginBottom'));
|
||||
|
||||
$pp_details = $pp_details.clone().addClass(settings.theme).width(width).appendTo($('body')).css({
|
||||
'position':'absolute',
|
||||
'top':-10000
|
||||
});
|
||||
detailsHeight += $pp_details.height();
|
||||
detailsHeight = (detailsHeight <= 34) ? 36 : detailsHeight; // Min-height for the details
|
||||
if($.browser.msie && $.browser.version==7) detailsHeight+=8;
|
||||
$pp_details.remove();
|
||||
|
||||
// Get the titles height, to do so, I need to clone it since it's invisible
|
||||
$pp_title = $pp_pic_holder.find('.ppt');
|
||||
$pp_title.width(width);
|
||||
titleHeight = parseFloat($pp_title.css('marginTop')) + parseFloat($pp_title.css('marginBottom'));
|
||||
$pp_title = $pp_title.clone().appendTo($('body')).css({
|
||||
'position':'absolute',
|
||||
'top':-10000
|
||||
});
|
||||
titleHeight += $pp_title.height();
|
||||
$pp_title.remove();
|
||||
|
||||
// Get the container size, to resize the holder to the right dimensions
|
||||
pp_contentHeight = height + detailsHeight;
|
||||
pp_contentWidth = width;
|
||||
pp_containerHeight = pp_contentHeight + titleHeight + $pp_pic_holder.find('.pp_top').height() + $pp_pic_holder.find('.pp_bottom').height();
|
||||
pp_containerWidth = width;
|
||||
}
|
||||
|
||||
function _getFileType(itemSrc){
|
||||
if (itemSrc.match(/youtube\.com\/watch/i) || itemSrc.match(/youtu\.be/i)) {
|
||||
return 'youtube';
|
||||
}else if (itemSrc.match(/vimeo\.com/i)) {
|
||||
return 'vimeo';
|
||||
}else if(itemSrc.match(/\b.mov\b/i)){
|
||||
return 'quicktime';
|
||||
}else if(itemSrc.match(/\b.swf\b/i)){
|
||||
return 'flash';
|
||||
}else if(itemSrc.match(/\biframe=true\b/i)){
|
||||
return 'iframe';
|
||||
}else if(itemSrc.match(/\bajax=true\b/i)){
|
||||
return 'ajax';
|
||||
}else if(itemSrc.match(/\bcustom=true\b/i)){
|
||||
return 'custom';
|
||||
}else if(itemSrc.substr(0,1) == '#'){
|
||||
return 'inline';
|
||||
}else{
|
||||
return 'image';
|
||||
};
|
||||
};
|
||||
|
||||
function _center_overlay(){
|
||||
if(doresize && typeof $pp_pic_holder != 'undefined') {
|
||||
scroll_pos = _get_scroll();
|
||||
contentHeight = $pp_pic_holder.height(), contentwidth = $pp_pic_holder.width();
|
||||
|
||||
projectedTop = (windowHeight/2) + scroll_pos['scrollTop'] - (contentHeight/2);
|
||||
if(projectedTop < 0) projectedTop = 0;
|
||||
|
||||
if(contentHeight > windowHeight)
|
||||
return;
|
||||
|
||||
$pp_pic_holder.css({
|
||||
'top': projectedTop,
|
||||
'left': (windowWidth/2) + scroll_pos['scrollLeft'] - (contentwidth/2)
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
function _get_scroll(){
|
||||
if (self.pageYOffset) {
|
||||
return {scrollTop:self.pageYOffset,scrollLeft:self.pageXOffset};
|
||||
} else if (document.documentElement && document.documentElement.scrollTop) { // Explorer 6 Strict
|
||||
return {scrollTop:document.documentElement.scrollTop,scrollLeft:document.documentElement.scrollLeft};
|
||||
} else if (document.body) {// all other Explorers
|
||||
return {scrollTop:document.body.scrollTop,scrollLeft:document.body.scrollLeft};
|
||||
};
|
||||
};
|
||||
|
||||
function _resize_overlay() {
|
||||
windowHeight = $(window).height(), windowWidth = $(window).width();
|
||||
|
||||
if(typeof $pp_overlay != "undefined") $pp_overlay.height($(document).height()).width(windowWidth);
|
||||
};
|
||||
|
||||
function _insert_gallery(){
|
||||
if(isSet && settings.overlay_gallery && _getFileType(pp_images[set_position])=="image" && (settings.ie6_fallback && !($.browser.msie && parseInt($.browser.version) == 6))) {
|
||||
itemWidth = 52+5; // 52 beign the thumb width, 5 being the right margin.
|
||||
navWidth = (settings.theme == "facebook" || settings.theme == "pp_default") ? 50 : 30; // Define the arrow width depending on the theme
|
||||
|
||||
itemsPerPage = Math.floor((pp_dimensions['containerWidth'] - 100 - navWidth) / itemWidth);
|
||||
itemsPerPage = (itemsPerPage < pp_images.length) ? itemsPerPage : pp_images.length;
|
||||
totalPage = Math.ceil(pp_images.length / itemsPerPage) - 1;
|
||||
|
||||
// Hide the nav in the case there's no need for links
|
||||
if(totalPage == 0){
|
||||
navWidth = 0; // No nav means no width!
|
||||
$pp_gallery.find('.pp_arrow_next,.pp_arrow_previous').hide();
|
||||
}else{
|
||||
$pp_gallery.find('.pp_arrow_next,.pp_arrow_previous').show();
|
||||
};
|
||||
|
||||
galleryWidth = itemsPerPage * itemWidth;
|
||||
fullGalleryWidth = pp_images.length * itemWidth;
|
||||
|
||||
// Set the proper width to the gallery items
|
||||
$pp_gallery
|
||||
.css('margin-left',-((galleryWidth/2) + (navWidth/2)))
|
||||
.find('div:first').width(galleryWidth+5)
|
||||
.find('ul').width(fullGalleryWidth)
|
||||
.find('li.selected').removeClass('selected');
|
||||
|
||||
goToPage = (Math.floor(set_position/itemsPerPage) < totalPage) ? Math.floor(set_position/itemsPerPage) : totalPage;
|
||||
|
||||
$.prettyPhoto.changeGalleryPage(goToPage);
|
||||
|
||||
$pp_gallery_li.filter(':eq('+set_position+')').addClass('selected');
|
||||
}else{
|
||||
$pp_pic_holder.find('.pp_content').unbind('mouseenter mouseleave');
|
||||
// $pp_gallery.hide();
|
||||
}
|
||||
}
|
||||
|
||||
function _build_overlay(caller){
|
||||
// Inject Social Tool markup into General markup
|
||||
if(settings.social_tools)
|
||||
facebook_like_link = settings.social_tools.replace('{location_href}', encodeURIComponent(location.href));
|
||||
|
||||
settings.markup=settings.markup.replace('{pp_social}',(settings.social_tools)?facebook_like_link:'');
|
||||
|
||||
$('body').append(settings.markup); // Inject the markup
|
||||
|
||||
$pp_pic_holder = $('.pp_pic_holder') , $ppt = $('.ppt'), $pp_overlay = $('div.pp_overlay'); // Set my global selectors
|
||||
|
||||
// Inject the inline gallery!
|
||||
if(isSet && settings.overlay_gallery) {
|
||||
currentGalleryPage = 0;
|
||||
toInject = "";
|
||||
for (var i=0; i < pp_images.length; i++) {
|
||||
if(!pp_images[i].match(/\b(jpg|jpeg|png|gif)\b/gi)){
|
||||
classname = 'default';
|
||||
img_src = '';
|
||||
}else{
|
||||
classname = '';
|
||||
img_src = pp_images[i];
|
||||
}
|
||||
toInject += "<li class='"+classname+"'><a href='#'><img src='" + img_src + "' width='50' alt='' /></a></li>";
|
||||
};
|
||||
|
||||
toInject = settings.gallery_markup.replace(/{gallery}/g,toInject);
|
||||
|
||||
$pp_pic_holder.find('#pp_full_res').after(toInject);
|
||||
|
||||
$pp_gallery = $('.pp_pic_holder .pp_gallery'), $pp_gallery_li = $pp_gallery.find('li'); // Set the gallery selectors
|
||||
|
||||
$pp_gallery.find('.pp_arrow_next').click(function(){
|
||||
$.prettyPhoto.changeGalleryPage('next');
|
||||
$.prettyPhoto.stopSlideshow();
|
||||
return false;
|
||||
});
|
||||
|
||||
$pp_gallery.find('.pp_arrow_previous').click(function(){
|
||||
$.prettyPhoto.changeGalleryPage('previous');
|
||||
$.prettyPhoto.stopSlideshow();
|
||||
return false;
|
||||
});
|
||||
|
||||
$pp_pic_holder.find('.pp_content').hover(
|
||||
function(){
|
||||
$pp_pic_holder.find('.pp_gallery:not(.disabled)').fadeIn();
|
||||
},
|
||||
function(){
|
||||
$pp_pic_holder.find('.pp_gallery:not(.disabled)').fadeOut();
|
||||
});
|
||||
|
||||
itemWidth = 52+5; // 52 beign the thumb width, 5 being the right margin.
|
||||
$pp_gallery_li.each(function(i){
|
||||
$(this)
|
||||
.find('a')
|
||||
.click(function(){
|
||||
$.prettyPhoto.changePage(i);
|
||||
$.prettyPhoto.stopSlideshow();
|
||||
return false;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// Inject the play/pause if it's a slideshow
|
||||
if(settings.slideshow){
|
||||
$pp_pic_holder.find('.pp_nav').prepend('<a href="#" class="pp_play">Play</a>')
|
||||
$pp_pic_holder.find('.pp_nav .pp_play').click(function(){
|
||||
$.prettyPhoto.startSlideshow();
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
$pp_pic_holder.attr('class','pp_pic_holder ' + settings.theme); // Set the proper theme
|
||||
|
||||
$pp_overlay
|
||||
.css({
|
||||
'opacity':0,
|
||||
'height':$(document).height(),
|
||||
'width':$(window).width()
|
||||
})
|
||||
.bind('click',function(){
|
||||
if(!settings.modal) $.prettyPhoto.close();
|
||||
});
|
||||
|
||||
$('a.pp_close').bind('click',function(){ $.prettyPhoto.close(); return false; });
|
||||
|
||||
$('a.pp_expand').bind('click',function(e){
|
||||
// Expand the image
|
||||
if($(this).hasClass('pp_expand')){
|
||||
$(this).removeClass('pp_expand').addClass('pp_contract');
|
||||
doresize = false;
|
||||
}else{
|
||||
$(this).removeClass('pp_contract').addClass('pp_expand');
|
||||
doresize = true;
|
||||
};
|
||||
|
||||
_hideContent(function(){ $.prettyPhoto.open(); });
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
$pp_pic_holder.find('.pp_previous, .pp_nav .pp_arrow_previous').bind('click',function(){
|
||||
$.prettyPhoto.changePage('previous');
|
||||
$.prettyPhoto.stopSlideshow();
|
||||
return false;
|
||||
});
|
||||
|
||||
$pp_pic_holder.find('.pp_next, .pp_nav .pp_arrow_next').bind('click',function(){
|
||||
$.prettyPhoto.changePage('next');
|
||||
$.prettyPhoto.stopSlideshow();
|
||||
return false;
|
||||
});
|
||||
|
||||
_center_overlay(); // Center it
|
||||
};
|
||||
|
||||
if(!pp_alreadyInitialized && getHashtag()){
|
||||
pp_alreadyInitialized = true;
|
||||
|
||||
// Grab the rel index to trigger the click on the correct element
|
||||
hashIndex = getHashtag();
|
||||
hashRel = hashIndex;
|
||||
hashIndex = hashIndex.substring(hashIndex.indexOf('/')+1,hashIndex.length-1);
|
||||
hashRel = hashRel.substring(0,hashRel.indexOf('/'));
|
||||
|
||||
// Little timeout to make sure all the prettyPhoto initialize scripts has been run.
|
||||
// Useful in the event the page contain several init scripts.
|
||||
setTimeout(function(){ $("a[rel^='"+hashRel+"']:eq("+hashIndex+")").trigger('click'); },50);
|
||||
}
|
||||
|
||||
return this.unbind('click.prettyphoto').bind('click.prettyphoto',$.prettyPhoto.initialize); // Return the jQuery object for chaining. The unbind method is used to avoid click conflict when the plugin is called more than once
|
||||
};
|
||||
|
||||
function getHashtag(){
|
||||
url = location.href;
|
||||
hashtag = (url.indexOf('#!') != -1) ? decodeURI(url.substring(url.indexOf('#!')+2,url.length)) : false;
|
||||
return hashtag;
|
||||
};
|
||||
|
||||
function setHashtag(){
|
||||
if(typeof theRel == 'undefined') return; // theRel is set on normal calls, it's impossible to deeplink using the API
|
||||
location.hash = '!' + theRel + '/'+rel_index+'/';
|
||||
};
|
||||
|
||||
function clearHashtag(){
|
||||
// Clear the hashtag only if it was set by prettyPhoto
|
||||
url = location.href;
|
||||
hashtag = (url.indexOf('#!prettyPhoto')) ? true : false;
|
||||
if(hashtag) location.hash = "!prettyPhoto";
|
||||
}
|
||||
|
||||
function getParam(name,url){
|
||||
name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
|
||||
var regexS = "[\\?&]"+name+"=([^&#]*)";
|
||||
var regex = new RegExp( regexS );
|
||||
var results = regex.exec( url );
|
||||
return ( results == null ) ? "" : results[1];
|
||||
}
|
||||
|
||||
})(jQuery);
|
||||
|
||||
var pp_alreadyInitialized = false; // Used for the deep linking to make sure not to call the same function several times.
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>log4net</id>
|
||||
<version>2.0.3</version>
|
||||
<title>log4net [1.2.13]</title>
|
||||
<authors>Apache Software Foundation</authors>
|
||||
<owners>Apache Software Foundation</owners>
|
||||
<licenseUrl>http://logging.apache.org/log4net/license.html</licenseUrl>
|
||||
<projectUrl>http://logging.apache.org/log4net/</projectUrl>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<description>log4net is a tool to help the programmer output log statements to a variety of output targets. In case of problems with an application, it is helpful to enable logging so that the problem can be located. With log4net it is possible to enable logging at runtime without modifying the application binary. The log4net package is designed so that log statements can remain in shipped code without incurring a high performance cost. It follows that the speed of logging (or rather not logging) is crucial.
|
||||
|
||||
At the same time, log output can be so voluminous that it quickly becomes overwhelming. One of the distinctive features of log4net is the notion of hierarchical loggers. Using these loggers it is possible to selectively control which log statements are output at arbitrary granularity.
|
||||
|
||||
log4net is designed with two distinct goals in mind: speed and flexibility</description>
|
||||
<summary>The Apache log4net library is a tool to help the programmer output log statements to a variety of output targets.</summary>
|
||||
<tags>logging log tracing logfiles</tags>
|
||||
</metadata>
|
||||
</package>
|
||||
BIN
dependency-check-core/src/test/resources/log4net.dll
Normal file
BIN
dependency-check-core/src/test/resources/log4net.dll
Normal file
Binary file not shown.
@@ -1,30 +1,34 @@
|
||||
Dependency-Check Jenkins Plugin
|
||||
==============================
|
||||
|
||||
The Dependency-Check Jenkins Plugin features the ability to perform a dependency
|
||||
analysis build and later view results post build. The plugin is built using [analysis-core]
|
||||
and features many of the same features that Jenkins static analysis plugins offer,
|
||||
including thresholds, charts and the ability to view vulnerability information should
|
||||
a dependency have one identified.
|
||||
Dependency-Check is a utility that identifies project dependencies and checks if there are any known, publicly disclosed, vulnerabilities. This tool can be part of the solution to the OWASP Top 10 2013: A9 - Using Components with Known Vulnerabilities. This plug-in can independently execute a Dependency-Check analysis and visualize results.
|
||||
|
||||
The main repository is located at [jenkins-cli/dependency-check-jenkins](https://github.com/jenkinsci/dependency-check-jenkins).
|
||||
|
||||
The main site for documentation is located at [OWASP Dependency-Check-Jenkins](https://wiki.jenkins-ci.org/display/JENKINS/OWASP+Dependency-Check+Plugin).
|
||||
The Dependency-Check Jenkins Plugin features the ability to perform a dependency analysis build and later view results post build. The plugin is built using [analysis-core] and features many of the same features that Jenkins static analysis plugins offer, including thresholds, charts and the ability to view vulnerability information should a dependency have one identified.
|
||||
|
||||
More information can be found on the [wiki].
|
||||
|
||||
Mailing List
|
||||
------------
|
||||
|
||||
Subscribe: [dependency-check+subscribe@googlegroups.com](mailto:dependency-check+subscribe@googlegroups.com)
|
||||
Subscribe: [dependency-check+subscribe@googlegroups.com] [subscribe]
|
||||
|
||||
Post: [dependency-check@googlegroups.com](mailto:dependency-check@googlegroups.com)
|
||||
Post: [dependency-check@googlegroups.com] [post]
|
||||
|
||||
Copyright
|
||||
Copyright & License
|
||||
-------------------
|
||||
|
||||
Dependency-Check is Copyright (c) 2012-2014 Jeremy Long. All Rights Reserved.
|
||||
|
||||
Dependency-Check Jenkins Plugin is Copyright (c) 2013-2014 Steve Springett. All Rights Reserved.
|
||||
|
||||
[wiki]: https://github.com/jenkinsci/dependency-check-jenkins/wiki
|
||||
Permission to modify and redistribute is granted under the terms of the Apache 2.0 license. See the [LICENSE.txt] [license] file for the full license.
|
||||
|
||||
Dependency-Check makes use of several other open source libraries. Please see the [NOTICE.txt] [notices] file for more information.
|
||||
|
||||
|
||||
[wiki]: https://wiki.jenkins-ci.org/display/JENKINS/OWASP+Dependency-Check+Plugin
|
||||
[analysis-core]: http://wiki.jenkins-ci.org/x/CwDgAQ
|
||||
[notices]: https://github.com/jenkinsci/dependency-check-jenkins/blob/master/NOTICES.txt
|
||||
[subscribe]: mailto:dependency-check+subscribe@googlegroups.com
|
||||
[post]: mailto:dependency-check@googlegroups.com
|
||||
[license]: https://github.com/jenkinsci/dependency-check-plugin/blob/master/LICENSE.txt
|
||||
[notices]: https://github.com/jenkinsci/dependency-check-plugin/blob/master/NOTICES.txt
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-parent</artifactId>
|
||||
<version>1.1.0</version>
|
||||
<version>1.1.2</version>
|
||||
</parent>
|
||||
|
||||
<groupId>org.owasp</groupId>
|
||||
|
||||
@@ -1,30 +1,34 @@
|
||||
Dependency-Check Jenkins Plugin
|
||||
==============================
|
||||
|
||||
The Dependency-Check Jenkins Plugin features the ability to perform a dependency
|
||||
analysis build and later view results post build. The plugin is built using [analysis-core]
|
||||
and features many of the same features that Jenkins static analysis plugins offer,
|
||||
including thresholds, charts and the ability to view vulnerability information should
|
||||
a dependency have one identified.
|
||||
Dependency-Check is a utility that identifies project dependencies and checks if there are any known, publicly disclosed, vulnerabilities. This tool can be part of the solution to the OWASP Top 10 2013: A9 - Using Components with Known Vulnerabilities. This plug-in can independently execute a Dependency-Check analysis and visualize results.
|
||||
|
||||
The main repository is located at [jenkins-cli/dependency-check-jenkins](https://github.com/jenkinsci/dependency-check-jenkins).
|
||||
|
||||
The main site for documentation is located at [OWASP Dependency-Check-Jenkins](https://wiki.jenkins-ci.org/display/JENKINS/OWASP+Dependency-Check+Plugin).
|
||||
The Dependency-Check Jenkins Plugin features the ability to perform a dependency analysis build and later view results post build. The plugin is built using [analysis-core] and features many of the same features that Jenkins static analysis plugins offer, including thresholds, charts and the ability to view vulnerability information should a dependency have one identified.
|
||||
|
||||
More information can be found on the [wiki].
|
||||
|
||||
Mailing List
|
||||
------------
|
||||
|
||||
Subscribe: [dependency-check+subscribe@googlegroups.com](mailto:dependency-check+subscribe@googlegroups.com)
|
||||
Subscribe: [dependency-check+subscribe@googlegroups.com] [subscribe]
|
||||
|
||||
Post: [dependency-check@googlegroups.com](mailto:dependency-check@googlegroups.com)
|
||||
Post: [dependency-check@googlegroups.com] [post]
|
||||
|
||||
Copyright
|
||||
Copyright & License
|
||||
-------------------
|
||||
|
||||
Dependency-Check is Copyright (c) 2012-2014 Jeremy Long. All Rights Reserved.
|
||||
|
||||
Dependency-Check Jenkins Plugin is Copyright (c) 2013-2014 Steve Springett. All Rights Reserved.
|
||||
|
||||
[wiki]: https://github.com/jenkinsci/dependency-check-jenkins/wiki
|
||||
Permission to modify and redistribute is granted under the terms of the Apache 2.0 license. See the [LICENSE.txt] [license] file for the full license.
|
||||
|
||||
Dependency-Check makes use of several other open source libraries. Please see the [NOTICE.txt] [notices] file for more information.
|
||||
|
||||
|
||||
[wiki]: https://wiki.jenkins-ci.org/display/JENKINS/OWASP+Dependency-Check+Plugin
|
||||
[analysis-core]: http://wiki.jenkins-ci.org/x/CwDgAQ
|
||||
[notices]: https://github.com/jenkinsci/dependency-check-jenkins/blob/master/NOTICES.txt
|
||||
[subscribe]: mailto:dependency-check+subscribe@googlegroups.com
|
||||
[post]: mailto:dependency-check@googlegroups.com
|
||||
[license]: https://github.com/jenkinsci/dependency-check-plugin/blob/master/LICENSE.txt
|
||||
[notices]: https://github.com/jenkinsci/dependency-check-plugin/blob/master/NOTICES.txt
|
||||
|
||||
@@ -23,7 +23,7 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved.
|
||||
<parent>
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-parent</artifactId>
|
||||
<version>1.1.0</version>
|
||||
<version>1.1.2</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>dependency-check-maven</artifactId>
|
||||
@@ -180,7 +180,7 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved.
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<version>2.5.2</version>
|
||||
<version>2.6</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
|
||||
@@ -76,10 +76,6 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR
|
||||
* Name of the logging properties file.
|
||||
*/
|
||||
private static final String LOG_PROPERTIES_FILE = "log.properties";
|
||||
/**
|
||||
* The name of the test scope.
|
||||
*/
|
||||
public static final String TEST_SCOPE = "test";
|
||||
/**
|
||||
* System specific new line character.
|
||||
*/
|
||||
@@ -202,11 +198,17 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR
|
||||
@SuppressWarnings({"CanBeFinal", "FieldCanBeLocal"})
|
||||
@Parameter(property = "nexusUrl", defaultValue = "", required = false)
|
||||
private String nexusUrl;
|
||||
/**
|
||||
* Whether or not the configured proxy is used to connect to Nexus.
|
||||
*/
|
||||
@SuppressWarnings({"CanBeFinal", "FieldCanBeLocal"})
|
||||
@Parameter(property = "nexusUsesProxy", defaultValue = "true", required = false)
|
||||
private boolean nexusUsesProxy = true;
|
||||
/**
|
||||
* The database connection string.
|
||||
*/
|
||||
@SuppressWarnings({"CanBeFinal", "FieldCanBeLocal"})
|
||||
@Parameter(property = "nexusUrl", defaultValue = "", required = false)
|
||||
@Parameter(property = "connectionString", defaultValue = "", required = false)
|
||||
private String connectionString;
|
||||
/**
|
||||
* The database driver name. An example would be org.h2.Driver.
|
||||
@@ -232,27 +234,90 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR
|
||||
@SuppressWarnings({"CanBeFinal", "FieldCanBeLocal"})
|
||||
@Parameter(property = "databasePassword", defaultValue = "", required = false)
|
||||
private String databasePassword;
|
||||
// </editor-fold>
|
||||
/**
|
||||
* A comma-separated list of file extensions to add to analysis next to jar, zip, ....
|
||||
*/
|
||||
@Parameter(property = "zipExtensions", required = false)
|
||||
private String zipExtensions;
|
||||
/**
|
||||
* Skip Analisys for Test Scope Dependencies
|
||||
*/
|
||||
@Parameter(property = "skipTestScope", defaultValue = "true", required = false)
|
||||
private boolean skipTestScope = true;
|
||||
/**
|
||||
* Skip Analisys for Runtime Scope Dependencies
|
||||
*/
|
||||
@Parameter(property = "skipRuntimeScope", defaultValue = "false", required = false)
|
||||
private boolean skipRuntimeScope = false;
|
||||
/**
|
||||
* Skip Analisys for Provided Scope Dependencies
|
||||
*/
|
||||
@Parameter(property = "skipProvidedScope", defaultValue = "false", required = false)
|
||||
private boolean skipProvidedScope = false;
|
||||
/**
|
||||
* The data directory, hold DC SQL DB.
|
||||
*/
|
||||
@Parameter(property = "dataDirectory", defaultValue = "", required = false)
|
||||
private String dataDirectory;
|
||||
/**
|
||||
* Data Mirror URL for CVE 1.2
|
||||
*/
|
||||
@Parameter(property = "cveUrl12Modified", defaultValue = "", required = false)
|
||||
private String cveUrl12Modified;
|
||||
/**
|
||||
* Data Mirror URL for CVE 2.0
|
||||
*/
|
||||
@Parameter(property = "cveUrl20Modified", defaultValue = "", required = false)
|
||||
private String cveUrl20Modified;
|
||||
/**
|
||||
* Base Data Mirror URL for CVE 1.2
|
||||
*/
|
||||
@Parameter(property = "cveUrl12Base", defaultValue = "", required = false)
|
||||
private String cveUrl12Base;
|
||||
/**
|
||||
* Data Mirror URL for CVE 2.0
|
||||
*/
|
||||
@Parameter(property = "cveUrl20Base", defaultValue = "", required = false)
|
||||
private String cveUrl20Base;
|
||||
|
||||
// </editor-fold>
|
||||
/**
|
||||
* Executes the Dependency-Check on the dependent libraries.
|
||||
*
|
||||
* @return the Engine used to scan the dependencies.
|
||||
* @throws DatabaseException thrown if there is an exception connecting to the database
|
||||
*/
|
||||
private Engine executeDependencyCheck() {
|
||||
private Engine executeDependencyCheck() throws DatabaseException {
|
||||
|
||||
final InputStream in = DependencyCheckMojo.class.getClassLoader().getResourceAsStream(LOG_PROPERTIES_FILE);
|
||||
LogUtils.prepareLogger(in, logFile);
|
||||
|
||||
populateSettings();
|
||||
final Engine engine = new Engine();
|
||||
final Set<Artifact> artifacts = project.getArtifacts();
|
||||
for (Artifact a : artifacts) {
|
||||
if (!TEST_SCOPE.equals(a.getScope())) {
|
||||
Engine engine = null;
|
||||
try {
|
||||
engine = new Engine();
|
||||
final Set<Artifact> artifacts = project.getArtifacts();
|
||||
for (Artifact a : artifacts) {
|
||||
if (skipTestScope && Artifact.SCOPE_TEST.equals(a.getScope())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (skipProvidedScope && Artifact.SCOPE_PROVIDED.equals(a.getScope())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (skipRuntimeScope && !Artifact.SCOPE_RUNTIME.equals(a.getScope())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
engine.scan(a.getFile().getAbsolutePath());
|
||||
}
|
||||
engine.analyzeDependencies();
|
||||
} finally {
|
||||
if (engine != null) {
|
||||
engine.cleanup();
|
||||
}
|
||||
}
|
||||
engine.analyzeDependencies();
|
||||
return engine;
|
||||
}
|
||||
|
||||
@@ -282,7 +347,7 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR
|
||||
Logger.getLogger(DependencyCheckMojo.class.getName()).log(Level.SEVERE,
|
||||
"Unexpected exception occurred during analysis; please see the verbose error log for more details.");
|
||||
Logger.getLogger(DependencyCheckMojo.class.getName()).log(Level.FINE, null, ex);
|
||||
} catch (Exception ex) {
|
||||
} catch (Throwable ex) {
|
||||
Logger.getLogger(DependencyCheckMojo.class.getName()).log(Level.SEVERE,
|
||||
"Unexpected exception occurred during analysis; please see the verbose error log for more details.");
|
||||
Logger.getLogger(DependencyCheckMojo.class.getName()).log(Level.FINE, null, ex);
|
||||
@@ -304,7 +369,6 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR
|
||||
int cnt = 0;
|
||||
for (Dependency d : dependencies) {
|
||||
writeSiteReportDependencyHeader(sink, d);
|
||||
cnt = writeSiteReportDependencyAnalysisExceptions(d, cnt, sink);
|
||||
cnt = writeSiteReportDependencyEvidenceUsed(d, cnt, sink);
|
||||
cnt = writeSiteReportDependencyRelatedDependencies(d, cnt, sink);
|
||||
writeSiteReportDependencyIdentifiers(d, sink);
|
||||
@@ -510,35 +574,6 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR
|
||||
return cnt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the analysis exceptions generated during analysis to the site report.
|
||||
*
|
||||
* @param d the dependency
|
||||
* @param sink the sink to write the data to
|
||||
* @param collapsibleHeaderCount the collapsible header count
|
||||
* @return the collapsible header count
|
||||
*/
|
||||
private int writeSiteReportDependencyAnalysisExceptions(Dependency d, int collapsibleHeaderCount, Sink sink) {
|
||||
int cnt = collapsibleHeaderCount;
|
||||
if (d.getAnalysisExceptions() != null && !d.getAnalysisExceptions().isEmpty()) {
|
||||
cnt += 1;
|
||||
sink.sectionTitle4();
|
||||
sink.rawText("<font style=\"color:red\">Errors occurred during analysis:</font> <a href=\"javascript:toggleElement(this, 'errors"
|
||||
+ cnt + "')\">[+]</a>");
|
||||
sink.sectionTitle4_();
|
||||
sink.rawText("<div id=\"errors" + cnt + "\">");
|
||||
sink.list();
|
||||
for (Exception e : d.getAnalysisExceptions()) {
|
||||
sink.listItem();
|
||||
sink.text(e.getMessage());
|
||||
sink.listItem_();
|
||||
}
|
||||
sink.list_();
|
||||
sink.rawText("</div>");
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the dependency header to the site report.
|
||||
*
|
||||
@@ -722,6 +757,7 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR
|
||||
if (nexusUrl != null && !nexusUrl.isEmpty()) {
|
||||
Settings.setString(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl);
|
||||
}
|
||||
Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_PROXY, nexusUsesProxy);
|
||||
if (databaseDriverName != null && !databaseDriverName.isEmpty()) {
|
||||
Settings.setString(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName);
|
||||
}
|
||||
@@ -737,6 +773,33 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR
|
||||
if (databasePassword != null && !databasePassword.isEmpty()) {
|
||||
Settings.setString(Settings.KEYS.DB_PASSWORD, databasePassword);
|
||||
}
|
||||
if (zipExtensions != null && !zipExtensions.isEmpty()) {
|
||||
Settings.setString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions);
|
||||
}
|
||||
|
||||
// Scope Exclusion
|
||||
Settings.setBoolean(Settings.KEYS.SKIP_TEST_SCOPE, skipTestScope);
|
||||
Settings.setBoolean(Settings.KEYS.SKIP_RUNTIME_SCOPE, skipRuntimeScope);
|
||||
Settings.setBoolean(Settings.KEYS.SKIP_PROVIDED_SCOPE, skipProvidedScope);
|
||||
|
||||
// Data Directory
|
||||
if (dataDirectory != null && !dataDirectory.isEmpty()) {
|
||||
Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory);
|
||||
}
|
||||
|
||||
// CVE Data Mirroring
|
||||
if (cveUrl12Modified != null && !cveUrl12Modified.isEmpty()) {
|
||||
Settings.setString(Settings.KEYS.CVE_MODIFIED_12_URL, cveUrl12Modified);
|
||||
}
|
||||
if (cveUrl20Modified != null && !cveUrl20Modified.isEmpty()) {
|
||||
Settings.setString(Settings.KEYS.CVE_MODIFIED_20_URL, cveUrl20Modified);
|
||||
}
|
||||
if (cveUrl12Base != null && !cveUrl12Base.isEmpty()) {
|
||||
Settings.setString(Settings.KEYS.CVE_SCHEMA_1_2, cveUrl12Base);
|
||||
}
|
||||
if (cveUrl20Base != null && !cveUrl20Base.isEmpty()) {
|
||||
Settings.setString(Settings.KEYS.CVE_SCHEMA_2_0, cveUrl20Base);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -746,13 +809,24 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR
|
||||
* @throws MojoFailureException thrown if a CVSS score is found that is higher then the configured level
|
||||
*/
|
||||
public void execute() throws MojoExecutionException, MojoFailureException {
|
||||
final Engine engine = executeDependencyCheck();
|
||||
generateExternalReports(engine);
|
||||
if (this.failBuildOnCVSS <= 10) {
|
||||
checkForFailure(engine.getDependencies());
|
||||
}
|
||||
if (this.showSummary) {
|
||||
showSummary(engine.getDependencies());
|
||||
Engine engine = null;
|
||||
try {
|
||||
engine = executeDependencyCheck();
|
||||
generateExternalReports(engine);
|
||||
if (this.showSummary) {
|
||||
showSummary(engine.getDependencies());
|
||||
}
|
||||
if (this.failBuildOnCVSS <= 10) {
|
||||
checkForFailure(engine.getDependencies());
|
||||
}
|
||||
} catch (DatabaseException ex) {
|
||||
Logger.getLogger(DependencyCheckMojo.class.getName()).log(Level.SEVERE,
|
||||
"Unable to connect to the dependency-check database; analysis has stopped");
|
||||
Logger.getLogger(DependencyCheckMojo.class.getName()).log(Level.FINE, "", ex);
|
||||
} finally {
|
||||
if (engine != null) {
|
||||
engine.cleanup();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -777,8 +851,19 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR
|
||||
* @throws MavenReportException if a maven report exception occurs
|
||||
*/
|
||||
public void generate(Sink sink, SinkFactory sinkFactory, Locale locale) throws MavenReportException {
|
||||
final Engine engine = executeDependencyCheck();
|
||||
generateMavenSiteReport(engine, sink);
|
||||
Engine engine = null;
|
||||
try {
|
||||
engine = executeDependencyCheck();
|
||||
generateMavenSiteReport(engine, sink);
|
||||
} catch (DatabaseException ex) {
|
||||
Logger.getLogger(DependencyCheckMojo.class.getName()).log(Level.SEVERE,
|
||||
"Unable to connect to the dependency-check database; analysis has stopped");
|
||||
Logger.getLogger(DependencyCheckMojo.class.getName()).log(Level.FINE, "", ex);
|
||||
} finally {
|
||||
if (engine != null) {
|
||||
engine.cleanup();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// <editor-fold defaultstate="collapsed" desc="required setter/getter methods">
|
||||
@@ -867,9 +952,12 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR
|
||||
private void checkForFailure(List<Dependency> dependencies) throws MojoFailureException {
|
||||
final StringBuilder ids = new StringBuilder();
|
||||
for (Dependency d : dependencies) {
|
||||
boolean addName = true;
|
||||
for (Vulnerability v : d.getVulnerabilities()) {
|
||||
if (v.getCvssScore() >= failBuildOnCVSS) {
|
||||
if (ids.length() == 0) {
|
||||
if (addName) {
|
||||
addName = false;
|
||||
ids.append(NEW_LINE).append(d.getFileName()).append(": ");
|
||||
ids.append(v.getName());
|
||||
} else {
|
||||
ids.append(", ").append(v.getName());
|
||||
|
||||
@@ -2,23 +2,33 @@ Configuration
|
||||
====================
|
||||
The following properties can be set on the dependency-check-maven plugin.
|
||||
|
||||
Property | Description | Default Value
|
||||
--------------------|------------------------------------|------------------
|
||||
autoUpdate | Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not recommended that this be turned to false. | true
|
||||
externalReport | When using as a Site plugin this parameter sets whether or not the external report format should be used. | false
|
||||
failBuildOnCVSS | Specifies if the build should be failed if a CVSS score above a specified level is identified. The default is 11 which means since the CVSS scores are 0-10, by default the build will never fail. | 11
|
||||
format | The report format to be generated (HTML, XML, VULN, ALL). This configuration option has no affect if using this within the Site plugin unless the externalReport is set to true. | HTML
|
||||
logFile | The file path to write verbose logging information. |
|
||||
suppressionFile | The file path to the XML suppression file \- used to suppress [false positives](../suppression.html) |
|
||||
connectionTimeout | The Connection Timeout. |
|
||||
proxyUrl | The Proxy URL. |
|
||||
proxyPort | The Proxy Port. |
|
||||
proxyUsername | Defines the proxy user name. |
|
||||
proxyPassword | Defines the proxy password. |
|
||||
nexusAnalyzerEnabled | The connection timeout used when downloading data files from the Internet. |
|
||||
nexusUrl | The connection timeout used when downloading data files from the Internet. |
|
||||
databaseDriverName | The name of the database driver. Example: org.h2.Driver. |
|
||||
databaseDriverPath | The path to the database driver JAR file; only used if the driver is not in the class path. |
|
||||
connectionString | The connection string used to connect to the database. |
|
||||
databaseUser | The username used when connecting to the database. |
|
||||
databasePassword | The password used when connecting to the database. |
|
||||
Property | Description | Default Value
|
||||
---------------------|------------------------------------|------------------
|
||||
autoUpdate | Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not recommended that this be turned to false. | true
|
||||
externalReport | When using as a Site plugin this parameter sets whether or not the external report format should be used. | false
|
||||
failBuildOnCVSS | Specifies if the build should be failed if a CVSS score above a specified level is identified. The default is 11 which means since the CVSS scores are 0-10, by default the build will never fail. | 11
|
||||
format | The report format to be generated (HTML, XML, VULN, ALL). This configuration option has no affect if using this within the Site plugin unless the externalReport is set to true. | HTML
|
||||
logFile | The file path to write verbose logging information. |
|
||||
suppressionFile | The file path to the XML suppression file \- used to suppress [false positives](../suppression.html) |
|
||||
connectionTimeout | The Connection Timeout. |
|
||||
proxyUrl | The Proxy URL. |
|
||||
proxyPort | The Proxy Port. |
|
||||
proxyUsername | Defines the proxy user name. |
|
||||
proxyPassword | Defines the proxy password. |
|
||||
nexusAnalyzerEnabled | Sets whether Nexus Analyzer will be used. |
|
||||
nexusUrl | Defines the Nexus URL. |
|
||||
nexusUsesProxy | Whether or not the defined proxy should be used when connecting to Nexus. | true
|
||||
databaseDriverName | The name of the database driver. Example: org.h2.Driver. |
|
||||
databaseDriverPath | The path to the database driver JAR file; only used if the driver is not in the class path. |
|
||||
connectionString | The connection string used to connect to the database. |
|
||||
databaseUser | The username used when connecting to the database. |
|
||||
databasePassword | The password used when connecting to the database. |
|
||||
zipExtensions | A comma-separated list of additional file extensions to be treated like a ZIP file, the contents will be extracted and analyzed. |
|
||||
skipTestScope | Should be skip analysis for artifacts with Test Scope | true
|
||||
skipProvidedScope | Should be skip analysis for artifacts with Provided Scope | false
|
||||
skipRuntimeScope | Should be skip analysis for artifacts with Runtime Scope | false
|
||||
dataDirectory | Data directory to hold SQL CVEs contents. This should generally not be changed. |
|
||||
cveUrl12Modified | URL for the modified CVE 1.2 | http://nvd.nist.gov/download/nvdcve-modified.xml
|
||||
cveUrl20Modified | URL for the modified CVE 2.0 | http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-modified.xml
|
||||
cveUrl12Base | Base URL for each year's CVE 1.2, the %d will be replaced with the year | http://nvd.nist.gov/download/nvdcve-%d.xml
|
||||
cveUrl20Base | Base URL for each year's CVE 2.0, the %d will be replaced with the year | http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-%d.xml
|
||||
|
||||
@@ -10,7 +10,9 @@ Vulnerability Database (NVD) hosted by NIST: https://nvd.nist.gov
|
||||
After the first batch download, as long as the plugin is executed at least once every
|
||||
seven days the update will only take a few seconds.
|
||||
|
||||
<h3>Create the DependencyCheck-report.html in the target directory</h3>
|
||||
Example 1:
|
||||
---------------------
|
||||
Create the DependencyCheck-report.html in the target directory
|
||||
|
||||
```xml
|
||||
<project>
|
||||
@@ -37,7 +39,9 @@ seven days the update will only take a few seconds.
|
||||
</project>
|
||||
```
|
||||
|
||||
<h3>Create the DependencyCheck-report.html and fail the build for CVSS greater then 8</h3>
|
||||
Example 2:
|
||||
---------------------
|
||||
Create the DependencyCheck-report.html and fail the build for CVSS greater then 8
|
||||
|
||||
```xml
|
||||
<project>
|
||||
@@ -67,7 +71,9 @@ seven days the update will only take a few seconds.
|
||||
</project>
|
||||
```
|
||||
|
||||
<h3>Create the dependency-check report within the site</h3>
|
||||
Example 3:
|
||||
---------------------
|
||||
Create the dependency-check report within the site
|
||||
|
||||
```xml
|
||||
<project>
|
||||
@@ -97,3 +103,70 @@ seven days the update will only take a few seconds.
|
||||
...
|
||||
</project>
|
||||
```
|
||||
Example 4:
|
||||
---------------------
|
||||
Create the DependencyCheck-report.html and skip artifacts no bundled in distribution (Provided and Runtime scope)
|
||||
|
||||
```xml
|
||||
<project>
|
||||
<build>
|
||||
<plugins>
|
||||
...
|
||||
<plugin>
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-maven</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<configuration>
|
||||
<skipProvidedScope>true</skipProvidedScope>
|
||||
<skipRuntimeScope>true</skipRuntimeScope>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>check</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
...
|
||||
</plugins>
|
||||
...
|
||||
</build>
|
||||
...
|
||||
</project>
|
||||
```
|
||||
Example 5:
|
||||
---------------------
|
||||
Create the DependencyCheck-report.html and use internal mirroring of CVE contents
|
||||
|
||||
```xml
|
||||
<project>
|
||||
<build>
|
||||
<plugins>
|
||||
...
|
||||
<plugin>
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-maven</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<configuration>
|
||||
<cveUrl12Modified>http://internal-mirror.mycorp.com/downloads/nist/nvdcve-modified.xml</cveUrl12Modified>
|
||||
<cveUrl20Modified>http://internal-mirror.mycorp.com/downloads/nist/nvdcve-2.0-modified.xml</cveUrl20Modified>
|
||||
<cveUrl12Base>http://internal-mirror.mycorp.com/downloads/nist/nvdcve-%d.xml</cveUrl12Base>
|
||||
<cveUrl20Base>http://internal-mirror.mycorp.com/downloads/nist/nvdcve-2.0-%d.xml</cveUrl20Base>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>check</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
...
|
||||
</plugins>
|
||||
...
|
||||
</build>
|
||||
...
|
||||
</project>
|
||||
```
|
||||
|
||||
|
||||
14
pom.xml
14
pom.xml
@@ -20,7 +20,7 @@ Copyright (c) 2012 - Jeremy Long
|
||||
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-parent</artifactId>
|
||||
<version>1.1.0</version>
|
||||
<version>1.1.2</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<modules>
|
||||
@@ -64,6 +64,18 @@ Copyright (c) 2012 - Jeremy Long
|
||||
<role>developer</role>
|
||||
</roles>
|
||||
</developer>
|
||||
<developer>
|
||||
<name>Will Stranathan</name>
|
||||
<email>Will.Stranathan@owasp.org</email>
|
||||
<organization>OWASP</organization>
|
||||
<organizationUrl>https://www.owasp.org/index.php/OWASP_Dependency_Check</organizationUrl>
|
||||
<roles>
|
||||
<role>developer</role>
|
||||
</roles>
|
||||
<properties>
|
||||
<twitter>@willathome</twitter>
|
||||
</properties>
|
||||
</developer>
|
||||
</developers>
|
||||
<contributors>
|
||||
<contributor>
|
||||
|
||||
@@ -18,6 +18,55 @@ A sample suppression file would look like:
|
||||
```
|
||||
The above XML file will suppress the cpe:/a:apache:struts:2.0.0 from any file with the a matching SHA1 hash.
|
||||
|
||||
The following shows some other ways to suppress individual findings. Note the ways to select files using either
|
||||
the sha1 hash or the filePath (the filePath can also be a regex). Additionally, there are several things that
|
||||
can be suppressed - individual CPEs, individual CVEs, or all CVE entries below a specified CVSS score. The most common
|
||||
would be suppressing CPEs based off of SHA1 hashes or filePath (regexes) - these entries can be generated using the
|
||||
HTML version of the report. The other common scenario would be to ignore all CVEs below a certain CVSS threshold.
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<suppressions
|
||||
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
|
||||
xmlns='https://www.owasp.org/index.php/OWASP_Dependency_Check_Suppression'
|
||||
xsi:schemaLocation='https://www.owasp.org/index.php/OWASP_Dependency_Check_Suppression suppression.xsd'>
|
||||
<suppress>
|
||||
<notes><![CDATA[
|
||||
This suppresses cpe:/a:csv:csv:1.0 for some.jar in the "c:\path\to" directory.
|
||||
]]></notes>
|
||||
<filePath>c:\path\to\some.jar</filePath>
|
||||
<cpe>cpe:/a:csv:csv:1.0</cpe>
|
||||
</suppress>
|
||||
<suppress>
|
||||
<notes><![CDATA[
|
||||
This suppresses any jboss:jboss cpe for any test.jar in any directory.
|
||||
]]></notes>
|
||||
<filePath regex="true">.*\btest\.jar</filePath>
|
||||
<cpe>cpe:/a:jboss:jboss</cpe>
|
||||
</suppress>
|
||||
<suppress>
|
||||
<notes><![CDATA[
|
||||
This suppresses a specific cve for any test.jar in any directory.
|
||||
]]></notes>
|
||||
<filePath regex="true">.*\btest\.jar</filePath>
|
||||
<cve>CVE-2013-1337</cve>
|
||||
</suppress>
|
||||
<suppress>
|
||||
<notes><![CDATA[
|
||||
This suppresses a specific cve for any dependency in any directory that has the specified sha1 checksum.
|
||||
]]></notes>
|
||||
<sha1>384FAA82E193D4E4B0546059CA09572654BC3970</sha1>
|
||||
<cve>CVE-2013-1337</cve>
|
||||
</suppress>
|
||||
<suppress>
|
||||
<notes><![CDATA[
|
||||
This suppresses all CVE entries that have a score below CVSS 7.
|
||||
]]></notes>
|
||||
<cvssBelow>7</cvssBelow>
|
||||
</suppress>
|
||||
</suppressions>
|
||||
```
|
||||
|
||||
The full schema for suppression files can be found here: [suppression.xsd](https://github.com/jeremylong/DependencyCheck/blob/master/dependency-check-core/src/main/resources/schema/suppression.xsd "Suppression Schema")
|
||||
|
||||
Please see the appropriate configuration option in each interfaces configuration guide:
|
||||
|
||||
BIN
src/site/resources/images/logos/Button-Built-on-CB-1.png
Normal file
BIN
src/site/resources/images/logos/Button-Built-on-CB-1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.3 KiB |
BIN
src/site/resources/images/logos/logo_intellij_idea.png
Normal file
BIN
src/site/resources/images/logos/logo_intellij_idea.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.9 KiB |
@@ -20,7 +20,7 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved.
|
||||
<skin>
|
||||
<groupId>org.apache.maven.skins</groupId>
|
||||
<artifactId>maven-fluido-skin</artifactId>
|
||||
<version>1.3.0</version>
|
||||
<version>1.3.1</version>
|
||||
</skin>
|
||||
<custom>
|
||||
<fluidoSkin>
|
||||
@@ -37,6 +37,7 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved.
|
||||
<showUser>true</showUser>
|
||||
<showFollowers>true</showFollowers>
|
||||
</twitter>
|
||||
<googlePlusOne />
|
||||
</fluidoSkin>
|
||||
</custom>
|
||||
<bannerLeft>
|
||||
@@ -44,6 +45,21 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved.
|
||||
</bannerLeft>
|
||||
<publishDate position="right" />
|
||||
<version position="right" />
|
||||
<poweredBy>
|
||||
<logo name="Maven" href="http://maven.apache.org/"
|
||||
title="built with maven"
|
||||
alt="built with maven"
|
||||
img="http://jeremylong.github.io/DependencyCheck/images/logos/maven-feather.png"/>
|
||||
<logo name="IntelliJ" href="http://maven.apache.org/"
|
||||
title="developed using" width="170px"
|
||||
alt="developed using"
|
||||
img="http://jeremylong.github.io/DependencyCheck/images/logos/logo_intellij_idea.png"/>
|
||||
<logo name="Cloudbees" href="http://www.cloudbees.com/"
|
||||
title="built on cloudbees"
|
||||
alt="built on cloudbees"
|
||||
img="http://jeremylong.github.io/DependencyCheck/images/logos/Button-Built-on-CB-1.png"/>
|
||||
</poweredBy>
|
||||
|
||||
<body>
|
||||
<head>
|
||||
<style type="text/css">
|
||||
@@ -59,13 +75,13 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved.
|
||||
<item name="False Positives" href="./suppression.html">
|
||||
<description>Suppressing False Positives</description>
|
||||
</item>
|
||||
<item name="Project Presentation (pptx)" href="./dependency-check.pptx">
|
||||
<item name="Project Presentation (pptx)" href="./dependency-check.pptx">
|
||||
<description>PowerPoint Deck</description>
|
||||
</item>
|
||||
<item name="Project Presentation (pdf)" href="./dependency-check.pdf">
|
||||
<item name="Project Presentation (pdf)" href="./dependency-check.pdf">
|
||||
<description>PowerPoint Deck</description>
|
||||
</item>
|
||||
<item name="Sample Report" href="./SampleReport.html">
|
||||
<item name="Sample Report" href="./SampleReport.html">
|
||||
<description>Sample Report</description>
|
||||
</item>
|
||||
</menu>
|
||||
@@ -86,6 +102,6 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved.
|
||||
<description>A Jenkins plugin for dependency-check.</description>
|
||||
</item>
|
||||
</menu>
|
||||
<footer/>
|
||||
<footer>Copyright © 2012-2014 Jeremy Long. All Rights Reserved.</footer>
|
||||
</body>
|
||||
</project>
|
||||
Reference in New Issue
Block a user