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