From 654a9227ed88560c6c1099909775eae44f54ab25 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Tue, 11 Sep 2012 23:30:46 -0400 Subject: [PATCH] bug fixes/checkstyle fixes --- .../dependencycheck/data/cpe/CPEQuery.java | 14 ++--- .../dependencycheck/data/cpe/Index.java | 4 +- .../scanner/AbstractAnalyzer.java | 8 +-- .../dependencycheck/scanner/Analyzer.java | 8 +-- .../scanner/AnalyzerService.java | 5 +- .../scanner/EvidenceCollection.java | 2 +- .../dependencycheck/scanner/JarAnalyzer.java | 40 ++++++--------- .../dependencycheck/scanner/Scanner.java | 6 +-- .../dependencycheck/utils/CliParser.java | 11 ++-- .../utils/DownloadFailedException.java | 51 +++++++++++++++---- .../dependencycheck/utils/Downloader.java | 11 ++-- .../dependencycheck/utils/Settings.java | 13 ++--- .../scanner/JarAnalyzerTest.java | 35 +++++++++++++ 13 files changed, 130 insertions(+), 78 deletions(-) diff --git a/src/main/java/org/codesecure/dependencycheck/data/cpe/CPEQuery.java b/src/main/java/org/codesecure/dependencycheck/data/cpe/CPEQuery.java index 7b660cae2..28a5aa544 100644 --- a/src/main/java/org/codesecure/dependencycheck/data/cpe/CPEQuery.java +++ b/src/main/java/org/codesecure/dependencycheck/data/cpe/CPEQuery.java @@ -243,24 +243,24 @@ public class CPEQuery { } /** - * Returns the text created by concatonating the text and the values from the + * Returns the text created by concatonating the text and the values from the * EvidenceCollection (filtered for a specific confidence). This attempts to * prevent duplicate terms from being added.
* Note, if the evidence is longer then 200 characters it will be truncated. - * + * * @param text the base text. * @param ec an EvidenceCollection * @param confidenceFilter a Confidence level to filter the evidence by. - * @return + * @return */ private String addEvidenceWithoutDuplicateTerms(final String text, final EvidenceCollection ec, Confidence confidenceFilter) { String txt = (text == null) ? "" : text; StringBuilder sb = new StringBuilder(txt.length() + (20 * ec.size())); for (Evidence e : ec.iterator(confidenceFilter)) { String value = e.getValue(); - if (sb.indexOf(value)<0) { - if (value.length()>200) { - sb.append(value.substring(0,200)); + if (sb.indexOf(value) < 0) { + if (value.length() > 200) { + sb.append(value.substring(0, 200)); } else { sb.append(value).append(' '); } @@ -268,7 +268,7 @@ public class CPEQuery { } return sb.toString(); } - + /** * Reduces the given confidence by one level. This returns LOW if the confidence * passed in is not HIGH. diff --git a/src/main/java/org/codesecure/dependencycheck/data/cpe/Index.java b/src/main/java/org/codesecure/dependencycheck/data/cpe/Index.java index 57aeaf631..f49add80b 100644 --- a/src/main/java/org/codesecure/dependencycheck/data/cpe/Index.java +++ b/src/main/java/org/codesecure/dependencycheck/data/cpe/Index.java @@ -137,7 +137,7 @@ public class Index { * @throws MalformedURLException is thrown if the URL for the CPE is malformed. * @throws ParserConfigurationException is thrown if the parser is misconfigured. * @throws SAXException is thrown if there is an error parsing the CPE XML. - * @throws IOException is thrown if a temporary file could not be created. + * @throws IOException is thrown if a temporary file could not be created. */ public void updateIndexFromWeb() throws MalformedURLException, ParserConfigurationException, SAXException, IOException { if (updateNeeded()) { @@ -148,7 +148,7 @@ public class Index { Downloader.fetchFile(url, outputPath); Importer.importXML(outputPath.toString()); writeLastUpdatedPropertyFile(); - + } catch (DownloadFailedException ex) { Logger.getLogger(Index.class.getName()).log(Level.SEVERE, null, ex); } finally { diff --git a/src/main/java/org/codesecure/dependencycheck/scanner/AbstractAnalyzer.java b/src/main/java/org/codesecure/dependencycheck/scanner/AbstractAnalyzer.java index b1c42ddf8..5348db287 100644 --- a/src/main/java/org/codesecure/dependencycheck/scanner/AbstractAnalyzer.java +++ b/src/main/java/org/codesecure/dependencycheck/scanner/AbstractAnalyzer.java @@ -26,19 +26,19 @@ import java.util.Set; * @author Jeremy Long (jeremy.long@gmail.com) */ public abstract class AbstractAnalyzer implements Analyzer { - + /** * Utility method to help in the creation of the extensions set. This constructs * a new Set that can be used in a final static declaration.

- * + * * This implementation was copied from http://stackoverflow.com/questions/2041778/initialize-java-hashset-values-by-construction - * + * * @param strings a list of strings to add to the set. * @return a Set of strings. */ protected static Set newHashSet(String... strings) { Set set = new HashSet(); - + //yes, in Java7 we could use Array.toList(...) - but I'm trying to keep this Java 6 compliant. for (String s : strings) { set.add(s); diff --git a/src/main/java/org/codesecure/dependencycheck/scanner/Analyzer.java b/src/main/java/org/codesecure/dependencycheck/scanner/Analyzer.java index a128eb05e..7ceb5f862 100644 --- a/src/main/java/org/codesecure/dependencycheck/scanner/Analyzer.java +++ b/src/main/java/org/codesecure/dependencycheck/scanner/Analyzer.java @@ -39,22 +39,22 @@ public interface Analyzer { * @throws IOException is thrown if there is an error reading the dependency file */ Dependency insepct(File file) throws IOException; - + /** * Returns a list of supported file extensions. An example would be an analyzer * that inpected java jar files. The getSupportedExtensions function would return * a set with a single element "jar". - * + * * @return The file extensions supported by this analyzer. */ Set getSupportedExtensions(); - + /** * Returns the name of the analyzer. * @return the name of the analyzer. */ String getName(); - + /** * Returns whether or not this analyzer can process the given extension. * @param extension the file extension to test for support. diff --git a/src/main/java/org/codesecure/dependencycheck/scanner/AnalyzerService.java b/src/main/java/org/codesecure/dependencycheck/scanner/AnalyzerService.java index d4b8579f0..07c874b84 100644 --- a/src/main/java/org/codesecure/dependencycheck/scanner/AnalyzerService.java +++ b/src/main/java/org/codesecure/dependencycheck/scanner/AnalyzerService.java @@ -22,10 +22,11 @@ import java.util.Iterator; import java.util.ServiceLoader; /** - * + * * @author Jeremy Long (jeremy.long@gmail.com) */ public class AnalyzerService { + private static AnalyzerService service; private ServiceLoader loader; @@ -46,7 +47,7 @@ public class AnalyzerService { } return service; } - + /** * Returns an Iterator for all instances of the Analyzer interface. * @return an iterator of Analyzers. diff --git a/src/main/java/org/codesecure/dependencycheck/scanner/EvidenceCollection.java b/src/main/java/org/codesecure/dependencycheck/scanner/EvidenceCollection.java index 7aaf53feb..5c90fca54 100644 --- a/src/main/java/org/codesecure/dependencycheck/scanner/EvidenceCollection.java +++ b/src/main/java/org/codesecure/dependencycheck/scanner/EvidenceCollection.java @@ -206,7 +206,7 @@ public class EvidenceCollection implements Iterable { } return ret; } -// Removed because this wasn't working right (the function returned the right data, but +// Removed because this wasn't working right (the function returned the right data, but // the use of the results was flawed. // /** // * Returns a string of evidence 'values' for a given confidence. diff --git a/src/main/java/org/codesecure/dependencycheck/scanner/JarAnalyzer.java b/src/main/java/org/codesecure/dependencycheck/scanner/JarAnalyzer.java index c4df214d4..6c99c28f9 100644 --- a/src/main/java/org/codesecure/dependencycheck/scanner/JarAnalyzer.java +++ b/src/main/java/org/codesecure/dependencycheck/scanner/JarAnalyzer.java @@ -22,11 +22,7 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.security.NoSuchAlgorithmException; -import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; -import java.util.HashSet; -import java.util.List; import java.util.Map.Entry; import java.util.Set; import java.util.jar.Attributes; @@ -52,12 +48,11 @@ import org.codesecure.dependencycheck.utils.Checksum; */ public class JarAnalyzer extends AbstractAnalyzer { - private final static String ANALYZER_NAME = "Jar Analyzer"; - + private static final String ANALYZER_NAME = "Jar Analyzer"; /** * A list of elements in the manifest to ignore. */ - private final static Set IGNORE_LIST = newHashSet( + private static final Set IGNORE_LIST = newHashSet( "built-by", "created-by", "license", @@ -70,9 +65,10 @@ public class JarAnalyzer extends AbstractAnalyzer { "archiver-version", "classpath", "bundle-manifestversion"); - - private final static Set extensions = newHashSet("jar"); - + /** + * The set of file extensions supported by this analyzer. + */ + private static final Set EXTENSIONS = newHashSet("jar"); /** * item in some manifest, should be considered medium confidence. */ @@ -91,11 +87,11 @@ public class JarAnalyzer extends AbstractAnalyzer { private static final String BUNDLE_VENDOR = "Bundle-Vendor"; //: Apache Software Foundation /** - * Returns a list of file extensions supported by this analyzer. - * @return a list of file extensions supported by this analyzer. + * Returns a list of file EXTENSIONS supported by this analyzer. + * @return a list of file EXTENSIONS supported by this analyzer. */ public Set getSupportedExtensions() { - return extensions; + return EXTENSIONS; } /** @@ -112,7 +108,7 @@ public class JarAnalyzer extends AbstractAnalyzer { * @return whether or not the specified file extension is supported by tihs analyzer. */ public boolean supportsExtension(String extension) { - return extensions.contains(extension); + return EXTENSIONS.contains(extension); } /** @@ -187,9 +183,10 @@ public class JarAnalyzer extends AbstractAnalyzer { fileNameEvidence, Evidence.Confidence.HIGH); dependency.getVendorEvidence().addEvidence("jar", "file name", fileNameEvidence, Evidence.Confidence.HIGH); - dependency.getVersionEvidence().addEvidence("jar", "file name", - fileNameEvidence, Evidence.Confidence.HIGH); - + if (fileNameEvidence.matches(".*\\d.*")) { + dependency.getVersionEvidence().addEvidence("jar", "file name", + fileNameEvidence, Evidence.Confidence.HIGH); + } String md5 = null; String sha1 = null; try { @@ -206,11 +203,6 @@ public class JarAnalyzer extends AbstractAnalyzer { parseManifest(dependency); analyzePackageNames(dependency); - //TODO - can we get "version" information from the filename? add it as medium confidence? - // strip extension. find first numeric, chop off the first part. consider replacing [_-] with . - //dependency.getVersionEvidence().addEvidence("jar", "file name", - // version from file, Evidence.Confidence.MEDIUM); - return dependency; } @@ -378,7 +370,7 @@ public class JarAnalyzer extends AbstractAnalyzer { *
  • Main Class
  • * * However, all but a handful of specific entries are read in. - * + * * @param dependency A reference to the dependency. * @throws IOException if there is an issue reading the JAR file. */ @@ -389,7 +381,7 @@ public class JarAnalyzer extends AbstractAnalyzer { EvidenceCollection vendorEvidence = dependency.getVendorEvidence(); EvidenceCollection titleEvidence = dependency.getTitleEvidence(); - EvidenceCollection versionEvidence = dependency.getVendorEvidence(); + EvidenceCollection versionEvidence = dependency.getVersionEvidence(); String source = "Manifest"; diff --git a/src/main/java/org/codesecure/dependencycheck/scanner/Scanner.java b/src/main/java/org/codesecure/dependencycheck/scanner/Scanner.java index 5947f3dbc..5e6afa896 100644 --- a/src/main/java/org/codesecure/dependencycheck/scanner/Scanner.java +++ b/src/main/java/org/codesecure/dependencycheck/scanner/Scanner.java @@ -21,14 +21,10 @@ package org.codesecure.dependencycheck.scanner; import java.io.File; import java.io.IOException; import java.util.ArrayList; -import java.util.HashMap; import java.util.Iterator; import java.util.List; -import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; -import org.codesecure.dependencycheck.utils.Settings; -import org.codesecure.dependencycheck.utils.Settings.KEYS; /** * Scans files, directories, etc. for Dependencies. Analyzers are loaded and @@ -62,7 +58,7 @@ public class Scanner { private void loadAnalyzers() { AnalyzerService service = AnalyzerService.getInstance(); Iterator iterator = service.getAnalyzers(); - while(iterator.hasNext()) { + while (iterator.hasNext()) { Analyzer a = iterator.next(); analyzers.add(a); } diff --git a/src/main/java/org/codesecure/dependencycheck/utils/CliParser.java b/src/main/java/org/codesecure/dependencycheck/utils/CliParser.java index ae2738c75..55300e2c4 100644 --- a/src/main/java/org/codesecure/dependencycheck/utils/CliParser.java +++ b/src/main/java/org/codesecure/dependencycheck/utils/CliParser.java @@ -135,6 +135,7 @@ public final class CliParser { throw new FileNotFoundException("Invalid file argument: " + path); } } + /** * Generates an Options collection that is used to parse the command line * and to display the help message. @@ -156,7 +157,8 @@ public final class CliParser { .withDescription("the name of the application being scanned").create(ArgumentName.APPNAME_SHORT); Option path = OptionBuilder.withArgName("path").hasArg().withLongOpt(ArgumentName.SCAN) - .withDescription("the path to scan - this option can be specified multiple times.").create(ArgumentName.SCAN_SHORT); + .withDescription("the path to scan - this option can be specified multiple times.") + .create(ArgumentName.SCAN_SHORT); Option load = OptionBuilder.withArgName("file").hasArg().withLongOpt(ArgumentName.CPE) .withDescription("load the CPE xml file").create(ArgumentName.CPE_SHORT); @@ -225,11 +227,11 @@ public final class CliParser { formatter.printHelp(Settings.getString("application.name", "DependencyCheck"), "\n" + Settings.getString("application.name", "DependencyCheck") + " can be used to identify if there are any known CVE vulnerabilities in libraries utillized by an application. " - + Settings.getString("application.name", "DependencyCheck") + " will automatically update required data from the Internet, such as the CVE and CPE data files from nvd.nist.gov.\n", + + Settings.getString("application.name", "DependencyCheck") + + " will automatically update required data from the Internet, such as the CVE and CPE data files from nvd.nist.gov.\n", options, "", true); } - /** * Retrieves the file command line parameter(s) specified for the 'cpe' argument. * @@ -264,6 +266,7 @@ public final class CliParser { public String getApplicationName() { return line.getOptionValue(ArgumentName.APPNAME); } + /** *

    Prints the manifest information to standard output:

    *
    • Implementation-Title: ${pom.name}
    • @@ -291,6 +294,7 @@ public final class CliParser { * line arguments. */ public static class ArgumentName { + /** * The long CLI argument name specifing the directory/file to scan */ @@ -347,6 +351,5 @@ public final class CliParser { * The short CLI argument name asking for the version. */ public static final String VERSION = "version"; - } } diff --git a/src/main/java/org/codesecure/dependencycheck/utils/DownloadFailedException.java b/src/main/java/org/codesecure/dependencycheck/utils/DownloadFailedException.java index f88fa8dac..49414b57e 100644 --- a/src/main/java/org/codesecure/dependencycheck/utils/DownloadFailedException.java +++ b/src/main/java/org/codesecure/dependencycheck/utils/DownloadFailedException.java @@ -1,30 +1,63 @@ -/* - * To change this template, choose Tools | Templates - * and open the template in the editor. - */ package org.codesecure.dependencycheck.utils; +/* + * This file is part of DependencyCheck. + * + * DependencyCheck is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * DependencyCheck is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with DependencyCheck. If not, see http://www.gnu.org/licenses/. + * + * Copyright (c) 2012 Jeremy Long. All Rights Reserved. + */ import java.io.IOException; /** - * + * An exception used when a download fails. + * * @author Jeremy Long (jeremy.long@gmail.com) */ public class DownloadFailedException extends IOException { - + private static final long serialVersionUID = 1L; - + + /** + * Creates a new DownloadFailedException. + */ public DownloadFailedException() { super(); } - + + /** + * Creates a new DownloadFailedException. + * @param msg a message for the exception. + */ public DownloadFailedException(String msg) { super(msg); } + + /** + * Creates a new DownloadFailedException. + * @param ex the cause of te download failure. + */ public DownloadFailedException(Throwable ex) { super(ex); } + + /** + * Creates a new DownloadFailedException. + * @param msg a message for the exception. + * @param ex the cause of te download failure. + */ public DownloadFailedException(String msg, Throwable ex) { - super(msg,ex); + super(msg, ex); } } diff --git a/src/main/java/org/codesecure/dependencycheck/utils/Downloader.java b/src/main/java/org/codesecure/dependencycheck/utils/Downloader.java index d27571e45..229197cec 100644 --- a/src/main/java/org/codesecure/dependencycheck/utils/Downloader.java +++ b/src/main/java/org/codesecure/dependencycheck/utils/Downloader.java @@ -42,7 +42,6 @@ public class Downloader { * Private constructor for utility class. */ private Downloader() { - } /** @@ -66,7 +65,7 @@ public class Downloader { HttpURLConnection conn = null; Proxy proxy = null; String proxyUrl = Settings.getString(Settings.KEYS.PROXY_URL); - + try { if (proxyUrl != null) { int proxyPort = Settings.getInt(Settings.KEYS.PROXY_PORT); @@ -80,11 +79,11 @@ public class Downloader { int timeout = Settings.getInt(Settings.KEYS.CONNECTION_TIMEOUT); conn.setConnectTimeout(timeout); } - + conn.connect(); } catch (IOException ex) { try { - if (conn!=null) { + if (conn != null) { conn.disconnect(); } } finally { @@ -92,13 +91,13 @@ public class Downloader { } throw new DownloadFailedException("Error downloading file.", ex); } - + BufferedOutputStream writer = null; try { //the following times out on some systems because the CPE is big. //InputStream reader = url.openStream(); InputStream reader = conn.getInputStream(); - + writer = new BufferedOutputStream(new FileOutputStream(outputPath)); byte[] buffer = new byte[4096]; int bytesRead = 0; diff --git a/src/main/java/org/codesecure/dependencycheck/utils/Settings.java b/src/main/java/org/codesecure/dependencycheck/utils/Settings.java index 4fa896eef..a8194547a 100644 --- a/src/main/java/org/codesecure/dependencycheck/utils/Settings.java +++ b/src/main/java/org/codesecure/dependencycheck/utils/Settings.java @@ -20,9 +20,6 @@ package org.codesecure.dependencycheck.utils; import java.io.IOException; import java.io.InputStream; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Map; import java.util.Properties; import java.util.logging.Level; import java.util.logging.Logger; @@ -34,7 +31,6 @@ import java.util.logging.Logger; */ public class Settings { - /** * The collection of keys used within the properties file. */ @@ -60,10 +56,6 @@ public class Settings { * The properties key for the path where the OSVDB Lucene Index will be stored. */ public static final String OSVDB_INDEX = "osvdb"; - /** - * The properties key prefix for the analyzer assocations. - */ - public static final String FILE_EXTENSION_ANALYZER_ASSOCIATION_PREFIX = "file.extension.analyzer.association."; /** * The properties key for the proxy url. */ @@ -120,7 +112,7 @@ public class Settings { public static void setString(String key, String value) { instance.props.setProperty(key, value); } - + /** * Returns a value from the properties file. If the value was specified as a * system property or passed in via the -Dprop=value argument - this method @@ -133,7 +125,7 @@ public class Settings { public static String getString(String key) { return System.getProperty(key, instance.props.getProperty(key)); } - + /** * Returns a integer value from the properties file. If the value was specified as a * system property or passed in via the -Dprop=value argument - this method @@ -146,6 +138,7 @@ public class Settings { public static int getInt(String key) { return Integer.parseInt(Settings.getString(key)); } + /** * Returns a boolean value from the properties file. If the value was specified as a * system property or passed in via the -Dprop=value argument - this method diff --git a/src/test/java/org/codesecure/dependencycheck/scanner/JarAnalyzerTest.java b/src/test/java/org/codesecure/dependencycheck/scanner/JarAnalyzerTest.java index 0d8b4de47..a0f8864dc 100644 --- a/src/test/java/org/codesecure/dependencycheck/scanner/JarAnalyzerTest.java +++ b/src/test/java/org/codesecure/dependencycheck/scanner/JarAnalyzerTest.java @@ -53,6 +53,41 @@ public class JarAnalyzerTest { assertEquals("89CE9E36AA9A9E03F1450936D2F4F8DD0F961F8B", result.getSha1sum()); assertTrue(result.getVendorEvidence().toString().toLowerCase().contains("apache")); assertTrue(result.getVendorEvidence().getWeighting().contains("apache")); + + + file = new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath()); + + result = instance.insepct(file); + boolean found = false; + for (Evidence e : result.getTitleEvidence()) { + if (e.getName().equals("package-title") && e.getValue().equals("org.mortbay.http")) { + found = true; + break; + } + } + assertTrue("package-title of org.mortbay.http not found in org.mortbay.jetty.jar", found); + + found = false; + for (Evidence e : result.getVendorEvidence()) { + if (e.getName().equals("implementation-url") && e.getValue().equals("http://jetty.mortbay.org")) { + found = true; + break; + } + } + assertTrue("implementation-url of http://jetty.mortbay.org not found in org.mortbay.jetty.jar", found); + + found = false; + for (Evidence e : result.getVersionEvidence()) { + if (e.getName().equals("Implementation-Version") && e.getValue().equals("4.2.27")) { + found = true; + break; + } + } + assertTrue("implementation-version of 4.2.27 not found in org.mortbay.jetty.jar", found); + + file = new File(this.getClass().getClassLoader().getResource("org.mortbay.jmx.jar").getPath()); + result = instance.insepct(file); + assertEquals("org.mortbar,jmx.jar has version evidence?",result.getVersionEvidence().size(),0); } /**