auto-format changed indentations

Former-commit-id: 1ef56dd84a5167644c2767cefdee54d555175c55
This commit is contained in:
Jeremy Long
2015-05-02 07:30:15 -04:00
parent e227b90370
commit 4f18e9ee7f

View File

@@ -47,298 +47,291 @@ import org.owasp.dependencycheck.utils.Settings;
import org.owasp.dependencycheck.utils.UrlStringUtils; import org.owasp.dependencycheck.utils.UrlStringUtils;
/** /**
* Used to analyze a Wheel or egg distriution files, or their contents in * Used to analyze a Wheel or egg distriution files, or their contents in unzipped form, and collect information that can be used
* unzipped form, and collect information that can be used to determine the * to determine the associated CPE.
* associated CPE.
* *
* @author Dale Visser <dvisser@ida.org> * @author Dale Visser <dvisser@ida.org>
*/ */
public class PythonDistributionAnalyzer extends AbstractFileTypeAnalyzer { public class PythonDistributionAnalyzer extends AbstractFileTypeAnalyzer {
/** /**
* Name of egg metatdata files to analyze. * Name of egg metatdata files to analyze.
*/ */
private static final String PKG_INFO = "PKG-INFO"; private static final String PKG_INFO = "PKG-INFO";
/** /**
* Name of wheel metadata files to analyze. * Name of wheel metadata files to analyze.
*/ */
private static final String METADATA = "METADATA"; private static final String METADATA = "METADATA";
/** /**
* The logger. * The logger.
*/ */
private static final Logger LOGGER = Logger private static final Logger LOGGER = Logger
.getLogger(PythonDistributionAnalyzer.class.getName()); .getLogger(PythonDistributionAnalyzer.class.getName());
/** /**
* The count of directories created during analysis. This is used for * The count of directories created during analysis. This is used for creating temporary directories.
* creating temporary directories. */
*/ private static int dirCount = 0;
private static int dirCount = 0;
/** /**
* The name of the analyzer. * The name of the analyzer.
*/ */
private static final String ANALYZER_NAME = "Python Distribution Analyzer"; private static final String ANALYZER_NAME = "Python Distribution Analyzer";
/** /**
* The phase that this analyzer is intended to run in. * The phase that this analyzer is intended to run in.
*/ */
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
/** /**
* The set of file extensions supported by this analyzer. * The set of file extensions supported by this analyzer.
*/ */
private static final Set<String> EXTENSIONS = newHashSet("whl", "egg", private static final Set<String> EXTENSIONS = newHashSet("whl", "egg",
"zip", METADATA, PKG_INFO); "zip", METADATA, PKG_INFO);
/** /**
* Used to match on egg archive candidate extenssions. * Used to match on egg archive candidate extenssions.
*/ */
private static final Pattern EGG_OR_ZIP = Pattern.compile("egg|zip"); private static final Pattern EGG_OR_ZIP = Pattern.compile("egg|zip");
/** /**
* The parent directory for the individual directories per archive. * The parent directory for the individual directories per archive.
*/ */
private File tempFileLocation; private File tempFileLocation;
/** /**
* Filter that detects *.dist-info files (but doesn't verify they are * Filter that detects *.dist-info files (but doesn't verify they are directories.
* directories. */
*/ private static final FilenameFilter DIST_INFO_FILTER = new SuffixFileFilter(
private static final FilenameFilter DIST_INFO_FILTER = new SuffixFileFilter( ".dist-info");
".dist-info");
/** /**
* Filter that detects files named "METADATA". * Filter that detects files named "METADATA".
*/ */
private static final FilenameFilter EGG_INFO_FILTER = new NameFileFilter( private static final FilenameFilter EGG_INFO_FILTER = new NameFileFilter(
"EGG-INFO"); "EGG-INFO");
/** /**
* Filter that detects files named "METADATA". * Filter that detects files named "METADATA".
*/ */
private static final FilenameFilter METADATA_FILTER = new NameFileFilter( private static final FilenameFilter METADATA_FILTER = new NameFileFilter(
METADATA); METADATA);
/** /**
* Filter that detects files named "PKG-INFO". * Filter that detects files named "PKG-INFO".
*/ */
private static final FilenameFilter PKG_INFO_FILTER = new NameFileFilter( private static final FilenameFilter PKG_INFO_FILTER = new NameFileFilter(
PKG_INFO); PKG_INFO);
/** /**
* Returns 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. * @return a list of file EXTENSIONS supported by this analyzer.
*/ */
@Override @Override
public Set<String> getSupportedExtensions() { public Set<String> getSupportedExtensions() {
return EXTENSIONS; return EXTENSIONS;
} }
/** /**
* Returns the name of the analyzer. * Returns the name of the analyzer.
* *
* @return the name of the analyzer. * @return the name of the analyzer.
*/ */
@Override @Override
public String getName() { public String getName() {
return ANALYZER_NAME; return ANALYZER_NAME;
} }
/** /**
* Returns the phase that the analyzer is intended to run in. * Returns the phase that the analyzer is intended to run in.
* *
* @return the phase that the analyzer is intended to run in. * @return the phase that the analyzer is intended to run in.
*/ */
public AnalysisPhase getAnalysisPhase() { public AnalysisPhase getAnalysisPhase() {
return ANALYSIS_PHASE; return ANALYSIS_PHASE;
} }
/** /**
* Returns the key used in the properties file to reference the analyzer's * Returns the key used in the properties file to reference the analyzer's enabled property.
* enabled property. *
* * @return the analyzer's enabled property setting key
* @return the analyzer's enabled property setting key */
*/ @Override
@Override protected String getAnalyzerEnabledSettingKey() {
protected String getAnalyzerEnabledSettingKey() { return Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED;
return Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED; }
}
@Override @Override
protected void analyzeFileType(Dependency dependency, Engine engine) protected void analyzeFileType(Dependency dependency, Engine engine)
throws AnalysisException { throws AnalysisException {
if ("whl".equals(dependency.getFileExtension())) { if ("whl".equals(dependency.getFileExtension())) {
collectMetadataFromArchiveFormat(dependency, DIST_INFO_FILTER, collectMetadataFromArchiveFormat(dependency, DIST_INFO_FILTER,
METADATA_FILTER); METADATA_FILTER);
} else if (EGG_OR_ZIP.matcher( } else if (EGG_OR_ZIP.matcher(
StringUtils.stripToEmpty(dependency.getFileExtension())) StringUtils.stripToEmpty(dependency.getFileExtension()))
.matches()) { .matches()) {
collectMetadataFromArchiveFormat(dependency, EGG_INFO_FILTER, collectMetadataFromArchiveFormat(dependency, EGG_INFO_FILTER,
PKG_INFO_FILTER); PKG_INFO_FILTER);
} else { } else {
final File actualFile = dependency.getActualFile(); final File actualFile = dependency.getActualFile();
final String name = actualFile.getName(); final String name = actualFile.getName();
final boolean metadata = METADATA.equals(name); final boolean metadata = METADATA.equals(name);
if (metadata || PKG_INFO.equals(name)) { if (metadata || PKG_INFO.equals(name)) {
final File parent = actualFile.getParentFile(); final File parent = actualFile.getParentFile();
final String parentName = parent.getName(); final String parentName = parent.getName();
dependency.setDisplayFileName(parentName + "/" + name); dependency.setDisplayFileName(parentName + "/" + name);
if (parent.isDirectory() if (parent.isDirectory()
&& (metadata && parentName.endsWith(".dist-info") && (metadata && parentName.endsWith(".dist-info")
|| parentName.endsWith(".egg-info") || "EGG-INFO" || parentName.endsWith(".egg-info") || "EGG-INFO"
.equals(parentName))) { .equals(parentName))) {
collectWheelMetadata(dependency, actualFile); collectWheelMetadata(dependency, actualFile);
} }
} }
} }
} }
private void collectMetadataFromArchiveFormat(Dependency dependency, private void collectMetadataFromArchiveFormat(Dependency dependency,
FilenameFilter folderFilter, FilenameFilter metadataFilter) FilenameFilter folderFilter, FilenameFilter metadataFilter)
throws AnalysisException { throws AnalysisException {
final File temp = getNextTempDirectory(); final File temp = getNextTempDirectory();
LOGGER.fine(String.format("%s exists? %b", temp, temp.exists())); LOGGER.fine(String.format("%s exists? %b", temp, temp.exists()));
try { try {
ExtractionUtil.extractFilesUsingFilter( ExtractionUtil.extractFilesUsingFilter(
new File(dependency.getActualFilePath()), temp, new File(dependency.getActualFilePath()), temp,
metadataFilter); metadataFilter);
} catch (ExtractionException ex) { } catch (ExtractionException ex) {
throw new AnalysisException(ex); throw new AnalysisException(ex);
} }
collectWheelMetadata( collectWheelMetadata(
dependency, dependency,
getMatchingFile(getMatchingFile(temp, folderFilter), getMatchingFile(getMatchingFile(temp, folderFilter),
metadataFilter)); metadataFilter));
} }
/** /**
* Makes sure a usable temporary directory is available. * Makes sure a usable temporary directory is available.
*/ */
@Override @Override
protected void initializeFileTypeAnalyzer() throws Exception { protected void initializeFileTypeAnalyzer() throws Exception {
final File baseDir = Settings.getTempDirectory(); final File baseDir = Settings.getTempDirectory();
tempFileLocation = File.createTempFile("check", "tmp", baseDir); tempFileLocation = File.createTempFile("check", "tmp", baseDir);
if (!tempFileLocation.delete()) { if (!tempFileLocation.delete()) {
final String msg = String.format( final String msg = String.format(
"Unable to delete temporary file '%s'.", "Unable to delete temporary file '%s'.",
tempFileLocation.getAbsolutePath()); tempFileLocation.getAbsolutePath());
throw new AnalysisException(msg); throw new AnalysisException(msg);
} }
if (!tempFileLocation.mkdirs()) { if (!tempFileLocation.mkdirs()) {
final String msg = String.format( final String msg = String.format(
"Unable to create directory '%s'.", "Unable to create directory '%s'.",
tempFileLocation.getAbsolutePath()); tempFileLocation.getAbsolutePath());
throw new AnalysisException(msg); throw new AnalysisException(msg);
} }
} }
/** /**
* Deletes any files extracted from the Wheel during analysis. * Deletes any files extracted from the Wheel during analysis.
*/ */
@Override @Override
public void close() { public void close() {
if (tempFileLocation != null && tempFileLocation.exists()) { if (tempFileLocation != null && tempFileLocation.exists()) {
LOGGER.log(Level.FINE, "Attempting to delete temporary files"); LOGGER.log(Level.FINE, "Attempting to delete temporary files");
final boolean success = FileUtils.delete(tempFileLocation); final boolean success = FileUtils.delete(tempFileLocation);
if (!success) { if (!success) {
LOGGER.log(Level.WARNING, LOGGER.log(Level.WARNING,
"Failed to delete some temporary files, see the log for more details"); "Failed to delete some temporary files, see the log for more details");
} }
} }
} }
/** /**
* Gathers evidence from the METADATA file. * Gathers evidence from the METADATA file.
* *
* @param dependency * @param dependency the dependency being analyzed
* the dependency being analyzed * @throws MalformedURLException
* @throws MalformedURLException */
*/ private static void collectWheelMetadata(Dependency dependency, File file)
private static void collectWheelMetadata(Dependency dependency, File file) throws AnalysisException {
throws AnalysisException { final InternetHeaders headers = getManifestProperties(file);
final InternetHeaders headers = getManifestProperties(file); addPropertyToEvidence(headers, dependency.getVersionEvidence(),
addPropertyToEvidence(headers, dependency.getVersionEvidence(), "Version", Confidence.HIGHEST);
"Version", Confidence.HIGHEST); addPropertyToEvidence(headers, dependency.getProductEvidence(), "Name",
addPropertyToEvidence(headers, dependency.getProductEvidence(), "Name", Confidence.HIGHEST);
Confidence.HIGHEST); final String url = headers.getHeader("Home-page", null);
final String url = headers.getHeader("Home-page", null); final EvidenceCollection vendorEvidence = dependency
final EvidenceCollection vendorEvidence = dependency .getVendorEvidence();
.getVendorEvidence(); if (StringUtils.isNotBlank(url)) {
if (StringUtils.isNotBlank(url)) { if (UrlStringUtils.isUrl(url)) {
if (UrlStringUtils.isUrl(url)) { vendorEvidence.addEvidence(METADATA, "vendor", url,
vendorEvidence.addEvidence(METADATA, "vendor", url, Confidence.MEDIUM);
Confidence.MEDIUM); }
} }
} addPropertyToEvidence(headers, vendorEvidence, "Author", Confidence.LOW);
addPropertyToEvidence(headers, vendorEvidence, "Author", Confidence.LOW); final String summary = headers.getHeader("Summary", null);
final String summary = headers.getHeader("Summary", null); if (StringUtils.isNotBlank(summary)) {
if (StringUtils.isNotBlank(summary)) { JarAnalyzer
JarAnalyzer .addDescription(dependency, summary, METADATA, "summary");
.addDescription(dependency, summary, METADATA, "summary"); }
} }
}
private static void addPropertyToEvidence(InternetHeaders headers, private static void addPropertyToEvidence(InternetHeaders headers,
EvidenceCollection evidence, String property, Confidence confidence) { EvidenceCollection evidence, String property, Confidence confidence) {
final String value = headers.getHeader(property, null); final String value = headers.getHeader(property, null);
LOGGER.fine(String.format("Property: %s, Value: %s\n", property, value)); LOGGER.fine(String.format("Property: %s, Value: %s\n", property, value));
if (StringUtils.isNotBlank(value)) { if (StringUtils.isNotBlank(value)) {
evidence.addEvidence(METADATA, property, value, confidence); evidence.addEvidence(METADATA, property, value, confidence);
} }
} }
private static final File getMatchingFile(File folder, FilenameFilter filter) { private static final File getMatchingFile(File folder, FilenameFilter filter) {
File result = null; File result = null;
final File[] matches = folder.listFiles(filter); final File[] matches = folder.listFiles(filter);
if (null != matches && 1 == matches.length) { if (null != matches && 1 == matches.length) {
result = matches[0]; result = matches[0];
} }
return result; return result;
} }
private static InternetHeaders getManifestProperties(File manifest) { private static InternetHeaders getManifestProperties(File manifest) {
final InternetHeaders result = new InternetHeaders(); final InternetHeaders result = new InternetHeaders();
if (null == manifest) { if (null == manifest) {
LOGGER.fine("Manifest file not found."); LOGGER.fine("Manifest file not found.");
} else { } else {
try { try {
result.load(new AutoCloseInputStream(new BufferedInputStream( result.load(new AutoCloseInputStream(new BufferedInputStream(
new FileInputStream(manifest)))); new FileInputStream(manifest))));
} catch (MessagingException e) { } catch (MessagingException e) {
LOGGER.log(Level.WARNING, e.getMessage(), e); LOGGER.log(Level.WARNING, e.getMessage(), e);
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
LOGGER.log(Level.WARNING, e.getMessage(), e); LOGGER.log(Level.WARNING, e.getMessage(), e);
} }
} }
return result; return result;
} }
/** /**
* Retrieves the next temporary destingation directory for extracting an * Retrieves the next temporary destingation directory for extracting an archive.
* archive. *
* * @return a directory
* @return a directory * @throws AnalysisException thrown if unable to create temporary directory
* @throws AnalysisException */
* thrown if unable to create temporary directory private File getNextTempDirectory() throws AnalysisException {
*/ File directory;
private File getNextTempDirectory() throws AnalysisException {
File directory;
// getting an exception for some directories not being able to be // getting an exception for some directories not being able to be
// created; might be because the directory already exists? // created; might be because the directory already exists?
do { do {
dirCount += 1; dirCount += 1;
directory = new File(tempFileLocation, String.valueOf(dirCount)); directory = new File(tempFileLocation, String.valueOf(dirCount));
} while (directory.exists()); } while (directory.exists());
if (!directory.mkdirs()) { if (!directory.mkdirs()) {
throw new AnalysisException(String.format( throw new AnalysisException(String.format(
"Unable to create temp directory '%s'.", "Unable to create temp directory '%s'.",
directory.getAbsolutePath())); directory.getAbsolutePath()));
} }
return directory; return directory;
} }
} }