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