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