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