Use shibboleth-sp as package name for compatibility.
[shibboleth/cpp-sp.git] / configs / metagen.sh
old mode 100644 (file)
new mode 100755 (executable)
index 1a1e62f..d616b1f
-#! /bin/sh
+#!/usr/bin/env bash
 
-while getopts a:c:e:h:n:o:s:t: c
+DECLS=1
+
+SAML1=0
+SAML2=0
+ARTIFACT=0
+DS=0
+LOGOUT=0
+NAMEIDMGMT=0
+
+SAML10PROT="urn:oasis:names:tc:SAML:1.0:protocol"
+SAML11PROT="urn:oasis:names:tc:SAML:1.1:protocol"
+SAML20PROT="urn:oasis:names:tc:SAML:2.0:protocol"
+
+SAML20SOAP="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
+SAML20REDIRECT="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
+SAML20POST="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
+SAML20POSTSS="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign"
+SAML20ART="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"
+SAML20PAOS="urn:oasis:names:tc:SAML:2.0:bindings:PAOS"
+
+SAML1POST="urn:oasis:names:tc:SAML:1.0:profiles:browser-post"
+SAML1ART="urn:oasis:names:tc:SAML:1.0:profiles:artifact-01"
+
+while getopts a:c:e:f:h:l:n:o:s:t:u:12ADLNO c
      do
          case $c in
