View Javadoc
1   /*
2    * This file is part of dependency-check-core.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   *
16   * Copyright (c) 2012 Jeremy Long. All Rights Reserved.
17   */
18  package org.owasp.dependencycheck.analyzer;
19  
20  import java.io.File;
21  
22  import org.apache.commons.io.FilenameUtils;
23  import org.apache.commons.io.filefilter.NameFileFilter;
24  import org.owasp.dependencycheck.Engine;
25  import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
26  import org.owasp.dependencycheck.dependency.Confidence;
27  import org.owasp.dependencycheck.dependency.Dependency;
28  import org.owasp.dependencycheck.utils.DependencyVersion;
29  import org.owasp.dependencycheck.utils.DependencyVersionUtil;
30  import org.owasp.dependencycheck.utils.Settings;
31  
32  /**
33   *
34   * Takes a dependency and analyzes the filename and determines the hashes.
35   *
36   * @author Jeremy Long
37   */
38  public class FileNameAnalyzer extends AbstractAnalyzer {
39  
40      //<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer">
41      /**
42       * The name of the analyzer.
43       */
44      private static final String ANALYZER_NAME = "File Name Analyzer";
45      /**
46       * The phase that this analyzer is intended to run in.
47       */
48      private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
49  
50      /**
51       * Returns the name of the analyzer.
52       *
53       * @return the name of the analyzer.
54       */
55      @Override
56      public String getName() {
57          return ANALYZER_NAME;
58      }
59  
60      /**
61       * Returns the phase that the analyzer is intended to run in.
62       *
63       * @return the phase that the analyzer is intended to run in.
64       */
65      @Override
66      public AnalysisPhase getAnalysisPhase() {
67          return ANALYSIS_PHASE;
68      }
69      /**
70       * <p>
71       * Returns the setting key to determine if the analyzer is enabled.</p>
72       *
73       * @return the key for the analyzer's enabled property
74       */
75      @Override
76      protected String getAnalyzerEnabledSettingKey() {
77          return Settings.KEYS.ANALYZER_FILE_NAME_ENABLED;
78      }
79      //</editor-fold>
80  
81      /**
82       * Python init files
83       */
84      //CSOFF: WhitespaceAfter
85      private static final NameFileFilter IGNORED_FILES = new NameFileFilter(new String[]{
86          "__init__.py",
87          "__init__.pyc",
88          "__init__.pyo",});
89      //CSON: WhitespaceAfter
90  
91      /**
92       * Collects information about the file name.
93       *
94       * @param dependency the dependency to analyze.
95       * @param engine the engine that is scanning the dependencies
96       * @throws AnalysisException is thrown if there is an error reading the JAR
97       * file.
98       */
99      @Override
100     protected void analyzeDependency(Dependency dependency, Engine engine) throws AnalysisException {
101 
102         //strip any path information that may get added by ArchiveAnalyzer, etc.
103         final File f = dependency.getActualFile();
104         final String fileName = FilenameUtils.removeExtension(f.getName());
105 
106         //add version evidence
107         final DependencyVersion version = DependencyVersionUtil.parseVersion(fileName);
108         final String packageName = DependencyVersionUtil.parsePreVersion(fileName);
109         if (version != null) {
110             // If the version number is just a number like 2 or 23, reduce the confidence
111             // a shade. This should hopefully correct for cases like log4j.jar or
112             // struts2-core.jar
113             if (version.getVersionParts() == null || version.getVersionParts().size() < 2) {
114                 dependency.getVersionEvidence().addEvidence("file", "version",
115                         version.toString(), Confidence.MEDIUM);
116             } else {
117                 dependency.getVersionEvidence().addEvidence("file", "version",
118                         version.toString(), Confidence.HIGHEST);
119             }
120             dependency.getVersionEvidence().addEvidence("file", "name",
121                     packageName, Confidence.MEDIUM);
122         }
123 
124         if (!IGNORED_FILES.accept(f)) {
125             dependency.getProductEvidence().addEvidence("file", "name",
126                     packageName, Confidence.HIGH);
127             dependency.getVendorEvidence().addEvidence("file", "name",
128                     packageName, Confidence.HIGH);
129         }
130     }
131 }