Use shibboleth-sp as package name for compatibility.
[shibboleth/cpp-sp.git] / configs / metagen.sh
1 #!/usr/bin/env bash
2
3 DECLS=1
4
5 SAML1=0
6 SAML2=0
7 ARTIFACT=0
8 DS=0
9 LOGOUT=0
10 NAMEIDMGMT=0
11
12 SAML10PROT="urn:oasis:names:tc:SAML:1.0:protocol"
13 SAML11PROT="urn:oasis:names:tc:SAML:1.1:protocol"
14 SAML20PROT="urn:oasis:names:tc:SAML:2.0:protocol"
15
16 SAML20SOAP="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
17 SAML20REDIRECT="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
18 SAML20POST="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
19 SAML20POSTSS="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign"
20 SAML20ART="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"
21 SAML20PAOS="urn:oasis:names:tc:SAML:2.0:bindings:PAOS"
22
23 SAML1POST="urn:oasis:names:tc:SAML:1.0:profiles:browser-post"
24 SAML1ART="urn:oasis:names:tc:SAML:1.0:profiles:artifact-01"
25
26 while getopts a:c:e:f:h:l:n:o:s:t:u:12ADLNO c
27      do
28          case $c in
29            c)   CERTS[${#CERTS[*]}]=$OPTARG;;
30            e)   ENTITYID=$OPTARG;;
31            f)   FORMATS[${#FORMATS[*]}]=$OPTARG;;
32            h)   HOSTS[${#HOSTS[*]}]=$OPTARG;;
33            l)   HOSTLIST=$OPTARG;;
34            n)   NAKEDHOSTS[${#NAKEDHOSTS[*]}]=$OPTARG;;
35            o)   ORGNAME=$OPTARG;;
36            a)   ADMIN[${#ADMIN[*]}]=$OPTARG;;
37            s)   SUP[${#SUP[*]}]=$OPTARG;;
38            t)   TECH[${#TECH[*]}]=$OPTARG;;
39            u)   URL=$OPTARG;;
40            1)   SAML1=1;;
41            2)   SAML2=1;;
42            A)   ARTIFACT=1;;
43            D)   DS=1;;
44            L)   LOGOUT=1;;
45            N)   NAMEIDMGMT=1;;
46            O)   DECLS=0;;
47            \?)  echo metagen [-12ADLNO] -c cert1 [-c cert2 ...] -h host1 [-h host2 ...] [-e entityID]
48                 exit 1;;
49          esac
50      done
51
52 if [ ${#HOSTS[*]} -eq 0 -a ${#NAKEDHOSTS[*]} -eq 0 ] ; then
53     echo metagen [-12ADLN] -c cert1 [-c cert2 ...] -h host1 [-h host2 ...] [-e entityID]
54     exit 1
55 fi
56
57 if [ ${#CERTS[*]} -eq 0 ] ; then
58     CERTS[${#CERTS[*]}]=sp-cert.pem
59 fi
60
61 for c in ${CERTS[@]}
62 do
63     if  [ ! -s $c ] ; then
64         echo Certificate file $c does not exist! 
65         exit 2
66     fi
67 done
68
69 if [ -z $ENTITYID ] ; then
70     if [ ${#HOSTS[*]} -eq 0 ] ; then
71         ENTITYID=https://${NAKEDHOSTS[0]}/shibboleth
72     else
73         ENTITYID=https://${HOSTS[0]}/shibboleth
74     fi
75 fi
76
77 if [ ! -z $HOSTLIST ] ; then
78     if [ -s $HOSTLIST ] ; then
79         while read h
80         do
81             HOSTS[${#HOSTS[@]}]=$h
82         done <$HOSTLIST
83     else
84         echo File with list of hostnames $l does not exist! 
85         exit 2
86     fi
87 fi
88
89 # Establish protocols and bindings.
90
91 if [ $SAML1 -eq 0 -a $SAML2 -eq 0 ] ; then
92     SAML1=1
93     SAML2=1
94 fi
95
96 if [ $LOGOUT -eq 1 -o $NAMEIDMGMT -eq 1 ] ; then
97     SAML2=1
98     SLO[${#SLO[*]}]=$SAML20SOAP
99     SLO[${#SLO[*]}]=$SAML20REDIRECT
100     SLO[${#SLO[*]}]=$SAML20POST
101     SLOLOC[${#SLOLOC[*]}]="SOAP"
102     SLOLOC[${#SLOLOC[*]}]="Redirect"
103     SLOLOC[${#SLOLOC[*]}]="POST"
104     if [ $ARTIFACT -eq 1 ] ; then
105         SLO[${#SLO[*]}]=$SAML20ART
106         SLOLOC[${#SLOLOC[*]}]="Artifact"
107     fi
108 fi
109
110 if [ $SAML1 -eq 1 -a $SAML2 -eq 1 ] ; then
111     PROTENUM="$SAML20PROT $SAML11PROT"
112 elif [ $SAML1 -eq 1 ] ; then
113     PROTENUM="$SAML11PROT"
114 else
115     PROTENUM="$SAML20PROT"
116 fi
117
118 if [ $SAML2 -eq 1 ] ; then
119     ACS[${#ACS[*]}]=$SAML20POST
120     ACSLOC[${#ACSLOC[*]}]="SAML2/POST"
121     ACS[${#ACS[*]}]=$SAML20POSTSS
122     ACSLOC[${#ACSLOC[*]}]="SAML2/POST-SimpleSign"
123     if [ $ARTIFACT -eq 1 ] ; then
124         ACS[${#ACS[*]}]=$SAML20ART
125         ACSLOC[${#ACSLOC[*]}]="SAML2/Artifact"
126     fi
127     ACS[${#ACS[*]}]=$SAML20PAOS
128     ACSLOC[${#ACSLOC[*]}]="SAML2/ECP"
129 fi
130
131 if [ $SAML1 -eq 1 ] ; then
132     ACS[${#ACS[*]}]=$SAML1POST
133     ACSLOC[${#ACSLOC[*]}]="SAML/POST"
134     if [ $ARTIFACT -eq 1 ] ; then
135         ACS[${#ACS[*]}]=$SAML1ART
136         ACSLOC[${#ACSLOC[*]}]="SAML/Artifact"
137     fi
138 fi
139
140 if [ $DECLS -eq 1 ] ; then
141     DECLS="xmlns:md=\"urn:oasis:names:tc:SAML:2.0:metadata\" xmlns:ds=\"http://www.w3.org/2000/09/xmldsig#\" "
142     if [ $DS -eq 1 ] ; then
143         DECLS="${DECLS}xmlns:disco=\"urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol\" "
144     fi
145 else
146     DECLS=""
147 fi
148
149 cat <<EOF
150 <md:EntityDescriptor ${DECLS}entityID="${ENTITYID}">
151   <md:SPSSODescriptor protocolSupportEnumeration="${PROTENUM}">
152 EOF
153
154 # Discovery BEGIN
155 if [ $DS -eq 1 ] ; then
156
157 cat << EOF
158     <md:Extensions>
159 EOF
160
161 count=1
162 for h in ${HOSTS[@]}
163 do
164   cat << EOF
165       <disco:DiscoveryResponse Binding="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Location="https://$h/Shibboleth.sso/DS" index="$count"/>
166 EOF
167   let "count++"
168 done
169
170 for h in ${NAKEDHOSTS[@]}
171 do
172   cat << EOF
173       <disco:DiscoveryResponse Binding="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Location="http://$h/Shibboleth.sso/DS" index="$count"/>
174 EOF
175   let "count++"
176 done
177
178 cat << EOF
179     </md:Extensions>
180 EOF
181
182 fi
183 # Discovery END
184
185 for c in ${CERTS[@]}
186 do
187 cat << EOF
188     <md:KeyDescriptor>
189       <ds:KeyInfo>
190         <ds:X509Data>
191           <ds:X509Certificate>
192 EOF
193 grep -v ^- $c
194 cat << EOF
195           </ds:X509Certificate>
196         </ds:X509Data>
197       </ds:KeyInfo>
198     </md:KeyDescriptor>
199 EOF
200 done
201
202 for f in ${FORMATS[@]}
203 do
204 cat << EOF
205     <md:NameIDFormat>$f</md:NameIDFormat>
206 EOF
207 done
208
209 # Logout BEGIN
210 if [ $LOGOUT -eq 1 ] ; then
211
212 for h in ${HOSTS[@]}
213 do
214   count=0
215   while [ $count -lt ${#SLO[*]} ]
216   do
217     cat <<EOF
218     <md:SingleLogoutService Binding="${SLO[$count]}" Location="https://$h/Shibboleth.sso/SLO/${SLOLOC[$count]}"/>
219 EOF
220     let "count++"
221   done
222 done
223
224 for h in ${NAKEDHOSTS[@]}
225 do
226   count=0
227   while [ $count -lt ${#SLO[*]} ]
228   do
229     cat <<EOF
230     <md:SingleLogoutService Binding="${SLO[$count]}" Location="http://$h/Shibboleth.sso/SLO/${SLOLOC[$count]}"/>
231 EOF
232     let "count++"
233   done
234 done
235
236 fi
237 # Logout END
238
239 # NameID Mgmt BEGIN
240 if [ $NAMEIDMGMT -eq 1 ] ; then
241
242 for h in ${HOSTS[@]}
243 do
244   count=0
245   while [ $count -lt ${#SLO[*]} ]
246   do
247     cat <<EOF
248     <md:ManageNameIDService Binding="${SLO[$count]}" Location="https://$h/Shibboleth.sso/NIM/${SLOLOC[$count]}"/>
249 EOF
250     let "count++"
251   done
252 done
253
254 for h in ${NAKEDHOSTS[@]}
255 do
256   count=0
257   while [ $count -lt ${#SLO[*]} ]
258   do
259     cat <<EOF
260     <md:ManageNameIDService Binding="${SLO[$count]}" Location="http://$h/Shibboleth.sso/NIM/${SLOLOC[$count]}"/>
261 EOF
262     let "count++"
263   done
264 done
265
266 fi
267 # NameID Mgmt END
268
269 index=0
270 for h in ${HOSTS[@]}
271 do
272   count=0
273   while [ $count -lt ${#ACS[*]} ]
274   do
275     cat <<EOF
276     <md:AssertionConsumerService Binding="${ACS[$count]}" Location="https://$h/Shibboleth.sso/${ACSLOC[$count]}" index="$((index+1))"/>
277 EOF
278     let "count++"
279     let "index++"
280   done
281 done
282
283 for h in ${NAKEDHOSTS[@]}
284 do
285   count=0
286   while [ $count -lt ${#ACS[*]} ]
287   do
288     cat <<EOF
289     <md:AssertionConsumerService Binding="${ACS[$count]}" Location="http://$h/Shibboleth.sso/${ACSLOC[$count]}" index="$((index+1))"/>
290 EOF
291     let "count++"
292     let "index++"
293   done
294 done
295
296 cat <<EOF 
297   </md:SPSSODescriptor>
298 EOF
299
300 if [ -n "$ORGNAME" ] ; then
301   if [ -z "$URL" ] ; then
302     URL=$ENTITYID
303   fi
304   cat <<EOF
305   <md:Organization>
306     <md:OrganizationName xml:lang="en">$ORGNAME</md:OrganizationName>
307     <md:OrganizationDisplayName xml:lang="en">$ORGNAME</md:OrganizationDisplayName>
308     <md:OrganizationURL xml:lang="en">$URL</md:OrganizationURL>
309   </md:Organization>
310 EOF
311 fi
312
313 count=${#ADMIN[*]}
314 for (( i=0; i<count; i++ ))
315 do
316   IFS="/"; declare -a c=(${ADMIN[$i]})
317   cat <<EOF
318   <md:ContactPerson contactType="administrative">
319     <md:GivenName>${c[0]}</md:GivenName>
320     <md:SurName>${c[1]}</md:SurName>
321     <md:EmailAddress>${c[2]}</md:EmailAddress>
322   </md:ContactPerson>
323 EOF
324 done
325
326 count=${#SUP[*]}
327 for (( i=0; i<count; i++ ))
328 do
329   IFS="/"; declare -a c=(${SUP[$i]})
330   cat <<EOF
331   <md:ContactPerson contactType="support">
332     <md:GivenName>${c[0]}</md:GivenName>
333     <md:SurName>${c[1]}</md:SurName>
334     <md:EmailAddress>${c[2]}</md:EmailAddress>
335   </md:ContactPerson>
336 EOF
337 done
338
339 count=${#TECH[*]}
340 for (( i=0; i<count; i++ ))
341 do
342   IFS="/"; declare -a c=(${TECH[$i]})
343   cat <<EOF
344   <md:ContactPerson contactType="technical">
345     <md:GivenName>${c[0]}</md:GivenName>
346     <md:SurName>${c[1]}</md:SurName>
347     <md:EmailAddress>${c[2]}</md:EmailAddress>
348   </md:ContactPerson>
349 EOF
350 done
351
352 cat <<EOF 
353 </md:EntityDescriptor>
354
355 EOF