Skip to content

Commit

Permalink
Check for duplicate xml:lang attributes in saml metadata
Browse files Browse the repository at this point in the history
To mitigate against https://issues.shibboleth.net/jira/browse/IDP-1647,
check for elements in the md namespace which have the same xml:lang value.
There are already checks for the mdui and mdrpi namespaces.

See ukf/ukf-meta#248 for details
  • Loading branch information
Alex Stuart committed Nov 10, 2020
1 parent fdebe00 commit 91c978a
Show file tree
Hide file tree
Showing 10 changed files with 309 additions and 0 deletions.
76 changes: 76 additions & 0 deletions mdx/_rules/check_saml2_lang.xsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Checking ruleset for elements with duplicate xml:lang
Originally reported in https://issues.shibboleth.net/jira/browse/IDP-1647
"Error with duplicate <ServiceDescription> with same xml:lang in the metadata"
This set of checks is for all appropriate elements in the namespace
urn:oasis:names:tc:SAML:2.0:metadata
-->
<xsl:stylesheet version="1.0"
xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
xmlns:set="http://exslt.org/sets"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="urn:oasis:names:tc:SAML:2.0:metadata">

<!--
Common support functions.
-->
<xsl:import href="check_framework.xsl"/>

<!--
Check for uniqueness within an AttributeConsumingService element
-->
<xsl:template match="md:AttributeConsumingService">
<!-- unique xml:lang over ServiceName elements -->
<xsl:call-template name="uniqueLang">
<xsl:with-param name="e" select="md:ServiceName"/>
</xsl:call-template>

<!-- unique xml:lang over ServiceDescription elements -->
<xsl:call-template name="uniqueLang">
<xsl:with-param name="e" select="md:ServiceDescription"/>
</xsl:call-template>

<!-- handle individual elements -->
<xsl:apply-templates select="*"/>
</xsl:template>

<!--
Check for uniqueness within an Organization element
-->
<xsl:template match="md:Organization">
<!-- unique xml:lang over OrganizationName elements -->
<xsl:call-template name="uniqueLang">
<xsl:with-param name="e" select="md:OrganizationName"/>
</xsl:call-template>

<!-- unique xml:lang over OrganizationDisplayName elements -->
<xsl:call-template name="uniqueLang">
<xsl:with-param name="e" select="md:OrganizationDisplayName"/>
</xsl:call-template>

<!-- handle individual elements -->
<xsl:apply-templates select="*"/>
</xsl:template>

<xsl:template name="uniqueLang">
<xsl:param name="e"/>
<xsl:variable name="l" select="$e/@xml:lang"></xsl:variable>
<xsl:variable name="u" select="set:distinct($l)"/>
<xsl:if test="count($l) != count($u)">
<xsl:call-template name="error">
<xsl:with-param name="m">
<xsl:text>non-unique lang values on </xsl:text>
<xsl:value-of select="name($e)"/>
<xsl:text> elements</xsl:text>
</xsl:with-param>
</xsl:call-template>
</xsl:if>
</xsl:template>

</xsl:stylesheet>
1 change: 1 addition & 0 deletions mdx/uk/verbs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,7 @@
<ref bean="check_reqattr"/>
<ref bean="check_saml1"/>
<ref bean="check_saml2"/>
<ref bean="check_saml2_lang"/>
<ref bean="check_saml2int"/>
<!-- <ref bean="check_saml2meta"/> -->
<ref bean="check_shib_noregscope"/>
Expand Down
17 changes: 17 additions & 0 deletions mdx/validation-beans.xml
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,22 @@
p:blacklistResource="classpath:net/shibboleth/metadata/validate/x509/compromised-2048.txt"/>


<!--
****************************************************
*** ***
*** S A M L 2 M E T A D A T A C H E C K S ***
*** ***
****************************************************
-->


<!--
check_saml2_lang
-->
<bean id="check_saml2_lang" parent="mda.XSLValidationStage"
p:XSLResource="classpath:_rules/check_saml2_lang.xsl"/>