-           c)         CERT=$OPTARG;;
-           e)         ENTITYID=$OPTARG;;
-           h)         HOSTS[${#HOSTS[*]}]=$OPTARG;;
-           n)         NAKEDHOSTS[${#NAKEDHOSTS[*]}]=$OPTARG;;
-           o)         ORGNAME=$OPTARG;;
-           a)         ADMIN[${#ADMIN[*]}]=$OPTARG;;
-           s)         SUP[${#SUP[*]}]=$OPTARG;;
-           t)         TECH[${#TECH[*]}]=$OPTARG;;
-           \?)        echo metagen -c certificate -h host1 [-h host2 ...] [-e entityID]
-                      exit 1;;
+           c)   CERTS[${#CERTS[*]}]=$OPTARG;;
+           e)   ENTITYID=$OPTARG;;
+           f)   FORMATS[${#FORMATS[*]}]=$OPTARG;;
+           h)   HOSTS[${#HOSTS[*]}]=$OPTARG;;
+           l)   HOSTLIST=$OPTARG;;
+           n)   NAKEDHOSTS[${#NAKEDHOSTS[*]}]=$OPTARG;;
+           o)   ORGNAME=$OPTARG;;
+           a)   ADMIN[${#ADMIN[*]}]=$OPTARG;;
+           s)   SUP[${#SUP[*]}]=$OPTARG;;
+           t)   TECH[${#TECH[*]}]=$OPTARG;;
+           u)   URL=$OPTARG;;
+           1)   SAML1=1;;
+           2)   SAML2=1;;
+           A)   ARTIFACT=1;;
+           D)   DS=1;;
+           L)   LOGOUT=1;;
+           N)   NAMEIDMGMT=1;;
+           O)   DECLS=0;;
+           \?)  echo metagen [-12ADLNO] -c cert1 [-c cert2 ...] -h host1 [-h host2 ...] [-e entityID]
+                exit 1;;
          esac
      done
 
 if [ ${#HOSTS[*]} -eq 0 -a ${#NAKEDHOSTS[*]} -eq 0 ] ; then
-    echo metagen -c certificate -h host1 [-h host2 ...] [-e entityID]
+    echo metagen [-12ADLN] -c cert1 [-c cert2 ...] -h host1 [-h host2 ...] [-e entityID]
     exit 1
 fi
 
-if [ -z $CERT ] ; then
-    CERT=sp-cert.pem
+if [ ${#CERTS[*]} -eq 0 ] ; then
+    CERTS[${#CERTS[*]}]=sp-cert.pem
 fi
 
-if  [ ! -s $CERT ] ; then
-    echo Certificate file $CERT does not exist! 
-    exit 2
-fi
+for c in ${CERTS[@]}
+do
+    if  [ ! -s $c ] ; then
+        echo Certificate file $c does not exist! 
+        exit 2
+    fi
+done
 
 if [ -z $ENTITYID ] ; then
-    ENTITYID=https://${HOSTS[0]}/shibboleth
+    if [ ${#HOSTS[*]} -eq 0 ] ; then
+        ENTITYID=https://${NAKEDHOSTS[0]}/shibboleth
+    else
+        ENTITYID=https://${HOSTS[0]}/shibboleth
+    fi
+fi
+
+if [ ! -z $HOSTLIST ] ; then
+    if [ -s $HOSTLIST ] ; then
+        while read h
+        do
+            HOSTS[${#HOSTS[@]}]=$h
+        done <$HOSTLIST
+    else
+        echo File with list of hostnames $l does not exist! 
+        exit 2
+    fi
+fi
+
+# Establish protocols and bindings.
+
+if [ $SAML1 -eq 0 -a $SAML2 -eq 0 ] ; then
+    SAML1=1
+    SAML2=1
+fi
+
+if [ $LOGOUT -eq 1 -o $NAMEIDMGMT -eq 1 ] ; then
+    SAML2=1
+    SLO[${#SLO[*]}]=$SAML20SOAP
+    SLO[${#SLO[*]}]=$SAML20REDIRECT
+    SLO[${#SLO[*]}]=$SAML20POST
+    SLOLOC[${#SLOLOC[*]}]="SOAP"
+    SLOLOC[${#SLOLOC[*]}]="Redirect"
+    SLOLOC[${#SLOLOC[*]}]="POST"
+    if [ $ARTIFACT -eq 1 ] ; then
+        SLO[${#SLO[*]}]=$SAML20ART
+        SLOLOC[${#SLOLOC[*]}]="Artifact"
+    fi
+fi
+
+if [ $SAML1 -eq 1 -a $SAML2 -eq 1 ] ; then
+    PROTENUM="$SAML20PROT $SAML11PROT"
+elif [ $SAML1 -eq 1 ] ; then
+    PROTENUM="$SAML11PROT"
+else
+    PROTENUM="$SAML20PROT"
+fi
+
+if [ $SAML2 -eq 1 ] ; then
+    ACS[${#ACS[*]}]=$SAML20POST
+    ACSLOC[${#ACSLOC[*]}]="SAML2/POST"
+    ACS[${#ACS[*]}]=$SAML20POSTSS
+    ACSLOC[${#ACSLOC[*]}]="SAML2/POST-SimpleSign"
+    if [ $ARTIFACT -eq 1 ] ; then
+        ACS[${#ACS[*]}]=$SAML20ART
+        ACSLOC[${#ACSLOC[*]}]="SAML2/Artifact"
+    fi
+    ACS[${#ACS[*]}]=$SAML20PAOS
+    ACSLOC[${#ACSLOC[*]}]="SAML2/ECP"
+fi
+
+if [ $SAML1 -eq 1 ] ; then
+    ACS[${#ACS[*]}]=$SAML1POST
+    ACSLOC[${#ACSLOC[*]}]="SAML/POST"
+    if [ $ARTIFACT -eq 1 ] ; then
+        ACS[${#ACS[*]}]=$SAML1ART
+        ACSLOC[${#ACSLOC[*]}]="SAML/Artifact"
+    fi
+fi
+
+if [ $DECLS -eq 1 ] ; then
+    DECLS="xmlns:md=\"urn:oasis:names:tc:SAML:2.0:metadata\" xmlns:ds=\"http://www.w3.org/2000/09/xmldsig#\" "
+    if [ $DS -eq 1 ] ; then
+        DECLS="${DECLS}xmlns:disco=\"urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol\" "
+    fi
+else
+    DECLS=""
 fi
 
 cat <<EOF
-<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" entityID="${ENTITYID}">
-  <md:SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol urn:oasis:names:tc:SAML:1.1:protocol urn:oasis:names:tc:SAML:1.0:protocol">
+<md:EntityDescriptor ${DECLS}entityID="${ENTITYID}">
+  <md:SPSSODescriptor protocolSupportEnumeration="${PROTENUM}">
+EOF
+
+# Discovery BEGIN
+if [ $DS -eq 1 ] ; then
+
+cat << EOF
     <md:Extensions>
 EOF
 
@@ -44,7 +162,7 @@ count=1
 for h in ${HOSTS[@]}
 do
   cat << EOF
-      <DiscoveryResponse xmlns="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Binding="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Location="https://$h/Shibboleth.sso/DS" index="$count"/>
+      <disco:DiscoveryResponse Binding="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Location="https://$h/Shibboleth.sso/DS" index="$count"/>
 EOF
   let "count++"
 done
@@ -52,98 +170,127 @@ done
 for h in ${NAKEDHOSTS[@]}
 do
   cat << EOF
-      <DiscoveryResponse xmlns="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Binding="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Location="http://$h/Shibboleth.sso/DS" index="$count"/>
+      <disco:DiscoveryResponse Binding="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Location="http://$h/Shibboleth.sso/DS" index="$count"/>
 EOF
   let "count++"
 done
 
 cat << EOF
     </md:Extensions>
+EOF
+
+fi
+# Discovery END
+
+for c in ${CERTS[@]}
+do
+cat << EOF
     <md:KeyDescriptor>
-      <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+      <ds:KeyInfo>
         <ds:X509Data>
           <ds:X509Certificate>
 EOF
-
-grep -v ^- $CERT
-
-cat <<EOF
+grep -v ^- $c
+cat << EOF
           </ds:X509Certificate>
         </ds:X509Data>
       </ds:KeyInfo>
     </md:KeyDescriptor>
-    <!--
 EOF
+done
+
+for f in ${FORMATS[@]}
+do
+cat << EOF
+    <md:NameIDFormat>$f</md:NameIDFormat>
+EOF
+done
+
+# Logout BEGIN
+if [ $LOGOUT -eq 1 ] ; then
 
 for h in ${HOSTS[@]}
 do
-  cat <<EOF
-    <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://$h/Shibboleth.sso/SLO/SOAP"/>
-    <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://$h/Shibboleth.sso/SLO/Redirect"/>
-    <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://$h/Shibboleth.sso/SLO/POST"/>
-    <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="https://$h/Shibboleth.sso/SLO/Artifact"/>
+  count=0
+  while [ $count -lt ${#SLO[*]} ]
+  do
+    cat <<EOF
+    <md:SingleLogoutService Binding="${SLO[$count]}" Location="https://$h/Shibboleth.sso/SLO/${SLOLOC[$count]}"/>
 EOF
+    let "count++"
+  done
 done
 
 for h in ${NAKEDHOSTS[@]}
 do
-  cat <<EOF
-    <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="http://$h/Shibboleth.sso/SLO/SOAP"/>
-    <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://$h/Shibboleth.sso/SLO/Redirect"/>
-    <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://$h/Shibboleth.sso/SLO/POST"/>
-    <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="http://$h/Shibboleth.sso/SLO/Artifact"/>
+  count=0
+  while [ $count -lt ${#SLO[*]} ]
+  do
+    cat <<EOF
+    <md:SingleLogoutService Binding="${SLO[$count]}" Location="http://$h/Shibboleth.sso/SLO/${SLOLOC[$count]}"/>
 EOF
+    let "count++"
+  done
 done
 
+fi
+# Logout END
+
+# NameID Mgmt BEGIN
+if [ $NAMEIDMGMT -eq 1 ] ; then
+
 for h in ${HOSTS[@]}
 do
-  cat <<EOF
-    <md:ManageNameIDService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://$h/Shibboleth.sso/NIM/SOAP"/>
-    <md:ManageNameIDService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://$h/Shibboleth.sso/NIM/Redirect"/>
-    <md:ManageNameIDService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://$h/Shibboleth.sso/NIM/POST"/>
-    <md:ManageNameIDService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="https://$h/Shibboleth.sso/NIM/Artifact"/>
+  count=0
+  while [ $count -lt ${#SLO[*]} ]
+  do
+    cat <<EOF
+    <md:ManageNameIDService Binding="${SLO[$count]}" Location="https://$h/Shibboleth.sso/NIM/${SLOLOC[$count]}"/>
 EOF
+    let "count++"
+  done
 done
 
 for h in ${NAKEDHOSTS[@]}
 do
-  cat <<EOF
-    <md:ManageNameIDService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="http://$h/Shibboleth.sso/NIM/SOAP"/>
-    <md:ManageNameIDService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://$h/Shibboleth.sso/NIM/Redirect"/>
-    <md:ManageNameIDService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://$h/Shibboleth.sso/NIM/POST"/>
-    <md:ManageNameIDService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="http://$h/Shibboleth.sso/NIM/Artifact"/>
+  count=0
+  while [ $count -lt ${#SLO[*]} ]
+  do
+    cat <<EOF
+    <md:ManageNameIDService Binding="${SLO[$count]}" Location="http://$h/Shibboleth.sso/NIM/${SLOLOC[$count]}"/>
 EOF
+    let "count++"
+  done
 done
 
-cat <<EOF
-    -->
-EOF
+fi
+# NameID Mgmt END
 
-count=0
+index=0
 for h in ${HOSTS[@]}
 do
-  cat <<EOF
-    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://$h/Shibboleth.sso/SAML2/POST" index="$((count+1))"/>
-    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign" Location="https://$h/Shibboleth.sso/SAML2/POST-SimpleSign" index="$((count+2))"/>
-    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="https://$h/Shibboleth.sso/SAML2/Artifact" index="$((count+3))"/>
-    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:PAOS" Location="https://$h/Shibboleth.sso/SAML2/ECP" index="$((count+4))"/>
-    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:1.0:profiles:browser-post" Location="https://$h/Shibboleth.sso/SAML/POST" index="$((count+5))"/>
-    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:1.0:profiles:artifact-01" Location="https://$h/Shibboleth.sso/SAML/Artifact" index="$((count+6))"/>
-EOF
-  let "count+=6"
+  count=0
+  while [ $count -lt ${#ACS[*]} ]
+  do
+    cat <<EOF
+    <md:AssertionConsumerService Binding="${ACS[$count]}" Location="https://$h/Shibboleth.sso/${ACSLOC[$count]}" index="$((index+1))"/>
+EOF
+    let "count++"
+    let "index++"
+  done
 done
 
 for h in ${NAKEDHOSTS[@]}
 do
-  cat <<EOF
-    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://$h/Shibboleth.sso/SAML2/POST" index="$((count+1))"/>
-    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign" Location="http://$h/Shibboleth.sso/SAML2/POST-SimpleSign" index="$((count+2))"/>
-    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="http://$h/Shibboleth.sso/SAML2/Artifact" index="$((count+3))"/>
-    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:PAOS" Location="http://$h/Shibboleth.sso/SAML2/ECP" index="$((count+4))"/>
-    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:1.0:profiles:browser-post" Location="http://$h/Shibboleth.sso/SAML/POST" index="$((count+5))"/>
-    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:1.0:profiles:artifact-01" Location="http://$h/Shibboleth.sso/SAML/Artifact" index="$((count+6))"/>
-EOF
-  let "count+=6"
+  count=0
+  while [ $count -lt ${#ACS[*]} ]
+  do
+    cat <<EOF
+    <md:AssertionConsumerService Binding="${ACS[$count]}" Location="http://$h/Shibboleth.sso/${ACSLOC[$count]}" index="$((index+1))"/>
+EOF
+    let "count++"
+    let "index++"
+  done
 done
 
 cat <<EOF 
@@ -151,18 +298,22 @@ cat <<EOF
 EOF
 
 if [ -n "$ORGNAME" ] ; then
+  if [ -z "$URL" ] ; then
+    URL=$ENTITYID
+  fi
   cat <<EOF
   <md:Organization>
     <md:OrganizationName xml:lang="en">$ORGNAME</md:OrganizationName>
     <md:OrganizationDisplayName xml:lang="en">$ORGNAME</md:OrganizationDisplayName>
-    <md:OrganizationURL xml:lang="en">$ENTITYID</md:OrganizationURL>
+    <md:OrganizationURL xml:lang="en">$URL</md:OrganizationURL>
   </md:Organization>
 EOF
 fi
 
-for c in ${ADMIN[@]}
+count=${#ADMIN[*]}
+for (( i=0; i<count; i++ ))
 do
-  c=(${c//\// })
+  IFS="/"; declare -a c=(${ADMIN[$i]})
   cat <<EOF
   <md:ContactPerson contactType="administrative">
     <md:GivenName>${c[0]}</md:GivenName>
@@ -172,9 +323,10 @@ do
 EOF
 done
 
-for c in ${SUP[@]}
+count=${#SUP[*]}
+for (( i=0; i<count; i++ ))
 do
-  c=(${c//\// })
+  IFS="/"; declare -a c=(${SUP[$i]})
   cat <<EOF
   <md:ContactPerson contactType="support">
     <md:GivenName>${c[0]}</md:GivenName>
@@ -184,9 +336,10 @@ do
 EOF
 done
 
-for c in ${TECH[@]}
+count=${#TECH[*]}
+for (( i=0; i<count; i++ ))
 do
-  c=(${c//\// })
+  IFS="/"; declare -a c=(${TECH[$i]})
   cat <<EOF
   <md:ContactPerson contactType="technical">
     <md:GivenName>${c[0]}</md:GivenName>
@@ -198,4 +351,5 @@ done
 
 cat <<EOF 
 </md:EntityDescriptor>
+
 EOF