[java-mvn-enforcer] branch main updated: JMVN-7 Make the enforcer understand zip/tgz files
Rod Widdowson
rdw at steadingsoftware.com
Mon Dec 6 15:22:58 UTC 2021
This is an automated email from the git hooks/post-receive script.
rdw pushed a commit to branch main
in repository java-mvn-enforcer.
View the commit online:
http://git.shibboleth.net/view/?p=java-mvn-enforcer.git;a=commit;h=f407810caf081811286744c42e53191c5c25ca18
The following commit(s) were added to refs/heads/main by this push:
new f407810 JMVN-7 Make the enforcer understand zip/tgz files
f407810 is described below
commit f407810caf081811286744c42e53191c5c25ca18
Author: Rod Widdowson <rdw at steadingsoftware.com>
AuthorDate: Mon Dec 6 15:14:34 2021 +0000
JMVN-7 Make the enforcer understand zip/tgz files
https://shibboleth.atlassian.net/browse/JMVN-7
This comes at the cost of no longer understansing directory trees
but I can live with that
---
pom.xml | 5 ++
.../mvn/enforcer/impl/BaseSigChecker.java | 6 +-
.../mvn/enforcer/impl/DependencyChecker.java | 41 ++++++----
.../shibboleth/mvn/enforcer/impl/JarEnforcer.java | 87 ++++++++++++++++------
.../shibboleth/mvn/enforcer/impl/M2SigChecker.java | 4 +-
.../shibboleth/mvn/enforcer/impl/SigChecker.java | 52 +++++++------
6 files changed, 129 insertions(+), 66 deletions(-)
diff --git a/pom.xml b/pom.xml
index bf97bc8..baf8cb7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -79,6 +79,11 @@
<artifactId>spring-context</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-compress</artifactId>
+ </dependency>
+
<!-- Provided because we are inside maven -->
<dependency>
<groupId>org.apache.maven.plugins</groupId>
diff --git a/src/main/java/net/shibboleth/mvn/enforcer/impl/BaseSigChecker.java b/src/main/java/net/shibboleth/mvn/enforcer/impl/BaseSigChecker.java
index 4b3682b..946e7ae 100644
--- a/src/main/java/net/shibboleth/mvn/enforcer/impl/BaseSigChecker.java
+++ b/src/main/java/net/shibboleth/mvn/enforcer/impl/BaseSigChecker.java
@@ -94,7 +94,7 @@ public class BaseSigChecker {
* @param artifact the {@link PomArtifact} for the jar file.
* @return true if the signature passed (or some other "usual conditions)
*/
- protected boolean checkSignature(final Path jarFile, final PomArtifact artifact) {
+ protected boolean checkSignature(final InputStream jarFile, final PomArtifact artifact) {
final String group = artifact.getGroupId();
final String id = artifact.getArtifactId();
final String version = artifact.getVersion();
@@ -128,8 +128,8 @@ public class BaseSigChecker {
return false;
}
- try (final BufferedInputStream stream = new BufferedInputStream(new FileInputStream(jarFile.toFile()))) {
- if (!keyRing.checkSignature(stream, sig)) {
+ try {
+ if (!keyRing.checkSignature(jarFile, sig)) {
report.format("%-30s: %-14s Signature Mismatch : %s in keyring %s\n",
id, version, keyRing.getKeyInfo(sig), group);
log.error("{} {} Signature Mismatch : ({}) in keyring for {}",
diff --git a/src/main/java/net/shibboleth/mvn/enforcer/impl/DependencyChecker.java b/src/main/java/net/shibboleth/mvn/enforcer/impl/DependencyChecker.java
index 1ad0854..962908a 100644
--- a/src/main/java/net/shibboleth/mvn/enforcer/impl/DependencyChecker.java
+++ b/src/main/java/net/shibboleth/mvn/enforcer/impl/DependencyChecker.java
@@ -38,6 +38,8 @@ import java.util.Set;
import javax.annotation.Nonnull;
+import org.apache.commons.compress.archivers.ArchiveEntry;
+import org.apache.commons.compress.archivers.ArchiveInputStream;
import org.apache.maven.shared.invoker.DefaultInvocationRequest;
import org.apache.maven.shared.invoker.DefaultInvoker;
import org.apache.maven.shared.invoker.InvocationRequest;
@@ -105,15 +107,14 @@ public class DependencyChecker {
}
/** The Body of the Dependency test. Are all the files what we expected? Who produced what?
- * @param roots where to start looking
+ * @param archive what to look at
* @param doAnalysis do we want to do the "and where did everything come from" analysis.
* @return true if OK, false otherwise
*/
- //Checkstyle: CyclomaticComplexity OFF
- public boolean checkDependencies(final List<Path> roots, final boolean doAnalysis) {
+ public boolean checkDependencies(final ArchiveInputStream archive, final boolean doAnalysis) {
final ParsedPom parentPom = projectContext.getParentPom();
final int dupEntries = reportDupEntries();
- if (!enumerateJars(roots)) {
+ if (!enumerateJars(archive)) {
return true;
}
@@ -295,21 +296,29 @@ public class DependencyChecker {
}
/** Get the jars and accumulate them into {@link #nameToVersion}.
- * @param roots where to start looking
+ * @param archive what to look in
* @return true if OK, false otherwise
*/
- private boolean enumerateJars(final List<Path> roots) {
- for (final Path root:roots) {
- if (Files.notExists(root)) {
- log.error("{} did not exist", root);
- return false;
- }
- try {
- Files.list(root).forEach(e -> addName(root.relativize(e).toString()));
- } catch (final IOException e) {
- log.error("Could not traverse tree from {}: ", root, e);
- return false;
+ private boolean enumerateJars(final ArchiveInputStream archive) {
+ ArchiveEntry entry = null;
+ try {
+ while ((entry = archive.getNextEntry()) != null) {
+ if (!archive.canReadEntryData(entry)) {
+ log.warn("Could not read next entry from {}", archive);
+ continue;
+ }
+ if (entry.isDirectory()) {
+ continue;
+ }
+ else if (!entry.getName().endsWith(".jar")) {
+ continue;
+ }
+ final Path nameAsPath = Path.of(entry.getName());
+ addName(nameAsPath.getFileName().toString());
}
+ } catch (final IOException e) {
+ log.error("Could not traverse archive");
+ return false;
}
return true;
}
diff --git a/src/main/java/net/shibboleth/mvn/enforcer/impl/JarEnforcer.java b/src/main/java/net/shibboleth/mvn/enforcer/impl/JarEnforcer.java
index 2b62462..8f5de57 100644
--- a/src/main/java/net/shibboleth/mvn/enforcer/impl/JarEnforcer.java
+++ b/src/main/java/net/shibboleth/mvn/enforcer/impl/JarEnforcer.java
@@ -22,6 +22,7 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
+import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.URL;
@@ -34,6 +35,9 @@ import java.util.List;
import javax.annotation.Nullable;
+import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
+import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
+import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
@@ -63,9 +67,10 @@ public class JarEnforcer implements EnforcerRule, MavenLoader{
/** Relative path of the parent pom.*/
private String parentPomDir=".";
- /** Space separated list of locations to look for jars in. */
- private String jarDirs="";
- /** Where to get external data. Group */
+ /** Space separated list of tgz files. */
+ private String tgzFiles="";
+ /** Space separated list of tgz files. */
+ private String zipFiles=""; /** Where to get external data. Group */
private String dataGroupId = "";
/** Where to get external data. ArtifactName*/
private String dataArtifactId = "";
@@ -111,17 +116,26 @@ public class JarEnforcer implements EnforcerRule, MavenLoader{
EnforcerLogger.setMavenLogger(helper.getLog());
log = EnforcerLogger.getLogger(JarEnforcer.class);
- final List<Path> jarPaths = new ArrayList<>();
- for (final String name: StringSupport.stringToList(jarDirs, XMLConstants.LIST_DELIMITERS)) {
+ final List<Path> tgzPaths = new ArrayList<>();
+ for (final String name: StringSupport.stringToList(tgzFiles, XMLConstants.LIST_DELIMITERS)) {
final Path result = Path.of(name);
- if (Files.notExists(result) || !Files.isDirectory(result)) {
- log.warn("Directory {{} does not exist or is not a directory", name);
+ if (Files.notExists(result)) {
+ log.warn("Input file {} does not exist", name);
} else {
- jarPaths.add(result);
+ tgzPaths.add(result);
}
}
- if (jarPaths.isEmpty()) {
- throw new EnforcerRuleException("No <jarsDirs/> provided");
+ final List<Path> zipPaths = new ArrayList<>();
+ for (final String name: StringSupport.stringToList(zipFiles, XMLConstants.LIST_DELIMITERS)) {
+ final Path result = Path.of(name);
+ if (Files.notExists(result)) {
+ log.warn("Input file {} does not exist", name);
+ } else {
+ zipPaths.add(result);
+ }
+ }
+ if (zipPaths.isEmpty() && tgzPaths.isEmpty()) {
+ throw new EnforcerRuleException("No <tgzFiles/> or <zipFiles/> provided");
}
try {
repositorySystem = helper.getComponent(org.apache.maven.repository.RepositorySystem.class);
@@ -158,8 +172,8 @@ public class JarEnforcer implements EnforcerRule, MavenLoader{
pomContext.initialize(pom);
final boolean m2Result = performM2Check(pomContext, target);
- final boolean depdendencyResult = performDependencyCheck(pomContext, target, jarPaths);
- final boolean signatureResult = performSignatureCheck(pomContext, target, jarPaths);
+ final boolean depdendencyResult = performDependencyCheck(pomContext, target, tgzPaths, zipPaths);
+ final boolean signatureResult = performSignatureCheck(pomContext, target, tgzPaths, zipPaths);
if (!depdendencyResult) {
throw new EnforcerRuleException(
"Dependency check failed, check the file ./target/dependencyReport.txt");
@@ -262,12 +276,14 @@ public class JarEnforcer implements EnforcerRule, MavenLoader{
/** Do the signature check
* @param pomContext Context for the work
* @param target Target Directory of this project
- * @param jarPaths the jars to look at.
+ * @param tgzPaths the tgzFiles to look at.
+ * @param zipPaths the zipFiles to look at.
* @return if this worked (or was suppressed)
- * @throws FileNotFoundException if a file was not found
- * @throws EnforcerRuleException if we were doing an invaluid SNAPSHOT/nonSNAPSHOT test
+ * @throws IOException if a file was not found or archive handling failed
+ * @throws EnforcerRuleException if we were doing an invalid SNAPSHOT/nonSNAPSHOT test
*/
- private boolean performSignatureCheck(final ProjectPomContext pomContext, final Path target, final List<Path> jarPaths) throws FileNotFoundException, EnforcerRuleException {
+ private boolean performSignatureCheck(final ProjectPomContext pomContext, final Path target,
+ final List<Path> tgzPaths, final List<Path> zipPaths) throws IOException, EnforcerRuleException {
boolean signatureResult = true;
if (checkSignatures) {
if (isGPGDataASnapshot() && !pomContext.isSnapShot()) {
@@ -276,9 +292,22 @@ public class JarEnforcer implements EnforcerRule, MavenLoader{
final File out = target.resolve("signatureReport.txt").toFile();
try (final PrintWriter report =
new PrintWriter(new BufferedOutputStream(new FileOutputStream(out)))) {
+
report.format("Signature Testing started at %s\n\n", Instant.now().toString());
final SigChecker sigChecker = new SigChecker(pomContext, report);
- signatureResult = sigChecker.testSignatures(jarPaths);
+
+ for (final Path tgzPath: tgzPaths) {
+ report.format("Scanning %s \n\n", tgzPath);
+ try (final InputStream inStream = new BufferedInputStream(new FileInputStream(tgzPath.toFile()))) {
+ signatureResult &= sigChecker.testSignatures(new TarArchiveInputStream(new GzipCompressorInputStream(inStream)));
+ }
+ }
+ for (final Path zipPath: zipPaths) {
+ report.format("Scanning %s \n\n", zipPath);
+ try (final InputStream inStream = new BufferedInputStream(new FileInputStream(zipPath.toFile()))) {
+ signatureResult &= sigChecker.testSignatures(new ZipArchiveInputStream(inStream));
+ }
+ }
report.format("Completed at %s\n\n", Instant.now().toString());
if (!signatureResult) {
log.error("Signature check failed, check the file ./target/signatureReport.txt");
@@ -291,11 +320,13 @@ public class JarEnforcer implements EnforcerRule, MavenLoader{
/** Do the dependency check
* @param pomContext Context for the work
* @param target Target Directory of this project
- * @param jarPaths the jars to look at.
+ * @param tgzPaths the tgzFiles to look at.
+ * @param zipPaths the zipFiles to look at.
* @return if this worked (or was suppressed)
- * @throws FileNotFoundException if a file was not found
+ * @throws IOException if a file was not found or archive handling failed
*/
- private boolean performDependencyCheck(final ProjectPomContext pomContext, final Path target, final List<Path> jarPaths) throws FileNotFoundException {
+ private boolean performDependencyCheck(final ProjectPomContext pomContext, final Path target,
+ final List<Path> tgzPaths, final List<Path> zipPaths) throws IOException {
boolean depdendencyResult = true;
if (checkDependencies) {
final File out = target.resolve("dependencyReport.txt").toFile();
@@ -303,8 +334,20 @@ public class JarEnforcer implements EnforcerRule, MavenLoader{
new BufferedOutputStream(new FileOutputStream(out)))) {
report.format("POM based Dependency Testing started at %s\n\n", Instant.now().toString());
- final DependencyChecker checker = new DependencyChecker(pomContext, report);
- depdendencyResult = checker.checkDependencies(jarPaths, listJarSources);
+ for (final Path tgzPath: tgzPaths) {
+ report.format("Scanning %s \n\n", tgzPath);
+ try (final InputStream inStream = new BufferedInputStream(new FileInputStream(tgzPath.toFile()))) {
+ final DependencyChecker checker = new DependencyChecker(pomContext, report);
+ depdendencyResult &= checker.checkDependencies(new TarArchiveInputStream(new GzipCompressorInputStream(inStream)), listJarSources);
+ }
+ }
+ for (final Path zipPath: zipPaths) {
+ report.format("Scanning %s \n\n", zipPath);
+ try (final InputStream inStream = new BufferedInputStream(new FileInputStream(zipPath.toFile()))) {
+ final DependencyChecker checker = new DependencyChecker(pomContext, report);
+ depdendencyResult &= checker.checkDependencies(new ZipArchiveInputStream(inStream), listJarSources);
+ }
+ }
report.format("Completed at %s\n\n", Instant.now().toString());
if (!depdendencyResult) {
log.error( "Dependency check failed, check the file ./target/dependencyReport.txt");
diff --git a/src/main/java/net/shibboleth/mvn/enforcer/impl/M2SigChecker.java b/src/main/java/net/shibboleth/mvn/enforcer/impl/M2SigChecker.java
index 5e48374..de5a625 100644
--- a/src/main/java/net/shibboleth/mvn/enforcer/impl/M2SigChecker.java
+++ b/src/main/java/net/shibboleth/mvn/enforcer/impl/M2SigChecker.java
@@ -17,6 +17,8 @@
package net.shibboleth.mvn.enforcer.impl;
+import java.io.BufferedInputStream;
+import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.FileVisitResult;
@@ -105,7 +107,7 @@ public class M2SigChecker extends BaseSigChecker {
info = pom.new PomArtifact(info.getGroupId(), info.getArtifactId(), info.getVersion() + versionExtra);
}
- if (!checkSignature(file, info)) {
+ if (!checkSignature(new BufferedInputStream(new FileInputStream(file.toFile())), info)) {
failCount ++;
}
return result;
diff --git a/src/main/java/net/shibboleth/mvn/enforcer/impl/SigChecker.java b/src/main/java/net/shibboleth/mvn/enforcer/impl/SigChecker.java
index 9ddb297..2d0ae2a 100644
--- a/src/main/java/net/shibboleth/mvn/enforcer/impl/SigChecker.java
+++ b/src/main/java/net/shibboleth/mvn/enforcer/impl/SigChecker.java
@@ -18,13 +18,14 @@
package net.shibboleth.mvn.enforcer.impl;
import java.io.IOException;
+import java.io.InputStream;
import java.io.PrintWriter;
-import java.nio.file.Files;
import java.nio.file.Path;
-import java.util.List;
import javax.annotation.Nonnull;
+import org.apache.commons.compress.archivers.ArchiveEntry;
+import org.apache.commons.compress.archivers.ArchiveInputStream;
import org.slf4j.Logger;
import net.shibboleth.mvn.enforcer.impl.ParsedPom.PomArtifact;
@@ -48,42 +49,45 @@ public class SigChecker extends BaseSigChecker {
}
/** The Body of the signature test. Are all the files what we expected?
- * @param roots where to start looking
+ * @param archive what to look at
* @return true if all was OK.
*/
- public boolean testSignatures(final List<Path> roots) {
+ public boolean testSignatures(final ArchiveInputStream archive) {
int sigFails = 0;
- for (final Path root:roots) {
- try {
- sigFails += Files.list(root).mapToInt(e -> checkSignature(e)).sum();
- } catch (final IOException e) {
- log.error("Failed to enumerate files at {}", root, e);
- return false;
+ try {
+ ArchiveEntry entry = null;
+ while ((entry = archive.getNextEntry()) != null) {
+ if (!archive.canReadEntryData(entry)) {
+ log.warn("Could not read next entry from {}", archive);
+ continue;
+ }
+ if (entry.isDirectory()) {
+ continue;
+ }
+ else if (!entry.getName().endsWith(".jar")) {
+ continue;
+ }
+ sigFails += checkSignature(entry.getName(), archive);
}
- }
- if (sigFails != 0) {
- getReport().format("\t%d non-exempt jar files did not have valid signatures\n", sigFails);
- } else {
- getReport().format("\tAll non-exempt jar files correctly signed\n");
+ } catch (final IOException e) {
+ log.error("Could not traverse archive");
+ return false;
}
return sigFails == 0;
}
/** Given the Path and the parent dir check the signature.
- * @param jarFile the file to check
+ * @param jarPath the name to check
+ * @param input the stream to check
* @return 1 if anything went wrong
*/
- // CheckStyle: ReturnCount|CyclomaticComplexity OFF
- private int checkSignature(final Path jarFile) {
- final String fileName = jarFile.getFileName().toString();
- if (!fileName.endsWith(".jar")) {
- return 0;
- }
- final Pair<String,String> name = getProjectContext().splitFileName(fileName);
+ private int checkSignature(final String jarPath, final InputStream input) {
+ final String jarName = Path.of(jarPath).getFileName().toString();
+ final Pair<String,String> name = getProjectContext().splitFileName(jarName);
final String group = getProjectContext().getGroup(name.getFirst());
final PomArtifact jarAsArtifact =
getProjectContext().getParentPom().new PomArtifact(group, name.getFirst(), name.getSecond());
- if (checkSignature(jarFile, jarAsArtifact)) {
+ if (checkSignature(input, jarAsArtifact)) {
return 0;
}
return 1;
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list