<!--
***************************************************
*** ***
Expand Down Expand Up @@ -645,6 +661,7 @@
<ref bean="check_reqattr"/>
<ref bean="check_saml1"/>
<ref bean="check_saml2"/>
<ref bean="check_saml2_lang"/>
<ref bean="check_saml2int"/>
<ref bean="check_saml2meta"/>
<ref bean="check_saml_strings"/>
Expand Down
11 changes: 11 additions & 0 deletions tests/manual/ukf-meta-248/AttributeConsumingService-fail.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata">
<SPSSODescriptor>
<AttributeConsumingService index="1" isDefault="true">
<ServiceName xml:lang="en">English e-learning</ServiceName>
<ServiceName xml:lang="en">英語e-learning</ServiceName>
<ServiceDescription xml:lang="en">English e-learning</ServiceDescription>
<ServiceDescription xml:lang="en">英語e-learning</ServiceDescription>
</AttributeConsumingService>
</SPSSODescriptor>
</EntityDescriptor>
13 changes: 13 additions & 0 deletions tests/manual/ukf-meta-248/AttributeConsumingService-pass.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata">
<SPSSODescriptor>
<AttributeConsumingService index="1">
<ServiceName xml:lang="en">English e-learning</ServiceName>
<ServiceDescription xml:lang="en">English e-learning</ServiceDescription>
</AttributeConsumingService>
<AttributeConsumingService index="2">
<ServiceName xml:lang="en">英語e-learning</ServiceName>
<ServiceDescription xml:lang="en">英語e-learning</ServiceDescription>
</AttributeConsumingService>
</SPSSODescriptor>
</EntityDescriptor>
9 changes: 9 additions & 0 deletions tests/manual/ukf-meta-248/Organization-fail.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata">
<Organization>
<OrganizationName xml:lang="en">English e-learning</OrganizationName>
<OrganizationName xml:lang="en">英語e-learning</OrganizationName>
<OrganizationDisplayName xml:lang="en">English e-learning</OrganizationDisplayName>
<OrganizationDisplayName xml:lang="en">英語e-learning</OrganizationDisplayName>
</Organization>
</EntityDescriptor>
11 changes: 11 additions & 0 deletions tests/manual/ukf-meta-248/Organization-pass.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata">
<Organization>
<OrganizationName xml:lang="en">English e-learning</OrganizationName>
<OrganizationDisplayName xml:lang="en">English e-learning</OrganizationDisplayName>
</Organization>
<Organization>
<OrganizationName xml:lang="en">英語e-learning</OrganizationName>
<OrganizationDisplayName xml:lang="en">英語e-learning</OrganizationDisplayName>
</Organization>
</EntityDescriptor>
38 changes: 38 additions & 0 deletions tests/manual/ukf-meta-248/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Tests for duplicate xml:lang

Ensuring well-formed:
```
for i in *xml; do xmllint --noout $i; done
```

Tests for existing checks:
```
xsltproc ../../../mdx/_rules/check_mdui.xsl test.xml
[ERROR] non-unique lang values on mdui:DisplayName elements
[ERROR] non-unique lang values on mdui:Description elements
[ERROR] non-unique lang values on mdui:Keywords elements
$ xsltproc ../../../mdx/_rules/check_mdrpi.xsl test.xml
[ERROR] non-unique lang values on mdrpi:RegistrationPolicy elements
```

New test should fail on md:ServiceName and md:ServiceDescription:
```
xsltproc ../../../mdx/_rules/check_saml2_lang.xsl AttributeConsumingService-fail.xml
[ERROR] non-unique lang values on ServiceName elements
[ERROR] non-unique lang values on ServiceDescription elements
```

New test should fail on md:Organization and md:OrganizationDisplayName
```
xsltproc ../../../mdx/_rules/check_saml2_lang.xsl Organization-fail.xml
[ERROR] non-unique lang values on OrganizationName elements
[ERROR] non-unique lang values on OrganizationDisplayName elements
```

Should pass on new tests:
```
xsltproc ../../../mdx/_rules/check_saml2_lang.xsl AttributeConsumingService-pass.xml
xsltproc ../../../mdx/_rules/check_saml2_lang.xsl Organization-pass.xml
```

`test-sp.xml` is a fragment file that is intended to fail on import
96 changes: 96 additions & 0 deletions tests/manual/ukf-meta-248/test-sp.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<!--
This is example metadata only. Do *NOT* supply it as is without review,
and do *NOT* provide it in real time to your partners.
-->
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" ID="_c0045678aa1b1e04e85d412f428ea95d2f627255" entityID="https://test.ukfederation.org.uk/entity">

<md:Extensions xmlns:alg="urn:oasis:names:tc:SAML:metadata:algsupport">
<alg:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha512"/>
<alg:DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#sha384"/>
<alg:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<alg:DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#sha224"/>
<alg:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512"/>
<alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384"/>
<alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"/>
<alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha224"/>
<alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"/>
<alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha384"/>
<alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
<alg:SigningMethod Algorithm="http://www.w3.org/2009/xmldsig11#dsa-sha256"/>
<alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1"/>
<alg:SigningMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<alg:SigningMethod Algorithm="http://www.w3.org/2000/09/xmldsig#dsa-sha1"/>
</md:Extensions>

