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