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