<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:Extensions>
<init:RequestInitiator xmlns:init="urn:oasis:names:tc:SAML:profiles:SSO:request-init" Binding="urn:oasis:names:tc:SAML:profiles:SSO:request-init" Location="https://test.ukfederation.org.uk/Shibboleth.sso/Login"/>
<idpdisc:DiscoveryResponse xmlns:idpdisc="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Binding="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Location="https://test.ukfederation.org.uk/Shibboleth.sso/Login" index="1"/>
<init:RequestInitiator xmlns:init="urn:oasis:names:tc:SAML:profiles:SSO:request-init" Binding="urn:oasis:names:tc:SAML:profiles:SSO:request-init" Location="https://test.ukfederation.org.uk/Shibboleth.sso/Login1"/>
<init:RequestInitiator xmlns:init="urn:oasis:names:tc:SAML:profiles:SSO:request-init" Binding="urn:oasis:names:tc:SAML:profiles:SSO:request-init" Location="https://test.ukfederation.org.uk/Shibboleth.sso/DS"/>
<init:RequestInitiator xmlns:init="urn:oasis:names:tc:SAML:profiles:SSO:request-init" Binding="urn:oasis:names:tc:SAML:profiles:SSO:request-init" Location="https://test.ukfederation.org.uk/Shibboleth.sso/UKfedWAYF"/>
<init:RequestInitiator xmlns:init="urn:oasis:names:tc:SAML:profiles:SSO:request-init" Binding="urn:oasis:names:tc:SAML:profiles:SSO:request-init" Location="https://test.ukfederation.org.uk/Shibboleth.sso/UKfedDS"/>
<idpdisc:DiscoveryResponse xmlns:idpdisc="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Binding="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Location="https://test.ukfederation.org.uk/Shibboleth.sso/UKfedDS" index="2"/>
<init:RequestInitiator xmlns:init="urn:oasis:names:tc:SAML:profiles:SSO:request-init" Binding="urn:oasis:names:tc:SAML:profiles:SSO:request-init" Location="https://test.ukfederation.org.uk/Shibboleth.sso/EDS"/>
<idpdisc:DiscoveryResponse xmlns:idpdisc="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Binding="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Location="https://test.ukfederation.org.uk/Shibboleth.sso/EDS" index="3"/>
<init:RequestInitiator xmlns:init="urn:oasis:names:tc:SAML:profiles:SSO:request-init" Binding="urn:oasis:names:tc:SAML:profiles:SSO:request-init" Location="https://test.ukfederation.org.uk/Shibboleth.sso/Wayfinder"/>
<idpdisc:DiscoveryResponse xmlns:idpdisc="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Binding="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Location="https://test.ukfederation.org.uk/Shibboleth.sso/Wayfinder" index="4"/>
</md:Extensions>
<md:KeyDescriptor>
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:KeyName>test-sp</ds:KeyName>
<ds:X509Data>
<ds:X509SubjectName>CN=test-sp</ds:X509SubjectName>
<ds:X509Certificate>MIIC3DCCAcSgAwIBAgIJAN+91XVXF36VMA0GCSqGSIb3DQEBBQUAMBIxEDAOBgNV
BAMTB3Rlc3Qtc3AwHhcNMTYwNTExMTI0MTA3WhcNMjYwNTA5MTI0MTA3WjASMRAw
DgYDVQQDEwd0ZXN0LXNwMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
zSnEqqkjqprYaIIiO3NOMHHMtvu3T4OP3lRFRp3arNgQTu6J54dj4Ljh2R6w2oFf
NW/SXKYmHQSv9L/wo57PH47QDvHpt/fSrcG5vr5E0GJFBsKLH21ejK2IaRh58m4k
xTpncRbdLDVntHs0ZOOAzXTyM9kzwNmLHnhkl6MH0q7qiHRsOXUFMJMM8VdEFZ3p
zGrOjZ36sFysjxwBH+2YYixgJCsmDJJI8/0XCFg9KvgHgtUudru4cO2PgU4MFj9V
mV+j3vPhZP3GPMNqLBlAqDTKKw6lRIHF2hHGE1zhqU6A3QGRxhkAonPEyGMvYfFT
tSW5MW2f58B+0+A5nMKqTwIDAQABozUwMzASBgNVHREECzAJggd0ZXN0LXNwMB0G
A1UdDgQWBBQob//Wa5StNlZteESM3e54WsDovzANBgkqhkiG9w0BAQUFAAOCAQEA
iaLcK3+i8w7AzYuaDiu0I4kclZoxz1zKHyI4o7s+iTTR5xJrX+d5WRZT4f72RkDS
gEH4L/f64XUufso8ilt7vCxJOIUAAcZSxHFD/4TvBhNBha9HjzlL11kOr8VNs3OJ
FQwsV8Or5xr2T1wpcT+JN5sDNbAxx7oz/vthnAdvo98vGMMx1VJcNz7B5irg3B5M
gegI3kOm1UfZLWxjfae/uX19d8N0r8AFD3Uuw4UX/07LVZmrtvjI5LB+ju/kv8kP
ENCjwhjjXq7NUW8hgSiqqdMkFA1iH+KMAYtn2xvll1TojluWAwpYjaCjOLyJSBuV
sIV9aK2TFEhoJD6KkXUNqg==
</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
<md:EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#aes128-gcm"/>
<md:EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#aes192-gcm"/>
<md:EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#aes256-gcm"/>
<md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
<md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes192-cbc"/>
<md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"/>
<md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/>
<md:EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#rsa-oaep"/>
<md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"/>
</md:KeyDescriptor>
<md:ArtifactResolutionService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://test.ukfederation.org.uk/Shibboleth.sso/Artifact/SOAP" index="1"/>
<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://test.ukfederation.org.uk/Shibboleth.sso/SLO/SOAP"/>
<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://test.ukfederation.org.uk/Shibboleth.sso/SLO/Redirect"/>
<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://test.ukfederation.org.uk/Shibboleth.sso/SLO/POST"/>
<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="https://test.ukfederation.org.uk/Shibboleth.sso/SLO/Artifact"/>
<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://test.ukfederation.org.uk/Shibboleth.sso/SAML2/POST" index="1"/>
<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign" Location="https://test.ukfederation.org.uk/Shibboleth.sso/SAML2/POST-SimpleSign" index="2"/>
<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="https://test.ukfederation.org.uk/Shibboleth.sso/SAML2/Artifact" index="3"/>
<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:PAOS" Location="https://test.ukfederation.org.uk/Shibboleth.sso/SAML2/ECP" index="4"/>
<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:1.0:profiles:browser-post" Location="https://test.ukfederation.org.uk/Shibboleth.sso/SAML/POST" index="5"/>
<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:1.0:profiles:artifact-01" Location="https://test.ukfederation.org.uk/Shibboleth.sso/SAML/Artifact" index="6"/>
<md:AttributeConsumingService index="1" isDefault="true">
<md:ServiceName xml:lang="en">English e-learning</md:ServiceName>
<md:ServiceName xml:lang="en">英語e-learning</md:ServiceName>
<md:ServiceDescription xml:lang="en">English e-learning</md:ServiceDescription>
<md:ServiceDescription xml:lang="en">英語e-learning</md:ServiceDescription>
<md:RequestedAttribute FriendlyName="eduPersonScopedAffiliation"
Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.9"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
</md:AttributeConsumingService>
</md:SPSSODescriptor>

