summaryrefslogtreecommitdiff
path: root/mellon_create_metadata.sh
diff options
context:
space:
mode:
Diffstat (limited to 'mellon_create_metadata.sh')
-rw-r--r--mellon_create_metadata.sh126
1 files changed, 126 insertions, 0 deletions
diff --git a/mellon_create_metadata.sh b/mellon_create_metadata.sh
new file mode 100644
index 0000000..9c587a6
--- /dev/null
+++ b/mellon_create_metadata.sh
@@ -0,0 +1,126 @@
+#!/usr/bin/env bash
+set -e
+
+PROG="$(basename "$0")"
+
+printUsage() {
+ echo "Usage: $PROG ENTITY-ID ENDPOINT-URL"
+ echo ""
+ echo "Example:"
+ echo " $PROG urn:someservice https://sp.example.org/mellon"
+ echo ""
+}
+
+if [ "$#" -lt 2 ]; then
+ printUsage
+ exit 1
+fi
+
+ENTITYID="$1"
+if [ -z "$ENTITYID" ]; then
+ echo "$PROG: An entity ID is required." >&2
+ exit 1
+fi
+
+BASEURL="$2"
+if [ -z "$BASEURL" ]; then
+ echo "$PROG: The URL to the MellonEndpointPath is required." >&2
+ exit 1
+fi
+
+if ! echo "$BASEURL" | grep -q '^https\?://'; then
+ echo "$PROG: The URL must start with \"http://\" or \"https://\"." >&2
+ exit 1
+fi
+
+HOST="$(echo "$BASEURL" | sed 's#^[a-z]*://\([^/]*\).*#\1#')"
+BASEURL="$(echo "$BASEURL" | sed 's#/$##')"
+
+OUTFILE="$(echo "$ENTITYID" | sed 's/[^0-9A-Za-z.]/_/g' | sed 's/__*/_/g')"
+echo "Output files:"
+echo "Private key: $OUTFILE.key"
+echo "Certificate: $OUTFILE.cert"
+echo "Metadata: $OUTFILE.xml"
+echo "Host: $HOST"
+echo
+echo "Endpoints:"
+echo "SingleLogoutService (SOAP): $BASEURL/logout"
+echo "SingleLogoutService (HTTP-Redirect): $BASEURL/logout"
+echo "AssertionConsumerService (HTTP-POST): $BASEURL/postResponse"
+echo "AssertionConsumerService (HTTP-Artifact): $BASEURL/artifactResponse"
+echo "AssertionConsumerService (PAOS): $BASEURL/paosResponse"
+echo
+
+# No files should not be readable by the rest of the world.
+umask 0077
+
+TEMPLATEFILE="$(mktemp -t mellon_create_sp.XXXXXXXXXX)"
+
+cat >"$TEMPLATEFILE" <<EOF
+RANDFILE = /dev/urandom
+[req]
+default_bits = 2048
+default_keyfile = privkey.pem
+distinguished_name = req_distinguished_name
+prompt = no
+policy = policy_anything
+[req_distinguished_name]
+commonName = $HOST
+EOF
+
+openssl req -utf8 -batch -config "$TEMPLATEFILE" -new -x509 -days 3652 -nodes -out "$OUTFILE.cert" -keyout "$OUTFILE.key" 2>/dev/null
+
+rm -f "$TEMPLATEFILE"
+
+CERT="$(grep -v '^-----' "$OUTFILE.cert")"
+
+cat >"$OUTFILE.xml" <<EOF
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<EntityDescriptor
+ entityID="$ENTITYID"
+ xmlns="urn:oasis:names:tc:SAML:2.0:metadata">
+ <SPSSODescriptor
+ AuthnRequestsSigned="true"
+ WantAssertionsSigned="true"
+ protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
+ <KeyDescriptor use="signing">
+ <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+ <ds:X509Data>
+ <ds:X509Certificate>$CERT</ds:X509Certificate>
+ </ds:X509Data>
+ </ds:KeyInfo>
+ </KeyDescriptor>
+ <KeyDescriptor use="encryption">
+ <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+ <ds:X509Data>
+ <ds:X509Certificate>$CERT</ds:X509Certificate>
+ </ds:X509Data>
+ </ds:KeyInfo>
+ </KeyDescriptor>
+ <SingleLogoutService
+ Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
+ Location="$BASEURL/logout" />
+ <SingleLogoutService
+ Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
+ Location="$BASEURL/logout" />
+ <NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
+ <AssertionConsumerService
+ index="0"
+ isDefault="true"
+ Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
+ Location="$BASEURL/postResponse" />
+ <AssertionConsumerService
+ index="1"
+ Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"
+ Location="$BASEURL/artifactResponse" />
+ <AssertionConsumerService
+ index="2"
+ Binding="urn:oasis:names:tc:SAML:2.0:bindings:PAOS"
+ Location="$BASEURL/paosResponse" />
+ </SPSSODescriptor>
+</EntityDescriptor>
+EOF
+
+umask 0777
+chmod go+r "$OUTFILE.xml"
+chmod go+r "$OUTFILE.cert"