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) 2013 Jeremy Long. All Rights Reserved.
17   */
18  package org.owasp.dependencycheck.taskdefs;
19  
20  import java.io.File;
21  import java.io.IOException;
22  import java.io.InputStream;
23  import java.util.List;
24  import java.util.logging.Level;
25  import java.util.logging.Logger;
26  import org.apache.tools.ant.BuildException;
27  import org.apache.tools.ant.Task;
28  import org.apache.tools.ant.types.EnumeratedAttribute;
29  import org.apache.tools.ant.types.Reference;
30  import org.apache.tools.ant.types.Resource;
31  import org.apache.tools.ant.types.ResourceCollection;
32  import org.apache.tools.ant.types.resources.FileProvider;
33  import org.apache.tools.ant.types.resources.Resources;
34  import org.owasp.dependencycheck.Engine;
35  import org.owasp.dependencycheck.data.nvdcve.CveDB;
36  import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
37  import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties;
38  import org.owasp.dependencycheck.dependency.Dependency;
39  import org.owasp.dependencycheck.dependency.Identifier;
40  import org.owasp.dependencycheck.dependency.Vulnerability;
41  import org.owasp.dependencycheck.reporting.ReportGenerator;
42  import org.owasp.dependencycheck.reporting.ReportGenerator.Format;
43  import org.owasp.dependencycheck.utils.LogUtils;
44  import org.owasp.dependencycheck.utils.Settings;
45  
46  /**
47   * An Ant task definition to execute dependency-check during an Ant build.
48   *
49   * @author Jeremy Long <jeremy.long@owasp.org>
50   */
51  public class DependencyCheckTask extends Task {
52  
53      /**
54       * The properties file location.
55       */
56      private static final String PROPERTIES_FILE = "task.properties";
57      /**
58       * Name of the logging properties file.
59       */
60      private static final String LOG_PROPERTIES_FILE = "log.properties";
61      /**
62       * System specific new line character.
63       */
64      private static final String NEW_LINE = System.getProperty("line.separator", "\n").intern();
65  
66      /**
67       * Construct a new DependencyCheckTask.
68       */
69      public DependencyCheckTask() {
70          super();
71      }
72      //The following code was copied Apache Ant PathConvert
73      //BEGIN COPY from org.apache.tools.ant.taskdefs.PathConvert
74      /**
75       * Path to be converted
76       */
77      private Resources path = null;
78      /**
79       * Reference to path/fileset to convert
80       */
81      private Reference refid = null;
82  
83      /**
84       * Add an arbitrary ResourceCollection.
85       *
86       * @param rc the ResourceCollection to add.
87       * @since Ant 1.7
88       */
89      public void add(ResourceCollection rc) {
90          if (isReference()) {
91              throw new BuildException("Nested elements are not allowed when using the refid attribute.");
92          }
93          getPath().add(rc);
94      }
95  
96      /**
97       * Returns the path. If the path has not been initialized yet, this class is synchronized, and will instantiate the
98       * path object.
99       *
100      * @return the path
101      */
102     private synchronized Resources getPath() {
103         if (path == null) {
104             path = new Resources(getProject());
105             path.setCache(true);
106         }
107         return path;
108     }
109 
110     /**
111      * Learn whether the refid attribute of this element been set.
112      *
113      * @return true if refid is valid.
114      */
115     public boolean isReference() {
116         return refid != null;
117     }
118 
119     /**
120      * Add a reference to a Path, FileSet, DirSet, or FileList defined elsewhere.
121      *
122      * @param r the reference to a path, fileset, dirset or filelist.
123      */
124     public void setRefid(Reference r) {
125         if (path != null) {
126             throw new BuildException("Nested elements are not allowed when using the refid attribute.");
127         }
128         refid = r;
129     }
130 
131     /**
132      * If this is a reference, this method will add the referenced resource collection to the collection of paths.
133      *
134      * @throws BuildException if the reference is not to a resource collection
135      */
136     private void dealWithReferences() throws BuildException {
137         if (isReference()) {
138             final Object o = refid.getReferencedObject(getProject());
139             if (!(o instanceof ResourceCollection)) {
140                 throw new BuildException("refid '" + refid.getRefId()
141                         + "' does not refer to a resource collection.");
142             }
143             getPath().add((ResourceCollection) o);
144         }
145     }
146     // END COPY from org.apache.tools.ant.taskdefs
147     /**
148      * The application name for the report.
149      */
150     private String applicationName = "Dependency-Check";
151 
152     /**
153      * Get the value of applicationName.
154      *
155      * @return the value of applicationName
156      */
157     public String getApplicationName() {
158         return applicationName;
159     }
160 
161     /**
162      * Set the value of applicationName.
163      *
164      * @param applicationName new value of applicationName
165      */
166     public void setApplicationName(String applicationName) {
167         this.applicationName = applicationName;
168     }
169     /**
170      * The location of the data directory that contains
171      */
172     private String dataDirectory = null;
173 
174     /**
175      * Get the value of dataDirectory.
176      *
177      * @return the value of dataDirectory
178      */
179     public String getDataDirectory() {
180         return dataDirectory;
181     }
182 
183     /**
184      * Set the value of dataDirectory.
185      *
186      * @param dataDirectory new value of dataDirectory
187      */
188     public void setDataDirectory(String dataDirectory) {
189         this.dataDirectory = dataDirectory;
190     }
191     /**
192      * Specifies the destination directory for the generated Dependency-Check report.
193      */
194     private String reportOutputDirectory = ".";
195 
196     /**
197      * Get the value of reportOutputDirectory.
198      *
199      * @return the value of reportOutputDirectory
200      */
201     public String getReportOutputDirectory() {
202         return reportOutputDirectory;
203     }
204 
205     /**
206      * Set the value of reportOutputDirectory.
207      *
208      * @param reportOutputDirectory new value of reportOutputDirectory
209      */
210     public void setReportOutputDirectory(String reportOutputDirectory) {
211         this.reportOutputDirectory = reportOutputDirectory;
212     }
213     /**
214      * Specifies if the build should be failed if a CVSS score above a specified level is identified. The default is 11
215      * which means since the CVSS scores are 0-10, by default the build will never fail and the CVSS score is set to 11.
216      * The valid range for the fail build on CVSS is 0 to 11, where anything above 10 will not cause the build to fail.
217      */
218     private float failBuildOnCVSS = 11;
219 
220     /**
221      * Get the value of failBuildOnCVSS.
222      *
223      * @return the value of failBuildOnCVSS
224      */
225     public float getFailBuildOnCVSS() {
226         return failBuildOnCVSS;
227     }
228 
229     /**
230      * Set the value of failBuildOnCVSS.
231      *
232      * @param failBuildOnCVSS new value of failBuildOnCVSS
233      */
234     public void setFailBuildOnCVSS(float failBuildOnCVSS) {
235         this.failBuildOnCVSS = failBuildOnCVSS;
236     }
237     /**
238      * Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not recommended that this be turned to
239      * false. Default is true.
240      */
241     private boolean autoUpdate = true;
242 
243     /**
244      * Get the value of autoUpdate.
245      *
246      * @return the value of autoUpdate
247      */
248     public boolean isAutoUpdate() {
249         return autoUpdate;
250     }
251 
252     /**
253      * Set the value of autoUpdate.
254      *
255      * @param autoUpdate new value of autoUpdate
256      */
257     public void setAutoUpdate(boolean autoUpdate) {
258         this.autoUpdate = autoUpdate;
259     }
260     /**
261      * The report format to be generated (HTML, XML, VULN, ALL). This configuration option has no affect if using this
262      * within the Site plugin unless the externalReport is set to true. Default is HTML.
263      */
264     private String reportFormat = "HTML";
265 
266     /**
267      * Get the value of reportFormat.
268      *
269      * @return the value of reportFormat
270      */
271     public String getReportFormat() {
272         return reportFormat;
273     }
274 
275     /**
276      * Set the value of reportFormat.
277      *
278      * @param reportFormat new value of reportFormat
279      */
280     public void setReportFormat(ReportFormats reportFormat) {
281         this.reportFormat = reportFormat.getValue();
282     }
283     /**
284      * The Proxy URL.
285      */
286     private String proxyUrl;
287 
288     /**
289      * Get the value of proxyUrl.
290      *
291      * @return the value of proxyUrl
292      */
293     public String getProxyUrl() {
294         return proxyUrl;
295     }
296 
297     /**
298      * Set the value of proxyUrl.
299      *
300      * @param proxyUrl new value of proxyUrl
301      */
302     public void setProxyUrl(String proxyUrl) {
303         this.proxyUrl = proxyUrl;
304     }
305     /**
306      * The Proxy Port.
307      */
308     private String proxyPort;
309 
310     /**
311      * Get the value of proxyPort.
312      *
313      * @return the value of proxyPort
314      */
315     public String getProxyPort() {
316         return proxyPort;
317     }
318 
319     /**
320      * Set the value of proxyPort.
321      *
322      * @param proxyPort new value of proxyPort
323      */
324     public void setProxyPort(String proxyPort) {
325         this.proxyPort = proxyPort;
326     }
327     /**
328      * The Proxy username.
329      */
330     private String proxyUsername;
331 
332     /**
333      * Get the value of proxyUsername.
334      *
335      * @return the value of proxyUsername
336      */
337     public String getProxyUsername() {
338         return proxyUsername;
339     }
340 
341     /**
342      * Set the value of proxyUsername.
343      *
344      * @param proxyUsername new value of proxyUsername
345      */
346     public void setProxyUsername(String proxyUsername) {
347         this.proxyUsername = proxyUsername;
348     }
349     /**
350      * The Proxy password.
351      */
352     private String proxyPassword;
353 
354     /**
355      * Get the value of proxyPassword.
356      *
357      * @return the value of proxyPassword
358      */
359     public String getProxyPassword() {
360         return proxyPassword;
361     }
362 
363     /**
364      * Set the value of proxyPassword.
365      *
366      * @param proxyPassword new value of proxyPassword
367      */
368     public void setProxyPassword(String proxyPassword) {
369         this.proxyPassword = proxyPassword;
370     }
371     /**
372      * The Connection Timeout.
373      */
374     private String connectionTimeout;
375 
376     /**
377      * Get the value of connectionTimeout.
378      *
379      * @return the value of connectionTimeout
380      */
381     public String getConnectionTimeout() {
382         return connectionTimeout;
383     }
384 
385     /**
386      * Set the value of connectionTimeout.
387      *
388      * @param connectionTimeout new value of connectionTimeout
389      */
390     public void setConnectionTimeout(String connectionTimeout) {
391         this.connectionTimeout = connectionTimeout;
392     }
393     /**
394      * The file path used for verbose logging.
395      */
396     private String logFile = null;
397 
398     /**
399      * Get the value of logFile.
400      *
401      * @return the value of logFile
402      */
403     public String getLogFile() {
404         return logFile;
405     }
406 
407     /**
408      * Set the value of logFile.
409      *
410      * @param logFile new value of logFile
411      */
412     public void setLogFile(String logFile) {
413         this.logFile = logFile;
414     }
415     /**
416      * The path to the suppression file.
417      */
418     private String suppressionFile;
419 
420     /**
421      * Get the value of suppressionFile.
422      *
423      * @return the value of suppressionFile
424      */
425     public String getSuppressionFile() {
426         return suppressionFile;
427     }
428 
429     /**
430      * Set the value of suppressionFile.
431      *
432      * @param suppressionFile new value of suppressionFile
433      */
434     public void setSuppressionFile(String suppressionFile) {
435         this.suppressionFile = suppressionFile;
436     }
437     /**
438      * flag indicating whether or not to show a summary of findings.
439      */
440     private boolean showSummary = true;
441 
442     /**
443      * Get the value of showSummary.
444      *
445      * @return the value of showSummary
446      */
447     public boolean isShowSummary() {
448         return showSummary;
449     }
450 
451     /**
452      * Set the value of showSummary.
453      *
454      * @param showSummary new value of showSummary
455      */
456     public void setShowSummary(boolean showSummary) {
457         this.showSummary = showSummary;
458     }
459 
460     /**
461      * Whether or not the nexus analyzer is enabled.
462      */
463     private boolean nexusAnalyzerEnabled = true;
464 
465     /**
466      * Get the value of nexusAnalyzerEnabled.
467      *
468      * @return the value of nexusAnalyzerEnabled
469      */
470     public boolean isNexusAnalyzerEnabled() {
471         return nexusAnalyzerEnabled;
472     }
473 
474     /**
475      * Set the value of nexusAnalyzerEnabled.
476      *
477      * @param nexusAnalyzerEnabled new value of nexusAnalyzerEnabled
478      */
479     public void setNexusAnalyzerEnabled(boolean nexusAnalyzerEnabled) {
480         this.nexusAnalyzerEnabled = nexusAnalyzerEnabled;
481     }
482 
483     /**
484      * The URL of the Nexus server.
485      */
486     private String nexusUrl;
487 
488     /**
489      * Get the value of nexusUrl.
490      *
491      * @return the value of nexusUrl
492      */
493     public String getNexusUrl() {
494         return nexusUrl;
495     }
496 
497     /**
498      * Set the value of nexusUrl.
499      *
500      * @param nexusUrl new value of nexusUrl
501      */
502     public void setNexusUrl(String nexusUrl) {
503         this.nexusUrl = nexusUrl;
504     }
505     /**
506      * Whether or not the defined proxy should be used when connecting to Nexus.
507      */
508     private boolean nexusUsesProxy = true;
509 
510     /**
511      * Get the value of nexusUsesProxy.
512      *
513      * @return the value of nexusUsesProxy
514      */
515     public boolean isNexusUsesProxy() {
516         return nexusUsesProxy;
517     }
518 
519     /**
520      * Set the value of nexusUsesProxy.
521      *
522      * @param nexusUsesProxy new value of nexusUsesProxy
523      */
524     public void setNexusUsesProxy(boolean nexusUsesProxy) {
525         this.nexusUsesProxy = nexusUsesProxy;
526     }
527 
528     /**
529      * The database driver name; such as org.h2.Driver.
530      */
531     private String databaseDriverName;
532 
533     /**
534      * Get the value of databaseDriverName.
535      *
536      * @return the value of databaseDriverName
537      */
538     public String getDatabaseDriverName() {
539         return databaseDriverName;
540     }
541 
542     /**
543      * Set the value of databaseDriverName.
544      *
545      * @param databaseDriverName new value of databaseDriverName
546      */
547     public void setDatabaseDriverName(String databaseDriverName) {
548         this.databaseDriverName = databaseDriverName;
549     }
550 
551     /**
552      * The path to the database driver JAR file if it is not on the class path.
553      */
554     private String databaseDriverPath;
555 
556     /**
557      * Get the value of databaseDriverPath.
558      *
559      * @return the value of databaseDriverPath
560      */
561     public String getDatabaseDriverPath() {
562         return databaseDriverPath;
563     }
564 
565     /**
566      * Set the value of databaseDriverPath.
567      *
568      * @param databaseDriverPath new value of databaseDriverPath
569      */
570     public void setDatabaseDriverPath(String databaseDriverPath) {
571         this.databaseDriverPath = databaseDriverPath;
572     }
573     /**
574      * The database connection string.
575      */
576     private String connectionString;
577 
578     /**
579      * Get the value of connectionString.
580      *
581      * @return the value of connectionString
582      */
583     public String getConnectionString() {
584         return connectionString;
585     }
586 
587     /**
588      * Set the value of connectionString.
589      *
590      * @param connectionString new value of connectionString
591      */
592     public void setConnectionString(String connectionString) {
593         this.connectionString = connectionString;
594     }
595     /**
596      * The user name for connecting to the database.
597      */
598     private String databaseUser;
599 
600     /**
601      * Get the value of databaseUser.
602      *
603      * @return the value of databaseUser
604      */
605     public String getDatabaseUser() {
606         return databaseUser;
607     }
608 
609     /**
610      * Set the value of databaseUser.
611      *
612      * @param databaseUser new value of databaseUser
613      */
614     public void setDatabaseUser(String databaseUser) {
615         this.databaseUser = databaseUser;
616     }
617 
618     /**
619      * The password to use when connecting to the database.
620      */
621     private String databasePassword;
622 
623     /**
624      * Get the value of databasePassword.
625      *
626      * @return the value of databasePassword
627      */
628     public String getDatabasePassword() {
629         return databasePassword;
630     }
631 
632     /**
633      * Set the value of databasePassword.
634      *
635      * @param databasePassword new value of databasePassword
636      */
637     public void setDatabasePassword(String databasePassword) {
638         this.databasePassword = databasePassword;
639     }
640 
641     /**
642      * Additional ZIP File extensions to add analyze. This should be a comma-separated list of file extensions to treat
643      * like ZIP files.
644      */
645     private String zipExtensions;
646 
647     /**
648      * Get the value of zipExtensions.
649      *
650      * @return the value of zipExtensions
651      */
652     public String getZipExtensions() {
653         return zipExtensions;
654     }
655 
656     /**
657      * Set the value of zipExtensions.
658      *
659      * @param zipExtensions new value of zipExtensions
660      */
661     public void setZipExtensions(String zipExtensions) {
662         this.zipExtensions = zipExtensions;
663     }
664 
665     /**
666      * The url for the modified NVD CVE (1.2 schema).
667      */
668     private String cveUrl12Modified;
669 
670     /**
671      * Get the value of cveUrl12Modified.
672      *
673      * @return the value of cveUrl12Modified
674      */
675     public String getCveUrl12Modified() {
676         return cveUrl12Modified;
677     }
678 
679     /**
680      * Set the value of cveUrl12Modified.
681      *
682      * @param cveUrl12Modified new value of cveUrl12Modified
683      */
684     public void setCveUrl12Modified(String cveUrl12Modified) {
685         this.cveUrl12Modified = cveUrl12Modified;
686     }
687 
688     /**
689      * The url for the modified NVD CVE (2.0 schema).
690      */
691     private String cveUrl20Modified;
692 
693     /**
694      * Get the value of cveUrl20Modified.
695      *
696      * @return the value of cveUrl20Modified
697      */
698     public String getCveUrl20Modified() {
699         return cveUrl20Modified;
700     }
701 
702     /**
703      * Set the value of cveUrl20Modified.
704      *
705      * @param cveUrl20Modified new value of cveUrl20Modified
706      */
707     public void setCveUrl20Modified(String cveUrl20Modified) {
708         this.cveUrl20Modified = cveUrl20Modified;
709     }
710 
711     /**
712      * Base Data Mirror URL for CVE 1.2.
713      */
714     private String cveUrl12Base;
715 
716     /**
717      * Get the value of cveUrl12Base.
718      *
719      * @return the value of cveUrl12Base
720      */
721     public String getCveUrl12Base() {
722         return cveUrl12Base;
723     }
724 
725     /**
726      * Set the value of cveUrl12Base.
727      *
728      * @param cveUrl12Base new value of cveUrl12Base
729      */
730     public void setCveUrl12Base(String cveUrl12Base) {
731         this.cveUrl12Base = cveUrl12Base;
732     }
733 
734     /**
735      * Data Mirror URL for CVE 2.0.
736      */
737     private String cveUrl20Base;
738 
739     /**
740      * Get the value of cveUrl20Base.
741      *
742      * @return the value of cveUrl20Base
743      */
744     public String getCveUrl20Base() {
745         return cveUrl20Base;
746     }
747 
748     /**
749      * Set the value of cveUrl20Base.
750      *
751      * @param cveUrl20Base new value of cveUrl20Base
752      */
753     public void setCveUrl20Base(String cveUrl20Base) {
754         this.cveUrl20Base = cveUrl20Base;
755     }
756 
757     @Override
758     public void execute() throws BuildException {
759         final InputStream in = DependencyCheckTask.class.getClassLoader().getResourceAsStream(LOG_PROPERTIES_FILE);
760         LogUtils.prepareLogger(in, logFile);
761 
762         dealWithReferences();
763         validateConfiguration();
764         populateSettings();
765 
766         Engine engine = null;
767         try {
768             engine = new Engine();
769 
770             for (Resource resource : path) {
771                 final FileProvider provider = resource.as(FileProvider.class);
772                 if (provider != null) {
773                     final File file = provider.getFile();
774                     if (file != null && file.exists()) {
775                         engine.scan(file);
776                     }
777                 }
778             }
779             try {
780                 engine.analyzeDependencies();
781                 DatabaseProperties prop = null;
782                 CveDB cve = null;
783                 try {
784                     cve = new CveDB();
785                     cve.open();
786                     prop = cve.getDatabaseProperties();
787                 } catch (DatabaseException ex) {
788                     Logger.getLogger(DependencyCheckTask.class.getName()).log(Level.FINE, "Unable to retrieve DB Properties", ex);
789                 } finally {
790                     if (cve != null) {
791                         cve.close();
792                     }
793                 }
794                 final ReportGenerator reporter = new ReportGenerator(applicationName, engine.getDependencies(), engine.getAnalyzers(), prop);
795                 reporter.generateReports(reportOutputDirectory, reportFormat);
796 
797                 if (this.failBuildOnCVSS <= 10) {
798                     checkForFailure(engine.getDependencies());
799                 }
800                 if (this.showSummary) {
801                     showSummary(engine.getDependencies());
802                 }
803             } catch (IOException ex) {
804                 Logger.getLogger(DependencyCheckTask.class.getName()).log(Level.FINE,
805                         "Unable to generate dependency-check report", ex);
806                 throw new BuildException("Unable to generate dependency-check report", ex);
807             } catch (Exception ex) {
808                 Logger.getLogger(DependencyCheckTask.class.getName()).log(Level.FINE,
809                         "An exception occurred; unable to continue task", ex);
810                 throw new BuildException("An exception occurred; unable to continue task", ex);
811             }
812         } catch (DatabaseException ex) {
813             Logger.getLogger(DependencyCheckTask.class.getName()).log(Level.SEVERE,
814                     "Unable to connect to the dependency-check database; analysis has stopped");
815             Logger.getLogger(DependencyCheckTask.class.getName()).log(Level.FINE, "", ex);
816         } finally {
817             if (engine != null) {
818                 engine.cleanup();
819             }
820         }
821     }
822 
823     /**
824      * Validate the configuration to ensure the parameters have been properly configured/initialized.
825      *
826      * @throws BuildException if the task was not configured correctly.
827      */
828     private void validateConfiguration() throws BuildException {
829         if (path == null) {
830             throw new BuildException("No project dependencies have been defined to analyze.");
831         }
832         if (failBuildOnCVSS < 0 || failBuildOnCVSS > 11) {
833             throw new BuildException("Invalid configuration, failBuildOnCVSS must be between 0 and 11.");
834         }
835     }
836 
837     /**
838      * Takes the properties supplied and updates the dependency-check settings. Additionally, this sets the system
839      * properties required to change the proxy url, port, and connection timeout.
840      */
841     private void populateSettings() {
842         InputStream taskProperties = null;
843         try {
844             taskProperties = this.getClass().getClassLoader().getResourceAsStream(PROPERTIES_FILE);
845             Settings.mergeProperties(taskProperties);
846         } catch (IOException ex) {
847             Logger.getLogger(DependencyCheckTask.class.getName()).log(Level.WARNING, "Unable to load the dependency-check ant task.properties file.");
848             Logger.getLogger(DependencyCheckTask.class.getName()).log(Level.FINE, null, ex);
849         } finally {
850             if (taskProperties != null) {
851                 try {
852                     taskProperties.close();
853                 } catch (IOException ex) {
854                     Logger.getLogger(DependencyCheckTask.class.getName()).log(Level.FINEST, null, ex);
855                 }
856             }
857         }
858         if (dataDirectory != null) {
859             Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory);
860         } else {
861             final File jarPath = new File(DependencyCheckTask.class.getProtectionDomain().getCodeSource().getLocation().getPath());
862             final File base = jarPath.getParentFile();
863             final String sub = Settings.getString(Settings.KEYS.DATA_DIRECTORY);
864             final File dataDir = new File(base, sub);
865             Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath());
866         }
867 
868         Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate);
869 
870         if (proxyUrl != null && !proxyUrl.isEmpty()) {
871             Settings.setString(Settings.KEYS.PROXY_URL, proxyUrl);
872         }
873         if (proxyPort != null && !proxyPort.isEmpty()) {
874             Settings.setString(Settings.KEYS.PROXY_PORT, proxyPort);
875         }
876         if (proxyUsername != null && !proxyUsername.isEmpty()) {
877             Settings.setString(Settings.KEYS.PROXY_USERNAME, proxyUsername);
878         }
879         if (proxyPassword != null && !proxyPassword.isEmpty()) {
880             Settings.setString(Settings.KEYS.PROXY_PASSWORD, proxyPassword);
881         }
882         if (connectionTimeout != null && !connectionTimeout.isEmpty()) {
883             Settings.setString(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout);
884         }
885         if (suppressionFile != null && !suppressionFile.isEmpty()) {
886             Settings.setString(Settings.KEYS.SUPPRESSION_FILE, suppressionFile);
887         }
888         Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled);
889         if (nexusUrl != null && !nexusUrl.isEmpty()) {
890             Settings.setString(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl);
891         }
892         Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_PROXY, nexusUsesProxy);
893         if (databaseDriverName != null && !databaseDriverName.isEmpty()) {
894             Settings.setString(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName);
895         }
896         if (databaseDriverPath != null && !databaseDriverPath.isEmpty()) {
897             Settings.setString(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath);
898         }
899         if (connectionString != null && !connectionString.isEmpty()) {
900             Settings.setString(Settings.KEYS.DB_CONNECTION_STRING, connectionString);
901         }
902         if (databaseUser != null && !databaseUser.isEmpty()) {
903             Settings.setString(Settings.KEYS.DB_USER, databaseUser);
904         }
905         if (databasePassword != null && !databasePassword.isEmpty()) {
906             Settings.setString(Settings.KEYS.DB_PASSWORD, databasePassword);
907         }
908         if (zipExtensions != null && !zipExtensions.isEmpty()) {
909             Settings.setString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions);
910         }
911         if (cveUrl12Modified != null && !cveUrl12Modified.isEmpty()) {
912             Settings.setString(Settings.KEYS.CVE_MODIFIED_12_URL, cveUrl12Modified);
913         }
914         if (cveUrl20Modified != null && !cveUrl20Modified.isEmpty()) {
915             Settings.setString(Settings.KEYS.CVE_MODIFIED_20_URL, cveUrl20Modified);
916         }
917         if (cveUrl12Base != null && !cveUrl12Base.isEmpty()) {
918             Settings.setString(Settings.KEYS.CVE_SCHEMA_1_2, cveUrl12Base);
919         }
920         if (cveUrl20Base != null && !cveUrl20Base.isEmpty()) {
921             Settings.setString(Settings.KEYS.CVE_SCHEMA_2_0, cveUrl20Base);
922         }
923     }
924 
925     /**
926      * Checks to see if a vulnerability has been identified with a CVSS score that is above the threshold set in the
927      * configuration.
928      *
929      * @param dependencies the list of dependency objects
930      * @throws BuildException thrown if a CVSS score is found that is higher then the threshold set
931      */
932     private void checkForFailure(List<Dependency> dependencies) throws BuildException {
933         final StringBuilder ids = new StringBuilder();
934         for (Dependency d : dependencies) {
935             for (Vulnerability v : d.getVulnerabilities()) {
936                 if (v.getCvssScore() >= failBuildOnCVSS) {
937                     if (ids.length() == 0) {
938                         ids.append(v.getName());
939                     } else {
940                         ids.append(", ").append(v.getName());
941                     }
942                 }
943             }
944         }
945         if (ids.length() > 0) {
946             final String msg = String.format("%n%nDependency-Check Failure:%n"
947                     + "One or more dependencies were identified with vulnerabilities that have a CVSS score greater then '%.1f': %s%n"
948                     + "See the dependency-check report for more details.%n%n", failBuildOnCVSS, ids.toString());
949             throw new BuildException(msg);
950         }
951     }
952 
953     /**
954      * Generates a warning message listing a summary of dependencies and their associated CPE and CVE entries.
955      *
956      * @param dependencies a list of dependency objects
957      */
958     private void showSummary(List<Dependency> dependencies) {
959         final StringBuilder summary = new StringBuilder();
960         for (Dependency d : dependencies) {
961             boolean firstEntry = true;
962             final StringBuilder ids = new StringBuilder();
963             for (Vulnerability v : d.getVulnerabilities()) {
964                 if (firstEntry) {
965                     firstEntry = false;
966                 } else {
967                     ids.append(", ");
968                 }
969                 ids.append(v.getName());
970             }
971             if (ids.length() > 0) {
972                 summary.append(d.getFileName()).append(" (");
973                 firstEntry = true;
974                 for (Identifier id : d.getIdentifiers()) {
975                     if (firstEntry) {
976                         firstEntry = false;
977                     } else {
978                         summary.append(", ");
979                     }
980                     summary.append(id.getValue());
981                 }
982                 summary.append(") : ").append(ids).append(NEW_LINE);
983             }
984         }
985         if (summary.length() > 0) {
986             final String msg = String.format("%n%n"
987                     + "One or more dependencies were identified with known vulnerabilities:%n%n%s"
988                     + "%n%nSee the dependency-check report for more details.%n%n", summary.toString());
989             Logger.getLogger(DependencyCheckTask.class.getName()).log(Level.WARNING, msg);
990         }
991     }
992 
993     /**
994      * An enumeration of supported report formats: "ALL", "HTML", "XML", "VULN", etc..
995      */
996     public static class ReportFormats extends EnumeratedAttribute {
997 
998         /**
999          * Returns the list of values for the report format.
1000          *
1001          * @return the list of values for the report format
1002          */
1003         @Override
1004         public String[] getValues() {
1005             int i = 0;
1006             final Format[] formats = Format.values();
1007             final String[] values = new String[formats.length];
1008             for (Format format : formats) {
1009                 values[i++] = format.name();
1010             }
1011             return values;
1012         }
1013     }
1014 }