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