[java-mvn-enforcer] branch main updated: JMVN-34 List all keys in the repository

Rod Widdowson rdw at steadingsoftware.com
Sun Mar 27 12:13:37 UTC 2022


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=d88a52eaa4994fa5690744a3a3f7a4c63f2a30dc

The following commit(s) were added to refs/heads/main by this push:
     new d88a52e  JMVN-34 List all keys in the repository
d88a52e is described below

commit d88a52eaa4994fa5690744a3a3f7a4c63f2a30dc
Author: Rod Widdowson <rdw at steadingsoftware.com>
AuthorDate: Sun Mar 27 13:13:11 2022 +0100

    JMVN-34 List all keys in the repository
    
    https://shibboleth.atlassian.net/browse/JMVN-34
---
 pom.xml                                            |   7 +
 .../mvn/enforcer/cli/impl/ListKeysCLI.java         | 227 +++++++++++++++++++++
 .../cli/impl/ListKeysCommandLineArguments.java     |  86 ++++++++
 3 files changed, 320 insertions(+)

diff --git a/pom.xml b/pom.xml
index fafc960..a230bc0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -84,6 +84,13 @@
           <artifactId>commons-compress</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>com.beust</groupId>
+            <artifactId>jcommander</artifactId>
+            <!-- Required for command line classes. -->
+            <scope>test</scope>
+        </dependency>
+
         <!--  Provided because we are inside maven  -->
          <dependency>
             <groupId>org.apache.maven.plugins</groupId>
