1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.owasp.dependencycheck.analyzer;
19
20 import org.apache.commons.io.FileUtils;
21 import org.owasp.dependencycheck.Engine;
22 import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
23 import org.owasp.dependencycheck.dependency.Confidence;
24 import org.owasp.dependencycheck.dependency.Dependency;
25 import org.owasp.dependencycheck.dependency.EvidenceCollection;
26 import org.owasp.dependencycheck.utils.FileFilterBuilder;
27 import org.owasp.dependencycheck.utils.Settings;
28 import org.owasp.dependencycheck.utils.UrlStringUtils;
29
30 import java.io.File;
31 import java.io.FileFilter;
32 import java.io.IOException;
33 import java.nio.charset.Charset;
34 import java.util.ArrayList;
35 import java.util.List;
36 import java.util.regex.Matcher;
37 import java.util.regex.Pattern;
38 import org.owasp.dependencycheck.exception.InitializationException;
39
40
41
42
43
44
45
46
47
48
49 @Experimental
50 public class AutoconfAnalyzer extends AbstractFileTypeAnalyzer {
51
52
53
54
55 private static final String CONFIGURE = "configure";
56
57
58
59
60 private static final String CONFIGURE_IN = "configure.in";
61
62
63
64
65 private static final String CONFIGURE_AC = "configure.ac";
66
67
68
69
70 private static final String ANALYZER_NAME = "Autoconf Analyzer";
71
72
73
74
75 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
76
77
78
79
80 private static final String[] EXTENSIONS = {"ac", "in"};
81
82
83
84
85 private static final Pattern PACKAGE_VAR = Pattern.compile(
86 "PACKAGE_(.+?)='(.*?)'", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
87
88
89
90
91 private static final Pattern AC_INIT_PATTERN;
92
93 static {
94
95 final String param = "\\[{0,2}(.+?)\\]{0,2}";
96 final String sepParam = "\\s*,\\s*" + param;
97
98
99
100
101
102
103
104
105 AC_INIT_PATTERN = Pattern.compile(String.format(
106 "AC_INIT\\(%s%s(%s)?(%s)?(%s)?\\s*\\)", param, sepParam,
107 sepParam, sepParam, sepParam), Pattern.DOTALL
108 | Pattern.CASE_INSENSITIVE);
109 }
110
111
112
113
114 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addFilenames(CONFIGURE).addExtensions(
115 EXTENSIONS).build();
116
117
118
119
120
121
122 @Override
123 protected FileFilter getFileFilter() {
124 return FILTER;
125 }
126
127
128
129
130
131
132 @Override
133 public String getName() {
134 return ANALYZER_NAME;
135 }
136
137
138
139
140
141
142 @Override
143 public AnalysisPhase getAnalysisPhase() {
144 return ANALYSIS_PHASE;
145 }
146
147
148
149
150
151
152
153 @Override
154 protected String getAnalyzerEnabledSettingKey() {
155 return Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED;
156 }
157
158 @Override
159 protected void analyzeFileType(Dependency dependency, Engine engine)
160 throws AnalysisException {
161 final File actualFile = dependency.getActualFile();
162 final String name = actualFile.getName();
163 if (name.startsWith(CONFIGURE)) {
164 final File parent = actualFile.getParentFile();
165 final String parentName = parent.getName();
166 dependency.setDisplayFileName(parentName + "/" + name);
167 final boolean isOutputScript = CONFIGURE.equals(name);
168 if (isOutputScript || CONFIGURE_AC.equals(name)
169 || CONFIGURE_IN.equals(name)) {
170 final String contents = getFileContents(actualFile);
171 if (!contents.isEmpty()) {
172 if (isOutputScript) {
173 extractConfigureScriptEvidence(dependency, name,
174 contents);
175 } else {
176 gatherEvidence(dependency, name, contents);
177 }
178 }
179 }
180 } else {
181
182 final List<Dependency> dependencies = new ArrayList<Dependency>(
183 engine.getDependencies());
184 dependencies.remove(dependency);
185 engine.setDependencies(dependencies);
186 }
187 }
188
189
190
191
192
193
194
195
196 private void extractConfigureScriptEvidence(Dependency dependency,
197 final String name, final String contents) {
198 final Matcher matcher = PACKAGE_VAR.matcher(contents);
199 while (matcher.find()) {
200 final String variable = matcher.group(1);
201 final String value = matcher.group(2);
202 if (!value.isEmpty()) {
203 if (variable.endsWith("NAME")) {
204 dependency.getProductEvidence().addEvidence(name, variable,
205 value, Confidence.HIGHEST);
206 } else if ("VERSION".equals(variable)) {
207 dependency.getVersionEvidence().addEvidence(name, variable,
208 value, Confidence.HIGHEST);
209 } else if ("BUGREPORT".equals(variable)) {
210 dependency.getVendorEvidence().addEvidence(name, variable,
211 value, Confidence.HIGH);
212 } else if ("URL".equals(variable)) {
213 dependency.getVendorEvidence().addEvidence(name, variable,
214 value, Confidence.HIGH);
215 }
216 }
217 }
218 }
219
220
221
222
223
224
225
226
227 private String getFileContents(final File actualFile)
228 throws AnalysisException {
229 try {
230 return FileUtils.readFileToString(actualFile, Charset.defaultCharset()).trim();
231 } catch (IOException e) {
232 throw new AnalysisException(
233 "Problem occurred while reading dependency file.", e);
234 }
235 }
236
237
238
239
240
241
242
243
244 private void gatherEvidence(Dependency dependency, final String name,
245 String contents) {
246 final Matcher matcher = AC_INIT_PATTERN.matcher(contents);
247 if (matcher.find()) {
248 final EvidenceCollection productEvidence = dependency
249 .getProductEvidence();
250 productEvidence.addEvidence(name, "Package", matcher.group(1),
251 Confidence.HIGHEST);
252 dependency.getVersionEvidence().addEvidence(name,
253 "Package Version", matcher.group(2), Confidence.HIGHEST);
254 final EvidenceCollection vendorEvidence = dependency
255 .getVendorEvidence();
256 if (null != matcher.group(3)) {
257 vendorEvidence.addEvidence(name, "Bug report address",
258 matcher.group(4), Confidence.HIGH);
259 }
260 if (null != matcher.group(5)) {
261 productEvidence.addEvidence(name, "Tarname", matcher.group(6),
262 Confidence.HIGH);
263 }
264 if (null != matcher.group(7)) {
265 final String url = matcher.group(8);
266 if (UrlStringUtils.isUrl(url)) {
267 vendorEvidence.addEvidence(name, "URL", url,
268 Confidence.HIGH);
269 }
270 }
271 }
272 }
273
274
275
276
277
278
279
280 @Override
281 protected void initializeFileTypeAnalyzer() throws InitializationException {
282
283 }
284 }