View Javadoc
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.Downloader;
26  import org.owasp.dependencycheck.utils.InvalidSettingException;
27  import org.owasp.dependencycheck.utils.Settings;
28  import org.slf4j.impl.StaticLoggerBinder;
29  
30  /**
31   * An Ant task definition to execute dependency-check update. This will download
32   * the latest data from the National Vulnerability Database (NVD) and store a
33   * copy in the local database.
34   *
35   * @author Jeremy Long
36   */
37  //While duplicate code is general bad - this is calling out getters/setters
38  //on unrelated ODC clients (the DependencyCheckScanAgent).
39  @SuppressWarnings("common-java:DuplicatedBlocks")
40  public class Update extends Purge {
41  
42      /**
43       * The NVD API endpoint.
44       */
45      private String nvdApiEndpoint;
46      /**
47       * The NVD API Key.
48       */
49      private String nvdApiKey;
50      /**
51       * The maximum number of retry requests for a single call to the NVD API.
52       */
53      private Integer nvdMaxRetryCount;
54      /**
55       * The number of hours to wait before checking for new updates from the NVD.
56       */
57      private Integer nvdValidForHours;
58      /**
59       * The NVD API Data Feed URL.
60       */
61      private String nvdDatafeedUrl;
62      /**
63       * The username for basic auth to the NVD Data Feed.
64       */
65      private String nvdUser;
66      /**
67       * The password for basic auth to the NVD Data Feed.
68       */
69      private String nvdPassword;
70      /**
71       * The time in milliseconds to wait between downloading NVD API data.
72       */
73      private int nvdApiDelay = 0;
74  
75      /**
76       * The number of records per page of NVD API data.
77       */
78      private Integer nvdApiResultsPerPage;
79  
80      /**
81       * The Proxy Server.
82       */
83      private String proxyServer;
84      /**
85       * The Proxy Port.
86       */
87      private String proxyPort;
88      /**
89       * The Proxy username.
90       */
91      private String proxyUsername;
92      /**
93       * The Proxy password.
94       */
95      private String proxyPassword;
96      /**
97       * Non proxy hosts
98       */
99      private String nonProxyHosts;
100     /**
101      * The Connection Timeout.
102      */
103     private String connectionTimeout;
104     /**
105      * The Read Timeout.
106      */
107     private String readTimeout;
108     /**
109      * The database driver name; such as org.h2.Driver.
110      */
111     private String databaseDriverName;
112     /**
113      * The path to the database driver JAR file if it is not on the class path.
114      */
115     private String databaseDriverPath;
116     /**
117      * The database connection string.
118      */
119     private String connectionString;
120     /**
121      * The user name for connecting to the database.
122      */
123     private String databaseUser;
124     /**
125      * The password to use when connecting to the database.
126      */
127     private String databasePassword;
128     /**
129      * The number of hours to wait before re-checking hosted suppressions file
130      * for updates.
131      */
132     private Integer hostedSuppressionsValidForHours;
133     /**
134      * Whether the hosted suppressions file will be updated regardless of the
135      * `autoupdate` settings. Defaults to false.
136      */
137     private Boolean hostedSuppressionsForceUpdate;
138     /**
139      * Whether the hosted suppressions file will be used. Defaults to true.
140      */
141     private Boolean hostedSuppressionsEnabled;
142 
143     /**
144      * Construct a new UpdateTask.
145      */
146     public Update() {
147         super();
148         // Call this before Dependency Check Core starts logging anything - this way, all SLF4J messages from
149         // core end up coming through this tasks logger
150         StaticLoggerBinder.getSingleton().setTask(this);
151     }
152 
153     /**
154      * Get the value of nvdApiEndpoint.
155      *
156      * @return the value of nvdApiEndpoint
157      */
158     public String getNvdApiEndpoint() {
159         return nvdApiEndpoint;
160     }
161 
162     /**
163      * Set the value of nvdApiEndpoint.
164      *
165      * @param nvdApiEndpoint new value of nvdApiEndpoint
166      */
167     public void setNvdApiEndpoint(String nvdApiEndpoint) {
168         this.nvdApiEndpoint = nvdApiEndpoint;
169     }
170 
171     /**
172      * Get the value of nvdApiKey.
173      *
174      * @return the value of nvdApiKey
175      */
176     public String getNvdApiKey() {
177         return nvdApiKey;
178     }
179 
180     /**
181      * Set the value of nvdApiKey.
182      *
183      * @param nvdApiKey new value of nvdApiKey
184      */
185     public void setNvdApiKey(String nvdApiKey) {
186         this.nvdApiKey = nvdApiKey;
187     }
188 
189     /**
190      * Get the value of nvdMaxRetryCount.
191      *
192      * @return the value of nvdMaxRetryCount
193      */
194     public int getNvdMaxRetryCounts() {
195         return nvdMaxRetryCount;
196     }
197 
198     /**
199      * Set the value of nvdMaxRetryCount.
200      *
201      * @param nvdMaxRetryCount new value of nvdMaxRetryCount
202      */
203     public void setNvdMaxRetryCount(int nvdMaxRetryCount) {
204         this.nvdMaxRetryCount = nvdMaxRetryCount;
205     }
206 
207     /**
208      * Get the value of nvdValidForHours.
209      *
210      * @return the value of nvdValidForHours
211      */
212     public int getNvdValidForHours() {
213         return nvdValidForHours;
214     }
215 
216     /**
217      * Set the value of nvdValidForHours.
218      *
219      * @param nvdValidForHours new value of nvdValidForHours
220      */
221     public void setNvdValidForHours(int nvdValidForHours) {
222         this.nvdValidForHours = nvdValidForHours;
223     }
224 
225     /**
226      * Get the value of nvdDatafeedUrl.
227      *
228      * @return the value of nvdDatafeedUrl
229      */
230     public String getNvdDatafeedUrl() {
231         return nvdDatafeedUrl;
232     }
233 
234     /**
235      * Set the value of nvdDatafeedUrl.
236      *
237      * @param nvdDatafeedUrl new value of nvdDatafeedUrl
238      */
239     public void setNvdDatafeedUrl(String nvdDatafeedUrl) {
240         this.nvdDatafeedUrl = nvdDatafeedUrl;
241     }
242 
243     /**
244      * Get the value of nvdUser.
245      *
246      * @return the value of nvdUser
247      */
248     public String getNvdUser() {
249         return nvdUser;
250     }
251 
252     /**
253      * Set the value of nvdUser.
254      *
255      * @param nvdUser new value of nvdUser
256      */
257     public void setNvdUser(String nvdUser) {
258         this.nvdUser = nvdUser;
259     }
260 
261     /**
262      * Get the value of nvdPassword.
263      *
264      * @return the value of nvdPassword
265      */
266     public String getNvdPassword() {
267         return nvdPassword;
268     }
269 
270     /**
271      * Set the value of nvdPassword.
272      *
273      * @param nvdPassword new value of nvdPassword
274      */
275     public void setNvdPassword(String nvdPassword) {
276         this.nvdPassword = nvdPassword;
277     }
278 
279     /**
280      * Get the value of nvdApiDelay.
281      *
282      * @return the value of nvdApiDelay
283      */
284     public int getNvdApiDelay() {
285         return nvdApiDelay;
286     }
287 
288     /**
289      * Set the value of nvdApiDelay.
290      *
291      * @param nvdApiDelay new value of nvdApiDelay
292      */
293     public void setNvdApiDelay(int nvdApiDelay) {
294         this.nvdApiDelay = nvdApiDelay;
295     }
296 
297     /**
298      * Get the value of nvdApiResultsPerPage.
299      *
300      * @return the value of nvdApiResultsPerPage
301      */
302     public int getNvdApiResultsPerPage() {
303         return nvdApiResultsPerPage;
304     }
305 
306     /**
307      * Set the value of nvdApiResultsPerPage.
308      *
309      * @param nvdApiResultsPerPage new value of nvdApiResultsPerPage
310      */
311     public void setApiResultsPerPage(int nvdApiResultsPerPage) {
312         this.nvdApiResultsPerPage = nvdApiResultsPerPage;
313     }
314 
315     /**
316      * Get the value of proxyServer.
317      *
318      * @return the value of proxyServer
319      */
320     public String getProxyServer() {
321         return proxyServer;
322     }
323 
324     /**
325      * Set the value of proxyServer.
326      *
327      * @param server new value of proxyServer
328      */
329     public void setProxyServer(String server) {
330         this.proxyServer = server;
331     }
332 
333     /**
334      * Get the value of proxyPort.
335      *
336      * @return the value of proxyPort
337      */
338     public String getProxyPort() {
339         return proxyPort;
340     }
341 
342     /**
343      * Set the value of proxyPort.
344      *
345      * @param proxyPort new value of proxyPort
346      */
347     public void setProxyPort(String proxyPort) {
348         this.proxyPort = proxyPort;
349     }
350 
351     /**
352      * Get the value of proxyUsername.
353      *
354      * @return the value of proxyUsername
355      */
356     public String getProxyUsername() {
357         return proxyUsername;
358     }
359 
360     /**
361      * Set the value of proxyUsername.
362      *
363      * @param proxyUsername new value of proxyUsername
364      */
365     public void setProxyUsername(String proxyUsername) {
366         this.proxyUsername = proxyUsername;
367     }
368 
369     /**
370      * Get the value of proxyPassword.
371      *
372      * @return the value of proxyPassword
373      */
374     public String getProxyPassword() {
375         return proxyPassword;
376     }
377 
378     /**
379      * Set the value of proxyPassword.
380      *
381      * @param proxyPassword new value of proxyPassword
382      */
383     public void setProxyPassword(String proxyPassword) {
384         this.proxyPassword = proxyPassword;
385     }
386 
387     /**
388      * Get the value of nonProxyHosts.
389      *
390      * @return the value of nonProxyHosts
391      */
392     public String getNonProxyHosts() {
393         return nonProxyHosts;
394     }
395 
396     /**
397      * Set the value of nonProxyHosts.
398      *
399      * @param nonProxyHosts new value of nonProxyHosts
400      */
401     public void setNonProxyHosts(String nonProxyHosts) {
402         this.nonProxyHosts = nonProxyHosts;
403     }
404 
405     /**
406      * Get the value of connectionTimeout.
407      *
408      * @return the value of connectionTimeout
409      */
410     public String getConnectionTimeout() {
411         return connectionTimeout;
412     }
413 
414     /**
415      * Set the value of connectionTimeout.
416      *
417      * @param connectionTimeout new value of connectionTimeout
418      */
419     public void setConnectionTimeout(String connectionTimeout) {
420         this.connectionTimeout = connectionTimeout;
421     }
422 
423     /**
424      * Get the value of readTimeout.
425      *
426      * @return the value of readTimeout
427      */
428     public String getReadTimeout() {
429         return readTimeout;
430     }
431 
432     /**
433      * Set the value of readTimeout.
434      *
435      * @param readTimeout new value of readTimeout
436      */
437     public void setReadTimeout(String readTimeout) {
438         this.readTimeout = readTimeout;
439     }
440 
441     /**
442      * Get the value of databaseDriverName.
443      *
444      * @return the value of databaseDriverName
445      */
446     public String getDatabaseDriverName() {
447         return databaseDriverName;
448     }
449 
450     /**
451      * Set the value of databaseDriverName.
452      *
453      * @param databaseDriverName new value of databaseDriverName
454      */
455     public void setDatabaseDriverName(String databaseDriverName) {
456         this.databaseDriverName = databaseDriverName;
457     }
458 
459     /**
460      * Get the value of databaseDriverPath.
461      *
462      * @return the value of databaseDriverPath
463      */
464     public String getDatabaseDriverPath() {
465         return databaseDriverPath;
466     }
467 
468     /**
469      * Set the value of databaseDriverPath.
470      *
471      * @param databaseDriverPath new value of databaseDriverPath
472      */
473     public void setDatabaseDriverPath(String databaseDriverPath) {
474         this.databaseDriverPath = databaseDriverPath;
475     }
476 
477     /**
478      * Get the value of connectionString.
479      *
480      * @return the value of connectionString
481      */
482     public String getConnectionString() {
483         return connectionString;
484     }
485 
486     /**
487      * Set the value of connectionString.
488      *
489      * @param connectionString new value of connectionString
490      */
491     public void setConnectionString(String connectionString) {
492         this.connectionString = connectionString;
493     }
494 
495     /**
496      * Get the value of databaseUser.
497      *
498      * @return the value of databaseUser
499      */
500     public String getDatabaseUser() {
501         return databaseUser;
502     }
503 
504     /**
505      * Set the value of databaseUser.
506      *
507      * @param databaseUser new value of databaseUser
508      */
509     public void setDatabaseUser(String databaseUser) {
510         this.databaseUser = databaseUser;
511     }
512 
513     /**
514      * Get the value of databasePassword.
515      *
516      * @return the value of databasePassword
517      */
518     public String getDatabasePassword() {
519         return databasePassword;
520     }
521 
522     /**
523      * Set the value of databasePassword.
524      *
525      * @param databasePassword new value of databasePassword
526      */
527     public void setDatabasePassword(String databasePassword) {
528         this.databasePassword = databasePassword;
529     }
530 
531     /**
532      * Get the value of hostedSuppressionsValidForHours.
533      *
534      * @return the value of hostedSuppressionsValidForHours
535      */
536     public Integer getHostedSuppressionsValidForHours() {
537         return hostedSuppressionsValidForHours;
538     }
539 
540     /**
541      * Set the value of hostedSuppressionsValidForHours.
542      *
543      * @param hostedSuppressionsValidForHours new value of
544      * hostedSuppressionsValidForHours
545      */
546     public void setHostedSuppressionsValidForHours(final Integer hostedSuppressionsValidForHours) {
547         this.hostedSuppressionsValidForHours = hostedSuppressionsValidForHours;
548     }
549 
550     /**
551      * Get the value of hostedSuppressionsForceUpdate.
552      *
553      * @return the value of hostedSuppressionsForceUpdate
554      */
555     public Boolean isHostedSuppressionsForceUpdate() {
556         return hostedSuppressionsForceUpdate;
557     }
558 
559     /**
560      * Set the value of hostedSuppressionsForceUpdate.
561      *
562      * @param hostedSuppressionsForceUpdate new value of
563      * hostedSuppressionsForceUpdate
564      */
565     public void setHostedSuppressionsForceUpdate(final Boolean hostedSuppressionsForceUpdate) {
566         this.hostedSuppressionsForceUpdate = hostedSuppressionsForceUpdate;
567     }
568 
569     /**
570      * Get the value of hostedSuppressionsEnabled.
571      *
572      * @return the value of hostedSuppressionsEnabled
573      */
574     public Boolean isHostedSuppressionsEnabled() {
575         return hostedSuppressionsEnabled;
576     }
577 
578     /**
579      * Set the value of hostedSuppressionsEnabled.
580      *
581      * @param hostedSuppressionsEnabled new value of hostedSuppressionsEnabled
582      */
583     public void setHostedSuppressionsEnabled(Boolean hostedSuppressionsEnabled) {
584         this.hostedSuppressionsEnabled = hostedSuppressionsEnabled;
585     }
586 
587     /**
588      * Executes the update by initializing the settings, downloads the NVD XML
589      * data, and then processes the data storing it in the local database.
590      *
591      * @throws BuildException thrown if a connection to the local database
592      * cannot be made.
593      */
594     //see note on `Check.dealWithReferences()` for information on this suppression
595     @SuppressWarnings("squid:RedundantThrowsDeclarationCheck")
596     @Override
597     protected void executeWithContextClassloader() throws BuildException {
598         populateSettings();
599         try {
600             Downloader.getInstance().configure(getSettings());
601         } catch (InvalidSettingException e) {
602             throw new BuildException(e);
603         }
604         try (Engine engine = new Engine(Update.class.getClassLoader(), getSettings())) {
605             engine.doUpdates();
606         } catch (UpdateException ex) {
607             if (this.isFailOnError()) {
608                 throw new BuildException(ex);
609             }
610             log(ex.getMessage(), Project.MSG_ERR);
611         } catch (DatabaseException ex) {
612             final String msg = "Unable to connect to the dependency-check database; unable to update the NVD data";
613             if (this.isFailOnError()) {
614                 throw new BuildException(msg, ex);
615             }
616             log(msg, Project.MSG_ERR);
617         } finally {
618             getSettings().cleanup();
619         }
620     }
621 
622     /**
623      * Takes the properties supplied and updates the dependency-check settings.
624      * Additionally, this sets the system properties required to change the
625      * proxy server, port, and connection timeout.
626      *
627      * @throws BuildException thrown when an invalid setting is configured.
628      */
629     //see note on `Check.dealWithReferences()` for information on this suppression
630     @SuppressWarnings("squid:RedundantThrowsDeclarationCheck")
631     @Override
632     protected void populateSettings() throws BuildException {
633         super.populateSettings();
634         getSettings().setStringIfNotEmpty(Settings.KEYS.PROXY_SERVER, proxyServer);
635         getSettings().setStringIfNotEmpty(Settings.KEYS.PROXY_PORT, proxyPort);
636         getSettings().setStringIfNotEmpty(Settings.KEYS.PROXY_USERNAME, proxyUsername);
637         getSettings().setStringIfNotEmpty(Settings.KEYS.PROXY_PASSWORD, proxyPassword);
638         getSettings().setStringIfNotEmpty(Settings.KEYS.PROXY_NON_PROXY_HOSTS, nonProxyHosts);
639         getSettings().setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout);
640         getSettings().setStringIfNotEmpty(Settings.KEYS.CONNECTION_READ_TIMEOUT, readTimeout);
641         getSettings().setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName);
642         getSettings().setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath);
643         getSettings().setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString);
644         getSettings().setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser);
645         getSettings().setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword);
646         getSettings().setIntIfNotNull(Settings.KEYS.HOSTED_SUPPRESSIONS_VALID_FOR_HOURS, hostedSuppressionsValidForHours);
647         getSettings().setBooleanIfNotNull(Settings.KEYS.HOSTED_SUPPRESSIONS_FORCEUPDATE, hostedSuppressionsForceUpdate);
648         getSettings().setBooleanIfNotNull(Settings.KEYS.HOSTED_SUPPRESSIONS_ENABLED, hostedSuppressionsEnabled);
649 
650         getSettings().setStringIfNotEmpty(Settings.KEYS.NVD_API_KEY, nvdApiKey);
651         getSettings().setStringIfNotEmpty(Settings.KEYS.NVD_API_ENDPOINT, nvdApiEndpoint);
652         getSettings().setIntIfNotNull(Settings.KEYS.NVD_API_DELAY, nvdApiDelay);
653         getSettings().setIntIfNotNull(Settings.KEYS.NVD_API_RESULTS_PER_PAGE, nvdApiResultsPerPage);
654         getSettings().setStringIfNotEmpty(Settings.KEYS.NVD_API_DATAFEED_URL, nvdDatafeedUrl);
655         getSettings().setStringIfNotEmpty(Settings.KEYS.NVD_API_DATAFEED_USER, nvdUser);
656         getSettings().setStringIfNotEmpty(Settings.KEYS.NVD_API_DATAFEED_PASSWORD, nvdPassword);
657         if (nvdMaxRetryCount != null) {
658             if (nvdMaxRetryCount > 0) {
659                 getSettings().setInt(Settings.KEYS.NVD_API_MAX_RETRY_COUNT, nvdMaxRetryCount);
660             } else {
661                 throw new BuildException("Invalid setting: `nvdMaxRetryCount` must be greater than zero");
662             }
663         }
664         if (nvdValidForHours != null) {
665             if (nvdValidForHours >= 0) {
666                 getSettings().setInt(Settings.KEYS.NVD_API_VALID_FOR_HOURS, nvdValidForHours);
667             } else {
668                 throw new BuildException("Invalid setting: `nvdValidForHours` must be 0 or greater");
669             }
670         }
671     }
672 }