[java-idp-plugin-metadatagen] 03/06: Rejig and copy in the 4.2 sources

Rod Widdowson rdw at steadingsoftware.com
Fri Jun 11 09:47:53 UTC 2021


This is an automated email from the git hooks/post-receive script.

rdw pushed a commit to branch main
in repository java-idp-plugin-metadatagen.

View the commit online:
http://git.shibboleth.net/view/?p=java-idp-plugin-metadatagen.git;a=commit;h=1a5ea8b818af1716535539747fec465627d016d0

commit 1a5ea8b818af1716535539747fec465627d016d0
Author: Rod Widdowson <rdw at steadingsoftware.com>
AuthorDate: Tue Jun 1 17:03:46 2021 +0100

    Rejig and copy in the 4.2 sources
---
 .../idp/plugin/metadatagen/MetadataGenModule.java  |  25 -
 .../plugin/metadatagen/impl/MetadataGenCLI.java    | 559 +++++++++++++++++++++
 .../impl/MetadataGenCommandLineArguments.java      | 236 +++++++++
 .../plugin/metadatagen/impl/MetadataGenModule.java |  42 ++
 .../metadatagen/impl/MetadataGenParameters.java    | 193 +++++++
 .../metadatagen/{ => impl}/MetadataGenPlugin.java  |  19 +-
 .../idp/plugin/metadatagen/impl/package-info.java  |  21 +
 .../plugin/metadatagen/bin/metadatagen-beta.bat    |   4 +
 .../idp/plugin/metadatagen/bin/metadatagen-beta.sh |   7 +
 .../idp/plugin/metadatagen/metadatagen.xml         |  23 +
 .../idp/plugin/metadatagen/module.properties       |   8 +-
 .../idp/plugin/metadatatgen/bin/metadatagen.bat    |   4 -
 .../idp/plugin/metadatatgen/bin/metadatagen.sh     |   7 -
 pom.xml                                            |   4 +-
 14 files changed, 1109 insertions(+), 43 deletions(-)

