1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.owasp.dependencycheck.maven;
19
20 import com.github.packageurl.MalformedPackageURLException;
21 import com.github.packageurl.PackageURL;
22 import com.github.packageurl.PackageURL.StandardTypes;
23 import org.apache.commons.lang3.StringUtils;
24 import org.apache.maven.artifact.Artifact;
25 import org.apache.maven.artifact.DefaultArtifact;
26 import org.apache.maven.artifact.handler.DefaultArtifactHandler;
27 import org.apache.maven.artifact.repository.ArtifactRepository;
28 import org.apache.maven.artifact.resolver.filter.ExcludesArtifactFilter;
29 import org.apache.maven.artifact.versioning.ArtifactVersion;
30 import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
31 import org.apache.maven.artifact.versioning.Restriction;
32 import org.apache.maven.artifact.versioning.VersionRange;
33 import org.apache.maven.doxia.sink.Sink;
34 import org.apache.maven.execution.MavenSession;
35 import org.apache.maven.model.License;
36 import org.apache.maven.plugin.AbstractMojo;
37 import org.apache.maven.plugin.MojoExecution;
38 import org.apache.maven.plugin.MojoExecutionException;
39 import org.apache.maven.plugin.MojoFailureException;
40 import org.apache.maven.plugins.annotations.Component;
41 import org.apache.maven.plugins.annotations.Parameter;
42 import org.apache.maven.project.DefaultProjectBuildingRequest;
43 import org.apache.maven.project.MavenProject;
44 import org.apache.maven.project.ProjectBuildingRequest;
45 import org.apache.maven.reporting.MavenReport;
46 import org.apache.maven.reporting.MavenReportException;
47 import org.apache.maven.settings.Proxy;
48 import org.apache.maven.settings.Server;
49 import org.apache.maven.settings.building.SettingsProblem;
50 import org.apache.maven.settings.crypto.DefaultSettingsDecryptionRequest;
51 import org.apache.maven.settings.crypto.SettingsDecrypter;
52 import org.apache.maven.settings.crypto.SettingsDecryptionResult;
53 import org.apache.maven.shared.artifact.filter.PatternExcludesArtifactFilter;
54 import org.apache.maven.shared.dependency.graph.DependencyGraphBuilder;
55 import org.apache.maven.shared.dependency.graph.DependencyGraphBuilderException;
56 import org.apache.maven.shared.dependency.graph.DependencyNode;
57 import org.apache.maven.shared.dependency.graph.filter.ArtifactDependencyNodeFilter;
58 import org.apache.maven.shared.dependency.graph.internal.DefaultDependencyNode;
59 import org.apache.maven.shared.dependency.graph.traversal.DependencyNodeVisitor;
60 import org.apache.maven.shared.dependency.graph.traversal.FilteringDependencyNodeVisitor;
61 import org.apache.maven.shared.model.fileset.FileSet;
62 import org.apache.maven.shared.model.fileset.util.FileSetManager;
63 import org.apache.maven.shared.transfer.artifact.DefaultArtifactCoordinate;
64 import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolver;
65 import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolverException;
66 import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult;
67 import org.apache.maven.shared.transfer.dependencies.DefaultDependableCoordinate;
68 import org.apache.maven.shared.transfer.dependencies.DependableCoordinate;
69 import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolver;
70 import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolverException;
71 import org.eclipse.aether.artifact.ArtifactType;
72 import org.owasp.dependencycheck.Engine;
73 import org.owasp.dependencycheck.agent.DependencyCheckScanAgent;
74 import org.owasp.dependencycheck.analyzer.JarAnalyzer;
75 import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
76 import org.owasp.dependencycheck.data.nexus.MavenArtifact;
77 import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
78 import org.owasp.dependencycheck.dependency.Confidence;
79 import org.owasp.dependencycheck.dependency.Dependency;
80 import org.owasp.dependencycheck.dependency.EvidenceType;
81 import org.owasp.dependencycheck.dependency.Vulnerability;
82 import org.owasp.dependencycheck.dependency.naming.GenericIdentifier;
83 import org.owasp.dependencycheck.dependency.naming.Identifier;
84 import org.owasp.dependencycheck.dependency.naming.PurlIdentifier;
85 import org.owasp.dependencycheck.exception.DependencyNotFoundException;
86 import org.owasp.dependencycheck.exception.ExceptionCollection;
87 import org.owasp.dependencycheck.exception.InitializationException;
88 import org.owasp.dependencycheck.exception.ReportException;
89 import org.owasp.dependencycheck.reporting.ReportGenerator;
90 import org.owasp.dependencycheck.utils.Checksum;
91 import org.owasp.dependencycheck.utils.Downloader;
92 import org.owasp.dependencycheck.utils.Filter;
93 import org.owasp.dependencycheck.utils.InvalidSettingException;
94 import org.owasp.dependencycheck.utils.Settings;
95 import org.owasp.dependencycheck.utils.SeverityUtil;
96 import org.owasp.dependencycheck.xml.pom.Model;
97 import org.owasp.dependencycheck.xml.pom.PomUtils;
98
99 import java.io.File;
100 import java.io.IOException;
101 import java.io.InputStream;
102 import java.util.ArrayList;
103 import java.util.Arrays;
104 import java.util.Collections;
105 import java.util.HashSet;
106 import java.util.List;
107 import java.util.Locale;
108 import java.util.Map;
109 import java.util.Objects;
110 import java.util.Optional;
111 import java.util.Set;
112 import java.util.stream.Collectors;
113 import java.util.stream.Stream;
114
115
116
117
118
119
120 public abstract class BaseDependencyCheckMojo extends AbstractMojo implements MavenReport {
121
122
123
124
125
126 private static final String PROPERTIES_FILE = "mojo.properties";
127
128
129
130 private static final String NEW_LINE = System.getProperty("line.separator", "\n").intern();
131
132
133
134 private static final String INCLUDE_ALL = "**/*";
135
136
137
138 public static final String PROTOCOL_HTTPS = "https";
139
140
141
142 public static final String PROTOCOL_HTTP = "http";
143
144
145
146 private boolean generatingSite = false;
147
148
149
150 private Settings settings = null;
151
152
153
154 private final List<File> scannedFiles = new ArrayList<>();
155
156
157
158
159
160 @SuppressWarnings("CanBeFinal")
161 @Parameter(property = "failOnError", defaultValue = "true", required = true)
162 private boolean failOnError;
163
164
165
166
167 @SuppressWarnings("CanBeFinal")
168 @Parameter(property = "project", required = true, readonly = true)
169 private MavenProject project;
170
171
172
173 @Parameter(defaultValue = "${mojoExecution}", readonly = true)
174 private MojoExecution mojoExecution;
175
176
177
178 @SuppressWarnings("CanBeFinal")
179 @Parameter(readonly = true, required = true, property = "reactorProjects")
180 private List<MavenProject> reactorProjects;
181
182
183
184
185
186 @SuppressWarnings("CanBeFinal")
187 @Component
188 private ArtifactResolver artifactResolver;
189
190
191
192
193
194
195
196 @SuppressWarnings("CanBeFinal")
197 @Component
198 private DependencyResolver dependencyResolver;
199
200
201
202
203 @SuppressWarnings("CanBeFinal")
204 @Parameter(defaultValue = "${session}", readonly = true, required = true)
205 private MavenSession session;
206
207
208
209
210 @Component
211 private DependencyGraphBuilder dependencyGraphBuilder;
212
213
214
215
216 @SuppressWarnings("CanBeFinal")
217 @Parameter(defaultValue = "${project.build.directory}", required = true, property = "odc.outputDirectory")
218 private File outputDirectory;
219
220
221
222
223
224 @Parameter(property = "project.reporting.outputDirectory", readonly = true)
225 private File reportOutputDirectory;
226
227
228
229
230
231 @SuppressWarnings("CanBeFinal")
232 @Parameter(property = "failBuildOnCVSS", defaultValue = "11", required = true)
233 private float failBuildOnCVSS = 11f;
234
235
236
237
238
239 @SuppressWarnings("CanBeFinal")
240 @Parameter(property = "junitFailOnCVSS", defaultValue = "0", required = true)
241 private float junitFailOnCVSS = 0;
242
243
244
245
246
247
248 @SuppressWarnings("CanBeFinal")
249 @Parameter(property = "failBuildOnAnyVulnerability", defaultValue = "false", required = true)
250 @Deprecated
251 private boolean failBuildOnAnyVulnerability = false;
252
253
254
255
256 @SuppressWarnings("CanBeFinal")
257 @Parameter(property = "autoUpdate")
258 private Boolean autoUpdate;
259
260
261
262 @SuppressWarnings("CanBeFinal")
263 @Parameter(property = "enableExperimental")
264 private Boolean enableExperimental;
265
266
267
268 @SuppressWarnings("CanBeFinal")
269 @Parameter(property = "enableRetired")
270 private Boolean enableRetired;
271
272
273
274 @SuppressWarnings("CanBeFinal")
275 @Parameter(property = "golangDepEnabled")
276 private Boolean golangDepEnabled;
277
278
279
280
281 @SuppressWarnings("CanBeFinal")
282 @Parameter(property = "golangModEnabled")
283 private Boolean golangModEnabled;
284
285
286
287 @SuppressWarnings("CanBeFinal")
288 @Parameter(property = "pathToGo")
289 private String pathToGo;
290
291
292
293
294 @SuppressWarnings("CanBeFinal")
295 @Parameter(property = "pathToYarn")
296 private String pathToYarn;
297
298
299
300 @SuppressWarnings("CanBeFinal")
301 @Parameter(property = "pathToPnpm")
302 private String pathToPnpm;
303
304
305
306
307 @Parameter(property = "dependency-check.virtualSnapshotsFromReactor", defaultValue = "true")
308 private Boolean virtualSnapshotsFromReactor;
309
310
311
312
313
314 @SuppressWarnings("CanBeFinal")
315 @Parameter(property = "format", defaultValue = "HTML", required = true)
316 private String format = "HTML";
317
318
319
320
321
322 @Parameter(property = "prettyPrint")
323 private Boolean prettyPrint;
324
325
326
327
328
329 @Parameter(property = "formats", required = true)
330 private String[] formats;
331
332
333
334 @SuppressWarnings("CanBeFinal")
335 @Parameter(property = "mavenSettings", defaultValue = "${settings}")
336 private org.apache.maven.settings.Settings mavenSettings;
337
338
339
340
341 @SuppressWarnings("CanBeFinal")
342 @Parameter(property = "mavenSettingsProxyId")
343 private String mavenSettingsProxyId;
344
345
346
347
348 @SuppressWarnings("CanBeFinal")
349 @Parameter(property = "connectionTimeout")
350 private String connectionTimeout;
351
352
353
354 @SuppressWarnings("CanBeFinal")
355 @Parameter(property = "readTimeout")
356 private String readTimeout;
357
358
359
360
361 @SuppressWarnings("CanBeFinal")
362 @Parameter(property = "versionCheckEnabled", defaultValue = "true")
363 private boolean versionCheckEnabled;
364
365
366
367
368
369
370 @SuppressWarnings("CanBeFinal")
371 @Parameter(property = "suppressionFiles")
372 private String[] suppressionFiles;
373
374
375
376
377
378
379 @SuppressWarnings("CanBeFinal")
380 @Parameter(property = "suppressionFile")
381 private String suppressionFile;
382
383
384
385 @Parameter(property = "suppressionFileUser")
386 private String suppressionFileUser;
387
388
389
390
391 @Parameter(property = "suppressionFilePassword")
392 private String suppressionFilePassword;
393
394
395
396
397 @Parameter(property = "suppressionFileBearerToken")
398 private String suppressionFileBearerToken;
399
400
401
402
403 @SuppressWarnings("CanBeFinal")
404 @Parameter(property = "suppressionFileServerId")
405 private String suppressionFileServerId;
406
407
408
409 @SuppressWarnings("CanBeFinal")
410 @Parameter(property = "hintsFile")
411 private String hintsFile;
412
413
414
415
416 @SuppressWarnings("CanBeFinal")
417 @Parameter(property = "showSummary", defaultValue = "true")
418 private boolean showSummary = true;
419
420
421
422
423 @SuppressWarnings("CanBeFinal")
424 @Parameter(property = "jarAnalyzerEnabled")
425 private Boolean jarAnalyzerEnabled;
426
427
428
429
430 @SuppressWarnings("CanBeFinal")
431 @Parameter(property = "dartAnalyzerEnabled")
432 private Boolean dartAnalyzerEnabled;
433
434
435
436
437 @SuppressWarnings("CanBeFinal")
438 @Parameter(property = "archiveAnalyzerEnabled")
439 private Boolean archiveAnalyzerEnabled;
440
441
442
443 @SuppressWarnings("CanBeFinal")
444 @Parameter(property = "knownExploitedEnabled")
445 private Boolean knownExploitedEnabled;
446
447
448
449 @SuppressWarnings("CanBeFinal")
450 @Parameter(property = "knownExploitedUrl")
451 private String knownExploitedUrl;
452
453
454
455
456
457 @SuppressWarnings("CanBeFinal")
458 @Parameter(property = "knownExploitedServerId")
459 private String knownExploitedServerId;
460
461
462
463
464 @SuppressWarnings("CanBeFinal")
465 @Parameter(property = "knownExploitedUser")
466 private String knownExploitedUser;
467
468
469
470
471 @SuppressWarnings("CanBeFinal")
472 @Parameter(property = "knownExploitedPassword")
473 private String knownExploitedPassword;
474
475
476
477
478 @SuppressWarnings("CanBeFinal")
479 @Parameter(property = "knownExploitedBearerToken")
480 private String knownExploitedBearerToken;
481
482
483
484 @SuppressWarnings("CanBeFinal")
485 @Parameter(property = "pyDistributionAnalyzerEnabled")
486 private Boolean pyDistributionAnalyzerEnabled;
487
488
489
490 @Parameter(property = "pyPackageAnalyzerEnabled")
491 private Boolean pyPackageAnalyzerEnabled;
492
493
494
495 @SuppressWarnings("CanBeFinal")
496 @Parameter(property = "rubygemsAnalyzerEnabled")
497 private Boolean rubygemsAnalyzerEnabled;
498
499
500
501 @SuppressWarnings("CanBeFinal")
502 @Parameter(property = "opensslAnalyzerEnabled")
503 private Boolean opensslAnalyzerEnabled;
504
505
506
507 @SuppressWarnings("CanBeFinal")
508 @Parameter(property = "cmakeAnalyzerEnabled")
509 private Boolean cmakeAnalyzerEnabled;
510
511
512
513 @SuppressWarnings("CanBeFinal")
514 @Parameter(property = "autoconfAnalyzerEnabled")
515 private Boolean autoconfAnalyzerEnabled;
516
517
518
519 @SuppressWarnings("CanBeFinal")
520 @Parameter(property = "mavenInstallAnalyzerEnabled")
521 private Boolean mavenInstallAnalyzerEnabled;
522
523
524
525 @SuppressWarnings("CanBeFinal")
526 @Parameter(property = "pipAnalyzerEnabled")
527 private Boolean pipAnalyzerEnabled;
528
529
530
531 @SuppressWarnings("CanBeFinal")
532 @Parameter(property = "pipfileAnalyzerEnabled")
533 private Boolean pipfileAnalyzerEnabled;
534
535
536
537 @SuppressWarnings("CanBeFinal")
538 @Parameter(property = "poetryAnalyzerEnabled")
539 private Boolean poetryAnalyzerEnabled;
540
541
542
543 @Parameter(property = "composerAnalyzerEnabled")
544 private Boolean composerAnalyzerEnabled;
545
546
547
548 @Parameter(property = "composerAnalyzerSkipDev")
549 private boolean composerAnalyzerSkipDev;
550
551
552
553 @Parameter(property = "cpanfileAnalyzerEnabled")
554 private Boolean cpanfileAnalyzerEnabled;
555
556
557
558 @SuppressWarnings("CanBeFinal")
559 @Parameter(property = "nodeAnalyzerEnabled")
560 private Boolean nodeAnalyzerEnabled;
561
562
563
564 @SuppressWarnings("CanBeFinal")
565 @Parameter(property = "nodeAuditAnalyzerEnabled")
566 private Boolean nodeAuditAnalyzerEnabled;
567
568
569
570
571 @SuppressWarnings("CanBeFinal")
572 @Parameter(property = "nodeAuditAnalyzerUrl")
573 private String nodeAuditAnalyzerUrl;
574
575
576
577
578 @SuppressWarnings("CanBeFinal")
579 @Parameter(property = "yarnAuditAnalyzerEnabled")
580 private Boolean yarnAuditAnalyzerEnabled;
581
582
583
584
585 @SuppressWarnings("CanBeFinal")
586 @Parameter(property = "pnpmAuditAnalyzerEnabled")
587 private Boolean pnpmAuditAnalyzerEnabled;
588
589
590
591
592 @SuppressWarnings("CanBeFinal")
593 @Parameter(property = "nodeAuditAnalyzerUseCache")
594 private Boolean nodeAuditAnalyzerUseCache;
595
596
597
598 @SuppressWarnings("CanBeFinal")
599 @Parameter(property = "nodeAuditSkipDevDependencies")
600 private Boolean nodeAuditSkipDevDependencies;
601
602
603
604 @SuppressWarnings("CanBeFinal")
605 @Parameter(property = "nodePackageSkipDevDependencies")
606 private Boolean nodePackageSkipDevDependencies;
607
608
609
610 @SuppressWarnings("CanBeFinal")
611 @Parameter(property = "retireJsAnalyzerEnabled")
612 private Boolean retireJsAnalyzerEnabled;
613
614
615
616 @SuppressWarnings("CanBeFinal")
617 @Parameter(property = "retireJsUrl")
618 private String retireJsUrl;
619
620
621
622 @Parameter(property = "retireJsUser")
623 private String retireJsUser;
624
625
626
627 @Parameter(property = "retireJsPassword")
628 private String retireJsPassword;
629
630
631
632
633 @Parameter(property = "retireJsBearerToken")
634 private String retireJsBearerToken;
635
636
637
638
639 @SuppressWarnings("CanBeFinal")
640 @Parameter(property = "retireJsUrlServerId")
641 private String retireJsUrlServerId;
642
643
644
645
646 @SuppressWarnings("CanBeFinal")
647 @Parameter(property = "retireJsForceUpdate")
648 private Boolean retireJsForceUpdate;
649
650
651
652 @Parameter(property = "assemblyAnalyzerEnabled")
653 private Boolean assemblyAnalyzerEnabled;
654
655
656
657 @Parameter(property = "msbuildAnalyzerEnabled")
658 private Boolean msbuildAnalyzerEnabled;
659
660
661
662 @SuppressWarnings("CanBeFinal")
663 @Parameter(property = "nuspecAnalyzerEnabled")
664 private Boolean nuspecAnalyzerEnabled;
665
666
667
668
669 @SuppressWarnings("CanBeFinal")
670 @Parameter(property = "nugetconfAnalyzerEnabled")
671 private Boolean nugetconfAnalyzerEnabled;
672
673
674
675
676 @SuppressWarnings("CanBeFinal")
677 @Parameter(property = "libmanAnalyzerEnabled")
678 private Boolean libmanAnalyzerEnabled;
679
680
681
682
683 @SuppressWarnings("CanBeFinal")
684 @Parameter(property = "centralAnalyzerEnabled")
685 private Boolean centralAnalyzerEnabled;
686
687
688
689
690 @SuppressWarnings("CanBeFinal")
691 @Parameter(property = "centralAnalyzerUseCache")
692 private Boolean centralAnalyzerUseCache;
693
694
695
696
697 @SuppressWarnings("CanBeFinal")
698 @Parameter(property = "artifactoryAnalyzerEnabled")
699 private Boolean artifactoryAnalyzerEnabled;
700
701
702
703
704 @SuppressWarnings("CanBeFinal")
705 @Parameter(property = "artifactoryAnalyzerServerId")
706 private String artifactoryAnalyzerServerId;
707
708
709
710
711 @SuppressWarnings("CanBeFinal")
712 @Parameter(property = "artifactoryAnalyzerUsername")
713 private String artifactoryAnalyzerUsername;
714
715
716
717 @SuppressWarnings("CanBeFinal")
718 @Parameter(property = "artifactoryAnalyzerApiToken")
719 private String artifactoryAnalyzerApiToken;
720
721
722
723 @SuppressWarnings("CanBeFinal")
724 @Parameter(property = "artifactoryAnalyzerBearerToken")
725 private String artifactoryAnalyzerBearerToken;
726
727
728
729 @SuppressWarnings("CanBeFinal")
730 @Parameter(property = "artifactoryAnalyzerUrl")
731 private String artifactoryAnalyzerUrl;
732
733
734
735 @SuppressWarnings("CanBeFinal")
736 @Parameter(property = "artifactoryAnalyzerUseProxy")
737 private Boolean artifactoryAnalyzerUseProxy;
738
739
740
741 @SuppressWarnings("CanBeFinal")
742 @Parameter(property = "artifactoryAnalyzerParallelAnalysis", defaultValue = "true")
743 private Boolean artifactoryAnalyzerParallelAnalysis;
744
745
746
747 @SuppressWarnings("CanBeFinal")
748 @Parameter(property = "failBuildOnUnusedSuppressionRule", defaultValue = "false")
749 private Boolean failBuildOnUnusedSuppressionRule;
750
751
752
753 @SuppressWarnings("CanBeFinal")
754 @Parameter(property = "nexusAnalyzerEnabled")
755 private Boolean nexusAnalyzerEnabled;
756
757
758
759
760 @SuppressWarnings("CanBeFinal")
761 @Parameter(property = "ossIndexAnalyzerEnabled", alias = "ossindexAnalyzerEnabled")
762 private Boolean ossIndexAnalyzerEnabled;
763
764
765
766
767 @SuppressWarnings("CanBeFinal")
768 @Parameter(property = "ossIndexAnalyzerUseCache", alias = "ossindexAnalyzerUseCache")
769 private Boolean ossIndexAnalyzerUseCache;
770
771
772
773
774 @SuppressWarnings("CanBeFinal")
775 @Parameter(property = "ossIndexAnalyzerCacheValidForHours")
776 private Integer ossIndexAnalyzerCacheValidForHours;
777
778
779
780
781 @SuppressWarnings("CanBeFinal")
782 @Parameter(property = "ossIndexAnalyzerUrl", alias = "ossindexAnalyzerUrl")
783 private String ossIndexAnalyzerUrl;
784
785
786
787
788
789
790 @SuppressWarnings("CanBeFinal")
791 @Parameter(property = "ossIndexServerId")
792 private String ossIndexServerId;
793
794
795
796
797
798
799
800 @SuppressWarnings("CanBeFinal")
801 @Parameter(property = "ossIndexUsername")
802 private String ossIndexUsername;
803
804
805
806
807
808
809
810 @SuppressWarnings("CanBeFinal")
811 @Parameter(property = "ossIndexPassword")
812 private String ossIndexPassword;
813
814
815
816
817
818 @SuppressWarnings("CanBeFinal")
819 @Parameter(property = "ossIndexWarnOnlyOnRemoteErrors")
820 private Boolean ossIndexWarnOnlyOnRemoteErrors;
821
822
823
824
825 @Parameter(property = "mixAuditAnalyzerEnabled")
826 private Boolean mixAuditAnalyzerEnabled;
827
828
829
830
831 @SuppressWarnings("CanBeFinal")
832 @Parameter(property = "mixAuditPath")
833 private String mixAuditPath;
834
835
836
837
838 @Parameter(property = "bundleAuditAnalyzerEnabled")
839 private Boolean bundleAuditAnalyzerEnabled;
840
841
842
843
844 @SuppressWarnings("CanBeFinal")
845 @Parameter(property = "bundleAuditPath")
846 private String bundleAuditPath;
847
848
849
850
851
852 @SuppressWarnings("CanBeFinal")
853 @Parameter(property = "bundleAuditWorkingDirectory")
854 private String bundleAuditWorkingDirectory;
855
856
857
858
859 @SuppressWarnings("CanBeFinal")
860 @Parameter(property = "cocoapodsAnalyzerEnabled")
861 private Boolean cocoapodsAnalyzerEnabled;
862
863
864
865
866 @SuppressWarnings("CanBeFinal")
867 @Parameter(property = "carthageAnalyzerEnabled")
868 private Boolean carthageAnalyzerEnabled;
869
870
871
872
873 @SuppressWarnings("CanBeFinal")
874 @Parameter(property = "swiftPackageManagerAnalyzerEnabled")
875 private Boolean swiftPackageManagerAnalyzerEnabled;
876
877
878
879 @SuppressWarnings("CanBeFinal")
880 @Parameter(property = "swiftPackageResolvedAnalyzerEnabled")
881 private Boolean swiftPackageResolvedAnalyzerEnabled;
882
883
884
885
886 @SuppressWarnings("CanBeFinal")
887 @Parameter(property = "nexusUrl")
888 private String nexusUrl;
889
890
891
892
893
894
895 @SuppressWarnings("CanBeFinal")
896 @Parameter(property = "nexusServerId")
897 private String nexusServerId;
898
899
900
901 @SuppressWarnings("CanBeFinal")
902 @Parameter(property = "nexusUsesProxy")
903 private Boolean nexusUsesProxy;
904
905
906
907 @SuppressWarnings("CanBeFinal")
908 @Parameter(property = "connectionString")
909 private String connectionString;
910
911
912
913
914 @SuppressWarnings("CanBeFinal")
915 @Parameter(property = "databaseDriverName")
916 private String databaseDriverName;
917
918
919
920 @SuppressWarnings("CanBeFinal")
921 @Parameter(property = "databaseDriverPath")
922 private String databaseDriverPath;
923
924
925
926 @SuppressWarnings("CanBeFinal")
927 @Parameter(defaultValue = "${settings}", readonly = true, required = true)
928 private org.apache.maven.settings.Settings settingsXml;
929
930
931
932
933 @Component
934 private SettingsDecrypter settingsDecrypter;
935
936
937
938
939 @Parameter(property = "databaseUser")
940 private String databaseUser;
941
942
943
944 @Parameter(property = "databasePassword")
945 private String databasePassword;
946
947
948
949
950 @SuppressWarnings("CanBeFinal")
951 @Parameter(property = "zipExtensions")
952 private String zipExtensions;
953
954
955
956 @SuppressWarnings("CanBeFinal")
957 @Parameter(property = "dependency-check.skip", defaultValue = "false")
958 private boolean skip = false;
959
960
961
962 @SuppressWarnings("CanBeFinal")
963 @Parameter(property = "skipTestScope", defaultValue = "true")
964 private boolean skipTestScope = true;
965
966
967
968 @SuppressWarnings("CanBeFinal")
969 @Parameter(property = "skipRuntimeScope", defaultValue = "false")
970 private boolean skipRuntimeScope = false;
971
972
973
974 @SuppressWarnings("CanBeFinal")
975 @Parameter(property = "skipProvidedScope", defaultValue = "false")
976 private boolean skipProvidedScope = false;
977
978
979
980
981 @SuppressWarnings("CanBeFinal")
982 @Parameter(property = "skipSystemScope", defaultValue = "false")
983 private boolean skipSystemScope = false;
984
985
986
987
988 @SuppressWarnings("CanBeFinal")
989 @Parameter(property = "skipDependencyManagement", defaultValue = "true")
990 private boolean skipDependencyManagement = true;
991
992
993
994
995
996
997 @SuppressWarnings("CanBeFinal")
998 @Parameter(property = "skipArtifactType")
999 private String skipArtifactType;
1000
1001
1002
1003
1004 @SuppressWarnings("CanBeFinal")
1005 @Parameter(property = "dataDirectory")
1006 private String dataDirectory;
1007
1008
1009
1010
1011 @SuppressWarnings("CanBeFinal")
1012 @Parameter(property = "dbFilename")
1013 private String dbFilename;
1014
1015
1016
1017
1018
1019 @SuppressWarnings("CanBeFinal")
1020 @Parameter(property = "serverId")
1021 private String serverId;
1022
1023
1024
1025
1026
1027 @SuppressWarnings("CanBeFinal")
1028 @Parameter(property = "nvdApiKey")
1029 private String nvdApiKey;
1030
1031
1032
1033 @SuppressWarnings("CanBeFinal")
1034 @Parameter(property = "nvdMaxRetryCount")
1035 private Integer nvdMaxRetryCount;
1036
1037
1038
1039
1040
1041
1042 @SuppressWarnings("CanBeFinal")
1043 @Parameter(property = "nvdApiServerId")
1044 private String nvdApiServerId;
1045
1046
1047
1048
1049
1050 @SuppressWarnings("CanBeFinal")
1051 @Parameter(property = "nvdApiKeyEnvironmentVariable")
1052 private String nvdApiKeyEnvironmentVariable;
1053
1054
1055
1056 @SuppressWarnings("CanBeFinal")
1057 @Parameter(property = "nvdValidForHours")
1058 private Integer nvdValidForHours;
1059
1060
1061
1062 @SuppressWarnings("CanBeFinal")
1063 @Parameter(property = "nvdApiEndpoint")
1064 private String nvdApiEndpoint;
1065
1066
1067
1068 @SuppressWarnings("CanBeFinal")
1069 @Parameter(property = "nvdDatafeedUrl")
1070 private String nvdDatafeedUrl;
1071
1072
1073
1074
1075
1076
1077 @SuppressWarnings("CanBeFinal")
1078 @Parameter(property = "nvdDatafeedServerId")
1079 private String nvdDatafeedServerId;
1080
1081
1082
1083
1084 @SuppressWarnings("CanBeFinal")
1085 @Parameter(property = "nvdUser")
1086 private String nvdUser;
1087
1088
1089
1090
1091 @SuppressWarnings("CanBeFinal")
1092 @Parameter(property = "nvdPassword")
1093 private String nvdPassword;
1094
1095
1096
1097
1098 @SuppressWarnings("CanBeFinal")
1099 @Parameter(property = "nvdBearerToken")
1100 private String nvdBearerToken;
1101
1102
1103
1104 @SuppressWarnings("CanBeFinal")
1105 @Parameter(property = "nvdApiDelay")
1106 private Integer nvdApiDelay;
1107
1108
1109
1110
1111 @SuppressWarnings("CanBeFinal")
1112 @Parameter(property = "nvdApiResultsPerPage")
1113 private Integer nvdApiResultsPerPage;
1114
1115
1116
1117
1118 @SuppressWarnings("CanBeFinal")
1119 @Parameter(property = "pathToCore")
1120 private String pathToCore;
1121
1122
1123
1124 @SuppressWarnings("CanBeFinal")
1125 @Parameter(property = "hostedSuppressionsUrl")
1126 private String hostedSuppressionsUrl;
1127
1128
1129
1130 @SuppressWarnings("CanBeFinal")
1131 @Parameter(property = "hostedSuppressionsUser")
1132 private String hostedSuppressionsUser;
1133
1134
1135
1136 @SuppressWarnings("CanBeFinal")
1137 @Parameter(property = "hostedSuppressionsPassword")
1138 private String hostedSuppressionsPassword;
1139
1140
1141
1142
1143 @SuppressWarnings("CanBeFinal")
1144 @Parameter(property = "hostedSuppressionsBearerToken")
1145 private String hostedSuppressionsBearerToken;
1146
1147
1148
1149
1150 @SuppressWarnings("CanBeFinal")
1151 @Parameter(property = "hostedSuppressionsServerId")
1152 private String hostedSuppressionsServerId;
1153
1154
1155
1156
1157 @SuppressWarnings("CanBeFinal")
1158 @Parameter(property = "hostedSuppressionsForceUpdate")
1159 private Boolean hostedSuppressionsForceUpdate;
1160
1161
1162
1163 @SuppressWarnings("CanBeFinal")
1164 @Parameter(property = "hostedSuppressionsEnabled")
1165 private Boolean hostedSuppressionsEnabled;
1166
1167
1168
1169
1170 @SuppressWarnings("CanBeFinal")
1171 @Parameter(property = "hostedSuppressionsValidForHours")
1172 private Integer hostedSuppressionsValidForHours;
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189 @SuppressWarnings("CanBeFinal")
1190 @Parameter(property = "retirejs")
1191 private Retirejs retirejs;
1192
1193
1194
1195
1196
1197
1198 @Parameter(property = "odc.excludes")
1199 private List<String> excludes;
1200
1201
1202
1203
1204 private Filter<String> artifactScopeExcluded;
1205
1206
1207
1208
1209 private Filter<String> artifactTypeExcluded;
1210
1211
1212
1213
1214
1215
1216
1217
1218 @Parameter
1219 private List<FileSet> scanSet;
1220
1221
1222
1223
1224
1225 @Parameter(property = "scanDirectory")
1226 private List<String> scanDirectory;
1227
1228
1229
1230
1231 @SuppressWarnings("CanBeFinal")
1232 @Parameter(property = "odc.plugins.scan", defaultValue = "false", required = false)
1233 private boolean scanPlugins = false;
1234
1235
1236
1237 @SuppressWarnings("CanBeFinal")
1238 @Parameter(property = "odc.dependencies.scan", defaultValue = "true", required = false)
1239 private boolean scanDependencies = true;
1240
1241
1242
1243 @Parameter
1244 private ProxyConfig proxy;
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257 private static boolean artifactsMatch(org.apache.maven.model.Dependency d, Artifact a) {
1258 return isEqualOrNull(a.getArtifactId(), d.getArtifactId())
1259 && isEqualOrNull(a.getGroupId(), d.getGroupId())
1260 && isEqualOrNull(a.getVersion(), d.getVersion());
1261 }
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272 private static boolean isEqualOrNull(String left, String right) {
1273 return (left != null && left.equals(right)) || (left == null && right == null);
1274 }
1275
1276
1277
1278
1279
1280
1281
1282
1283 @Override
1284 public void execute() throws MojoExecutionException, MojoFailureException {
1285 generatingSite = false;
1286 final boolean shouldSkip = Boolean.parseBoolean(System.getProperty("dependency-check.skip", Boolean.toString(skip)));
1287 if (shouldSkip) {
1288 getLog().info("Skipping " + getName(Locale.US));
1289 } else {
1290 project.setContextValue("dependency-check-output-dir", this.outputDirectory);
1291 runCheck();
1292 }
1293 }
1294
1295
1296
1297
1298
1299
1300 protected boolean isGeneratingSite() {
1301 return generatingSite;
1302 }
1303
1304
1305
1306
1307
1308
1309 protected String getConnectionString() {
1310 return connectionString;
1311 }
1312
1313
1314
1315
1316
1317
1318 protected boolean isFailOnError() {
1319 return failOnError;
1320 }
1321
1322
1323
1324
1325
1326
1327
1328
1329 public void generate(Sink sink, Locale locale) throws MavenReportException {
1330 final boolean shouldSkip = Boolean.parseBoolean(System.getProperty("dependency-check.skip", Boolean.toString(skip)));
1331 if (shouldSkip) {
1332 getLog().info("Skipping report generation " + getName(Locale.US));
1333 return;
1334 }
1335
1336 generatingSite = true;
1337 project.setContextValue("dependency-check-output-dir", getReportOutputDirectory());
1338 try {
1339 runCheck();
1340 } catch (MojoExecutionException ex) {
1341 throw new MavenReportException(ex.getMessage(), ex);
1342 } catch (MojoFailureException ex) {
1343 getLog().warn("Vulnerabilities were identifies that exceed the CVSS threshold for failing the build");
1344 }
1345 }
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355 protected File getCorrectOutputDirectory() throws MojoExecutionException {
1356 return getCorrectOutputDirectory(this.project);
1357 }
1358
1359
1360
1361
1362
1363
1364
1365
1366 protected File getCorrectOutputDirectory(MavenProject current) {
1367 final Object obj = current.getContextValue("dependency-check-output-dir");
1368 if (obj != null && obj instanceof File) {
1369 return (File) obj;
1370 }
1371
1372 File target = new File(current.getBuild().getDirectory());
1373 if (target.getParentFile() != null && "target".equals(target.getParentFile().getName())) {
1374 target = target.getParentFile();
1375 }
1376 return target;
1377 }
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388 protected ExceptionCollection scanArtifacts(MavenProject project, Engine engine) {
1389 return scanArtifacts(project, engine, false);
1390 }
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402 protected ExceptionCollection scanArtifacts(MavenProject project, Engine engine, boolean aggregate) {
1403 try {
1404 final List<String> filterItems = Collections.singletonList(String.format("%s:%s", project.getGroupId(), project.getArtifactId()));
1405 final ProjectBuildingRequest buildingRequest = newResolveArtifactProjectBuildingRequest(project, project.getRemoteArtifactRepositories());
1406
1407
1408 final DependencyNode dn = dependencyGraphBuilder.buildDependencyGraph(buildingRequest, null);
1409
1410 final CollectingRootDependencyGraphVisitor collectorVisitor = new CollectingRootDependencyGraphVisitor();
1411
1412
1413 final DependencyNodeVisitor transitiveFilterVisitor = new FilteringDependencyTransitiveNodeVisitor(collectorVisitor,
1414 new ArtifactDependencyNodeFilter(new PatternExcludesArtifactFilter(getExcludes())));
1415
1416
1417 final DependencyNodeVisitor artifactFilter = new FilteringDependencyNodeVisitor(transitiveFilterVisitor,
1418 new ArtifactDependencyNodeFilter(new ExcludesArtifactFilter(filterItems)));
1419 dn.accept(artifactFilter);
1420
1421
1422 final Map<DependencyNode, List<DependencyNode>> nodes = collectorVisitor.getNodes();
1423
1424 return collectDependencies(engine, project, nodes, buildingRequest, aggregate);
1425 } catch (DependencyGraphBuilderException ex) {
1426 final String msg = String.format("Unable to build dependency graph on project %s", project.getName());
1427 getLog().debug(msg, ex);
1428 return new ExceptionCollection(ex);
1429 }
1430 }
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443 protected ExceptionCollection scanPlugins(MavenProject project, Engine engine, ExceptionCollection exCollection) {
1444 ExceptionCollection exCol = exCollection;
1445 final Set<Artifact> plugins = new HashSet<>();
1446 final Set<Artifact> buildPlugins = getProject().getPluginArtifacts();
1447 final Set<Artifact> reportPlugins = getProject().getReportArtifacts();
1448 final Set<Artifact> extensions = getProject().getExtensionArtifacts();
1449
1450 plugins.addAll(buildPlugins);
1451 plugins.addAll(reportPlugins);
1452 plugins.addAll(extensions);
1453
1454 final ProjectBuildingRequest buildingRequest = newResolveArtifactProjectBuildingRequest(project, project.getPluginArtifactRepositories());
1455 for (Artifact plugin : plugins) {
1456 try {
1457 final Artifact resolved = artifactResolver.resolveArtifact(buildingRequest, plugin).getArtifact();
1458
1459 exCol = addPluginToDependencies(project, engine, resolved, "pom.xml (plugins)", exCol);
1460
1461 final DefaultDependableCoordinate pluginCoordinate = new DefaultDependableCoordinate();
1462 pluginCoordinate.setGroupId(resolved.getGroupId());
1463 pluginCoordinate.setArtifactId(resolved.getArtifactId());
1464 pluginCoordinate.setVersion(resolved.getVersion());
1465
1466 final String parent = buildReference(resolved.getGroupId(), resolved.getArtifactId(), resolved.getVersion());
1467 for (Artifact artifact : resolveArtifactDependencies(pluginCoordinate, project)) {
1468 exCol = addPluginToDependencies(project, engine, artifact, parent, exCol);
1469 }
1470 } catch (ArtifactResolverException ex) {
1471 throw new RuntimeException(ex);
1472 } catch (IllegalArgumentException ex) {
1473 throw new RuntimeException(ex);
1474 } catch (DependencyResolverException ex) {
1475 throw new RuntimeException(ex);
1476 }
1477 }
1478
1479 return null;
1480
1481 }
1482
1483 private ExceptionCollection addPluginToDependencies(MavenProject project, Engine engine, Artifact artifact, String parent, ExceptionCollection exCollection) {
1484 ExceptionCollection exCol = exCollection;
1485 final String groupId = artifact.getGroupId();
1486 final String artifactId = artifact.getArtifactId();
1487 final String version = artifact.getVersion();
1488 final File artifactFile = artifact.getFile();
1489 if (artifactFile.isFile()) {
1490 final List<ArtifactVersion> availableVersions = artifact.getAvailableVersions();
1491
1492 final List<Dependency> deps = engine.scan(artifactFile.getAbsoluteFile(),
1493 project.getName() + " (plugins)");
1494 if (deps != null) {
1495 Dependency d = null;
1496 if (deps.size() == 1) {
1497 d = deps.get(0);
1498 } else {
1499 for (Dependency possible : deps) {
1500 if (artifactFile.getAbsoluteFile().equals(possible.getActualFile())) {
1501 d = possible;
1502 break;
1503 }
1504 }
1505 for (Dependency dep : deps) {
1506 if (d != null && d != dep) {
1507 final String includedBy = buildReference(groupId, artifactId, version);
1508 dep.addIncludedBy(includedBy, "plugins");
1509 }
1510 }
1511 }
1512 if (d != null) {
1513 final MavenArtifact ma = new MavenArtifact(groupId, artifactId, version);
1514 d.addAsEvidence("pom", ma, Confidence.HIGHEST);
1515 if (parent != null) {
1516 d.addIncludedBy(parent, "plugins");
1517 } else {
1518 final String includedby = buildReference(
1519 project.getGroupId(),
1520 project.getArtifactId(),
1521 project.getVersion());
1522 d.addIncludedBy(includedby, "plugins");
1523 }
1524 if (availableVersions != null) {
1525 for (ArtifactVersion av : availableVersions) {
1526 d.addAvailableVersion(av.toString());
1527 }
1528 }
1529 }
1530 }
1531 } else {
1532 if (exCol == null) {
1533 exCol = new ExceptionCollection();
1534 }
1535 exCol.addException(new DependencyNotFoundException("Unable to resolve plugin: "
1536 + groupId + ":" + artifactId + ":" + version));
1537 }
1538
1539 return exCol;
1540 }
1541
1542 private String buildReference(final String groupId, final String artifactId, final String version) {
1543 String includedBy;
1544 try {
1545 final PackageURL purl = new PackageURL("maven", groupId, artifactId, version, null, null);
1546 includedBy = purl.toString();
1547 } catch (MalformedPackageURLException ex) {
1548 getLog().warn("Unable to generate build reference for " + groupId
1549 + ":" + artifactId + ":" + version, ex);
1550 includedBy = groupId + ":" + artifactId + ":" + version;
1551 }
1552 return includedBy;
1553 }
1554
1555 protected Set<Artifact> resolveArtifactDependencies(final DependableCoordinate artifact, MavenProject project)
1556 throws DependencyResolverException {
1557 final ProjectBuildingRequest buildingRequest = newResolveArtifactProjectBuildingRequest(project, project.getRemoteArtifactRepositories());
1558
1559 final Iterable<ArtifactResult> artifactResults = dependencyResolver.resolveDependencies(buildingRequest, artifact, null);
1560
1561 final Set<Artifact> artifacts = new HashSet<>();
1562
1563 for (ArtifactResult artifactResult : artifactResults) {
1564 artifacts.add(artifactResult.getArtifact());
1565 }
1566
1567 return artifacts;
1568
1569 }
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582 private DependencyNode toDependencyNode(List<DependencyNode> nodes, ProjectBuildingRequest buildingRequest,
1583 DependencyNode parent, org.apache.maven.model.Dependency dependency) throws ArtifactResolverException {
1584
1585 final DefaultArtifactCoordinate coordinate = new DefaultArtifactCoordinate();
1586
1587 coordinate.setGroupId(dependency.getGroupId());
1588 coordinate.setArtifactId(dependency.getArtifactId());
1589 String version = null;
1590 final VersionRange vr;
1591 try {
1592 vr = VersionRange.createFromVersionSpec(dependency.getVersion());
1593 } catch (InvalidVersionSpecificationException ex) {
1594 throw new ArtifactResolverException("Invalid version specification: "
1595 + dependency.getGroupId() + ":"
1596 + dependency.getArtifactId() + ":"
1597 + dependency.getVersion(), ex);
1598 }
1599 if (vr.hasRestrictions()) {
1600 version = findVersion(nodes, dependency.getGroupId(), dependency.getArtifactId());
1601 if (version == null) {
1602
1603
1604 if (vr.getRecommendedVersion() != null) {
1605 version = vr.getRecommendedVersion().toString();
1606 } else if (vr.hasRestrictions()) {
1607 for (Restriction restriction : vr.getRestrictions()) {
1608 if (restriction.getLowerBound() != null) {
1609 version = restriction.getLowerBound().toString();
1610 }
1611 if (restriction.getUpperBound() != null) {
1612 version = restriction.getUpperBound().toString();
1613 }
1614 }
1615 } else {
1616 version = vr.toString();
1617 }
1618 }
1619 }
1620 if (version == null) {
1621 version = dependency.getVersion();
1622 }
1623 coordinate.setVersion(version);
1624
1625 final ArtifactType type = session.getRepositorySession().getArtifactTypeRegistry().get(dependency.getType());
1626 coordinate.setExtension(type.getExtension());
1627 coordinate.setClassifier((null == dependency.getClassifier() || dependency.getClassifier().isEmpty())
1628 ? type.getClassifier() : dependency.getClassifier());
1629 final Artifact artifact = artifactResolver.resolveArtifact(buildingRequest, coordinate).getArtifact();
1630 artifact.setScope(dependency.getScope());
1631 return new DefaultDependencyNode(parent, artifact, dependency.getVersion(), dependency.getScope(), null);
1632 }
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644 private String findVersion(List<DependencyNode> nodes, String groupId, String artifactId) {
1645 final Optional<DependencyNode> f = nodes.stream().filter(p
1646 -> groupId.equals(p.getArtifact().getGroupId())
1647 && artifactId.equals(p.getArtifact().getArtifactId())).findFirst();
1648 if (f.isPresent()) {
1649 return f.get().getArtifact().getVersion();
1650 }
1651 return null;
1652 }
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665 private ExceptionCollection collectDependencyManagementDependencies(Engine engine, ProjectBuildingRequest buildingRequest,
1666 MavenProject project, List<DependencyNode> nodes, boolean aggregate) {
1667 if (skipDependencyManagement || project.getDependencyManagement() == null) {
1668 return null;
1669 }
1670
1671 ExceptionCollection exCol = null;
1672 for (org.apache.maven.model.Dependency dependency : project.getDependencyManagement().getDependencies()) {
1673 try {
1674 nodes.add(toDependencyNode(nodes, buildingRequest, null, dependency));
1675 } catch (ArtifactResolverException ex) {
1676 getLog().debug(String.format("Aggregate : %s", aggregate));
1677 boolean addException = true;
1678
1679 if (!aggregate) {
1680
1681 } else if (addReactorDependency(engine,
1682 new DefaultArtifact(dependency.getGroupId(), dependency.getArtifactId(),
1683 dependency.getVersion(), dependency.getScope(), dependency.getType(), dependency.getClassifier(),
1684 new DefaultArtifactHandler()), project)) {
1685 addException = false;
1686 }
1687
1688 if (addException) {
1689 if (exCol == null) {
1690 exCol = new ExceptionCollection();
1691 }
1692 exCol.addException(ex);
1693 }
1694 }
1695 }
1696 return exCol;
1697 }
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713 private ExceptionCollection collectMavenDependencies(Engine engine, MavenProject project,
1714 Map<DependencyNode, List<DependencyNode>> nodeMap, ProjectBuildingRequest buildingRequest, boolean aggregate) {
1715
1716 final List<ArtifactResult> allResolvedDeps = new ArrayList<>();
1717
1718
1719 final List<DependencyNode> dmNodes = new ArrayList<>();
1720 ExceptionCollection exCol = collectDependencyManagementDependencies(engine, buildingRequest, project, dmNodes, aggregate);
1721 for (DependencyNode dependencyNode : dmNodes) {
1722 exCol = scanDependencyNode(dependencyNode, null, engine, project, allResolvedDeps, buildingRequest, aggregate, exCol);
1723 }
1724
1725
1726 for (Map.Entry<DependencyNode, List<DependencyNode>> entry : nodeMap.entrySet()) {
1727 exCol = scanDependencyNode(entry.getKey(), null, engine, project, allResolvedDeps, buildingRequest, aggregate, exCol);
1728 for (DependencyNode dependencyNode : entry.getValue()) {
1729 exCol = scanDependencyNode(dependencyNode, entry.getKey(), engine, project, allResolvedDeps, buildingRequest, aggregate, exCol);
1730 }
1731 }
1732 return exCol;
1733 }
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747 private Artifact findInAllDeps(final List<ArtifactResult> allDeps, final Artifact unresolvedArtifact,
1748 final MavenProject project)
1749 throws DependencyNotFoundException {
1750 Artifact result = null;
1751 for (final ArtifactResult res : allDeps) {
1752 if (sameArtifact(res, unresolvedArtifact)) {
1753 result = res.getArtifact();
1754 break;
1755 }
1756 }
1757 if (result == null) {
1758 throw new DependencyNotFoundException(String.format("Expected dependency not found in resolved artifacts for "
1759 + "dependency %s of project-artifact %s", unresolvedArtifact, project.getArtifactId()));
1760 }
1761 return result;
1762 }
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773 private boolean sameArtifact(final ArtifactResult res, final Artifact unresolvedArtifact) {
1774 if (res == null || res.getArtifact() == null || unresolvedArtifact == null) {
1775 return false;
1776 }
1777 boolean result = Objects.equals(res.getArtifact().getGroupId(), unresolvedArtifact.getGroupId());
1778 result &= Objects.equals(res.getArtifact().getArtifactId(), unresolvedArtifact.getArtifactId());
1779
1780 if ("RELEASE".equals(unresolvedArtifact.getBaseVersion())) {
1781 result &= !res.getArtifact().isSnapshot();
1782 } else if (!"LATEST".equals(unresolvedArtifact.getBaseVersion())) {
1783 result &= Objects.equals(res.getArtifact().getBaseVersion(), unresolvedArtifact.getBaseVersion());
1784 }
1785 result &= Objects.equals(res.getArtifact().getClassifier(), unresolvedArtifact.getClassifier());
1786 result &= Objects.equals(res.getArtifact().getType(), unresolvedArtifact.getType());
1787 return result;
1788 }
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799 protected String createProjectReferenceName(MavenProject project, DependencyNode dependencyNode) {
1800 return project.getName() + ":" + dependencyNode.getArtifact().getScope();
1801 }
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816 private ExceptionCollection collectDependencies(Engine engine, MavenProject project,
1817 Map<DependencyNode, List<DependencyNode>> nodes, ProjectBuildingRequest buildingRequest, boolean aggregate) {
1818
1819 ExceptionCollection exCol;
1820 exCol = collectMavenDependencies(engine, project, nodes, buildingRequest, aggregate);
1821
1822 final List<FileSet> projectScan;
1823
1824 if (scanDirectory != null && !scanDirectory.isEmpty()) {
1825 if (scanSet == null) {
1826 scanSet = new ArrayList<>();
1827 }
1828 scanDirectory.forEach(d -> {
1829 final FileSet fs = new FileSet();
1830 fs.setDirectory(d);
1831 fs.addInclude(INCLUDE_ALL);
1832 scanSet.add(fs);
1833 });
1834 }
1835
1836 if (scanSet == null || scanSet.isEmpty()) {
1837
1838 final FileSet resourcesSet = new FileSet();
1839 final FileSet filtersSet = new FileSet();
1840 final FileSet webappSet = new FileSet();
1841 final FileSet mixedLangSet = new FileSet();
1842 try {
1843 resourcesSet.setDirectory(new File(project.getBasedir(), "src/main/resources").getCanonicalPath());
1844 resourcesSet.addInclude(INCLUDE_ALL);
1845 filtersSet.setDirectory(new File(project.getBasedir(), "src/main/filters").getCanonicalPath());
1846 filtersSet.addInclude(INCLUDE_ALL);
1847 webappSet.setDirectory(new File(project.getBasedir(), "src/main/webapp").getCanonicalPath());
1848 webappSet.addInclude(INCLUDE_ALL);
1849 mixedLangSet.setDirectory(project.getBasedir().getCanonicalPath());
1850 mixedLangSet.addInclude("package.json");
1851 mixedLangSet.addInclude("package-lock.json");
1852 mixedLangSet.addInclude("npm-shrinkwrap.json");
1853 mixedLangSet.addInclude("Gopkg.lock");
1854 mixedLangSet.addInclude("go.mod");
1855 mixedLangSet.addInclude("yarn.lock");
1856 mixedLangSet.addInclude("pnpm-lock.yaml");
1857 mixedLangSet.addExclude("/node_modules/");
1858 } catch (IOException ex) {
1859 if (exCol == null) {
1860 exCol = new ExceptionCollection();
1861 }
1862 exCol.addException(ex);
1863 }
1864 projectScan = new ArrayList<>();
1865 projectScan.add(resourcesSet);
1866 projectScan.add(filtersSet);
1867 projectScan.add(webappSet);
1868 projectScan.add(mixedLangSet);
1869
1870 } else if (aggregate) {
1871 projectScan = new ArrayList<>();
1872 for (FileSet copyFrom : scanSet) {
1873
1874 final FileSet fsCopy = new FileSet();
1875 final File f = new File(copyFrom.getDirectory());
1876 if (f.isAbsolute()) {
1877 fsCopy.setDirectory(copyFrom.getDirectory());
1878 } else {
1879 try {
1880 fsCopy.setDirectory(new File(project.getBasedir(), copyFrom.getDirectory()).getCanonicalPath());
1881 } catch (IOException ex) {
1882 if (exCol == null) {
1883 exCol = new ExceptionCollection();
1884 }
1885 exCol.addException(ex);
1886 fsCopy.setDirectory(copyFrom.getDirectory());
1887 }
1888 }
1889 fsCopy.setDirectoryMode(copyFrom.getDirectoryMode());
1890 fsCopy.setExcludes(copyFrom.getExcludes());
1891 fsCopy.setFileMode(copyFrom.getFileMode());
1892 fsCopy.setFollowSymlinks(copyFrom.isFollowSymlinks());
1893 fsCopy.setIncludes(copyFrom.getIncludes());
1894 fsCopy.setLineEnding(copyFrom.getLineEnding());
1895 fsCopy.setMapper(copyFrom.getMapper());
1896 fsCopy.setModelEncoding(copyFrom.getModelEncoding());
1897 fsCopy.setOutputDirectory(copyFrom.getOutputDirectory());
1898 fsCopy.setUseDefaultExcludes(copyFrom.isUseDefaultExcludes());
1899 projectScan.add(fsCopy);
1900 }
1901 } else {
1902 projectScan = scanSet;
1903 }
1904
1905
1906 final FileSetManager fileSetManager = new FileSetManager();
1907 for (FileSet fileSet : projectScan) {
1908 getLog().debug("Scanning fileSet: " + fileSet.getDirectory());
1909 final String[] includedFiles = fileSetManager.getIncludedFiles(fileSet);
1910 for (String include : includedFiles) {
1911 final File includeFile = new File(fileSet.getDirectory(), include).getAbsoluteFile();
1912 if (includeFile.exists()) {
1913 engine.scan(includeFile, project.getName());
1914 }
1915 }
1916 }
1917 return exCol;
1918 }
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931 private boolean addReactorDependency(Engine engine, Artifact artifact, final MavenProject depender) {
1932 return addVirtualDependencyFromReactor(engine, artifact, depender, "Unable to resolve %s as it has not been built yet "
1933 + "- creating a virtual dependency instead.");
1934 }
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950 private boolean addVirtualDependencyFromReactor(Engine engine, Artifact artifact,
1951 final MavenProject depender, String infoLogTemplate) {
1952
1953 getLog().debug(String.format("Checking the reactor projects (%d) for %s:%s:%s",
1954 reactorProjects.size(),
1955 artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion()));
1956
1957 for (MavenProject prj : reactorProjects) {
1958
1959 getLog().debug(String.format("Comparing %s:%s:%s to %s:%s:%s",
1960 artifact.getGroupId(), artifact.getArtifactId(), artifact.getBaseVersion(),
1961 prj.getGroupId(), prj.getArtifactId(), prj.getVersion()));
1962
1963 if (prj.getArtifactId().equals(artifact.getArtifactId())
1964 && prj.getGroupId().equals(artifact.getGroupId())
1965 && prj.getVersion().equals(artifact.getBaseVersion())) {
1966
1967 final String displayName = String.format("%s:%s:%s",
1968 prj.getGroupId(), prj.getArtifactId(), prj.getVersion());
1969 getLog().info(String.format(infoLogTemplate,
1970 displayName));
1971 final Dependency d = newDependency(prj);
1972 final String key = String.format("%s:%s:%s", prj.getGroupId(), prj.getArtifactId(), prj.getVersion());
1973 d.setSha1sum(Checksum.getSHA1Checksum(key));
1974 d.setSha256sum(Checksum.getSHA256Checksum(key));
1975 d.setMd5sum(Checksum.getMD5Checksum(key));
1976 d.setEcosystem(JarAnalyzer.DEPENDENCY_ECOSYSTEM);
1977 d.setDisplayFileName(displayName);
1978 d.addProjectReference(depender.getName());
1979 final String includedby = buildReference(
1980 depender.getGroupId(),
1981 depender.getArtifactId(),
1982 depender.getVersion());
1983 d.addIncludedBy(includedby);
1984 d.addEvidence(EvidenceType.PRODUCT, "project", "artifactid", prj.getArtifactId(), Confidence.HIGHEST);
1985 d.addEvidence(EvidenceType.VENDOR, "project", "artifactid", prj.getArtifactId(), Confidence.LOW);
1986
1987 d.addEvidence(EvidenceType.VENDOR, "project", "groupid", prj.getGroupId(), Confidence.HIGHEST);
1988 d.addEvidence(EvidenceType.PRODUCT, "project", "groupid", prj.getGroupId(), Confidence.LOW);
1989 d.setEcosystem(JarAnalyzer.DEPENDENCY_ECOSYSTEM);
1990 Identifier id;
1991 try {
1992 id = new PurlIdentifier(StandardTypes.MAVEN, artifact.getGroupId(),
1993 artifact.getArtifactId(), artifact.getVersion(), Confidence.HIGHEST);
1994 } catch (MalformedPackageURLException ex) {
1995 getLog().debug("Unable to create PackageURL object:" + key);
1996 id = new GenericIdentifier("maven:" + key, Confidence.HIGHEST);
1997 }
1998 d.addSoftwareIdentifier(id);
1999
2000 d.setName(String.format("%s:%s", prj.getGroupId(), prj.getArtifactId()));
2001 d.setVersion(prj.getVersion());
2002 d.setPackagePath(displayName);
2003 if (prj.getDescription() != null) {
2004 JarAnalyzer.addDescription(d, prj.getDescription(), "project", "description");
2005 }
2006 for (License l : prj.getLicenses()) {
2007 final StringBuilder license = new StringBuilder();
2008 if (l.getName() != null) {
2009 license.append(l.getName());
2010 }
2011 if (l.getUrl() != null) {
2012 license.append(" ").append(l.getUrl());
2013 }
2014 if (d.getLicense() == null) {
2015 d.setLicense(license.toString());
2016 } else if (!d.getLicense().contains(license)) {
2017 d.setLicense(String.format("%s%n%s", d.getLicense(), license));
2018 }
2019 }
2020 engine.addDependency(d);
2021 return true;
2022 }
2023 }
2024 return false;
2025 }
2026
2027 Dependency newDependency(MavenProject prj) {
2028 final File pom = new File(prj.getBasedir(), "pom.xml");
2029
2030 if (pom.isFile()) {
2031 getLog().debug("Adding virtual dependency from pom.xml");
2032 return new Dependency(pom, true);
2033 } else if (prj.getFile().isFile()) {
2034 getLog().debug("Adding virtual dependency from file");
2035 return new Dependency(prj.getFile(), true);
2036 } else {
2037 return new Dependency(true);
2038 }
2039 }
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052 private boolean addSnapshotReactorDependency(Engine engine, Artifact artifact, final MavenProject depender) {
2053 if (!artifact.isSnapshot()) {
2054 return false;
2055 }
2056 return addVirtualDependencyFromReactor(engine, artifact, depender, "Found snapshot reactor project in aggregate for %s - "
2057 + "creating a virtual dependency as the snapshot found in the repository may contain outdated dependencies.");
2058 }
2059
2060
2061
2062
2063
2064
2065
2066
2067 public ProjectBuildingRequest newResolveArtifactProjectBuildingRequest(MavenProject project, List<ArtifactRepository> repos) {
2068 final ProjectBuildingRequest buildingRequest = new DefaultProjectBuildingRequest(session.getProjectBuildingRequest());
2069 buildingRequest.setRemoteRepositories(repos);
2070 buildingRequest.setProject(project);
2071 return buildingRequest;
2072 }
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082 protected void runCheck() throws MojoExecutionException, MojoFailureException {
2083 muteNoisyLoggers();
2084 try (Engine engine = initializeEngine()) {
2085 ExceptionCollection exCol = null;
2086 if (scanDependencies) {
2087 exCol = scanDependencies(engine);
2088 }
2089 if (scanPlugins) {
2090 exCol = scanPlugins(engine, exCol);
2091 }
2092 try {
2093 engine.analyzeDependencies();
2094 } catch (ExceptionCollection ex) {
2095 exCol = handleAnalysisExceptions(exCol, ex);
2096 }
2097 if (exCol == null || !exCol.isFatal()) {
2098
2099 File outputDir = getCorrectOutputDirectory(this.getProject());
2100 if (outputDir == null) {
2101
2102
2103 outputDir = new File(this.getProject().getBuild().getDirectory());
2104 }
2105 try {
2106 final MavenProject p = this.getProject();
2107 for (String f : getFormats()) {
2108 engine.writeReports(p.getName(), p.getGroupId(), p.getArtifactId(), p.getVersion(), outputDir, f, exCol);
2109 }
2110 } catch (ReportException ex) {
2111 if (exCol == null) {
2112 exCol = new ExceptionCollection(ex);
2113 } else {
2114 exCol.addException(ex);
2115 }
2116 if (this.isFailOnError()) {
2117 throw new MojoExecutionException("One or more exceptions occurred during dependency-check analysis", exCol);
2118 } else {
2119 getLog().debug("Error writing the report", ex);
2120 }
2121 }
2122 showSummary(this.getProject(), engine.getDependencies());
2123 checkForFailure(engine.getDependencies());
2124 if (exCol != null && this.isFailOnError()) {
2125 throw new MojoExecutionException("One or more exceptions occurred during dependency-check analysis", exCol);
2126 }
2127 }
2128 } catch (DatabaseException ex) {
2129 if (getLog().isDebugEnabled()) {
2130 getLog().debug("Database connection error", ex);
2131 }
2132 final String msg = "An exception occurred connecting to the local database. Please see the log file for more details.";
2133 if (this.isFailOnError()) {
2134 throw new MojoExecutionException(msg, ex);
2135 }
2136 getLog().error(msg, ex);
2137 } finally {
2138 getSettings().cleanup();
2139 }
2140 }
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152 private ExceptionCollection handleAnalysisExceptions(ExceptionCollection currentEx, ExceptionCollection newEx) throws MojoExecutionException {
2153 ExceptionCollection returnEx = currentEx;
2154 if (returnEx == null) {
2155 returnEx = newEx;
2156 } else {
2157 returnEx.getExceptions().addAll(newEx.getExceptions());
2158 if (newEx.isFatal()) {
2159 returnEx.setFatal(true);
2160 }
2161 }
2162 if (returnEx.isFatal()) {
2163 final String msg = String.format("Fatal exception(s) analyzing %s", getProject().getName());
2164 if (this.isFailOnError()) {
2165 throw new MojoExecutionException(msg, returnEx);
2166 }
2167 getLog().error(msg);
2168 if (getLog().isDebugEnabled()) {
2169 getLog().debug(returnEx);
2170 }
2171 } else {
2172 final String msg = String.format("Exception(s) analyzing %s", getProject().getName());
2173 if (getLog().isDebugEnabled()) {
2174 getLog().debug(msg, returnEx);
2175 }
2176 }
2177 return returnEx;
2178 }
2179
2180
2181
2182
2183
2184
2185
2186
2187 protected abstract ExceptionCollection scanDependencies(Engine engine) throws MojoExecutionException;
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198 protected abstract ExceptionCollection scanPlugins(Engine engine, ExceptionCollection exCol) throws MojoExecutionException;
2199
2200
2201
2202
2203
2204
2205 @Override
2206 public File getReportOutputDirectory() {
2207 return reportOutputDirectory;
2208 }
2209
2210
2211
2212
2213
2214
2215 @Override
2216 public void setReportOutputDirectory(File directory) {
2217 reportOutputDirectory = directory;
2218 }
2219
2220
2221
2222
2223
2224
2225 public File getOutputDirectory() {
2226 return outputDirectory;
2227 }
2228
2229
2230
2231
2232
2233
2234
2235 @Override
2236 public final boolean isExternalReport() {
2237 return true;
2238 }
2239
2240
2241
2242
2243
2244
2245 @Override
2246 public String getOutputName() {
2247 final Set<String> selectedFormats = getFormats();
2248 if (selectedFormats.contains("HTML") || selectedFormats.contains("ALL") || selectedFormats.size() > 1) {
2249 return "dependency-check-report";
2250 } else if (selectedFormats.contains("JENKINS")) {
2251 return "dependency-check-jenkins.html";
2252 } else if (selectedFormats.contains("XML")) {
2253 return "dependency-check-report.xml";
2254 } else if (selectedFormats.contains("JUNIT")) {
2255 return "dependency-check-junit.xml";
2256 } else if (selectedFormats.contains("JSON")) {
2257 return "dependency-check-report.json";
2258 } else if (selectedFormats.contains("SARIF")) {
2259 return "dependency-check-report.sarif";
2260 } else if (selectedFormats.contains("CSV")) {
2261 return "dependency-check-report.csv";
2262 } else {
2263 getLog().warn("Unknown report format used during site generation.");
2264 return "dependency-check-report";
2265 }
2266 }
2267
2268
2269
2270
2271
2272
2273 @Override
2274 public String getCategoryName() {
2275 return MavenReport.CATEGORY_PROJECT_REPORTS;
2276 }
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289 protected Engine initializeEngine() throws DatabaseException, MojoExecutionException, MojoFailureException {
2290 populateSettings();
2291 try {
2292 Downloader.getInstance().configure(settings);
2293 } catch (InvalidSettingException e) {
2294 if (this.failOnError) {
2295 throw new MojoFailureException(e.getMessage(), e);
2296 } else {
2297 throw new MojoExecutionException(e.getMessage(), e);
2298 }
2299 }
2300 return new Engine(settings);
2301 }
2302
2303
2304
2305
2306
2307
2308
2309
2310 protected void populateSettings() throws MojoFailureException, MojoExecutionException {
2311 settings = new Settings();
2312 InputStream mojoProperties = null;
2313 try {
2314 mojoProperties = this.getClass().getClassLoader().getResourceAsStream(PROPERTIES_FILE);
2315 settings.mergeProperties(mojoProperties);
2316 } catch (IOException ex) {
2317 getLog().warn("Unable to load the dependency-check maven mojo.properties file.");
2318 if (getLog().isDebugEnabled()) {
2319 getLog().debug("", ex);
2320 }
2321 } finally {
2322 if (mojoProperties != null) {
2323 try {
2324 mojoProperties.close();
2325 } catch (IOException ex) {
2326 if (getLog().isDebugEnabled()) {
2327 getLog().debug("", ex);
2328 }
2329 }
2330 }
2331 }
2332 checkForDeprecatedParameters();
2333
2334 settings.setStringIfNotEmpty(Settings.KEYS.MAVEN_LOCAL_REPO, mavenSettings.getLocalRepository());
2335 settings.setBooleanIfNotNull(Settings.KEYS.AUTO_UPDATE, autoUpdate);
2336 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, enableExperimental);
2337 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_RETIRED_ENABLED, enableRetired);
2338 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_GOLANG_DEP_ENABLED, golangDepEnabled);
2339 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_GOLANG_MOD_ENABLED, golangModEnabled);
2340 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_DART_ENABLED, dartAnalyzerEnabled);
2341 settings.setStringIfNotNull(Settings.KEYS.ANALYZER_GOLANG_PATH, pathToGo);
2342 settings.setStringIfNotNull(Settings.KEYS.ANALYZER_YARN_PATH, pathToYarn);
2343 settings.setStringIfNotNull(Settings.KEYS.ANALYZER_PNPM_PATH, pathToPnpm);
2344
2345
2346 final Proxy mavenProxyHttp = getMavenProxy(PROTOCOL_HTTP);
2347 final Proxy mavenProxyHttps = getMavenProxy(PROTOCOL_HTTPS);
2348 String httpsNonProxyHosts = null;
2349 String httpNonProxyHosts = null;
2350 boolean proxySetFromMavenSettings = false;
2351 if (mavenProxyHttps != null || mavenProxyHttp != null) {
2352 final String existingHttps = StringUtils.trimToNull(System.getProperty("https.proxyHost"));
2353 if (existingHttps == null) {
2354 proxySetFromMavenSettings = true;
2355 if (mavenProxyHttps != null) {
2356 setProxyServerSysPropsFromMavenProxy(mavenProxyHttps, PROTOCOL_HTTPS);
2357 if (mavenProxyHttps.getNonProxyHosts() != null && !mavenProxyHttps.getNonProxyHosts().isEmpty()) {
2358 httpsNonProxyHosts = mavenProxyHttps.getNonProxyHosts();
2359 }
2360 } else {
2361 setProxyServerSysPropsFromMavenProxy(mavenProxyHttp, PROTOCOL_HTTPS);
2362 httpsNonProxyHosts = mavenProxyHttp.getNonProxyHosts();
2363 }
2364 }
2365 final String existingHttp = StringUtils.trimToNull(System.getProperty("http.proxyHost"));
2366 if (mavenProxyHttp != null && existingHttp == null) {
2367 proxySetFromMavenSettings = true;
2368 setProxyServerSysPropsFromMavenProxy(mavenProxyHttp, PROTOCOL_HTTP);
2369 httpNonProxyHosts = mavenProxyHttp.getNonProxyHosts();
2370 }
2371 if (proxySetFromMavenSettings) {
2372 final String existingNonProxyHosts = System.getProperty("http.nonProxyHosts");
2373 System.setProperty("http.nonProxyHosts", mergeNonProxyHosts(existingNonProxyHosts, httpNonProxyHosts, httpsNonProxyHosts));
2374 }
2375 } else if (this.proxy != null && this.proxy.getHost() != null) {
2376
2377 settings.setString(Settings.KEYS.PROXY_SERVER, this.proxy.getHost());
2378 settings.setString(Settings.KEYS.PROXY_PORT, Integer.toString(this.proxy.getPort()));
2379
2380 configureServerCredentials(this.proxy.getServerId(), Settings.KEYS.PROXY_USERNAME, Settings.KEYS.PROXY_PASSWORD);
2381 }
2382
2383 final String[] suppressions = determineSuppressions();
2384 settings.setArrayIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressions);
2385 settings.setBooleanIfNotNull(Settings.KEYS.UPDATE_VERSION_CHECK_ENABLED, versionCheckEnabled);
2386 settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout);
2387 settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_READ_TIMEOUT, readTimeout);
2388 settings.setStringIfNotEmpty(Settings.KEYS.HINTS_FILE, hintsFile);
2389 settings.setFloat(Settings.KEYS.JUNIT_FAIL_ON_CVSS, junitFailOnCVSS);
2390 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_JAR_ENABLED, jarAnalyzerEnabled);
2391 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, nuspecAnalyzerEnabled);
2392 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NUGETCONF_ENABLED, nugetconfAnalyzerEnabled);
2393 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_LIBMAN_ENABLED, libmanAnalyzerEnabled);
2394 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, centralAnalyzerEnabled);
2395 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CENTRAL_USE_CACHE, centralAnalyzerUseCache);
2396 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ARTIFACTORY_ENABLED, artifactoryAnalyzerEnabled);
2397 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled);
2398 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, assemblyAnalyzerEnabled);
2399 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_MSBUILD_PROJECT_ENABLED, msbuildAnalyzerEnabled);
2400 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, archiveAnalyzerEnabled);
2401 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_KNOWN_EXPLOITED_ENABLED, knownExploitedEnabled);
2402 settings.setStringIfNotEmpty(Settings.KEYS.KEV_URL, knownExploitedUrl);
2403 try {
2404 configureCredentials(knownExploitedServerId, knownExploitedUser, knownExploitedPassword, knownExploitedBearerToken,
2405 Settings.KEYS.KEV_USER, Settings.KEYS.KEV_PASSWORD, Settings.KEYS.KEV_BEARER_TOKEN);
2406 } catch (InitializationException ex) {
2407 if (this.failOnError) {
2408 throw new MojoFailureException("Invalid plugin configuration specified for Known Exploited data feed authentication", ex);
2409 } else {
2410 throw new MojoExecutionException("Invalid plugin configuration specified for Known Exploited data feed authentication", ex);
2411 }
2412 }
2413 settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions);
2414 settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_DOTNET_PATH, pathToCore);
2415 settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl);
2416 configureServerCredentials(nexusServerId, Settings.KEYS.ANALYZER_NEXUS_USER, Settings.KEYS.ANALYZER_NEXUS_PASSWORD);
2417 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy);
2418 settings.setStringIfNotNull(Settings.KEYS.ANALYZER_ARTIFACTORY_URL, artifactoryAnalyzerUrl);
2419 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ARTIFACTORY_USES_PROXY, artifactoryAnalyzerUseProxy);
2420 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ARTIFACTORY_PARALLEL_ANALYSIS, artifactoryAnalyzerParallelAnalysis);
2421 settings.setBooleanIfNotNull(Settings.KEYS.FAIL_ON_UNUSED_SUPPRESSION_RULE, failBuildOnUnusedSuppressionRule);
2422 if (Boolean.TRUE.equals(artifactoryAnalyzerEnabled)) {
2423 if (artifactoryAnalyzerServerId != null) {
2424 configureServerCredentials(artifactoryAnalyzerServerId, Settings.KEYS.ANALYZER_ARTIFACTORY_API_USERNAME,
2425 Settings.KEYS.ANALYZER_ARTIFACTORY_API_TOKEN);
2426 } else {
2427 settings.setStringIfNotNull(Settings.KEYS.ANALYZER_ARTIFACTORY_API_USERNAME, artifactoryAnalyzerUsername);
2428 settings.setStringIfNotNull(Settings.KEYS.ANALYZER_ARTIFACTORY_API_TOKEN, artifactoryAnalyzerApiToken);
2429 }
2430 settings.setStringIfNotNull(Settings.KEYS.ANALYZER_ARTIFACTORY_BEARER_TOKEN, artifactoryAnalyzerBearerToken);
2431 }
2432 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, pyDistributionAnalyzerEnabled);
2433 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, pyPackageAnalyzerEnabled);
2434 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED, rubygemsAnalyzerEnabled);
2435 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, opensslAnalyzerEnabled);
2436 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CMAKE_ENABLED, cmakeAnalyzerEnabled);
2437 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_AUTOCONF_ENABLED, autoconfAnalyzerEnabled);
2438 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_MAVEN_INSTALL_ENABLED, mavenInstallAnalyzerEnabled);
2439 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PIP_ENABLED, pipAnalyzerEnabled);
2440 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PIPFILE_ENABLED, pipfileAnalyzerEnabled);
2441 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_POETRY_ENABLED, poetryAnalyzerEnabled);
2442 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED, composerAnalyzerEnabled);
2443 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_COMPOSER_LOCK_SKIP_DEV, composerAnalyzerSkipDev);
2444 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CPANFILE_ENABLED, cpanfileAnalyzerEnabled);
2445 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED, nodeAnalyzerEnabled);
2446 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NODE_AUDIT_ENABLED, nodeAuditAnalyzerEnabled);
2447 settings.setStringIfNotNull(Settings.KEYS.ANALYZER_NODE_AUDIT_URL, nodeAuditAnalyzerUrl);
2448 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NODE_AUDIT_USE_CACHE, nodeAuditAnalyzerUseCache);
2449 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NODE_PACKAGE_SKIPDEV, nodePackageSkipDevDependencies);
2450 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NODE_AUDIT_SKIPDEV, nodeAuditSkipDevDependencies);
2451 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_YARN_AUDIT_ENABLED, yarnAuditAnalyzerEnabled);
2452 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PNPM_AUDIT_ENABLED, pnpmAuditAnalyzerEnabled);
2453 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_RETIREJS_ENABLED, retireJsAnalyzerEnabled);
2454 settings.setStringIfNotNull(Settings.KEYS.ANALYZER_RETIREJS_REPO_JS_URL, retireJsUrl);
2455 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_RETIREJS_FORCEUPDATE, retireJsForceUpdate);
2456
2457 try {
2458 configureCredentials(retireJsUrlServerId, retireJsUser, retireJsPassword, retireJsBearerToken,
2459 Settings.KEYS.ANALYZER_RETIREJS_REPO_JS_USER, Settings.KEYS.ANALYZER_RETIREJS_REPO_JS_PASSWORD,
2460 Settings.KEYS.ANALYZER_RETIREJS_REPO_JS_BEARER_TOKEN);
2461 } catch (InitializationException ex) {
2462 if (this.failOnError) {
2463 throw new MojoFailureException("Invalid plugin configuration specified for retireJsUrl authentication", ex);
2464 } else {
2465 throw new MojoExecutionException("Invalid plugin configuration specified for retireJsUrl authentication", ex);
2466 }
2467 }
2468 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_MIX_AUDIT_ENABLED, mixAuditAnalyzerEnabled);
2469 settings.setStringIfNotNull(Settings.KEYS.ANALYZER_MIX_AUDIT_PATH, mixAuditPath);
2470 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_ENABLED, bundleAuditAnalyzerEnabled);
2471 settings.setStringIfNotNull(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH, bundleAuditPath);
2472 settings.setStringIfNotNull(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_WORKING_DIRECTORY, bundleAuditWorkingDirectory);
2473 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_COCOAPODS_ENABLED, cocoapodsAnalyzerEnabled);
2474 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CARTHAGE_ENABLED, carthageAnalyzerEnabled);
2475 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_SWIFT_PACKAGE_MANAGER_ENABLED, swiftPackageManagerAnalyzerEnabled);
2476 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_SWIFT_PACKAGE_RESOLVED_ENABLED, swiftPackageResolvedAnalyzerEnabled);
2477 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_OSSINDEX_ENABLED, ossIndexAnalyzerEnabled);
2478 settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_OSSINDEX_URL, ossIndexAnalyzerUrl);
2479 if (StringUtils.isEmpty(ossIndexPassword)) {
2480 configureServerCredentialsUserPassOrApiKey(ossIndexServerId, Settings.KEYS.ANALYZER_OSSINDEX_USER, Settings.KEYS.ANALYZER_OSSINDEX_PASSWORD);
2481 } else {
2482 settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_OSSINDEX_USER, ossIndexUsername);
2483 settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_OSSINDEX_PASSWORD, ossIndexPassword);
2484 }
2485 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_OSSINDEX_USE_CACHE, ossIndexAnalyzerUseCache);
2486 settings.setIntIfNotNull(Settings.KEYS.ANALYZER_OSSINDEX_CACHE_VALID_FOR_HOURS, ossIndexAnalyzerCacheValidForHours);
2487 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_OSSINDEX_WARN_ONLY_ON_REMOTE_ERRORS, ossIndexWarnOnlyOnRemoteErrors);
2488 if (retirejs != null) {
2489 settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_RETIREJS_FILTER_NON_VULNERABLE, retirejs.getFilterNonVulnerable());
2490 settings.setArrayIfNotEmpty(Settings.KEYS.ANALYZER_RETIREJS_FILTERS, retirejs.getFilters());
2491 }
2492
2493 settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName);
2494 settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath);
2495 settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString);
2496 if (databaseUser == null && databasePassword == null && serverId != null) {
2497 configureServerCredentials(serverId, Settings.KEYS.DB_USER, Settings.KEYS.DB_PASSWORD);
2498 } else {
2499 settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser);
2500 settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword);
2501 }
2502 settings.setStringIfNotEmpty(Settings.KEYS.DATA_DIRECTORY, dataDirectory);
2503 settings.setStringIfNotEmpty(Settings.KEYS.DB_FILE_NAME, dbFilename);
2504 settings.setStringIfNotNull(Settings.KEYS.NVD_API_ENDPOINT, nvdApiEndpoint);
2505 settings.setIntIfNotNull(Settings.KEYS.NVD_API_DELAY, nvdApiDelay);
2506 settings.setIntIfNotNull(Settings.KEYS.NVD_API_RESULTS_PER_PAGE, nvdApiResultsPerPage);
2507 settings.setStringIfNotEmpty(Settings.KEYS.NVD_API_DATAFEED_URL, nvdDatafeedUrl);
2508 settings.setIntIfNotNull(Settings.KEYS.NVD_API_VALID_FOR_HOURS, nvdValidForHours);
2509 settings.setIntIfNotNull(Settings.KEYS.NVD_API_MAX_RETRY_COUNT, nvdMaxRetryCount);
2510 if (nvdApiKey == null) {
2511 if (nvdApiKeyEnvironmentVariable != null) {
2512 settings.setStringIfNotEmpty(Settings.KEYS.NVD_API_KEY, System.getenv(nvdApiKeyEnvironmentVariable));
2513 getLog().debug("Using NVD API key from environment variable " + nvdApiKeyEnvironmentVariable);
2514 } else if (nvdApiServerId != null) {
2515 try {
2516 configureServerCredentialsApiKey(nvdApiServerId, Settings.KEYS.NVD_API_KEY);
2517 } catch (InitializationException ex) {
2518 if (this.failOnError) {
2519 throw new MojoFailureException("Invalid plugin configuration specified for NVD API authentication", ex);
2520 } else {
2521 throw new MojoExecutionException("Invalid plugin configuration specified for NVD API authentication", ex);
2522 }
2523 }
2524 getLog().debug("Using NVD API key from server's password with id " + nvdApiServerId + " in settings.xml");
2525 }
2526 } else {
2527 settings.setStringIfNotEmpty(Settings.KEYS.NVD_API_KEY, nvdApiKey);
2528 }
2529 try {
2530 configureCredentials(nvdDatafeedServerId, nvdUser, nvdPassword, nvdBearerToken,
2531 Settings.KEYS.NVD_API_DATAFEED_USER, Settings.KEYS.NVD_API_DATAFEED_PASSWORD, Settings.KEYS.NVD_API_DATAFEED_BEARER_TOKEN);
2532 } catch (InitializationException ex) {
2533 if (this.failOnError) {
2534 throw new MojoFailureException("Invalid plugin configuration specified for NVD Datafeed authentication", ex);
2535 } else {
2536 throw new MojoExecutionException("Invalid plugin configuration specified for NVD Datafeed authentication", ex);
2537 }
2538 }
2539 settings.setBooleanIfNotNull(Settings.KEYS.PRETTY_PRINT, prettyPrint);
2540 artifactScopeExcluded = new ArtifactScopeExcluded(skipTestScope, skipProvidedScope, skipSystemScope, skipRuntimeScope);
2541 artifactTypeExcluded = new ArtifactTypeExcluded(skipArtifactType);
2542 try {
2543 configureCredentials(suppressionFileServerId, suppressionFileUser, suppressionFilePassword, suppressionFileBearerToken,
2544 Settings.KEYS.SUPPRESSION_FILE_USER, Settings.KEYS.SUPPRESSION_FILE_PASSWORD, Settings.KEYS.SUPPRESSION_FILE_BEARER_TOKEN);
2545 } catch (InitializationException ex) {
2546 if (this.failOnError) {
2547 throw new MojoFailureException("Invalid plugin configuration specified for suppression file authentication", ex);
2548 } else {
2549 throw new MojoExecutionException("Invalid plugin configuration specified for suppression file authentication", ex);
2550 }
2551 }
2552
2553 settings.setIntIfNotNull(Settings.KEYS.HOSTED_SUPPRESSIONS_VALID_FOR_HOURS, hostedSuppressionsValidForHours);
2554 settings.setStringIfNotNull(Settings.KEYS.HOSTED_SUPPRESSIONS_URL, hostedSuppressionsUrl);
2555 settings.setBooleanIfNotNull(Settings.KEYS.HOSTED_SUPPRESSIONS_FORCEUPDATE, hostedSuppressionsForceUpdate);
2556 settings.setBooleanIfNotNull(Settings.KEYS.HOSTED_SUPPRESSIONS_ENABLED, hostedSuppressionsEnabled);
2557 try {
2558 configureCredentials(hostedSuppressionsServerId, hostedSuppressionsUser, hostedSuppressionsPassword, hostedSuppressionsBearerToken,
2559 Settings.KEYS.HOSTED_SUPPRESSIONS_USER, Settings.KEYS.HOSTED_SUPPRESSIONS_PASSWORD, Settings.KEYS.HOSTED_SUPPRESSIONS_BEARER_TOKEN);
2560 } catch (InitializationException ex) {
2561 if (this.failOnError) {
2562 throw new MojoFailureException("Invalid plugin configuration specified for hostedSuppressions authentication", ex);
2563 } else {
2564 throw new MojoExecutionException("Invalid plugin configuration specified for hostedSuppressions authentication", ex);
2565 }
2566 }
2567 }
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587 private void configureCredentials(String serverId, String usernameValue, String passwordValue, String tokenValue,
2588 String userKey, String passwordKey, String tokenKey) throws InitializationException {
2589 if (serverId != null) {
2590 if (usernameValue != null || passwordValue != null || tokenValue != null) {
2591 throw new InitializationException(
2592 "Username/password/token configurations should be left out when a serverId (" + serverId + ") is configured");
2593 }
2594 final Server server = settingsXml.getServer(serverId);
2595 if (server != null) {
2596 configureFromServer(server, userKey, passwordKey, tokenKey, serverId);
2597 } else {
2598 getLog().error(String.format("Server '%s' not found in the settings.xml file", serverId));
2599 }
2600 } else {
2601 settings.setStringIfNotEmpty(userKey, usernameValue);
2602 settings.setStringIfNotEmpty(passwordKey, passwordValue);
2603 settings.setStringIfNotEmpty(tokenKey, tokenValue);
2604 }
2605 }
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620 private void configureFromServer(Server server, String userKey, String passwordKey, String tokenKey, String serverId) throws InitializationException {
2621 final SettingsDecryptionResult result = settingsDecrypter.decrypt(new DefaultSettingsDecryptionRequest(server));
2622 final String username = server.getUsername();
2623 final String password;
2624 if (result.getProblems().isEmpty()) {
2625 password = result.getServer().getPassword();
2626 } else {
2627 logProblems(result.getProblems(), "server setting for " + serverId);
2628 getLog().debug("Using raw password from settings.xml for server " + serverId);
2629 password = server.getPassword();
2630 }
2631 if (username != null) {
2632 if (userKey != null && passwordKey != null) {
2633 settings.setStringIfNotEmpty(userKey, username);
2634 settings.setStringIfNotEmpty(passwordKey, password);
2635 } else {
2636 getLog().warn("Basic type server authentication encountered in serverId " + serverId + ", but only Bearer authentication is "
2637 + "supported for the resource. For Bearer authentication tokens you should leave out the username in the server-entry in"
2638 + " settings.xml");
2639 settings.setStringIfNotEmpty(tokenKey, password);
2640 }
2641 } else {
2642 if (tokenKey != null) {
2643 settings.setStringIfNotEmpty(tokenKey, password);
2644 } else {
2645 throw new InitializationException(
2646 "Bearer type server authentication encountered in serverId " + serverId + ", but only Basic authentication is supported for "
2647 + "the resource. Looks like the username was forgotten to be added in the server-entry in settings.xml");
2648 }
2649 }
2650 }
2651
2652 private String mergeNonProxyHosts(String existingNonProxyHosts, String httpNonProxyHosts, String httpsNonProxyHosts) {
2653 final HashSet<String> mergedNonProxyHosts = new HashSet<>();
2654 mergedNonProxyHosts.addAll(Arrays.asList(StringUtils.trimToEmpty(existingNonProxyHosts).split("\\|")));
2655 mergedNonProxyHosts.addAll(Arrays.asList(StringUtils.trimToEmpty(httpNonProxyHosts).split("\\|")));
2656 mergedNonProxyHosts.addAll(Arrays.asList(StringUtils.trimToEmpty(httpsNonProxyHosts).split("\\|")));
2657 return String.join("|", mergedNonProxyHosts);
2658 }
2659
2660 private void setProxyServerSysPropsFromMavenProxy(Proxy mavenProxy, String protocol) {
2661 System.setProperty(protocol + ".proxyHost", mavenProxy.getHost());
2662 if (mavenProxy.getPort() > 0) {
2663 System.setProperty(protocol + ".proxyPort", String.valueOf(mavenProxy.getPort()));
2664 }
2665 if (mavenProxy.getUsername() != null && !mavenProxy.getUsername().isEmpty()) {
2666 System.setProperty(protocol + ".proxyUser", mavenProxy.getUsername());
2667 }
2668 final SettingsDecryptionResult result = settingsDecrypter.decrypt(new DefaultSettingsDecryptionRequest(mavenProxy));
2669 final String password;
2670 if (result.getProblems().isEmpty()) {
2671 password = result.getProxy().getPassword();
2672 } else {
2673 logProblems(result.getProblems(), "proxy settings for " + mavenProxy.getId());
2674 getLog().debug("Using raw password from settings.xml for proxy " + mavenProxy.getId());
2675 password = mavenProxy.getPassword();
2676 }
2677 if (password != null && !password.isEmpty()) {
2678 System.setProperty(protocol + ".proxyPassword", password);
2679 }
2680 }
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691 private void configureServerCredentials(String serverId, String userSettingKey, String passwordSettingKey) throws MojoFailureException, MojoExecutionException {
2692 try {
2693 configureCredentials(serverId, null, null, null, userSettingKey, passwordSettingKey, null);
2694 } catch (InitializationException ex) {
2695 if (this.failOnError) {
2696 throw new MojoFailureException(String.format("Error setting credentials (%s, %s) from serverId %s", userSettingKey, passwordSettingKey, serverId), ex);
2697 } else {
2698 throw new MojoExecutionException(String.format("Error setting credentials (%s, %s) from serverId %s", userSettingKey, passwordSettingKey, serverId), ex);
2699 }
2700 }
2701 }
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712 @SuppressWarnings("SameParameterValue")
2713 private void configureServerCredentialsUserPassOrApiKey(String serverId, String userSettingKey, String passwordOrApiKeySetting) throws MojoFailureException, MojoExecutionException {
2714 try {
2715 configureCredentials(serverId, null, null, null, userSettingKey, passwordOrApiKeySetting, passwordOrApiKeySetting);
2716 } catch (InitializationException ex) {
2717 if (this.failOnError) {
2718 throw new MojoFailureException(String.format("Error setting credentials (%s, %s) from serverId %s", userSettingKey, passwordOrApiKeySetting, serverId), ex);
2719 } else {
2720 throw new MojoExecutionException(String.format("Error setting credentials (%s, %s) from serverId %s", userSettingKey, passwordOrApiKeySetting, serverId), ex);
2721 }
2722 }
2723 }
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734 private void configureServerCredentialsApiKey(String serverId, String apiKeySetting) throws InitializationException {
2735 configureCredentials(serverId, null, null, null, null, null, apiKeySetting);
2736 }
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747 private void logProblems(List<SettingsProblem> problems, String credentialDesc) {
2748 final String message = "Problems while decrypting " + credentialDesc;
2749 getLog().warn(message);
2750 if (getLog().isDebugEnabled()) {
2751 final StringBuilder dbgMessage = new StringBuilder("Problems while decrypting ").append(credentialDesc).append(": ");
2752 boolean first = true;
2753 for (SettingsProblem problem : problems) {
2754 dbgMessage.append(first ? "" : ", ").append(problem.getMessage());
2755 dbgMessage.append("caused by ").append(problem.getException());
2756 first = false;
2757 }
2758 getLog().debug(dbgMessage.toString());
2759 }
2760 }
2761
2762
2763
2764
2765
2766
2767
2768 private String[] determineSuppressions() {
2769 String[] suppressions = suppressionFiles;
2770 if (suppressionFile != null) {
2771 if (suppressions == null) {
2772 suppressions = new String[]{suppressionFile};
2773 } else {
2774 suppressions = Arrays.copyOf(suppressions, suppressions.length + 1);
2775 suppressions[suppressions.length - 1] = suppressionFile;
2776 }
2777 }
2778 return suppressions;
2779 }
2780
2781
2782
2783
2784 void muteNoisyLoggers() {
2785
2786 final List<String> noisyLoggers = List.of(
2787 "org.apache.lucene",
2788 "org.apache.commons.jcs3",
2789 "org.apache.hc"
2790 );
2791 for (String loggerName : noisyLoggers) {
2792 System.setProperty("org.slf4j.simpleLogger.log." + loggerName, "error");
2793 }
2794 }
2795
2796
2797
2798
2799
2800
2801
2802 private Proxy getMavenProxy(String protocol) {
2803 if (mavenSettings != null) {
2804 final List<Proxy> proxies = mavenSettings.getProxies();
2805 if (proxies != null && !proxies.isEmpty()) {
2806 if (mavenSettingsProxyId != null) {
2807 for (Proxy proxy : proxies) {
2808 if (mavenSettingsProxyId.equalsIgnoreCase(proxy.getId())) {
2809 return proxy;
2810 }
2811 }
2812 } else {
2813 for (Proxy aProxy : proxies) {
2814 if (aProxy.isActive() && aProxy.getProtocol().equals(protocol)) {
2815 return aProxy;
2816 }
2817 }
2818 }
2819 }
2820 }
2821 return null;
2822 }
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834 protected MavenProject getProject() {
2835 return project;
2836 }
2837
2838
2839
2840
2841
2842
2843 protected List<MavenProject> getReactorProjects() {
2844 return reactorProjects;
2845 }
2846
2847
2848
2849
2850
2851
2852 private Set<String> getFormats() {
2853 final Set<String> invalid = new HashSet<>();
2854 final Set<String> selectedFormats = formats == null || formats.length == 0 ? new HashSet<>() : new HashSet<>(Arrays.asList(formats));
2855 selectedFormats.forEach((s) -> {
2856 try {
2857 ReportGenerator.Format.valueOf(s.toUpperCase());
2858 } catch (IllegalArgumentException ex) {
2859 invalid.add(s);
2860 }
2861 });
2862 invalid.forEach((s) -> getLog().warn("Invalid report format specified: " + s));
2863 if (selectedFormats.contains("true")) {
2864 selectedFormats.remove("true");
2865 }
2866 if (format != null && selectedFormats.isEmpty()) {
2867 selectedFormats.add(format);
2868 }
2869 return selectedFormats;
2870 }
2871
2872
2873
2874
2875
2876
2877
2878 public List<String> getExcludes() {
2879 if (excludes == null) {
2880 excludes = new ArrayList<>();
2881 }
2882 return excludes;
2883 }
2884
2885
2886
2887
2888
2889
2890 protected Filter<String> getArtifactScopeExcluded() {
2891 return artifactScopeExcluded;
2892 }
2893
2894
2895
2896
2897
2898
2899 protected Settings getSettings() {
2900 return settings;
2901 }
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913 protected void checkForFailure(Dependency[] dependencies) throws MojoFailureException {
2914 final StringBuilder ids = new StringBuilder();
2915 for (Dependency d : dependencies) {
2916 boolean addName = true;
2917 for (Vulnerability v : d.getVulnerabilities()) {
2918 final double cvssV2 = v.getCvssV2() != null && v.getCvssV2().getCvssData() != null && v.getCvssV2().getCvssData().getBaseScore() != null ? v.getCvssV2().getCvssData().getBaseScore() : -1;
2919 final double cvssV3 = v.getCvssV3() != null && v.getCvssV3().getCvssData() != null && v.getCvssV3().getCvssData().getBaseScore() != null ? v.getCvssV3().getCvssData().getBaseScore() : -1;
2920 final double cvssV4 = v.getCvssV4() != null && v.getCvssV4().getCvssData() != null && v.getCvssV4().getCvssData().getBaseScore() != null ? v.getCvssV4().getCvssData().getBaseScore() : -1;
2921 final boolean useUnscored = cvssV2 == -1 && cvssV3 == -1 && cvssV4 == -1;
2922 final double unscoredCvss = (useUnscored && v.getUnscoredSeverity() != null) ? SeverityUtil.estimateCvssV2(v.getUnscoredSeverity()) : -1;
2923
2924 if (failBuildOnAnyVulnerability
2925 || cvssV2 >= failBuildOnCVSS
2926 || cvssV3 >= failBuildOnCVSS
2927 || cvssV4 >= failBuildOnCVSS
2928 || unscoredCvss >= failBuildOnCVSS
2929
2930 || failBuildOnCVSS <= 0.0
2931 ) {
2932 String name = v.getName();
2933 if (cvssV4 >= 0.0) {
2934 name += "(" + cvssV4 + ")";
2935 } else if (cvssV3 >= 0.0) {
2936 name += "(" + cvssV3 + ")";
2937 } else if (cvssV2 >= 0.0) {
2938 name += "(" + cvssV2 + ")";
2939 } else if (unscoredCvss >= 0.0) {
2940 name += "(" + unscoredCvss + ")";
2941 }
2942 if (addName) {
2943 addName = false;
2944 ids.append(NEW_LINE).append(d.getFileName()).append(" (")
2945 .append(Stream.concat(d.getSoftwareIdentifiers().stream(), d.getVulnerableSoftwareIdentifiers().stream())
2946 .map(Identifier::getValue)
2947 .collect(Collectors.joining(", ")))
2948 .append("): ")
2949 .append(name);
2950 } else {
2951 ids.append(", ").append(name);
2952 }
2953 }
2954 }
2955 }
2956 if (ids.length() > 0) {
2957 final String msg;
2958 if (showSummary) {
2959 if (failBuildOnAnyVulnerability) {
2960 msg = String.format("%n%nOne or more dependencies were identified with vulnerabilities: %n%s%n%n"
2961 + "See the dependency-check report for more details.%n%n", ids);
2962 } else {
2963 msg = String.format("%n%nOne or more dependencies were identified with vulnerabilities that have a CVSS score greater than or "
2964 + "equal to '%.1f': %n%s%n%nSee the dependency-check report for more details.%n%n", failBuildOnCVSS, ids);
2965 }
2966 } else {
2967 msg = String.format("%n%nOne or more dependencies were identified with vulnerabilities.%n%n"
2968 + "See the dependency-check report for more details.%n%n");
2969 }
2970 throw new MojoFailureException(msg);
2971 }
2972 }
2973
2974
2975
2976
2977
2978
2979
2980
2981 protected void showSummary(MavenProject mp, Dependency[] dependencies) {
2982 if (showSummary) {
2983 DependencyCheckScanAgent.showSummary(mp.getName(), dependencies);
2984 }
2985 }
2986
2987
2988
2989 private ExceptionCollection scanDependencyNode(DependencyNode dependencyNode, DependencyNode root,
2990 Engine engine, MavenProject project, List<ArtifactResult> allResolvedDeps,
2991 ProjectBuildingRequest buildingRequest, boolean aggregate, ExceptionCollection exceptionCollection) {
2992 ExceptionCollection exCol = exceptionCollection;
2993 if (artifactScopeExcluded.passes(dependencyNode.getArtifact().getScope())
2994 || artifactTypeExcluded.passes(dependencyNode.getArtifact().getType())) {
2995 return exCol;
2996 }
2997
2998 boolean isResolved = false;
2999 File artifactFile = null;
3000 String artifactId = null;
3001 String groupId = null;
3002 String version = null;
3003 List<ArtifactVersion> availableVersions = null;
3004 if (org.apache.maven.artifact.Artifact.SCOPE_SYSTEM.equals(dependencyNode.getArtifact().getScope())) {
3005 final Artifact a = dependencyNode.getArtifact();
3006 if (a.isResolved() && a.getFile().isFile()) {
3007 artifactFile = a.getFile();
3008 isResolved = artifactFile.isFile();
3009 groupId = a.getGroupId();
3010 artifactId = a.getArtifactId();
3011 version = a.getVersion();
3012 availableVersions = a.getAvailableVersions();
3013 } else {
3014 for (org.apache.maven.model.Dependency d : project.getDependencies()) {
3015 if (d.getSystemPath() != null && artifactsMatch(d, a)) {
3016 artifactFile = new File(d.getSystemPath());
3017 isResolved = artifactFile.isFile();
3018 groupId = a.getGroupId();
3019 artifactId = a.getArtifactId();
3020 version = a.getVersion();
3021 availableVersions = a.getAvailableVersions();
3022 break;
3023 }
3024 }
3025 }
3026 Throwable ignored = null;
3027 if (!isResolved) {
3028
3029
3030 try {
3031 tryResolutionOnce(project, allResolvedDeps, buildingRequest);
3032 final Artifact result = findInAllDeps(allResolvedDeps, dependencyNode.getArtifact(), project);
3033 isResolved = result.isResolved();
3034 artifactFile = result.getFile();
3035 groupId = result.getGroupId();
3036 artifactId = result.getArtifactId();
3037 version = result.getVersion();
3038 availableVersions = result.getAvailableVersions();
3039 } catch (DependencyNotFoundException | DependencyResolverException e) {
3040 getLog().warn("Error performing last-resort System-scoped dependency resolution: " + e.getMessage());
3041 ignored = e;
3042 }
3043 }
3044 if (!isResolved) {
3045 final StringBuilder message = new StringBuilder("Unable to resolve system scoped dependency: ");
3046 if (artifactFile != null) {
3047 message.append(dependencyNode.toNodeString()).append(" at path ").append(artifactFile);
3048 } else {
3049 message.append(dependencyNode.toNodeString()).append(" at path ").append(a.getFile());
3050 }
3051 getLog().error(message);
3052 if (exCol == null) {
3053 exCol = new ExceptionCollection();
3054 }
3055 final Exception thrown = new DependencyNotFoundException(message.toString());
3056 if (ignored != null) {
3057 thrown.addSuppressed(ignored);
3058 }
3059 exCol.addException(thrown);
3060 }
3061 } else {
3062 final Artifact dependencyArtifact = dependencyNode.getArtifact();
3063 final Artifact result;
3064 if (dependencyArtifact.isResolved()) {
3065
3066
3067
3068 getLog().debug(String.format("Skipping artifact %s, already resolved", dependencyArtifact.getArtifactId()));
3069 result = dependencyArtifact;
3070 } else {
3071 try {
3072 tryResolutionOnce(project, allResolvedDeps, buildingRequest);
3073 result = findInAllDeps(allResolvedDeps, dependencyNode.getArtifact(), project);
3074 } catch (DependencyNotFoundException | DependencyResolverException ex) {
3075 getLog().debug(String.format("Aggregate : %s", aggregate));
3076 boolean addException = true;
3077
3078 if (!aggregate) {
3079
3080 } else if (addReactorDependency(engine, dependencyNode.getArtifact(), project)) {
3081
3082 addException = false;
3083 }
3084 if (addException) {
3085 if (exCol == null) {
3086 exCol = new ExceptionCollection();
3087 }
3088 exCol.addException(ex);
3089 }
3090 return exCol;
3091 }
3092 }
3093 if (aggregate && virtualSnapshotsFromReactor
3094 && dependencyNode.getArtifact().isSnapshot()
3095 && addSnapshotReactorDependency(engine, dependencyNode.getArtifact(), project)) {
3096 return exCol;
3097 }
3098 isResolved = result.isResolved();
3099 artifactFile = result.getFile();
3100 groupId = result.getGroupId();
3101 artifactId = result.getArtifactId();
3102 version = result.getVersion();
3103 availableVersions = result.getAvailableVersions();
3104 }
3105 if (isResolved && artifactFile != null) {
3106 final List<Dependency> deps = engine.scan(artifactFile.getAbsoluteFile(),
3107 createProjectReferenceName(project, dependencyNode));
3108 if (deps != null) {
3109 processResolvedArtifact(artifactFile, deps, groupId, artifactId, version, root, project, availableVersions, dependencyNode);
3110 } else if ("import".equals(dependencyNode.getArtifact().getScope())) {
3111 final String msg = String.format("Skipping '%s:%s' in project %s as it uses an `import` scope",
3112 dependencyNode.getArtifact().getId(), dependencyNode.getArtifact().getScope(), project.getName());
3113 getLog().debug(msg);
3114 } else if ("pom".equals(dependencyNode.getArtifact().getType())) {
3115 exCol = processPomArtifact(artifactFile, root, project, engine, exCol);
3116 } else {
3117 if (!scannedFiles.contains(artifactFile)) {
3118 final String msg = String.format("No analyzer could be found or the artifact has been scanned twice for '%s:%s' in project %s",
3119 dependencyNode.getArtifact().getId(), dependencyNode.getArtifact().getScope(), project.getName());
3120 getLog().warn(msg);
3121 }
3122 }
3123 } else {
3124 final String msg = String.format("Unable to resolve '%s' in project %s",
3125 dependencyNode.getArtifact().getId(), project.getName());
3126 getLog().debug(msg);
3127 if (exCol == null) {
3128 exCol = new ExceptionCollection();
3129 }
3130 }
3131 return exCol;
3132 }
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153 private void tryResolutionOnce(MavenProject project, List<ArtifactResult> allResolvedDeps, ProjectBuildingRequest buildingRequest) throws DependencyResolverException {
3154 if (allResolvedDeps.isEmpty()) {
3155 try {
3156 final List<org.apache.maven.model.Dependency> dependencies = project.getDependencies();
3157 final List<org.apache.maven.model.Dependency> managedDependencies = project
3158 .getDependencyManagement() == null ? null : project.getDependencyManagement().getDependencies();
3159 final Iterable<ArtifactResult> allDeps = dependencyResolver
3160 .resolveDependencies(buildingRequest, dependencies, managedDependencies, null);
3161 allDeps.forEach(allResolvedDeps::add);
3162 } catch (DependencyResolverException dre) {
3163 if (dre.getCause() instanceof org.eclipse.aether.resolution.DependencyResolutionException) {
3164 final List<ArtifactResult> successResults = Mshared998Util
3165 .getResolutionResults((org.eclipse.aether.resolution.DependencyResolutionException) dre.getCause());
3166 allResolvedDeps.addAll(successResults);
3167 } else {
3168 throw dre;
3169 }
3170 }
3171 }
3172 }
3173
3174
3175
3176 private void processResolvedArtifact(File artifactFile, final List<Dependency> deps,
3177 String groupId, String artifactId, String version, DependencyNode root,
3178 MavenProject project1, List<ArtifactVersion> availableVersions,
3179 DependencyNode dependencyNode) {
3180 scannedFiles.add(artifactFile);
3181 Dependency d = null;
3182 if (deps.size() == 1) {
3183 d = deps.get(0);
3184
3185 } else {
3186 for (Dependency possible : deps) {
3187 if (artifactFile.getAbsoluteFile().equals(possible.getActualFile())) {
3188 d = possible;
3189 break;
3190 }
3191 }
3192 for (Dependency dep : deps) {
3193 if (d != null && d != dep) {
3194 final String includedBy = buildReference(groupId, artifactId, version);
3195 dep.addIncludedBy(includedBy);
3196 }
3197 }
3198 }
3199 if (d != null) {
3200 final MavenArtifact ma = new MavenArtifact(groupId, artifactId, version);
3201 d.addAsEvidence("pom", ma, Confidence.HIGHEST);
3202 if (root != null) {
3203 final String includedby = buildReference(
3204 root.getArtifact().getGroupId(),
3205 root.getArtifact().getArtifactId(),
3206 root.getArtifact().getVersion());
3207 d.addIncludedBy(includedby);
3208 } else {
3209 final String includedby = buildReference(project1.getGroupId(), project1.getArtifactId(), project1.getVersion());
3210 d.addIncludedBy(includedby);
3211 }
3212 if (availableVersions != null) {
3213 for (ArtifactVersion av : availableVersions) {
3214 d.addAvailableVersion(av.toString());
3215 }
3216 }
3217 getLog().debug(String.format("Adding project reference %s on dependency %s", project1.getName(), d.getDisplayFileName()));
3218 } else if (getLog().isDebugEnabled()) {
3219 final String msg = String.format("More than 1 dependency was identified in first pass scan of '%s' in project %s", dependencyNode.getArtifact().getId(), project1.getName());
3220 getLog().debug(msg);
3221 }
3222 }
3223
3224
3225 private ExceptionCollection processPomArtifact(File artifactFile, DependencyNode root,
3226 MavenProject project1, Engine engine, ExceptionCollection exCollection) {
3227 ExceptionCollection exCol = exCollection;
3228 try {
3229 final Dependency d = new Dependency(artifactFile.getAbsoluteFile());
3230 final Model pom = PomUtils.readPom(artifactFile.getAbsoluteFile());
3231 JarAnalyzer.setPomEvidence(d, pom, null, true);
3232 if (root != null) {
3233 final String includedby = buildReference(
3234 root.getArtifact().getGroupId(),
3235 root.getArtifact().getArtifactId(),
3236 root.getArtifact().getVersion());
3237 d.addIncludedBy(includedby);
3238 } else {
3239 final String includedby = buildReference(project1.getGroupId(), project1.getArtifactId(), project1.getVersion());
3240 d.addIncludedBy(includedby);
3241 }
3242 engine.addDependency(d);
3243 } catch (AnalysisException ex) {
3244 if (exCol == null) {
3245 exCol = new ExceptionCollection();
3246 }
3247 exCol.addException(ex);
3248 getLog().debug("Error reading pom " + artifactFile.getAbsoluteFile(), ex);
3249 }
3250 return exCol;
3251 }
3252
3253
3254 private void checkForDeprecatedParameters() {
3255 warnIfDeprecatedParamUsed("ossIndexAnalyzerEnabled", "ossindexAnalyzerEnabled");
3256 warnIfDeprecatedParamUsed("ossIndexAnalyzerUseCache", "ossindexAnalyzerUseCache");
3257 warnIfDeprecatedParamUsed("ossIndexAnalyzerUrl", "ossindexAnalyzerUrl");
3258 }
3259
3260
3261
3262
3263
3264
3265
3266 private void warnIfDeprecatedParamUsed(String currentName, String deprecatedName) {
3267 final org.apache.maven.model.Plugin plugin = project.getBuild().getPluginsAsMap()
3268 .get(mojoExecution.getGroupId() + ":" + mojoExecution.getArtifactId());
3269 if (plugin == null) {
3270 return;
3271 }
3272 final Object cfg = plugin.getConfiguration();
3273 if (cfg instanceof org.codehaus.plexus.util.xml.Xpp3Dom) {
3274 final org.codehaus.plexus.util.xml.Xpp3Dom dom = (org.codehaus.plexus.util.xml.Xpp3Dom) cfg;
3275 if (dom.getChild(deprecatedName) != null) {
3276 getLog().warn(String.format(
3277 "The parameter '%s' is deprecated and should not be used anymore. Please use '%s' instead.",
3278 deprecatedName, currentName));
3279 }
3280 }
3281 }
3282 }
3283