1 /*
2 * This file is part of dependency-check-ant.
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) 2015 Jeremy Long. All Rights Reserved.
17 */
18 package org.owasp.dependencycheck.taskdefs;
19
20 import org.apache.tools.ant.BuildException;
21 import org.apache.tools.ant.Project;
22 import org.owasp.dependencycheck.Engine;
23 import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
24 import org.owasp.dependencycheck.data.update.exception.UpdateException;
25 import org.owasp.dependencycheck.utils.Settings;
26 import org.slf4j.impl.StaticLoggerBinder;
27
28 /**
29 * An Ant task definition to execute dependency-check update. This will download
30 * the latest data from the National Vulnerability Database (NVD) and store a
31 * copy in the local database.
32 *
33 * @author Jeremy Long
34 */
35 public class Update extends Purge {
36
37 /**
38 * Construct a new UpdateTask.
39 */
40 public Update() {
41 super();
42 // Call this before Dependency Check Core starts logging anything - this way, all SLF4J messages from
43 // core end up coming through this tasks logger
44 StaticLoggerBinder.getSingleton().setTask(this);
45 }
46
47 /**
48 * The Proxy Server.
49 */
50 private String proxyServer;
51
52 /**
53 * Get the value of proxyServer.
54 *
55 * @return the value of proxyServer
56 */
57 public String getProxyServer() {
58 return proxyServer;
59 }
60
61 /**
62 * Set the value of proxyServer.
63 *
64 * @param server new value of proxyServer
65 */
66 public void setProxyServer(String server) {
67 this.proxyServer = server;
68 }
69
70 /**
71 * The Proxy Port.
72 */
73 private String proxyPort;
74
75 /**
76 * Get the value of proxyPort.
77 *
78 * @return the value of proxyPort
79 */
80 public String getProxyPort() {
81 return proxyPort;
82 }
83
84 /**
85 * Set the value of proxyPort.
86 *
87 * @param proxyPort new value of proxyPort
88 */
89 public void setProxyPort(String proxyPort) {
90 this.proxyPort = proxyPort;
91 }
92 /**
93 * The Proxy username.
94 */
95 private String proxyUsername;
96
97 /**
98 * Get the value of proxyUsername.
99 *
100 * @return the value of proxyUsername
101 */
102 public String getProxyUsername() {
103 return proxyUsername;
104 }
105
106 /**
107 * Set the value of proxyUsername.
108 *
109 * @param proxyUsername new value of proxyUsername
110 */
111 public void setProxyUsername(String proxyUsername) {
112 this.proxyUsername = proxyUsername;
113 }
114 /**
115 * The Proxy password.
116 */
117 private String proxyPassword;
118
119 /**
120 * Get the value of proxyPassword.
121 *
122 * @return the value of proxyPassword
123 */
124 public String getProxyPassword() {
125 return proxyPassword;
126 }
127
128 /**
129 * Set the value of proxyPassword.
130 *
131 * @param proxyPassword new value of proxyPassword
132 */
133 public void setProxyPassword(String proxyPassword) {
134 this.proxyPassword = proxyPassword;
135 }
136 /**
137 * The Connection Timeout.
138 */
139 private String connectionTimeout;
140
141 /**
142 * Get the value of connectionTimeout.
143 *
144 * @return the value of connectionTimeout
145 */
146 public String getConnectionTimeout() {
147 return connectionTimeout;
148 }
149
150 /**
151 * Set the value of connectionTimeout.
152 *
153 * @param connectionTimeout new value of connectionTimeout
154 */
155 public void setConnectionTimeout(String connectionTimeout) {
156 this.connectionTimeout = connectionTimeout;
157 }
158 /**
159 * The database driver name; such as org.h2.Driver.
160 */
161 private String databaseDriverName;
162
163 /**
164 * Get the value of databaseDriverName.
165 *
166 * @return the value of databaseDriverName
167 */
168 public String getDatabaseDriverName() {
169 return databaseDriverName;
170 }
171
172 /**
173 * Set the value of databaseDriverName.
174 *
175 * @param databaseDriverName new value of databaseDriverName
176 */
177 public void setDatabaseDriverName(String databaseDriverName) {
178 this.databaseDriverName = databaseDriverName;
179 }
180
181 /**
182 * The path to the database driver JAR file if it is not on the class path.
183 */
184 private String databaseDriverPath;
185
186 /**
187 * Get the value of databaseDriverPath.
188 *
189 * @return the value of databaseDriverPath
190 */
191 public String getDatabaseDriverPath() {
192 return databaseDriverPath;
193 }
194
195 /**
196 * Set the value of databaseDriverPath.
197 *
198 * @param databaseDriverPath new value of databaseDriverPath
199 */
200 public void setDatabaseDriverPath(String databaseDriverPath) {
201 this.databaseDriverPath = databaseDriverPath;
202 }
203 /**
204 * The database connection string.
205 */
206 private String connectionString;
207
208 /**
209 * Get the value of connectionString.
210 *
211 * @return the value of connectionString
212 */
213 public String getConnectionString() {
214 return connectionString;
215 }
216
217 /**
218 * Set the value of connectionString.
219 *
220 * @param connectionString new value of connectionString
221 */
222 public void setConnectionString(String connectionString) {
223 this.connectionString = connectionString;
224 }
225 /**
226 * The user name for connecting to the database.
227 */
228 private String databaseUser;
229
230 /**
231 * Get the value of databaseUser.
232 *
233 * @return the value of databaseUser
234 */
235 public String getDatabaseUser() {
236 return databaseUser;
237 }
238
239 /**
240 * Set the value of databaseUser.
241 *
242 * @param databaseUser new value of databaseUser
243 */
244 public void setDatabaseUser(String databaseUser) {
245 this.databaseUser = databaseUser;
246 }
247
248 /**
249 * The password to use when connecting to the database.
250 */
251 private String databasePassword;
252
253 /**
254 * Get the value of databasePassword.
255 *
256 * @return the value of databasePassword
257 */
258 public String getDatabasePassword() {
259 return databasePassword;
260 }
261
262 /**
263 * Set the value of databasePassword.
264 *
265 * @param databasePassword new value of databasePassword
266 */
267 public void setDatabasePassword(String databasePassword) {
268 this.databasePassword = databasePassword;
269 }
270
271 /**
272 * The url for the modified NVD CVE (1.2 schema).
273 */
274 private String cveUrl12Modified;
275
276 /**
277 * Get the value of cveUrl12Modified.
278 *
279 * @return the value of cveUrl12Modified
280 */
281 public String getCveUrl12Modified() {
282 return cveUrl12Modified;
283 }
284
285 /**
286 * Set the value of cveUrl12Modified.
287 *
288 * @param cveUrl12Modified new value of cveUrl12Modified
289 */
290 public void setCveUrl12Modified(String cveUrl12Modified) {
291 this.cveUrl12Modified = cveUrl12Modified;
292 }
293
294 /**
295 * The url for the modified NVD CVE (2.0 schema).
296 */
297 private String cveUrl20Modified;
298
299 /**
300 * Get the value of cveUrl20Modified.
301 *
302 * @return the value of cveUrl20Modified
303 */
304 public String getCveUrl20Modified() {
305 return cveUrl20Modified;
306 }
307
308 /**
309 * Set the value of cveUrl20Modified.
310 *
311 * @param cveUrl20Modified new value of cveUrl20Modified
312 */
313 public void setCveUrl20Modified(String cveUrl20Modified) {
314 this.cveUrl20Modified = cveUrl20Modified;
315 }
316
317 /**
318 * Base Data Mirror URL for CVE 1.2.
319 */
320 private String cveUrl12Base;
321
322 /**
323 * Get the value of cveUrl12Base.
324 *
325 * @return the value of cveUrl12Base
326 */
327 public String getCveUrl12Base() {
328 return cveUrl12Base;
329 }
330
331 /**
332 * Set the value of cveUrl12Base.
333 *
334 * @param cveUrl12Base new value of cveUrl12Base
335 */
336 public void setCveUrl12Base(String cveUrl12Base) {
337 this.cveUrl12Base = cveUrl12Base;
338 }
339
340 /**
341 * Data Mirror URL for CVE 2.0.
342 */
343 private String cveUrl20Base;
344
345 /**
346 * Get the value of cveUrl20Base.
347 *
348 * @return the value of cveUrl20Base
349 */
350 public String getCveUrl20Base() {
351 return cveUrl20Base;
352 }
353
354 /**
355 * Set the value of cveUrl20Base.
356 *
357 * @param cveUrl20Base new value of cveUrl20Base
358 */
359 public void setCveUrl20Base(String cveUrl20Base) {
360 this.cveUrl20Base = cveUrl20Base;
361 }
362
363 /**
364 * The number of hours to wait before re-checking for updates.
365 */
366 private Integer cveValidForHours;
367
368 /**
369 * Get the value of cveValidForHours.
370 *
371 * @return the value of cveValidForHours
372 */
373 public Integer getCveValidForHours() {
374 return cveValidForHours;
375 }
376
377 /**
378 * Set the value of cveValidForHours.
379 *
380 * @param cveValidForHours new value of cveValidForHours
381 */
382 public void setCveValidForHours(Integer cveValidForHours) {
383 this.cveValidForHours = cveValidForHours;
384 }
385
386 /**
387 * Executes the update by initializing the settings, downloads the NVD XML
388 * data, and then processes the data storing it in the local database.
389 *
390 * @throws BuildException thrown if a connection to the local database
391 * cannot be made.
392 */
393 @Override
394 public void execute() throws BuildException {
395 populateSettings();
396 Engine engine = null;
397 try {
398 engine = new Engine(Update.class.getClassLoader());
399 try {
400 engine.doUpdates();
401 } catch (UpdateException ex) {
402 if (this.isFailOnError()) {
403 throw new BuildException(ex);
404 }
405 log(ex.getMessage(), Project.MSG_ERR);
406 }
407 } catch (DatabaseException ex) {
408 final String msg = "Unable to connect to the dependency-check database; unable to update the NVD data";
409 if (this.isFailOnError()) {
410 throw new BuildException(msg, ex);
411 }
412 log(msg, Project.MSG_ERR);
413 } finally {
414 Settings.cleanup(true);
415 if (engine != null) {
416 engine.cleanup();
417 }
418 }
419 }
420
421 /**
422 * Takes the properties supplied and updates the dependency-check settings.
423 * Additionally, this sets the system properties required to change the
424 * proxy server, port, and connection timeout.
425 *
426 * @throws BuildException thrown when an invalid setting is configured.
427 */
428 @Override
429 protected void populateSettings() throws BuildException {
430 super.populateSettings();
431 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_SERVER, proxyServer);
432 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PORT, proxyPort);
433 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_USERNAME, proxyUsername);
434 Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PASSWORD, proxyPassword);
435 Settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout);
436 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName);
437 Settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath);
438 Settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString);
439 Settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser);
440 Settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword);
441 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_12_URL, cveUrl12Modified);
442 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_MODIFIED_20_URL, cveUrl20Modified);
443 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_1_2, cveUrl12Base);
444 Settings.setStringIfNotEmpty(Settings.KEYS.CVE_SCHEMA_2_0, cveUrl20Base);
445 if (cveValidForHours != null) {
446 if (cveValidForHours >= 0) {
447 Settings.setInt(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, cveValidForHours);
448 } else {
449 throw new BuildException("Invalid setting: `cpeValidForHours` must be 0 or greater");
450 }
451 }
452 }
453 }