diff --git a/metadatagen-impl/src/main/java/net/shibboleth/idp/plugin/metadatagen/MetadataGenModule.java b/metadatagen-impl/src/main/java/net/shibboleth/idp/plugin/metadatagen/MetadataGenModule.java
deleted file mode 100644
index 4eeb119..0000000
--- a/metadatagen-impl/src/main/java/net/shibboleth/idp/plugin/metadatagen/MetadataGenModule.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package net.shibboleth.idp.plugin.metadatagen;
-
-import java.io.IOException;
-
-import net.shibboleth.idp.module.ModuleException;
-import net.shibboleth.idp.module.impl.PluginIdPModule;
-
-
-/**
- * {@link net.shibboleth.idp.module.IdPModule IdP Module} implementation.
- */
-public class MetadataGenModule extends PluginIdPModule{
-    
-    /**
-     * Constructor.
-     *  
-     * @throws ModuleException on error
-     * @throws IOException on error
-     */
-    public MetadataGenModule() throws IOException, ModuleException {
-        super(MetadataGenModule.class);
-    }
-    
-
-}
\ No newline at end of file
diff --git a/metadatagen-impl/src/main/java/net/shibboleth/idp/plugin/metadatagen/impl/MetadataGenCLI.java b/metadatagen-impl/src/main/java/net/shibboleth/idp/plugin/metadatagen/impl/MetadataGenCLI.java
new file mode 100644
index 0000000..993d854
--- /dev/null
+++ b/metadatagen-impl/src/main/java/net/shibboleth/idp/plugin/metadatagen/impl/MetadataGenCLI.java
@@ -0,0 +1,559 @@
+/*
+ * 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.idp.plugin.metadatagen.impl;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.core.xml.LangBearing;
+import org.opensaml.saml.common.xml.SAMLConstants;
+import org.opensaml.saml.ext.reqattr.RequestedAttributes;
+import org.opensaml.saml.ext.saml2mdui.Description;
+import org.opensaml.saml.ext.saml2mdui.DisplayName;
+import org.opensaml.saml.ext.saml2mdui.Logo;
+import org.opensaml.saml.ext.saml2mdui.UIInfo;
+import org.opensaml.saml.saml2.core.Extensions;
+import org.opensaml.saml.saml2.metadata.ArtifactResolutionService;
+import org.opensaml.saml.saml2.metadata.AssertionConsumerService;
+import org.opensaml.saml.saml2.metadata.AttributeAuthorityDescriptor;
+import org.opensaml.saml.saml2.metadata.AttributeService;
+import org.opensaml.saml.saml2.metadata.EntityDescriptor;
+import org.opensaml.saml.saml2.metadata.IDPSSODescriptor;
+import org.opensaml.saml.saml2.metadata.KeyDescriptor;
+import org.opensaml.saml.saml2.metadata.SPSSODescriptor;
+import org.opensaml.saml.saml2.metadata.SingleLogoutService;
+import org.opensaml.saml.saml2.metadata.SingleSignOnService;
+import org.opensaml.xmlsec.signature.KeyInfo;
+import org.opensaml.xmlsec.signature.X509Certificate;
+import org.opensaml.xmlsec.signature.X509Data;
+import org.opensaml.xmlsec.signature.support.SignatureConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.core.env.Environment;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+
+import net.shibboleth.ext.spring.cli.AbstractCommandLine;
+import net.shibboleth.idp.Version;
+import net.shibboleth.idp.cli.AbstractIdPHomeAwareCommandLine;
+import net.shibboleth.idp.saml.xmlobject.ExtensionsConstants;
+import net.shibboleth.idp.saml.xmlobject.Scope;
+import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
+import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
+import net.shibboleth.utilities.java.support.primitive.StringSupport;
+import net.shibboleth.utilities.java.support.xml.DOMTypeSupport;
+import net.shibboleth.utilities.java.support.xml.XMLConstants;
+
+/**
+ * Command Line to generate Metadata.
+ */
+public class MetadataGenCLI extends AbstractIdPHomeAwareCommandLine<MetadataGenCommandLineArguments> {
+
+    /** Class logger. */
+    @Nullable private Logger log;
+
+    /** Certificate and other property driven data. */
+    private MetadataGenParameters parameters;
+
+    /** Where we are outputting to? */
+    private PrintWriter output;
+
+    /** The processed arguments. */
+    private MetadataGenCommandLineArguments args;
+    
+    /** The DnsName (cached because we need it often). */
+    private String dnsName;
+    
+    /** {@inheritDoc} */
+    @Override
+    @Nonnull protected synchronized Logger getLogger() {
+        if (log == null) {
+            log = LoggerFactory.getLogger(MetadataGenCLI.class);
+        }
+        return log;
+    }
+
+    /** {@inheritDoc} */
+    protected Class<MetadataGenCommandLineArguments> getArgumentClass() {
+        return MetadataGenCommandLineArguments.class;
+    }
+
+    /** {@inheritDoc} */
+    protected String getVersion() {
+        return Version.getVersion();
+    }
+
+    /** {@inheritDoc} */
+    @Nonnull @NonnullElements protected List<Resource> getAdditionalSpringResources() {
+        return List.of(
+               new ClassPathResource("net/shibboleth/idp/plugin/metadatagen/metadatagen.xml"));
+    }
+
+    /**
+     * Write out any <KeyDescriptor>Elements.
+     * @param outputBackChannel Do we output the back channel certificates?
+     */
+    private void outputKeyDescriptors(final boolean outputBackChannel) {
+        final List<List<String>> signing = new ArrayList<>(2);
+        if (outputBackChannel &&
+            parameters.getBackchannelCert() != null &&
+            !parameters.getBackchannelCert().isEmpty()) {
+            output.format("        <!--  First signing certificate is BackChannel, the Second is FrontChannel -->\n");
+            signing.add(parameters.getBackchannelCert());
+        }
+        if (parameters.getSigningCert() != null && !parameters.getSigningCert().isEmpty()) {
+            signing.add(parameters.getSigningCert());
+        }
+        outputKeyDescriptors(signing, "signing");
+        outputKeyDescriptors(Collections.singletonList(parameters.getEncryptionCert()), "encryption");
+        output.format("\n");
+    }
+
+    /**
+     * Write out <KeyDescriptor>Elements. of a specific type
+     *
+     * @param certs the certificates
+     * @param use the type - signing or encryption
+     */
+    private void outputKeyDescriptors(@Nullable final List<List<String>> certs, @Nonnull @NotEmpty final String use) {
+
+        if (null == certs || certs.isEmpty()) {
+            return;
+        }
+        for (final List<String> cert : certs) {
+            output.format("        <%s use=\"%s\">\n",KeyDescriptor.DEFAULT_ELEMENT_LOCAL_NAME, use);
+            output.format("          <%s:%s>\n", SignatureConstants.XMLSIG_PREFIX, KeyInfo.DEFAULT_ELEMENT_LOCAL_NAME);
+            output.format("            <%s:%s>\n",
+                    SignatureConstants.XMLSIG_PREFIX, X509Data.DEFAULT_ELEMENT_LOCAL_NAME);
+            output.format("              <%s:%s>\n",
+                    SignatureConstants.XMLSIG_PREFIX, X509Certificate.DEFAULT_ELEMENT_LOCAL_NAME);
+            output.format("%s\n",String.join("\n", cert));
+            output.format("              </%s:%s>\n",
+                    SignatureConstants.XMLSIG_PREFIX, X509Certificate.DEFAULT_ELEMENT_LOCAL_NAME);
+            output.format("            </%s:%s>\n",
+                    SignatureConstants.XMLSIG_PREFIX, X509Data.DEFAULT_ELEMENT_LOCAL_NAME);
+            output.format("          </%s:%s>\n",SignatureConstants.XMLSIG_PREFIX, KeyInfo.DEFAULT_ELEMENT_LOCAL_NAME);
+            output.format("        </%s>\n\n",KeyDescriptor.DEFAULT_ELEMENT_LOCAL_NAME);
+        }
+    }
+
+    /** Output the MDUI for one language.
+     * @param lang the language to emit
+     *
+     */
+    private void outputMDUI(final String lang) {
+        final Environment env = getApplicationContext().getEnvironment();
+        final String displayName = env.getProperty(MetadataGenCommandLineArguments.MDUI_DISPLAY_NAME_PREFIX+lang);
+        if (displayName != null) {
+            output.format("            <%s:%s %s:%s=\"%s\">%s<%s:%s>\n",
+                    SAMLConstants.SAML20MDUI_PREFIX, DisplayName.DEFAULT_ELEMENT_LOCAL_NAME,
+                    XMLConstants.XML_PREFIX, LangBearing.XML_LANG_ATTR_LOCAL_NAME,
+                    lang, displayName,
+                    SAMLConstants.SAML20MDUI_PREFIX, DisplayName.DEFAULT_ELEMENT_LOCAL_NAME);
+        }
+        final String description = env.getProperty(MetadataGenCommandLineArguments.MDUI_DESCRIPTION_PREFIX+lang);
+        if (description != null) {
+            output.format("            <%s:%s %s:%s=\"%s\">%s<%s:%s>\n",
+                    SAMLConstants.SAML20MDUI_PREFIX, Description.DEFAULT_ELEMENT_LOCAL_NAME,
+                    XMLConstants.XML_PREFIX, LangBearing.XML_LANG_ATTR_LOCAL_NAME,
+                    lang, description,
+                    SAMLConstants.SAML20MDUI_PREFIX, Description.DEFAULT_ELEMENT_LOCAL_NAME);
+        }
+    }
+
+    /** Output Scope and MDUI.
+     * @param includeMDUI do we output the MDUI
+     */
+    private void outputExtensions(final boolean includeMDUI) {
+        output.format("        <%s>\n", Extensions.DEFAULT_ELEMENT_LOCAL_NAME);
+        final Environment env = getApplicationContext().getEnvironment();
+        final String scope = StringSupport.trimOrNull(env.getProperty("idp.scope"));
+        if (scope != null) {
+            output.format("          <%s:%s regexp=\"false\">%s</%s:%s>\n",
+                    ExtensionsConstants.SHIB_MDEXT10_PREFIX, Scope.DEFAULT_ELEMENT_LOCAL_NAME,
+                    scope,
+                    ExtensionsConstants.SHIB_MDEXT10_PREFIX, Scope.DEFAULT_ELEMENT_LOCAL_NAME);
+        }
+
+        if (includeMDUI) {
+            output.format("          <%s:%s>\n",
+                    SAMLConstants.SAML20MDUI_PREFIX, UIInfo.DEFAULT_ELEMENT_LOCAL_NAME);
+            final String mduiLangs = env.getProperty(MetadataGenCommandLineArguments.MDUI_LANGS_PROPERTY);
+            if (mduiLangs == null) {
+                output.format("\n<!--\n          Fill in the details for your IdP here\n\n");
+                output.format("            <%s:%s %s:%s=\"en\">A Name for the IdP<%s:%s>\n",
+                        SAMLConstants.SAML20MDUI_PREFIX, DisplayName.DEFAULT_ELEMENT_LOCAL_NAME,
+                        XMLConstants.XML_PREFIX, LangBearing.XML_LANG_ATTR_LOCAL_NAME,
+                        SAMLConstants.SAML20MDUI_PREFIX, DisplayName.DEFAULT_ELEMENT_LOCAL_NAME);
+                output.format("            <%s:%s %s:%s=\"en\">A Description for the IdP<%s:%s>\n",
+                        SAMLConstants.SAML20MDUI_PREFIX, Description.DEFAULT_ELEMENT_LOCAL_NAME,
+                        XMLConstants.XML_PREFIX, LangBearing.XML_LANG_ATTR_LOCAL_NAME,
+                        SAMLConstants.SAML20MDUI_PREFIX, Description.DEFAULT_ELEMENT_LOCAL_NAME);
+            } else {
+                for (final String lang:mduiLangs.split(" ")) {
+                    outputMDUI(lang);
+                }
+            }
+            final String logoY = env.getProperty(MetadataGenCommandLineArguments.MDUI_LOGO_HEIGHT, "80");
+            final String logoX = env.getProperty(MetadataGenCommandLineArguments.MDUI_LOGO_WIDTH, "80");
+            final String logoPath = env.getProperty(MetadataGenCommandLineArguments.MDUI_LOGO_PATH, "/path/to/logo");
+            output.format("            <%s:%s height=\"%s\" width=\"%s\">https://%s%s</%s:%s>\n",
+                    SAMLConstants.SAML20MDUI_PREFIX, Logo.DEFAULT_ELEMENT_LOCAL_NAME,
+                    logoY, logoX,  getDnsName(), logoPath,
+                    SAMLConstants.SAML20MDUI_PREFIX, Logo.DEFAULT_ELEMENT_LOCAL_NAME);
+            if (mduiLangs == null) {
+                output.format("-->\n\n");
+            }
+            output.format("          </%s:%s>\n", SAMLConstants.SAML20MDUI_PREFIX, UIInfo.DEFAULT_ELEMENT_LOCAL_NAME);
+        }
+        output.format("\n        </%s>\n\n", Extensions.DEFAULT_ELEMENT_LOCAL_NAME);
+    }
+
+    /** Output Logout end points. */
+    private void outputLogoutEndpoints() {
+        output.format("        <%s Binding=\"%s\""
+                + " Location=\"https://%s/idp/profile/SAML2/Redirect/SLO\"/>\n",
+                SingleLogoutService.DEFAULT_ELEMENT_LOCAL_NAME,
+                SAMLConstants.SAML2_REDIRECT_BINDING_URI,
+                getDnsName());
+        output.format("        <%s Binding=\"%s\""
+                + " Location=\"https://%s/idp/profile/SAML2/POST/SLO\"/>\n",
+                SingleLogoutService.DEFAULT_ELEMENT_LOCAL_NAME,
+                SAMLConstants.SAML2_POST_BINDING_URI,
+                getDnsName());
+        output.format("        <%s Binding=\"%s\""
+                + " Location=\"https://%s/idp/profile/SAML2/POST/SLO-SimpleSign\"/>\n",
+                SingleLogoutService.DEFAULT_ELEMENT_LOCAL_NAME,
+                SAMLConstants.SAML2_POST_SIMPLE_SIGN_BINDING_URI,
+                getDnsName());
+
+        if (parameters.getBackchannelCert() != null && !parameters.getBackchannelCert().isEmpty()) {
+            output.format("        <%s Binding=\"%s\""
+                    + " Location=\"https://%s:8443/idp/profile/SAML2/SOAP/SLO\"/>\n",
+                    SingleLogoutService.DEFAULT_ELEMENT_LOCAL_NAME,
+                    SAMLConstants.SAML2_SOAP11_BINDING_URI,
+                    getDnsName());
+        }
+    }
+
+    /** Output Artifact Endpoints. */
+    private void outputArtifactEndpoints() {
+        if (args.isSaml1()) {
+            output.format("        <%s Binding=\"%s\""
+                    + " Location=\"https://%s:8443/idp/profile/SAML1/SOAP/ArtifactResolution\" index=\"1\"/>\n",
+                    ArtifactResolutionService.DEFAULT_ELEMENT_LOCAL_NAME,
+                    SAMLConstants.SAML1_SOAP11_BINDING_URI,
+                    getDnsName());
+        }
+        output.format("        <%s Binding=\"%s\""
+                + " Location=\"https://%s:8443/idp/profile/SAML2/SOAP/ArtifactResolution\" index=\"2\"/>\n",
+                ArtifactResolutionService.DEFAULT_ELEMENT_LOCAL_NAME,
+                SAMLConstants.SAML2_SOAP11_BINDING_URI,
+                getDnsName());
+    }
+
+    /** Output SSO Endpoints. */
+    private void outputSSOEndpoints() {
+        if (args.isSaml1()) {
+            output.format("        <%s Binding=\"%s\""
+                    + " Location=\"https://%s/idp/profile/Shibboleth/SSO\"/>\n",
+                    SingleSignOnService.DEFAULT_ELEMENT_LOCAL_NAME,
+                    "urn:mace:shibboleth:1.0:profiles:AuthnRequest",
+                    getDnsName());
+
+        }
+        output.format("        <%s Binding=\"%s\""
+                + " %s:%s=\"true\""
+                + " Location=\"https://%s/idp/profile/SAML2/POST/SSO\"/>\n",
+                SingleSignOnService.DEFAULT_ELEMENT_LOCAL_NAME,
+                SAMLConstants.SAML2_POST_BINDING_URI,
+                SAMLConstants.SAML20PREQ_ATTRR_PREFIX, RequestedAttributes.SUPPORTS_REQUESTED_ATTRIBUTES_LOCAL_NAME,
+                getDnsName());
+        output.format("        <%s Binding=\"%s\""
+                + " %s:%s=\"true\""
+                + " Location=\"https://%s/idp/profile/SAML2/POST-SimpleSign/SSO\"/>\n",
+                SingleSignOnService.DEFAULT_ELEMENT_LOCAL_NAME,
+                SAMLConstants.SAML2_POST_SIMPLE_SIGN_BINDING_URI,
+                SAMLConstants.SAML20PREQ_ATTRR_PREFIX, RequestedAttributes.SUPPORTS_REQUESTED_ATTRIBUTES_LOCAL_NAME,
+                getDnsName());
+        output.format("        <%s Binding=\"%s\""
+                + " %s:%s=\"true\""
+                + " Location=\"https://%s/idp/profile/SAML2/Redirect/SSO\"/>\n",
+                SingleSignOnService.DEFAULT_ELEMENT_LOCAL_NAME,
+                SAMLConstants.SAML2_REDIRECT_BINDING_URI,
+                SAMLConstants.SAML20PREQ_ATTRR_PREFIX, RequestedAttributes.SUPPORTS_REQUESTED_ATTRIBUTES_LOCAL_NAME,
+                getDnsName());
+    }
+
+    /**
+     * Write the <IDPSSODescriptor>.
+     */
+    private void outputIDPSSO() {
+        final List<String> protocols = new ArrayList<>(4);
+        if (!args.isSaml1() && !args.isSaml2()) {
+            return;
+        }
+        if (args.isSaml1()) {
+            protocols.add(SAMLConstants.SAML20P_NS);
+        }
+        if (args.isSaml2()) {
+            protocols.add(SAMLConstants.SAML20P_NS);
+            protocols.add(SAMLConstants.SAML11P_NS);
+            protocols.add("urn:mace:shibboleth:1.0");
+        }
+        output.format("    <%s protocolSupportEnumeration=\"%s\">\n",
+                IDPSSODescriptor.DEFAULT_ELEMENT_LOCAL_NAME,
+                String.join(" ", protocols));
+
+        outputExtensions(true);
+
+        outputKeyDescriptors(true);
+
+        if (args.isArtifact()) {
+            outputArtifactEndpoints();
+        }
+
+        if (args.isLogout()) {
+            outputLogoutEndpoints();
+        }
+
+        outputSSOEndpoints();
+
+        output.format("    </%s>\n", IDPSSODescriptor.DEFAULT_ELEMENT_LOCAL_NAME);
+    }
+
+    /**
+     * Write the <AttributeAuthorityDescriptor>.*/
+    private void outputAtttributeAuthorityDescriptor() {
+        final List<String> protocols;
+
+        if (args.isSaml1()) {
+            if (args.isAttributeFetch()) {
+                // Both
+                protocols = Arrays.asList(SAMLConstants.SAML20P_NS, SAMLConstants.SAML11P_NS);
+            } else {
+                // SAML1 only
+                protocols = Collections.singletonList(SAMLConstants.SAML11P_NS);
+            }
+        } else if (args.isAttributeFetch()) {
+            // SAML2 only
+            protocols = Collections.singletonList(SAMLConstants.SAML20P_NS);
+        } else {
+            // Neither
+            return;
+        }
+
+        output.format("    <%s protocolSupportEnumeration=\"%s\">\n",
+                AttributeAuthorityDescriptor.DEFAULT_ELEMENT_LOCAL_NAME,
+                String.join(" ", protocols));
+
+        outputExtensions(false);
+        outputKeyDescriptors(true);
+        if (args.isSaml1()) {
+            output.format("        <%s Binding=\"%s\""
+                    + " Location=\"https://%s:8443/idp/profile/SAML1/SOAP/AttributeQuery\"/>\n",
+                    AttributeService.DEFAULT_ELEMENT_LOCAL_NAME,
+                    SAMLConstants.SAML1_SOAP11_BINDING_URI,
+                    getDnsName());
+        }
+        if (args.isAttributeFetch()) {
+            output.format("        <%s Binding=\"%s\""
+                    + " Location=\"https://%s:8443/idp/profile/SAML2/SOAP/AttributeQuery\"/>\n",
+                    AttributeService.DEFAULT_ELEMENT_LOCAL_NAME,
+                    SAMLConstants.SAML2_SOAP11_BINDING_URI,
+                    getDnsName());
+        }
+        output.format("    </%s>\n", AttributeAuthorityDescriptor.DEFAULT_ELEMENT_LOCAL_NAME);
+    }
+
+    /**
+     * Write the <SPSSODescriptor>.
+     */
+    private void outputSPSSO() {
+        if (!args.isSamlSP()) {
+            return;
+        }
+        output.format("    <%s protocolSupportEnumeration=\"%s\">\n",
+                SPSSODescriptor.DEFAULT_ELEMENT_LOCAL_NAME,
+                SAMLConstants.SAML20P_NS);
+
+        outputKeyDescriptors(false);
+
+        output.format("        <%s Binding=\"%s\""
+                + " Location=\"https://%s/idp/profile/Authn/SAML2/POST/SSO\" index=\"0\"/>\n",
+                AssertionConsumerService.DEFAULT_ELEMENT_LOCAL_NAME,
+                SAMLConstants.SAML2_POST_BINDING_URI,
+                getDnsName());
+
+        output.format("    </%s>\n", SPSSODescriptor.DEFAULT_ELEMENT_LOCAL_NAME);
+    }
+
+
+    /** Output the metadata.
+     * @return true iff this worked.
+     */
+    private int outputMetadata() {
+        output.format("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+        output.format("   <!--\n");
+        output.format("     This is example metadata only. Do *NOT* supply it as is without review,\n");
+        output.format("     and do *NOT* provide it in real time to your partners.\n");
+        output.format("     This metadata is not dynamic - run metadatagen again to recreate.\n");
+        output.format("     Created: %s\n   -->\n", Instant.now().toString());
+        output.format("<%s  xmlns=\"%s\" xmlns:%s=\"%s\"\n", EntityDescriptor.DEFAULT_ELEMENT_LOCAL_NAME,
+                SAMLConstants.SAML20MD_NS,
+                SignatureConstants.XMLSIG_PREFIX, SignatureConstants.XMLSIG_NS);
+        output.format("      xmlns:%s=\"%s\" xmlns:%s=\"%s\"\n",
+                ExtensionsConstants.SHIB_MDEXT10_PREFIX, ExtensionsConstants.SHIB_MDEXT10_NS,
+                XMLConstants.XML_PREFIX, XMLConstants.XML_NS);
+        output.format("      xmlns:%s=\"%s\" xmlns:%s=\"%s\"\n",
+                SAMLConstants.SAML20MDUI_PREFIX, SAMLConstants.SAML20MDUI_NS,
+                SAMLConstants.SAML20PREQ_ATTRR_PREFIX, SAMLConstants.SAML20PREQ_ATTR_NS);
+        output.format(" validUntil=\"%s\" entityID=\"%s\">\n\n",
+                DOMTypeSupport.instantToString(Instant.now()), 
+                getApplicationContext().getEnvironment().getProperty("idp.entityID", "idp.example.org"));
+        outputIDPSSO();
+        outputAtttributeAuthorityDescriptor();
+        outputSPSSO();
+        output.format("</EntityDescriptor>\n");
+        output.flush();
+        output.close();
+        return RC_OK;
+    }
+    
+    /** Lookup the dns name with a default and cache it.
+     *  @return the dns name
+     */
+    @Nonnull String getDnsName() {
+        if (dnsName == null) {
+            dnsName = getApplicationContext().
+                    getEnvironment().
+                    getProperty(MetadataGenCommandLineArguments.DNS_NAME_PROPERTY, "idp.example.org");
+        }
+        return dnsName;
+    }
+
+    /** Build the {@link MetadataGenCLI#parameters} object.
+     * @return true iff this worked and if everything needed was there.
+     */
+    // Checkstyle: CyclomaticComplexity OFF
+    private boolean populateParameters() {
+        try {
+            parameters = getApplicationContext().getBean(MetadataGenParameters.class);
+        } catch (final NoSuchBeanDefinitionException e) {
+            getLogger().error("Could not locate IdPConfiguration");
+            return false;
+        }
+        final boolean hasBackChannel = parameters.getBackchannelCert() != null 
+                && !parameters.getBackchannelCert().isEmpty();
+        boolean worked = true;
+        if (args.isArtifact() && !hasBackChannel) {
+            getLogger().error("Must specify --backChannel <path> if +artifact speificied");
+            worked = false;
+        }
+        if (args.isAttributeFetch() && !hasBackChannel) {
+            getLogger().error("Must specify --backChannel <path> if +attributeFetch speificied");
+            worked = false;
+        }
+        if (hasBackChannel && !args.isAttributeFetch() && !args.isArtifact()  && !args.isSaml1()) {
+            getLogger().error("--backChannel <path> requires +artifact and/or +attributeFetch and/or +saml1");
+            worked = false;
+        }
+        return worked;
+    }
+    // Checkstyle: CyclomaticComplexity ON
+
+
+    /** Set up {@link MetadataGenCLI#output}.
+     * @return true iff this worked.
+     */
+    private boolean setupWriter() {
+        if (args.getOutput() == null) {
+            output = System.console().writer();
+        } 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;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected int doRun(@Nonnull final MetadataGenCommandLineArguments arguments) {
+
+        args = arguments;
+        final int ret = super.doRun(args);
+        if (ret != RC_OK) {
+            return ret;
+        }
+        if (!setupWriter()) {
+            return RC_IO;
+        }
+        if (!populateParameters()) {
+            return RC_IO;
+        }
+        final int i = outputMetadata();
+        this.output.close();
+        return i;
+    }
+
+    /** 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 MetadataGenCLI cli = new MetadataGenCLI();
+
+       return cli.run(args);
+   }
+
+   /**
+    * CLI entry point.
+    * @param args arguments
+    */
+   public static void main(@Nonnull final String[] args) {
+	   final String version = Version.getVersion();
+	   final String badVersion="4.2";
+	   if (version != null && version.startsWith(badVersion)) {
+		   System.console().format("Not compatible with version %s, uninstall and run non beta version", version);
+		   System.exit(RC_INIT);
+	   }
+       System.exit(runMain(args));
+   }
+}
diff --git a/metadatagen-impl/src/main/java/net/shibboleth/idp/plugin/metadatagen/impl/MetadataGenCommandLineArguments.java b/metadatagen-impl/src/main/java/net/shibboleth/idp/plugin/metadatagen/impl/MetadataGenCommandLineArguments.java
new file mode 100644
index 0000000..f695529
--- /dev/null
+++ b/metadatagen-impl/src/main/java/net/shibboleth/idp/plugin/metadatagen/impl/MetadataGenCommandLineArguments.java
@@ -0,0 +1,236 @@
+/*
+ * 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.idp.plugin.metadatagen.impl;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Properties;
+
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.beust.jcommander.Parameter;
+
+import net.shibboleth.idp.cli.AbstractIdPHomeAwareCommandLineArguments;
+
+/**
+ * Command line arguments for Metadata Generation.
+ */
+public class MetadataGenCommandLineArguments extends AbstractIdPHomeAwareCommandLineArguments {
+    
+    /** Property name for the back channel certificate. */
+    public static final String BACKCHANNEL_PROPERTY = "idp.metadata.backchannel.cert";
+    
+    /** Property name for the back channel certificate. */
+    public static final String DNS_NAME_PROPERTY = "idp.metadata.dnsname";
+
+    /** Property name for the MDUI languages. */
+    public static final String MDUI_LANGS_PROPERTY = "idp.metadata.idpsso.mdui.langs";
+
+    /** Property prefix for DisplayName. */
+    public static final String MDUI_DISPLAY_NAME_PREFIX = "idp.metadata.idpsso.mdui.displayname.";
+
+    /** Property prefix for Description. */
+    public static final String MDUI_DESCRIPTION_PREFIX = "idp.metadata.idpsso.mdui.description.";
+
+    /** Property for logo y. */
+    public static final String MDUI_LOGO_HEIGHT = "idp.metadata.idpsso.mdui.logo.height";
+
+    /** Property for logo x. */
+    public static final String MDUI_LOGO_WIDTH = "idp.metadata.idpsso.mdui.logo.width";
+
+    /** Property for logo path. */
+    public static final String MDUI_LOGO_PATH = "idp.metadata.idpsso.mdui.logo.path";
+
+    /** Logger. */
+    private Logger log;
+
+    /** Do we output SAML2. */
+    @Parameter(names = { "+saml2", "+2", "+SAML2"} )
+    @Nullable private boolean saml2;
+
+    /** Do we NOT output SAML2. */
+    @Parameter(names = { "-saml2", "-2", "-SAML2"} )
+    @Nullable private boolean noSaml2;
+
+    /** Do we output SAM1.?*/
+    @Parameter(names = { "+saml1", "+1", "+SAML1"})
+    @Nullable private boolean saml1;
+
+    /** Do we output for an SP.*/
+    @Parameter(names = { "+samlSP", "+sp", "+SP", "+SAMLSP"})
+    @Nullable private boolean samlSP;
+
+    /** Do we output logout.*/
+    @Parameter(names = { "+logout", "+lo"})
+    @Nullable private boolean logout;
+
+    /** Do we output Artifact.*/
+    @Parameter(names = { "+artifact", "+artefact"})
+    @Nullable private boolean artifact;
+
+    /** Do we output for an Attribute Fetch.*/
+    @Parameter(names = { "+attributeFetch"})
+    @Nullable private boolean attributeFetch;
+
+    /** Certificate for (IdP) BackChannel (attribute, artifact, logout).*/
+    @Parameter(names = { "--backChannel", "-bc"})
+    @Nullable private String backChannelPath;
+
+    /** DNS name (for back channel addresses). */
+    @Parameter(names = { "--DNSName", "-d"})
+    @Nullable private String dnsName;
+
+    /** Output.*/
+    @Parameter(names = { "--output", "-o"})
+    @Nullable private String output;
+
+    /** Do we output SAML2 metadata?
+     * @return what.
+     */
+    public boolean isSaml2() {
+        return saml2;
+    }
+
+    /** Do we output SAML1 metadata?
+     * @return what.
+     */
+    public boolean isSaml1() {
+        return saml1;
+    }
+
+    /** Do we output SAML SP metadata.
+     * @return what.
+     */
+    public boolean isSamlSP() {
+        return samlSP;
+    }
+
+    /** Do we output Logout metadata?
+     * @return what.
+     */
+    public boolean isLogout() {
+        return logout;
+    }
+
+    /** Do we output Artifact metadata?
+     * @return what.
+     */
+    public boolean isArtifact() {
+        return artifact;
+    }
+
+    /** Do we output Attribute Fetch metadata?
+     * @return what.
+     */
+    public boolean isAttributeFetch() {
+        return attributeFetch;
+    }
+
+    /** Where to put the data.
+     * @return where
+     */
+    @Nullable public String getOutput() {
+        return output;
+    }
+
+    /** {@inheritDoc}
+     * We override this to add a property file of our own making for
+     * the backchannel (if needed) and dnsname.
+     * */
+    public List<String> getPropertyFiles() {
+        final List<String> fromCmdline = super.getPropertyFiles();
+        if (dnsName == null && backChannelPath == null) {
+            return fromCmdline;
+        }
+
+        final Properties props = new Properties(2);
+        if (dnsName != null) {
+            props.setProperty(DNS_NAME_PROPERTY, dnsName);
+        }
+        if (backChannelPath != null) {
+            props.setProperty(BACKCHANNEL_PROPERTY, backChannelPath);
+        }
+        
+        File file = null;
+        try {
+            file = File.createTempFile("MetadataGen", ".properties");
+            file.deleteOnExit();
+            try (final FileOutputStream out = new FileOutputStream(file)) {
+                props.store(out, "created");
+            }
+        } catch (final IOException e) {
+            getLog().error("Could not generate property file", e);
+        }
+        if (fromCmdline.isEmpty()) {
+            return Collections.singletonList(file.getAbsolutePath());
+        }
+        final List<String> result = new ArrayList<>(fromCmdline.size() + 1);
+        result.addAll(fromCmdline);
+        result.add(file.getAbsolutePath());
+        return result;
+    }
+
+    @Override
+    public synchronized Logger getLog() {
+        if (log == null) {
+            log = LoggerFactory.getLogger(MetadataGenCommandLineArguments.class);
+        }
+        return log;
+    }
+
+    @Override
+    public void validate() throws IllegalArgumentException {
+        if (!saml2 && noSaml2) {
+            saml2 = false;
+        } else {
+            saml2 = true;
+        }
+    }
+    // Checkstyle: CyclomaticComplcity ON
+
+    @Override
+    public void printHelp(final PrintStream out) {
+        super.printHelp(out);
+        out.println(String.format("  %-20s %s", "+SAML1, +1",
+                                  "Output SAML1 Metadata."));
+        out.println(String.format("  %-20s %s", "-SAML2, -2",
+                                  "do NOT Output SAML2 Metadata."));
+        out.println(String.format("  %-20s %s", "+SP, +SAMLSP",
+                                  "Output SAML2 SP Metadata."));
+        out.println(String.format("  %-20s %s", "+logout",
+                                  "Output Logout Metadata."));
+        out.println(String.format("  %-20s %s", "+artifact",
+                                  "Output SAML artifact Metadata (requires -bc),"));
+        out.println(String.format("  %-20s %s", "+attributeFetch",
+                                  "Output SAML attributeFetch Metadata  (requires -bc)."));
+        out.println(String.format("  %-20s %s", "-bc, --backchannel <Path>",
+                                  "Path to backchannel certificate"));
+        out.println(String.format("  %-20s %s", "-d, --DNSName name",
+                                  "DNS name to use in back channel addresses (default idp.example.org)"));
+        out.println(String.format("  %-20s %s", "--output, -o",
+                                  "Output location."));
+        out.println();
+    }
+}
diff --git a/metadatagen-impl/src/main/java/net/shibboleth/idp/plugin/metadatagen/impl/MetadataGenModule.java b/metadatagen-impl/src/main/java/net/shibboleth/idp/plugin/metadatagen/impl/MetadataGenModule.java
new file mode 100644
index 0000000..e1bfcab
--- /dev/null
+++ b/metadatagen-impl/src/main/java/net/shibboleth/idp/plugin/metadatagen/impl/MetadataGenModule.java
@@ -0,0 +1,42 @@
+/*
+ * 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.idp.plugin.metadatagen.impl;
+
+import java.io.IOException;
+
+import net.shibboleth.idp.module.ModuleException;
+import net.shibboleth.idp.module.impl.PluginIdPModule;
+
+
+/**
+ * {@link net.shibboleth.idp.module.IdPModule IdP Module} implementation.
+ */
+public class MetadataGenModule extends PluginIdPModule{
+    
+    /**
+     * Constructor.
+     *  
+     * @throws ModuleException on error
+     * @throws IOException on error
+     */
+    public MetadataGenModule() throws IOException, ModuleException {
+        super(MetadataGenModule.class);
+    }
+    
+
+}
\ No newline at end of file
diff --git a/metadatagen-impl/src/main/java/net/shibboleth/idp/plugin/metadatagen/impl/MetadataGenParameters.java b/metadatagen-impl/src/main/java/net/shibboleth/idp/plugin/metadatagen/impl/MetadataGenParameters.java
new file mode 100644
index 0000000..642e48e
--- /dev/null
+++ b/metadatagen-impl/src/main/java/net/shibboleth/idp/plugin/metadatagen/impl/MetadataGenParameters.java
@@ -0,0 +1,193 @@
+/*
+ * 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.idp.plugin.metadatagen.impl;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.annotation.Nullable;
+
+import org.springframework.core.io.Resource;
+
+import net.shibboleth.utilities.java.support.component.AbstractInitializableComponent;
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
+
+/**
+ * A simple bean for processing certificates in an easy to digest manner.
+ */
+public class MetadataGenParameters extends AbstractInitializableComponent {
+
+    /**
+     * The file with the certificate the IDP uses to encrypt.
+     */
+    private File encryptionCert;
+
+    /**
+     * The strings with the encryption cert in them (to allow for multiline output).
+     */
+    private List<String> encryptionCerts;
+
+    /**
+     * The file with the certificate that TLS uses to 'sign'.
+     */
+    @Nullable private File backChannelCert;
+
+    /**
+     * The strings with the back channel cert in them (to allow for multiline output).
+     */
+    private List<String> backChannelCerts;
+
+    /**
+     * The file with the certificate the IDP uses to sign.
+     */
+    private File signingCert;
+
+    /**
+     * The strings with the signing certs in them (to allow for multiline output).
+     */
+    private List<String> signingCerts;
+
+    /** {@inheritDoc} */
+    protected void doInitialize() throws ComponentInitializationException {
+        try {
+            encryptionCerts = getCertificateContents(encryptionCert);
+            signingCerts = getCertificateContents(signingCert);
+            backChannelCerts = getCertificateContents(backChannelCert);
+        } catch (final IOException e) {
+            throw new ComponentInitializationException(e);
+        }
+    }
+
+    /**
+     * Get the (mutli-line) string representations of the encryption certs.
+     *
+     * @return Returns the encryption cert or null if none available.
+     */
+    @Nullable public List<String> getEncryptionCert() {
+        return encryptionCerts;
+    }
+
+    /**
+     * Set the encryption Certificate file.
+     *
+     * @param resource what to set.
+     */
+    public void setEncryptionCertResource(final Resource resource) {
+
+        try {
+            encryptionCert = resource.getFile();
+        } catch (final IOException e) {
+            encryptionCert = null;
+        }
+    }
+
+    /**
+     * Get the (mutli-line) string representation of the signing cert.
+     *
+     * @return Returns the signing cert or null if none available.
+     */
+    @Nullable public List<String> getSigningCert() {
+        return signingCerts;
+    }
+
+    /**
+     * Set the signing Certificate file.
+     *
+     * @param resource what to set.
+     */
+    public void setSigningCertResource(final Resource resource) {
+        try {
+            signingCert = resource.getFile();
+        } catch (final IOException e) {
+            signingCert = null;
+        }
+    }
+
+    /**
+     * Get the (mutli-line)string representation of the back channel cert.
+     *
+     * @return Returns the back channel cert or null if non available.
+     */
+    @Nullable public List<String> getBackchannelCert() {
+        return backChannelCerts;
+    }
+
+    /**
+     * Set the Backchannel Certificate file.
+     *
+     * @param file what to set.
+     */
+    public void setBackchannelCert(final File file) {
+        backChannelCert = file;
+    }
+    
+    /**
+     * Set the Backchannel Certificate.
+     *
+     * @param resource what to set.
+     */
+    public void setBackchannelCertResource(@Nullable final Resource resource) {
+        if (resource == null) {
+           backChannelCert = null;
+        } else {
+            try {
+                backChannelCert = resource.getFile();
+            } catch (final IOException e) {
+                backChannelCert = null;
+            }
+        }
+    }
+
+    /**
+     * Open the file and return the contents and a list of lines.
+     *
+     * @param file the file
+     * @return the contents
+     * @throws IOException if we have issues with reading an existing file.
+     */
+    private List<String> getCertificateContents(@Nullable final File file) throws IOException {
+        if (null == file || !file.exists()) {
+            return null;
+        }
+
+        try (final FileReader fr = new FileReader(file);
+                final BufferedReader reader = new BufferedReader(fr)) {
+            final List<String> output = new ArrayList<>();
+            String s = reader.readLine();
+            while (s != null) {
+                output.add(s);
+                s = reader.readLine();
+            }
+            if ((output.size() > 0) && output.get(0).startsWith("----")) {
+                output.remove(0);
+            }
+            final int last = output.size() - 1;
+            if (last <= 0) {
+                return null;
+            }
+            if (output.get(last).startsWith("----")) {
+                output.remove(last);
+            }
+            return output;
+        }
+    }
+}
diff --git a/metadatagen-impl/src/main/java/net/shibboleth/idp/plugin/metadatagen/MetadataGenPlugin.java b/metadatagen-impl/src/main/java/net/shibboleth/idp/plugin/metadatagen/impl/MetadataGenPlugin.java
similarity index 53%
rename from metadatagen-impl/src/main/java/net/shibboleth/idp/plugin/metadatagen/MetadataGenPlugin.java
rename to metadatagen-impl/src/main/java/net/shibboleth/idp/plugin/metadatagen/impl/MetadataGenPlugin.java
index d05f8e2..ec0728f 100644
--- a/metadatagen-impl/src/main/java/net/shibboleth/idp/plugin/metadatagen/MetadataGenPlugin.java
+++ b/metadatagen-impl/src/main/java/net/shibboleth/idp/plugin/metadatagen/impl/MetadataGenPlugin.java
@@ -1,4 +1,21 @@
-package net.shibboleth.idp.plugin.metadatagen;
+/*
+ * 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.idp.plugin.metadatagen.impl;
 
 import java.io.IOException;
 import java.util.Collections;
diff --git a/metadatagen-impl/src/main/java/net/shibboleth/idp/plugin/metadatagen/impl/package-info.java b/metadatagen-impl/src/main/java/net/shibboleth/idp/plugin/metadatagen/impl/package-info.java
new file mode 100644
index 0000000..8d39207
--- /dev/null
+++ b/metadatagen-impl/src/main/java/net/shibboleth/idp/plugin/metadatagen/impl/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * 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 to contain classes to do with the metadata generation command line.
+ */
+
+package net.shibboleth.idp.plugin.metadatagen.impl;
diff --git a/metadatagen-impl/src/main/resources/net/shibboleth/idp/plugin/metadatagen/bin/metadatagen-beta.bat b/metadatagen-impl/src/main/resources/net/shibboleth/idp/plugin/metadatagen/bin/metadatagen-beta.bat
new file mode 100644
index 0000000..0412d11
--- /dev/null
+++ b/metadatagen-impl/src/main/resources/net/shibboleth/idp/plugin/metadatagen/bin/metadatagen-beta.bat
@@ -0,0 +1,4 @@
+ at echo off
+setlocal
+
+"%~dp0\runclass.bat" net.shibboleth.idp.plugin.metadatagen.impl.MetadataGenCLI --home "%~dp0\.." %*
diff --git a/metadatagen-impl/src/main/resources/net/shibboleth/idp/plugin/metadatagen/bin/metadatagen-beta.sh b/metadatagen-impl/src/main/resources/net/shibboleth/idp/plugin/metadatagen/bin/metadatagen-beta.sh
new file mode 100644
index 0000000..c718eab
--- /dev/null
+++ b/metadatagen-impl/src/main/resources/net/shibboleth/idp/plugin/metadatagen/bin/metadatagen-beta.sh
@@ -0,0 +1,7 @@
+#!/usr/bin/env bash
+
+declare LOCATION
+
+LOCATION=$(dirname $0)
+
+$LOCATION/runclass.sh net.shibboleth.idp.plugin.metadatagen.impl.MetadataGenCLI --ansi --home "$LOCATION/.." "$@"
diff --git a/metadatagen-impl/src/main/resources/net/shibboleth/idp/plugin/metadatagen/metadatagen.xml b/metadatagen-impl/src/main/resources/net/shibboleth/idp/plugin/metadatagen/metadatagen.xml
new file mode 100644
index 0000000..98ad360
--- /dev/null
+++ b/metadatagen-impl/src/main/resources/net/shibboleth/idp/plugin/metadatagen/metadatagen.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+	xmlns:context="http://www.springframework.org/schema/context"
+	xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p"
+	xmlns:c="http://www.springframework.org/schema/c" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
+                           http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
+    default-init-method="initialize"
+    default-destroy-method="destroy">
+
+	<bean
+		class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer"
+		p:placeholderPrefix="%{" p:placeholderSuffix="}" />
+
+    <context:property-placeholder />
+
+	<bean id="IdPConfiguration"
+		class="net.shibboleth.idp.plugin.metadatagen.impl.MetadataGenParameters"
+		p:encryptionCertResource="%{idp.encryption.cert}"
+        p:signingCertResource="%{idp.signing.cert}"
+        p:backchannelCertResource="#{ environment.containsProperty('idp.metadata.backchannel.cert')  ? '%{idp.metadata.backchannel.cert:0}' : null}" />
+</beans>
\ No newline at end of file
diff --git a/metadatagen-impl/src/main/resources/net/shibboleth/idp/plugin/metadatagen/module.properties b/metadatagen-impl/src/main/resources/net/shibboleth/idp/plugin/metadatagen/module.properties
index 79138db..4c17768 100644
--- a/metadatagen-impl/src/main/resources/net/shibboleth/idp/plugin/metadatagen/module.properties
+++ b/metadatagen-impl/src/main/resources/net/shibboleth/idp/plugin/metadatagen/module.properties
@@ -9,9 +9,9 @@ idp.metadatagen.plugin = net.shibboleth.idp.plugin.metadatagen
 idp.metadatagen.name = Metadata Generator (Beta)
 idp.metadatagen.desc = A test Metadata Generator
 idp.metadatagen.url = /Metadatagen
-idp.metadatagen.1.src = /net/shibboleth/idp/plugin/metadatatgen/bin/metadatagen.sh
-idp.metadatagen.1.dest = bin/metadatagen.sh
+idp.metadatagen.1.src = /net/shibboleth/idp/plugin/metadatagen/bin/metadatagen-beta.sh
+idp.metadatagen.1.dest = bin/metadatagen-beta.sh
 idp.metadatagen.1.replace = true
-idp.metadatagen.2.src = /net/shibboleth/idp/plugin/metadatatgen/bin/metadatagen.bat
-idp.metadatagen.2.dest = bin/metadatagen.bat
+idp.metadatagen.2.src = /net/shibboleth/idp/plugin/metadatagen/bin/metadatagen-beta.bat
+idp.metadatagen.2.dest = bin/metadatagen-beta.bat
 idp.metadatagen.2.replace = true
diff --git a/metadatagen-impl/src/main/resources/net/shibboleth/idp/plugin/metadatatgen/bin/metadatagen.bat b/metadatagen-impl/src/main/resources/net/shibboleth/idp/plugin/metadatatgen/bin/metadatagen.bat
deleted file mode 100644
index 79b7299..0000000
--- a/metadatagen-impl/src/main/resources/net/shibboleth/idp/plugin/metadatatgen/bin/metadatagen.bat
+++ /dev/null
@@ -1,4 +0,0 @@
- at echo off
-setlocal
-
-"%~dp0\runclass.bat" net.shibboleth.idp.plugin.metadatagen.MetadataGen --home "%~dp0\.." %*
diff --git a/metadatagen-impl/src/main/resources/net/shibboleth/idp/plugin/metadatatgen/bin/metadatagen.sh b/metadatagen-impl/src/main/resources/net/shibboleth/idp/plugin/metadatatgen/bin/metadatagen.sh
deleted file mode 100644
index fc4268d..0000000
--- a/metadatagen-impl/src/main/resources/net/shibboleth/idp/plugin/metadatatgen/bin/metadatagen.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/usr/bin/env bash
-
-declare LOCATION
-
-LOCATION=$(dirname $0)
-
-$LOCATION/runclass.sh net.shibboleth.idp.module.impl.ModuleManagerCLI --ansi --home "$LOCATION/.." "$@"
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index b25834d..d5a074e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
   <parent>
     <groupId>net.shibboleth</groupId>
     <artifactId>parent</artifactId>
-    <version>11.2.0</version>
+    <version>11.2.1</version>
   </parent>
   <groupId>net.shibboleth.idp.plugin.metadatagen</groupId>
   <artifactId>idp-plugin-metadatagen-parent</artifactId>
@@ -14,7 +14,7 @@
   <description>metadatagen plugin for the Shibboleth IdP.</description>
   <properties>
     <idp.groupId>net.shibboleth.idp</idp.groupId>
-    <idp.version>4.1.0</idp.version>
+    <idp.version>4.1.2</idp.version>
     <opensaml.groupId>org.opensaml</opensaml.groupId>
     <opensaml.version>4.1.0</opensaml.version>
     <checkstyle.configLocation>${project.basedir}/checkstyle.xml</checkstyle.configLocation>

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


More information about the commits mailing list