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
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      * Whether only the update phase should be executed.
266      */
267     private boolean updateOnly = false;
268 
269     /**
270      * Get the value of updateOnly.
271      *
272      * @return the value of updateOnly
273      */
274     public boolean isUpdateOnly() {
275         return updateOnly;
276     }
277 
278     /**
279      * Set the value of updateOnly.
280      *
281      * @param updateOnly new value of updateOnly
282      */
283     public void setUpdateOnly(boolean updateOnly) {
284         this.updateOnly = updateOnly;
285     }
286 
287     /**
288      * The report format to be generated (HTML, XML, VULN, ALL). This configuration option has no affect if using this within the
289      * Site plugin unless the externalReport is set to true. Default is HTML.
290      */
291     private String reportFormat = "HTML";
292 
293     /**
294      * Get the value of reportFormat.
295      *
296      * @return the value of reportFormat
297      */
298     public String getReportFormat() {
299         return reportFormat;
300     }
301 
302     /**
303      * Set the value of reportFormat.
304      *
305      * @param reportFormat new value of reportFormat
306      */
307     public void setReportFormat(ReportFormats reportFormat) {
308         this.reportFormat = reportFormat.getValue();
309     }
310     /**
311      * The Proxy Server.
312      */
313     private String proxyServer;
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 proxyServer.
335      *
336      * @return the value of proxyServer
337      * @deprecated use {@link org.owasp.dependencycheck.taskdefs.DependencyCheckTask#getProxyServer()} instead
338      */
339     @Deprecated
340     public String getProxyUrl() {
341         return proxyServer;
342     }
343 
344     /**
345      * Set the value of proxyServer.
346      *
347      * @param proxyUrl new value of proxyServer
348      * @deprecated use {@link org.owasp.dependencycheck.taskdefs.DependencyCheckTask#setProxyServer(java.lang.String)} instead
349      */
350     @Deprecated
351     public void setProxyUrl(String proxyUrl) {
352         LOGGER.warning("A deprecated configuration option 'proxyUrl' was detected; use 'proxyServer' instead.");
353         this.proxyServer = proxyUrl;
354     }
355     /**
356      * The Proxy Port.
357      */
358     private String proxyPort;
359 
360     /**
361      * Get the value of proxyPort.
362      *
363      * @return the value of proxyPort
364      */
365     public String getProxyPort() {
366         return proxyPort;
367     }
368 
369     /**
370      * Set the value of proxyPort.
371      *
372      * @param proxyPort new value of proxyPort
373      */
374     public void setProxyPort(String proxyPort) {
375         this.proxyPort = proxyPort;
376     }
377     /**
378      * The Proxy username.
379      */
380     private String proxyUsername;
381 
382     /**
383      * Get the value of proxyUsername.
384      *
385      * @return the value of proxyUsername
386      */
387     public String getProxyUsername() {
388         return proxyUsername;
389     }
390 
391     /**
392      * Set the value of proxyUsername.
393      *
394      * @param proxyUsername new value of proxyUsername
395      */
396     public void setProxyUsername(String proxyUsername) {
397         this.proxyUsername = proxyUsername;
398     }
399     /**
400      * The Proxy password.
401      */
402     private String proxyPassword;
403 
404     /**
405      * Get the value of proxyPassword.
406      *
407      * @return the value of proxyPassword
408      */
409     public String getProxyPassword() {
410         return proxyPassword;
411     }
412 
413     /**
414      * Set the value of proxyPassword.
415      *
416      * @param proxyPassword new value of proxyPassword
417      */
418     public void setProxyPassword(String proxyPassword) {
419         this.proxyPassword = proxyPassword;
420     }
421     /**
422      * The Connection Timeout.
423      */
424     private String connectionTimeout;
425 
426     /**
427      * Get the value of connectionTimeout.
428      *
429      * @return the value of connectionTimeout
430      */
431     public String getConnectionTimeout() {
432         return connectionTimeout;
433     }
434 
435     /**
436      * Set the value of connectionTimeout.
437      *
438      * @param connectionTimeout new value of connectionTimeout
439      */
440     public void setConnectionTimeout(String connectionTimeout) {
441         this.connectionTimeout = connectionTimeout;
442     }
443     /**
444      * The file path used for verbose logging.
445      */
446     private String logFile = null;
447 
448     /**
449      * Get the value of logFile.
450      *
451      * @return the value of logFile
452      */
453     public String getLogFile() {
454         return logFile;
455     }
456 
457     /**
458      * Set the value of logFile.
459      *
460      * @param logFile new value of logFile
461      */
462     public void setLogFile(String logFile) {
463         this.logFile = logFile;
464     }
465     /**
466      * The path to the suppression file.
467      */
468     private String suppressionFile;
469 
470     /**
471      * Get the value of suppressionFile.
472      *
473      * @return the value of suppressionFile
474      */
475     public String getSuppressionFile() {
476         return suppressionFile;
477     }
478 
479     /**
480      * Set the value of suppressionFile.
481      *
482      * @param suppressionFile new value of suppressionFile
483      */
484     public void setSuppressionFile(String suppressionFile) {
485         this.suppressionFile = suppressionFile;
486     }
487     /**
488      * flag indicating whether or not to show a summary of findings.
489      */
490     private boolean showSummary = true;
491 
492     /**
493      * Get the value of showSummary.
494      *
495      * @return the value of showSummary
496      */
497     public boolean isShowSummary() {
498         return showSummary;
499     }
500 
501     /**
502      * Set the value of showSummary.
503      *
504      * @param showSummary new value of showSummary
505      */
506     public void setShowSummary(boolean showSummary) {
507         this.showSummary = showSummary;
508     }
509 
510     /**
511      * Sets whether or not the analyzer is enabled.
512      *
513      * @param jarAnalyzerEnabled the value of the new setting
514      */
515     public void setJarAnalyzerEnabled(boolean jarAnalyzerEnabled) {
516         this.jarAnalyzerEnabled = jarAnalyzerEnabled;
517     }
518     /**
519      * Whether or not the Archive Analyzer is enabled.
520      */
521     private boolean archiveAnalyzerEnabled = true;
522 
523     /**
524      * Returns whether or not the analyzer is enabled.
525      *
526      * @return true if the analyzer is enabled
527      */
528     public boolean isArchiveAnalyzerEnabled() {
529         return archiveAnalyzerEnabled;
530     }
531     /**
532      * Whether or not the .NET Assembly Analyzer is enabled.
533      */
534     private boolean assemblyAnalyzerEnabled = true;
535 
536     /**
537      * Sets whether or not the analyzer is enabled.
538      *
539      * @param archiveAnalyzerEnabled the value of the new setting
540      */
541     public void setArchiveAnalyzerEnabled(boolean archiveAnalyzerEnabled) {
542         this.archiveAnalyzerEnabled = archiveAnalyzerEnabled;
543     }
544 
545     /**
546      * Returns whether or not the analyzer is enabled.
547      *
548      * @return true if the analyzer is enabled
549      */
550     public boolean isAssemblyAnalyzerEnabled() {
551         return assemblyAnalyzerEnabled;
552     }
553 
554     /**
555      * Sets whether or not the analyzer is enabled.
556      *
557      * @param assemblyAnalyzerEnabled the value of the new setting
558      */
559     public void setAssemblyAnalyzerEnabled(boolean assemblyAnalyzerEnabled) {
560         this.assemblyAnalyzerEnabled = assemblyAnalyzerEnabled;
561     }
562     /**
563      * Whether or not the .NET Nuspec Analyzer is enabled.
564      */
565     private boolean nuspecAnalyzerEnabled = true;
566 
567     /**
568      * Returns whether or not the analyzer is enabled.
569      *
570      * @return true if the analyzer is enabled
571      */
572     public boolean isNuspecAnalyzerEnabled() {
573         return nuspecAnalyzerEnabled;
574     }
575 
576     /**
577      * Sets whether or not the analyzer is enabled.
578      *
579      * @param nuspecAnalyzerEnabled the value of the new setting
580      */
581     public void setNuspecAnalyzerEnabled(boolean nuspecAnalyzerEnabled) {
582         this.nuspecAnalyzerEnabled = nuspecAnalyzerEnabled;
583     }
584     /**
585      * Whether or not the central analyzer is enabled.
586      */
587     private boolean centralAnalyzerEnabled = false;
588 
589     /**
590      * Get the value of centralAnalyzerEnabled.
591      *
592      * @return the value of centralAnalyzerEnabled
593      */
594     public boolean isCentralAnalyzerEnabled() {
595         return centralAnalyzerEnabled;
596     }
597 
598     /**
599      * Set the value of centralAnalyzerEnabled.
600      *
601      * @param centralAnalyzerEnabled new value of centralAnalyzerEnabled
602      */
603     public void setCentralAnalyzerEnabled(boolean centralAnalyzerEnabled) {
604         this.centralAnalyzerEnabled = centralAnalyzerEnabled;
605     }
606 
607     /**
608      * Whether or not the nexus analyzer is enabled.
609      */
610     private boolean nexusAnalyzerEnabled = true;
611 
612     /**
613      * Get the value of nexusAnalyzerEnabled.
614      *
615      * @return the value of nexusAnalyzerEnabled
616      */
617     public boolean isNexusAnalyzerEnabled() {
618         return nexusAnalyzerEnabled;
619     }
620 
621     /**
622      * Set the value of nexusAnalyzerEnabled.
623      *
624      * @param nexusAnalyzerEnabled new value of nexusAnalyzerEnabled
625      */
626     public void setNexusAnalyzerEnabled(boolean nexusAnalyzerEnabled) {
627         this.nexusAnalyzerEnabled = nexusAnalyzerEnabled;
628     }
629 
630     /**
631      * The URL of a Nexus server's REST API end point (http://domain/nexus/service/local).
632      */
633     private String nexusUrl;
634 
635     /**
636      * Get the value of nexusUrl.
637      *
638      * @return the value of nexusUrl
639      */
640     public String getNexusUrl() {
641         return nexusUrl;
642     }
643 
644     /**
645      * Set the value of nexusUrl.
646      *
647      * @param nexusUrl new value of nexusUrl
648      */
649     public void setNexusUrl(String nexusUrl) {
650         this.nexusUrl = nexusUrl;
651     }
652     /**
653      * Whether or not the defined proxy should be used when connecting to Nexus.
654      */
655     private boolean nexusUsesProxy = true;
656 
657     /**
658      * Get the value of nexusUsesProxy.
659      *
660      * @return the value of nexusUsesProxy
661      */
662     public boolean isNexusUsesProxy() {
663         return nexusUsesProxy;
664     }
665 
666     /**
667      * Set the value of nexusUsesProxy.
668      *
669      * @param nexusUsesProxy new value of nexusUsesProxy
670      */
671     public void setNexusUsesProxy(boolean nexusUsesProxy) {
672         this.nexusUsesProxy = nexusUsesProxy;
673     }
674 
675     /**
676      * The database driver name; such as org.h2.Driver.
677      */
678     private String databaseDriverName;
679 
680     /**
681      * Get the value of databaseDriverName.
682      *
683      * @return the value of databaseDriverName
684      */
685     public String getDatabaseDriverName() {
686         return databaseDriverName;
687     }
688 
689     /**
690      * Set the value of databaseDriverName.
691      *
692      * @param databaseDriverName new value of databaseDriverName
693      */
694     public void setDatabaseDriverName(String databaseDriverName) {
695         this.databaseDriverName = databaseDriverName;
696     }
697 
698     /**
699      * The path to the database driver JAR file if it is not on the class path.
700      */
701     private String databaseDriverPath;
702 
703     /**
704      * Get the value of databaseDriverPath.
705      *
706      * @return the value of databaseDriverPath
707      */
708     public String getDatabaseDriverPath() {
709         return databaseDriverPath;
710     }
711 
712     /**
713      * Set the value of databaseDriverPath.
714      *
715      * @param databaseDriverPath new value of databaseDriverPath
716      */
717     public void setDatabaseDriverPath(String databaseDriverPath) {
718         this.databaseDriverPath = databaseDriverPath;
719     }
720     /**
721      * The database connection string.
722      */
723     private String connectionString;
724 
725     /**
726      * Get the value of connectionString.
727      *
728      * @return the value of connectionString
729      */
730     public String getConnectionString() {
731         return connectionString;
732     }
733 
734     /**
735      * Set the value of connectionString.
736      *
737      * @param connectionString new value of connectionString
738      */
739     public void setConnectionString(String connectionString) {
740         this.connectionString = connectionString;
741     }
742     /**
743      * The user name for connecting to the database.
744      */
745     private String databaseUser;
746 
747     /**
748      * Get the value of databaseUser.
749      *
750      * @return the value of databaseUser
751      */
752     public String getDatabaseUser() {
753         return databaseUser;
754     }
755 
756     /**
757      * Set the value of databaseUser.
758      *
759      * @param databaseUser new value of databaseUser
760      */
761     public void setDatabaseUser(String databaseUser) {
762         this.databaseUser = databaseUser;
763     }
764 
765     /**
766      * The password to use when connecting to the database.
767      */
768     private String databasePassword;
769 
770     /**
771      * Get the value of databasePassword.
772      *
773      * @return the value of databasePassword
774      */
775     public String getDatabasePassword() {
776         return databasePassword;
777     }
778 
779     /**
780      * Set the value of databasePassword.
781      *
782      * @param databasePassword new value of databasePassword
783      */
784     public void setDatabasePassword(String databasePassword) {
785         this.databasePassword = databasePassword;
786     }
787 
788     /**
789      * Additional ZIP File extensions to add analyze. This should be a comma-separated list of file extensions to treat like ZIP
790      * files.
791      */
792     private String zipExtensions;
793 
794     /**
795      * Get the value of zipExtensions.
796      *
797      * @return the value of zipExtensions
798      */
799     public String getZipExtensions() {
800         return zipExtensions;
801     }
802 
803     /**
804      * Set the value of zipExtensions.
805      *
806      * @param zipExtensions new value of zipExtensions
807      */
808     public void setZipExtensions(String zipExtensions) {
809         this.zipExtensions = zipExtensions;
810     }
811 
812     /**
813      * The url for the modified NVD CVE (1.2 schema).
814      */
815     private String cveUrl12Modified;
816 
817     /**
818      * Get the value of cveUrl12Modified.
819      *
820      * @return the value of cveUrl12Modified
821      */
822     public String getCveUrl12Modified() {
823         return cveUrl12Modified;
824     }
825 
826     /**
827      * Set the value of cveUrl12Modified.
828      *
829      * @param cveUrl12Modified new value of cveUrl12Modified
830      */
831     public void setCveUrl12Modified(String cveUrl12Modified) {
832         this.cveUrl12Modified = cveUrl12Modified;
833     }
834 
835     /**
836      * The url for the modified NVD CVE (2.0 schema).
837      */
838     private String cveUrl20Modified;
839 
840     /**
841      * Get the value of cveUrl20Modified.
842      *
843      * @return the value of cveUrl20Modified
844      */
845     public String getCveUrl20Modified() {
846         return cveUrl20Modified;
847     }
848 
849     /**
850      * Set the value of cveUrl20Modified.
851      *
852      * @param cveUrl20Modified new value of cveUrl20Modified
853      */
854     public void setCveUrl20Modified(String cveUrl20Modified) {
855         this.cveUrl20Modified = cveUrl20Modified;
856     }
857 
858     /**
859      * Base Data Mirror URL for CVE 1.2.
860      */
861     private String cveUrl12Base;
862 
863     /**
864      * Get the value of cveUrl12Base.
865      *
866      * @return the value of cveUrl12Base
867      */
868     public String getCveUrl12Base() {
869         return cveUrl12Base;
870     }
871 
872     /**
873      * Set the value of cveUrl12Base.
874      *
875      * @param cveUrl12Base new value of cveUrl12Base
876      */
877     public void setCveUrl12Base(String cveUrl12Base) {
878         this.cveUrl12Base = cveUrl12Base;
879     }
880 
881     /**
882      * Data Mirror URL for CVE 2.0.
883      */
884     private String cveUrl20Base;
885 
886     /**
887      * Get the value of cveUrl20Base.
888      *
889      * @return the value of cveUrl20Base
890      */
891     public String getCveUrl20Base() {
892         return cveUrl20Base;
893     }
894 
895     /**
896      * Set the value of cveUrl20Base.
897      *
898      * @param cveUrl20Base new value of cveUrl20Base
899      */
900     public void setCveUrl20Base(String cveUrl20Base) {
901         this.cveUrl20Base = cveUrl20Base;
902     }
903     /**
904      * The path to Mono for .NET assembly analysis on non-windows systems.
905      */
906     private String pathToMono;
907 
908     /**
909      * Get the value of pathToMono.
910      *
911      * @return the value of pathToMono
912      */
913     public String getPathToMono() {
914         return pathToMono;
915     }
916 
917     /**
918      * Set the value of pathToMono.
919      *
920      * @param pathToMono new value of pathToMono
921      */
922     public void setPathToMono(String pathToMono) {
923         this.pathToMono = pathToMono;
924     }
925 
926     @Override
927     public void execute() throws BuildException {
928         final InputStream in = DependencyCheckTask.class.getClassLoader().getResourceAsStream(LOG_PROPERTIES_FILE);
929         LogUtils.prepareLogger(in, logFile);
930 
931         dealWithReferences();
932         validateConfiguration();
933         populateSettings();
934 
935         Engine engine = null;
936         try {
937             engine = new Engine(DependencyCheckTask.class.getClassLoader());
938             //todo - should this be its own task?
939             if (updateOnly) {
940                 engine.doUpdates();
941             } else {
942                 try {
943                     for (Resource resource : path) {
944                         final FileProvider provider = resource.as(FileProvider.class);
945                         if (provider != null) {
946                             final File file = provider.getFile();
947                             if (file != null && file.exists()) {
948                                 engine.scan(file);
949                             }
950                         }
951                     }
952 
953                     engine.analyzeDependencies();
954                     DatabaseProperties prop = null;
955                     CveDB cve = null;
956                     try {
957                         cve = new CveDB();
958                         cve.open();
959                         prop = cve.getDatabaseProperties();
960                     } catch (DatabaseException ex) {
961                         LOGGER.log(Level.FINE, "Unable to retrieve DB Properties", ex);
962                     } finally {
963                         if (cve != null) {
964                             cve.close();
965                         }
966                     }
967                     final ReportGenerator reporter = new ReportGenerator(applicationName, engine.getDependencies(), engine.getAnalyzers(), prop);
968                     reporter.generateReports(reportOutputDirectory, reportFormat);
969 
970                     if (this.failBuildOnCVSS <= 10) {
971                         checkForFailure(engine.getDependencies());
972                     }
973                     if (this.showSummary) {
974                         showSummary(engine.getDependencies());
975                     }
976                 } catch (IOException ex) {
977                     LOGGER.log(Level.FINE, "Unable to generate dependency-check report", ex);
978                     throw new BuildException("Unable to generate dependency-check report", ex);
979                 } catch (Exception ex) {
980                     LOGGER.log(Level.FINE, "An exception occurred; unable to continue task", ex);
981                     throw new BuildException("An exception occurred; unable to continue task", ex);
982                 }
983             }
984         } catch (DatabaseException ex) {
985             LOGGER.log(Level.SEVERE, "Unable to connect to the dependency-check database; analysis has stopped");
986             LOGGER.log(Level.FINE, "", ex);
987         } finally {
988             Settings.cleanup(true);
989             if (engine != null) {
990                 engine.cleanup();
991             }
992         }
993     }
994 
995     /**
996      * Validate the configuration to ensure the parameters have been properly configured/initialized.
997      *
998      * @throws BuildException if the task was not configured correctly.
999      */
1000     private void validateConfiguration() throws BuildException {
1001         if (path == null) {
1002             throw new BuildException("No project dependencies have been defined to analyze.");
1003         }
1004         if (failBuildOnCVSS < 0 || failBuildOnCVSS > 11) {
1005             throw new BuildException("Invalid configuration, failBuildOnCVSS must be between 0 and 11.");
1006         }
1007     }
1008 
1009     /**
1010      * Takes the properties supplied and updates the dependency-check settings. Additionally, this sets the system properties
1011      * required to change the proxy server, port, and connection timeout.
1012      */
1013     private void populateSettings() {
1014         Settings.initialize();
1015         InputStream taskProperties = null;
1016         try {
1017             taskProperties = this.getClass().getClassLoader().getResourceAsStream(PROPERTIES_FILE);
1018             Settings.mergeProperties(taskProperties);
1019         } catch (IOException ex) {
1020             LOGGER.log(Level.WARNING, "Unable to load the dependency-check ant task.properties file.");
1021             LOGGER.log(Level.FINE, null, ex);
1022         } finally {
1023             if (taskProperties != null) {
1024                 try {
1025                     taskProperties.close();
1026                 } catch (IOException ex) {
1027                     LOGGER.log(Level.FINEST, null, ex);
1028                 }
1029             }
1030         }
1031         if (dataDirectory != null) {
1032             Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory);
1033         } else {
1034             final File jarPath = new File(DependencyCheckTask.class.getProtectionDomain().getCodeSource().getLocation().getPath());
1035             final File base = jarPath.getParentFile();
1036             final String sub = Settings.getString(Settings.KEYS.DATA_DIRECTORY);
1037             final File dataDir = new File(base, sub);
1038             Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath());
1039         }
1040 
1041         Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate);
1042 
1043         if (proxyServer != null && !proxyServer.isEmpty()) {
1044             Settings.setString(Settings.KEYS.PROXY_SERVER, proxyServer);
1045         }
1046         if (proxyPort != null && !proxyPort.isEmpty()) {
1047             Settings.setString(Settings.KEYS.PROXY_PORT, proxyPort);
1048         }
1049         if (proxyUsername != null && !proxyUsername.isEmpty()) {
1050             Settings.setString(Settings.KEYS.PROXY_USERNAME, proxyUsername);
1051         }
1052         if (proxyPassword != null && !proxyPassword.isEmpty()) {
1053             Settings.setString(Settings.KEYS.PROXY_PASSWORD, proxyPassword);
1054         }
1055         if (connectionTimeout != null && !connectionTimeout.isEmpty()) {
1056             Settings.setString(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout);
1057         }
1058         if (suppressionFile != null && !suppressionFile.isEmpty()) {
1059             Settings.setString(Settings.KEYS.SUPPRESSION_FILE, suppressionFile);
1060         }
1061 
1062         //File Type Analyzer Settings
1063         //JAR ANALYZER
1064         Settings.setBoolean(Settings.KEYS.ANALYZER_JAR_ENABLED, jarAnalyzerEnabled);
1065         //NUSPEC ANALYZER
1066         Settings.setBoolean(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, nuspecAnalyzerEnabled);
1067         //CENTRAL ANALYZER
1068         Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, centralAnalyzerEnabled);
1069         //NEXUS ANALYZER
1070         Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled);
1071         if (nexusUrl != null && !nexusUrl.isEmpty()) {
1072             Settings.setString(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl);
1073         }
1074         Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_PROXY, nexusUsesProxy);
1075         //ARCHIVE ANALYZER
1076         Settings.setBoolean(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, archiveAnalyzerEnabled);
1077         if (zipExtensions != null && !zipExtensions.isEmpty()) {
1078             Settings.setString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions);
1079         }
1080         //ASSEMBLY ANALYZER
1081         Settings.setBoolean(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, assemblyAnalyzerEnabled);
1082         if (pathToMono != null && !pathToMono.isEmpty()) {
1083             Settings.setString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono);
1084         }
1085 
1086         if (databaseDriverName != null && !databaseDriverName.isEmpty()) {
1087             Settings.setString(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName);
1088         }
1089         if (databaseDriverPath != null && !databaseDriverPath.isEmpty()) {
1090             Settings.setString(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath);
1091         }
1092         if (connectionString != null && !connectionString.isEmpty()) {
1093             Settings.setString(Settings.KEYS.DB_CONNECTION_STRING, connectionString);
1094         }
1095         if (databaseUser != null && !databaseUser.isEmpty()) {
1096             Settings.setString(Settings.KEYS.DB_USER, databaseUser);
1097         }
1098         if (databasePassword != null && !databasePassword.isEmpty()) {
1099             Settings.setString(Settings.KEYS.DB_PASSWORD, databasePassword);
1100         }
1101         if (cveUrl12Modified != null && !cveUrl12Modified.isEmpty()) {
1102             Settings.setString(Settings.KEYS.CVE_MODIFIED_12_URL, cveUrl12Modified);
1103         }
1104         if (cveUrl20Modified != null && !cveUrl20Modified.isEmpty()) {
1105             Settings.setString(Settings.KEYS.CVE_MODIFIED_20_URL, cveUrl20Modified);
1106         }
1107         if (cveUrl12Base != null && !cveUrl12Base.isEmpty()) {
1108             Settings.setString(Settings.KEYS.CVE_SCHEMA_1_2, cveUrl12Base);
1109         }
1110         if (cveUrl20Base != null && !cveUrl20Base.isEmpty()) {
1111             Settings.setString(Settings.KEYS.CVE_SCHEMA_2_0, cveUrl20Base);
1112         }
1113     }
1114 
1115     /**
1116      * Checks to see if a vulnerability has been identified with a CVSS score that is above the threshold set in the
1117      * configuration.
1118      *
1119      * @param dependencies the list of dependency objects
1120      * @throws BuildException thrown if a CVSS score is found that is higher then the threshold set
1121      */
1122     private void checkForFailure(List<Dependency> dependencies) throws BuildException {
1123         final StringBuilder ids = new StringBuilder();
1124         for (Dependency d : dependencies) {
1125             for (Vulnerability v : d.getVulnerabilities()) {
1126                 if (v.getCvssScore() >= failBuildOnCVSS) {
1127                     if (ids.length() == 0) {
1128                         ids.append(v.getName());
1129                     } else {
1130                         ids.append(", ").append(v.getName());
1131                     }
1132                 }
1133             }
1134         }
1135         if (ids.length() > 0) {
1136             final String msg = String.format("%n%nDependency-Check Failure:%n"
1137                     + "One or more dependencies were identified with vulnerabilities that have a CVSS score greater then '%.1f': %s%n"
1138                     + "See the dependency-check report for more details.%n%n", failBuildOnCVSS, ids.toString());
1139             throw new BuildException(msg);
1140         }
1141     }
1142 
1143     /**
1144      * Generates a warning message listing a summary of dependencies and their associated CPE and CVE entries.
1145      *
1146      * @param dependencies a list of dependency objects
1147      */
1148     private void showSummary(List<Dependency> dependencies) {
1149         final StringBuilder summary = new StringBuilder();
1150         for (Dependency d : dependencies) {
1151             boolean firstEntry = true;
1152             final StringBuilder ids = new StringBuilder();
1153             for (Vulnerability v : d.getVulnerabilities()) {
1154                 if (firstEntry) {
1155                     firstEntry = false;
1156                 } else {
1157                     ids.append(", ");
1158                 }
1159                 ids.append(v.getName());
1160             }
1161             if (ids.length() > 0) {
1162                 summary.append(d.getFileName()).append(" (");
1163                 firstEntry = true;
1164                 for (Identifier id : d.getIdentifiers()) {
1165                     if (firstEntry) {
1166                         firstEntry = false;
1167                     } else {
1168                         summary.append(", ");
1169                     }
1170                     summary.append(id.getValue());
1171                 }
1172                 summary.append(") : ").append(ids).append(NEW_LINE);
1173             }
1174         }
1175         if (summary.length() > 0) {
1176             final String msg = String.format("%n%n"
1177                     + "One or more dependencies were identified with known vulnerabilities:%n%n%s"
1178                     + "%n%nSee the dependency-check report for more details.%n%n", summary.toString());
1179             LOGGER.log(Level.WARNING, msg);
1180         }
1181     }
1182 
1183     /**
1184      * An enumeration of supported report formats: "ALL", "HTML", "XML", "VULN", etc..
1185      */
1186     public static class ReportFormats extends EnumeratedAttribute {
1187 
1188         /**
1189          * Returns the list of values for the report format.
1190          *
1191          * @return the list of values for the report format
1192          */
1193         @Override
1194         public String[] getValues() {
1195             int i = 0;
1196             final Format[] formats = Format.values();
1197             final String[] values = new String[formats.length];
1198             for (Format format : formats) {
1199                 values[i++] = format.name();
1200             }
1201             return values;
1202         }
1203     }
1204 
1205     /**
1206      * Whether or not the Jar Analyzer is enabled.
1207      */
1208     private boolean jarAnalyzerEnabled = true;
1209 
1210     /**
1211      * Returns whether or not the analyzer is enabled.
1212      *
1213      * @return true if the analyzer is enabled
1214      */
1215     public boolean isJarAnalyzerEnabled() {
1216         return jarAnalyzerEnabled;
1217     }
1218 }