diff --git a/src/test/java/net/shibboleth/mvn/enforcer/cli/impl/ListKeysCLI.java b/src/test/java/net/shibboleth/mvn/enforcer/cli/impl/ListKeysCLI.java
new file mode 100644
index 0000000..ecca3ef
--- /dev/null
+++ b/src/test/java/net/shibboleth/mvn/enforcer/cli/impl/ListKeysCLI.java
@@ -0,0 +1,227 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements.  See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.mvn.enforcer.cli.impl;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.security.Security;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.openpgp.PGPException;
+import org.bouncycastle.openpgp.PGPPublicKey;
+import org.bouncycastle.openpgp.PGPPublicKeyRing;
+import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
+import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import net.shibboleth.ext.spring.cli.AbstractCommandLine;
+
+/**
+ * Command Line to generate list keys in an KeyRing folder.
+ */
+public final class ListKeysCLI extends AbstractCommandLine<ListKeysCommandLineArguments> {
+
+    /** Class logger. */
+    @Nullable private Logger log;
+
+    /** Where we are outputting to? */
+    private PrintWriter output;
+
+    /** The processed arguments. */
+    private ListKeysCommandLineArguments args;
+    
+    /** How many files?*/
+    private int fileCount;
+    
+    /** Keys.*/
+    private Set<Long> keys = new HashSet<>();
+    
+    /** {@inheritDoc} */
+    @Override
+    @Nonnull protected synchronized Logger getLogger() {
+        if (log == null) {
+            log = LoggerFactory.getLogger(ListKeysCLI.class);
+        }
+        return log;
+    }
+
+    /** {@inheritDoc} */
+    @Override @Nonnull protected Class<ListKeysCommandLineArguments> getArgumentClass() {
+        return ListKeysCommandLineArguments.class;
+    }
+
+
+
+    /** Set up {@link ListKeysCLI#output}.
+     * @return true iff this worked.
+     */
+    private boolean setupWriter() {
+        if (args.getOutput() == null) {
+            output = new PrintWriter(System.out);
+        } else {
+            final File out = new File(args.getOutput());
+            try {
+                final FileOutputStream outStream = new FileOutputStream(out);
+                output = new PrintWriter(new BufferedOutputStream(outStream));
+            } catch (final IOException e) {
+                getLogger().error("Could not open {}", args.getOutput(), e);
+                return false;
+            }
+        }
+        return true;
+    }
+    
+    /** Enumerate (via a call to {@link #enumerateKeysIn(Path)} every gpg file in the provided directory. 
+     * @param dirName where to enumerate from
+     * @return true if all OK.
+     */
+    private boolean enumerateKeyringsIn(String dirName) {
+        output.printf("Enumerating %s\n\n", dirName);
+        final Path dir = Path.of(dirName);
+        final File dirAsFile = dir.toFile();
+        boolean result = true;
+        if (!dirAsFile.exists()) {
+            output.println("   Directory does not exist");
+            result = false;
+        } else if (!dirAsFile.isDirectory()) {
+            output.println("   Is not a directory");
+            result = false;
+        } else {
+            try (final DirectoryStream<Path> dirstream  = Files.newDirectoryStream(dir, "*.gpg")) {
+                for (final Path child : dirstream) {
+                    fileCount++;
+                    if (!enumerateKeysIn(child)) {
+                        result = false;
+                    }
+                }
+            } catch (IOException e) {
+                getLogger().error("Failed", e);
+                result = false;
+            }
+        }
+        return result;
+    }
+
+    /** Enumerate all the keys in the file at the provided path.
+     * @param keyring the keyring
+     * @return true if OK.
+     */
+    private boolean enumerateKeysIn(Path keyring) {
+        try (final InputStream gpg = new BufferedInputStream(new FileInputStream(keyring.toFile()))) {
+            output.printf("Contents of %s\n", keyring.getFileName());
+            final PGPPublicKeyRingCollection bcKeyRingCollection = new PGPPublicKeyRingCollection(gpg, new JcaKeyFingerprintCalculator());
+            Iterator<PGPPublicKeyRing> bcKeyRings = bcKeyRingCollection.getKeyRings();
+            while (bcKeyRings.hasNext()) {
+                final PGPPublicKeyRing bcKeyRing = bcKeyRings.next();
+                final PGPPublicKey masterKey = bcKeyRing.getPublicKeys().next();
+                keys.add(masterKey.getKeyID());
+                final Set<String> seenNames = new HashSet<>();
+                final StringBuilder builder = new StringBuilder(String.format("\t0x%016X\t", masterKey.getKeyID()));
+                final Iterator<String> namesIterator = masterKey.getUserIDs();
+                while (namesIterator.hasNext()) {
+                    final String name =  namesIterator.next();
+                    if (seenNames.add(name)) {
+                        builder.append("\tUsername:\t").append(name);
+                    }
+                }
+                output.println(builder.toString());
+            }
+        } catch (IOException e) {
+           getLogger().error("Could not open keyring {}", keyring, e);
+           return false;
+        } catch (PGPException e) {
+            getLogger().error("Could not parse keyring {}", keyring, e);
+            return false;
+        }
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    @Nullable protected String getVersion() {
+        return "Unversioned - only for test";
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected int doRun(@Nonnull final ListKeysCommandLineArguments arguments) {
+
+        args = arguments;
+        int ret = super.doRun(args);
+        if (ret != RC_OK) {
+            return ret;
+        }
+        if (!setupWriter()) {
+            return RC_IO;
+        }
+        if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
+            Security.addProvider(new BouncyCastleProvider());
+        }
+        final List<String> dirs = arguments.getKeyRings();
+        for (final String dir:dirs) {
+            if (!enumerateKeyringsIn(dir)) {
+                ret = RC_IO;
+            }
+        }
+        if (ret == RC_OK) {
+            output.printf("A total of %d keys in %d keyrings\n", keys.size(), fileCount);
+        }
+        output.flush();
+        return ret;
+    }
+
+    /** Shim for CLI entry point: Allows the code to be run from a test.
+    *
+    * @return one of the predefines {@link AbstractCommandLine#RC_INIT},
+    * {@link AbstractCommandLine#RC_IO}, {@link AbstractCommandLine#RC_OK}
+    * or {@link AbstractCommandLine#RC_UNKNOWN}
+    *
+    * @param args arguments
+    */
+   public static int runMain(@Nonnull final String[] args) {
+       final ListKeysCLI cli = new ListKeysCLI();
+
+       return cli.run(args);
+   }
+
+   /**
+    * CLI entry point.
+    * @param args arguments
+    */
+   public static void main(@Nonnull final String[] args) {
+       System.exit(runMain(args));
+   }
+
+}
diff --git a/src/test/java/net/shibboleth/mvn/enforcer/cli/impl/ListKeysCommandLineArguments.java b/src/test/java/net/shibboleth/mvn/enforcer/cli/impl/ListKeysCommandLineArguments.java
new file mode 100644
index 0000000..a742981
--- /dev/null
+++ b/src/test/java/net/shibboleth/mvn/enforcer/cli/impl/ListKeysCommandLineArguments.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements.  See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.shibboleth.mvn.enforcer.cli.impl;
+
+import java.io.PrintStream;
+import java.util.List;
+
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.beust.jcommander.Parameter;
+
+import net.shibboleth.ext.spring.cli.AbstractCommandLineArguments;
+
+/**
+ * Command line arguments for Metadata Generation.
+ */
+public class ListKeysCommandLineArguments extends AbstractCommandLineArguments {
+    
+    /** Logger. */
+    private Logger log;
+
+    /** Output.*/
+    @Parameter(names = { "--output", "-o"})
+    @Nullable private String output;
+    
+    /** Where to look.*/
+    @Parameter(names = { "--keyRings", "-k"})
+    @Nullable private List<String> keyRings;
+
+
+    /** Where to put the data.
+     * @return where
+     */
+    @Nullable public String getOutput() {
+        return output;
+    }
+    
+    /** Where to look.
+     * @return Returns the keyRing location(s).
+     */
+    public List<String> getKeyRings() {
+        return keyRings;
+    }
+    
+    @Override
+    public synchronized Logger getLog() {
+        if (log == null) {
+            log = LoggerFactory.getLogger(ListKeysCommandLineArguments.class);
+        }
+        return log;
+    }
+    
+    /** {@inheritDoc} */
+    public void validate() throws IllegalArgumentException {
+        if (getKeyRings().isEmpty()) {
+            throw new IllegalArgumentException("At least one keyring folder (-k) must be specified");
+        }
+    }
+
+    @Override
+    public void printHelp(final PrintStream out) {
+        super.printHelp(out);
+        out.println(String.format("  %-20s %s", "--ketRings, -k",
+                "KeyRing directory(s) Required."));
+        out.println(String.format("  %-20s %s", "--output, -o",
+                                  "Output location."));
+        out.println();
+    }
+}

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list