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 java.io.File;
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.net.MalformedURLException;
24 import java.net.URL;
25 import java.util.List;
26 import java.util.Set;
27 import java.util.regex.Pattern;
28 import org.owasp.dependencycheck.exception.InitializationException;
29 import org.owasp.dependencycheck.xml.suppression.SuppressionParseException;
30 import org.owasp.dependencycheck.xml.suppression.SuppressionParser;
31 import org.owasp.dependencycheck.xml.suppression.SuppressionRule;
32 import org.owasp.dependencycheck.utils.DownloadFailedException;
33 import org.owasp.dependencycheck.utils.Downloader;
34 import org.owasp.dependencycheck.utils.FileUtils;
35 import org.owasp.dependencycheck.utils.Settings;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38 import org.xml.sax.SAXException;
39
40
41
42
43
44
45
46 public abstract class AbstractSuppressionAnalyzer extends AbstractAnalyzer {
47
48
49
50
51 private static final Logger LOGGER = LoggerFactory.getLogger(AbstractSuppressionAnalyzer.class);
52
53
54
55
56
57
58
59 public Set<String> getSupportedExtensions() {
60 return null;
61 }
62
63
64
65
66
67
68
69 @Override
70 public void initializeAnalyzer() throws InitializationException {
71 try {
72 loadSuppressionData();
73 } catch (SuppressionParseException ex) {
74 throw new InitializationException("Error initializing the suppression analyzer", ex);
75 }
76 }
77
78
79
80
81 private List<SuppressionRule> rules;
82
83
84
85
86
87
88 public List<SuppressionRule> getRules() {
89 return rules;
90 }
91
92
93
94
95
96
97 public void setRules(List<SuppressionRule> rules) {
98 this.rules = rules;
99 }
100
101
102
103
104
105
106 private void loadSuppressionData() throws SuppressionParseException {
107 final SuppressionParser parser = new SuppressionParser();
108 File file = null;
109 try {
110 final InputStream in = this.getClass().getClassLoader().getResourceAsStream("dependencycheck-base-suppression.xml");
111 rules = parser.parseSuppressionRules(in);
112 } catch (SAXException ex) {
113 throw new SuppressionParseException("Unable to parse the base suppression data file", ex);
114 }
115 final String suppressionFilePath = Settings.getString(Settings.KEYS.SUPPRESSION_FILE);
116 if (suppressionFilePath == null) {
117 return;
118 }
119 boolean deleteTempFile = false;
120 try {
121 final Pattern uriRx = Pattern.compile("^(https?|file)\\:.*", Pattern.CASE_INSENSITIVE);
122 if (uriRx.matcher(suppressionFilePath).matches()) {
123 deleteTempFile = true;
124 file = FileUtils.getTempFile("suppression", "xml");
125 final URL url = new URL(suppressionFilePath);
126 try {
127 Downloader.fetchFile(url, file, false);
128 } catch (DownloadFailedException ex) {
129 Downloader.fetchFile(url, file, true);
130 }
131 } else {
132 file = new File(suppressionFilePath);
133 InputStream suppressionsFromClasspath = null;
134 if (!file.exists()) {
135 try {
136 suppressionsFromClasspath = this.getClass().getClassLoader().getResourceAsStream(suppressionFilePath);
137 if (suppressionsFromClasspath != null) {
138 deleteTempFile = true;
139 file = FileUtils.getTempFile("suppression", "xml");
140 try {
141 org.apache.commons.io.FileUtils.copyInputStreamToFile(suppressionsFromClasspath, file);
142 } catch (IOException ex) {
143 throwSuppressionParseException("Unable to locate suppressions file in classpath", ex);
144 }
145 }
146 } finally {
147 if (suppressionsFromClasspath != null) {
148 try {
149 suppressionsFromClasspath.close();
150 } catch (IOException ex) {
151 LOGGER.debug("Failed to close stream", ex);
152 }
153 }
154 }
155 }
156 }
157 if (file != null) {
158 if (!file.exists()) {
159 final String msg = String.format("Suppression file '%s' does not exists", file.getPath());
160 LOGGER.warn(msg);
161 throw new SuppressionParseException(msg);
162 }
163 try {
164 rules.addAll(parser.parseSuppressionRules(file));
165 LOGGER.debug("{} suppression rules were loaded.", rules.size());
166 } catch (SuppressionParseException ex) {
167 LOGGER.warn("Unable to parse suppression xml file '{}'", file.getPath());
168 LOGGER.warn(ex.getMessage());
169 throw ex;
170 }
171 }
172 } catch (DownloadFailedException ex) {
173 throwSuppressionParseException("Unable to fetch the configured suppression file", ex);
174 } catch (MalformedURLException ex) {
175 throwSuppressionParseException("Configured suppression file has an invalid URL", ex);
176 } catch (SuppressionParseException ex) {
177 throw ex;
178 } catch (IOException ex) {
179 throwSuppressionParseException("Unable to create temp file for suppressions", ex);
180 } finally {
181 if (deleteTempFile && file != null) {
182 FileUtils.delete(file);
183 }
184 }
185 }
186
187
188
189
190
191
192
193
194
195 private void throwSuppressionParseException(String message, Exception exception) throws SuppressionParseException {
196 LOGGER.warn(message);
197 LOGGER.debug("", exception);
198 throw new SuppressionParseException(message, exception);
199 }
200 }