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