[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