</md:EntityDescriptor>
37 changes: 37 additions & 0 deletions tests/manual/ukf-meta-248/test.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
xmlns:mdrpi="urn:oasis:names:tc:SAML:metadata:rpi"
xmlns:mdui="urn:oasis:names:tc:SAML:metadata:ui"
entityID="test">
<Extensions>
<mdrpi:RegistrationInfo registrationAuthority="http://ukfederation.org.uk"
registrationInstant="2012-07-13T11:19:55Z">
<mdrpi:RegistrationPolicy xml:lang="en"
>http://ukfederation.org.uk/doc/mdrps-20130902</mdrpi:RegistrationPolicy>
<mdrpi:RegistrationPolicy xml:lang="en"
>http://ukfederation.org.uk/doc/mdrps-20130902</mdrpi:RegistrationPolicy>
</mdrpi:RegistrationInfo>
</Extensions>
<SPSSODescriptor>
<Extensions>
<mdui:UIInfo>
<mdui:DisplayName xml:lang="en">First display name</mdui:DisplayName>
<mdui:DisplayName xml:lang="en">Second display name</mdui:DisplayName>
<mdui:Description xml:lang="en">First description</mdui:Description>
<mdui:Description xml:lang="en">Second description</mdui:Description>
<mdui:Keywords xml:lang="en-sco">wee sleekit</mdui:Keywords>
<mdui:Keywords xml:lang="en-sco">cowran tim'rous</mdui:Keywords>
<!--
<mdui:InformationURL xml:lang="en">https://www.example.ac.uk/information.html</mdui:InformationURL>
<mdui:InformationURL xml:lang="en">https://www2.example.ac.uk/information.html</mdui:InformationURL>
<mdui:PrivacyStatementURL xml:lang="en">https://www.example.ac.uk/privacy.html</mdui:PrivacyStatementURL>
<mdui:PrivacyStatementURL xml:lang="en">https://www2.example.ac.uk/privacy.html</mdui:PrivacyStatementURL>
-->
</mdui:UIInfo>
</Extensions>
<AttributeConsumingService index="1" isDefault="true">
<ServiceDescription xml:lang="en">English e-learning</ServiceDescription>
<ServiceDescription xml:lang="en">英語e-learning</ServiceDescription>
</AttributeConsumingService>
</SPSSODescriptor>
</EntityDescriptor>

0 comments on commit 91c978a

Please sign in to comment.