Rework decoder handling in simple resolver, add IdP/SP names to decoder API, hook...
authorcantor <cantor@cb58f699-b61c-0410-a6fe-9272a202ed29>
Thu, 1 Mar 2007 18:11:43 +0000 (18:11 +0000)
committercantor <cantor@cb58f699-b61c-0410-a6fe-9272a202ed29>
Thu, 1 Mar 2007 18:11:43 +0000 (18:11 +0000)
git-svn-id: https://svn.middleware.georgetown.edu/cpp-sp/trunk@2179 cb58f699-b61c-0410-a6fe-9272a202ed29

14 files changed:
configs/AAP.xml.in [deleted file]
configs/Makefile.am
configs/resolver-simple.xml.in [new file with mode: 0644]
configs/shibboleth.xml.in
schemas/shibboleth-2.0-simple-resolver.xsd
schemas/shibboleth-spconfig-2.0.xsd
shibd/shibd.cpp
shibsp/Application.h
shibsp/attribute/AttributeDecoder.h
shibsp/attribute/NameIDAttributeDecoder.cpp
shibsp/attribute/ScopedAttributeDecoder.cpp
shibsp/attribute/SimpleAttributeDecoder.cpp
shibsp/attribute/resolver/impl/SimpleAttributeResolver.cpp
shibsp/impl/XMLServiceProvider.cpp

diff --git a/configs/AAP.xml.in b/configs/AAP.xml.in
deleted file mode 100644 (file)
index fb467ad..0000000
+++ /dev/null
@@ -1,314 +0,0 @@
-<AttributeAcceptancePolicy xmlns="urn:mace:shibboleth:1.0"
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:schemaLocation="urn:mace:shibboleth:1.0 @-PKGXMLDIR-@/shibboleth.xsd">
-
-       <!--
-       An AAP is a set of AttributeRule elements, each one
-       referencing a specific attribute by URI. All attributes that
-       should be visible to an application running at the target should
-       be listed, or they will be filtered out.
-       
-       The Header and Alias attributes map an attribute to an HTTP header
-       and to an htaccess rule name respectively. Without Header, the attribute
-       will only be obtainable from the exported SAML assertion in raw XML.
-       
-       Scoped attributes can also be filtered on Scope via rules in the
-       asserting identity provider's metadata.
-       
-       Finally, a note on naming. The attributes in this file are mostly drawn from
-       the set documented here:
-       
-       http://middleware.internet2.edu/urn-mace/urn-mace-dir-attribute-def.html
-       
-       The     actual naming convention most of them follow is NOT to be used for
-       any subsequent attributes bound to SAML, and you are NOT free to just
-       make up names using it, because the urn:mace:dir namespace tree is
-       controlled. For help and advice on defining new attributes, refer to:
-       
-       https://authdev.it.ohio-state.edu/twiki/bin/view/Shibboleth/AttributeNaming
-       -->
-       
-       <!-- First some useful eduPerson attributes that many sites might use. -->
-       
-       <AttributeRule Name="urn:mace:dir:attribute-def:eduPersonScopedAffiliation" Scoped="true" CaseSensitive="false" Header="Shib-EP-Affiliation" Alias="affiliation">
-               <!-- Filtering rule to limit values to eduPerson-defined enumeration. -->
-        <AnySite>
-            <Value>MEMBER</Value>
-            <Value>FACULTY</Value>
-            <Value>STUDENT</Value>
-            <Value>STAFF</Value>
-            <Value>ALUM</Value>
-            <Value>AFFILIATE</Value>
-            <Value>EMPLOYEE</Value>
-        </AnySite>
-        
-        <!-- Example of Scope rule to override site metadata. -->
-        <SiteRule Name="urn:mace:inqueue:shibdev.edu">
-               <Scope Accept="false">shibdev.edu</Scope>
-               <Scope Type="regexp">^.+\.shibdev\.edu$</Scope>
-        </SiteRule>
-       </AttributeRule>
-
-       <!--
-       This attribute is provided mostly to ease testing because an IdP out of the box only
-       sends the unscoped version. It has little use because it lacks the context needed to
-       work in a multi-domain scenario and is a subset of the scoped version anyway.
-        -->
-       <AttributeRule Name="urn:mace:dir:attribute-def:eduPersonAffiliation" CaseSensitive="false" Header="Shib-EP-UnscopedAffiliation" Alias="unscoped-affiliation">
-        <AnySite>
-            <Value>MEMBER</Value>
-            <Value>FACULTY</Value>
-            <Value>STUDENT</Value>
-            <Value>STAFF</Value>
-            <Value>ALUM</Value>
-            <Value>AFFILIATE</Value>
-            <Value>EMPLOYEE</Value>
-        </AnySite>
-       </AttributeRule>
-       
-    <AttributeRule Name="urn:mace:dir:attribute-def:eduPersonPrincipalName" Scoped="true" Header="REMOTE_USER" Alias="user">
-               <!-- Basic rule to pass through any value. -->
-        <AnySite>
-            <Value Type="regexp">^[^@]+$</Value>
-        </AnySite>
-    </AttributeRule>
-
-       <AttributeRule Name="urn:mace:dir:attribute-def:eduPersonEntitlement" Header="Shib-EP-Entitlement" Alias="entitlement">
-               <!-- Entitlements tend to be filtered per-site. -->
-               
-               <!--
-               Optional site rule that applies to any site
-               <AnySite>
-                       <Value>urn:mace:example.edu:exampleEntitlement</Value>
-               </AnySite>
-               -->
-               
-               <!-- Specific rules for an origin site, these are just development/sample sites. -->
-               <SiteRule Name="urn:mace:inqueue:example.edu">
-                       <Value Type="regexp">^urn:mace:.+$</Value>
-               </SiteRule>
-               <SiteRule Name="urn:mace:inqueue:shibdev.edu">
-                       <Value Type="regexp">^urn:mace:.+$</Value>
-               </SiteRule>
-       </AttributeRule>
-
-       <!-- A persistent id attribute that supports personalized anonymous access. -->
-       
-       <!-- First, the deprecated version: -->
-       <AttributeRule Name="urn:mace:dir:attribute-def:eduPersonTargetedID" Scoped="true" Header="Shib-TargetedID" Alias="targeted_id">
-        <AnySite>
-            <AnyValue/>
-        </AnySite>
-       </AttributeRule>
-
-       <!-- Second, the new version (note the OID-style name): -->
-       <AttributeRule Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10" Header="Shib-TargetedID" Alias="targeted_id">
-        <AnySite>
-            <AnyValue/>
-        </AnySite>
-       </AttributeRule>
-       
-       <!-- Some more eduPerson attributes, uncomment these to use them... -->
-       <!--
-       
-       <AttributeRule Name="urn:mace:dir:attribute-def:eduPersonNickname">
-        <AnySite>
-            <AnyValue/>
-        </AnySite>
-       </AttributeRule>
-
-       <AttributeRule Name="urn:mace:dir:attribute-def:eduPersonPrimaryAffiliation" CaseSensitive="false" Header="Shib-EP-PrimaryAffiliation">
-        <AnySite>
-            <Value>MEMBER</Value>
-            <Value>FACULTY</Value>
-            <Value>STUDENT</Value>
-            <Value>STAFF</Value>
-            <Value>ALUM</Value>
-            <Value>AFFILIATE</Value>
-            <Value>EMPLOYEE</Value>
-        </AnySite>
-       </AttributeRule>
-       
-       <AttributeRule Name="urn:mace:dir:attribute-def:eduPersonPrimaryOrgUnitDN" Header="Shib-EP-PrimaryOrgUnitDN">
-        <AnySite>
-            <AnyValue/>
-        </AnySite>
-       </AttributeRule>
-       
-       <AttributeRule Name="urn:mace:dir:attribute-def:eduPersonOrgUnitDN" Header="Shib-EP-OrgUnitDN">
-        <AnySite>
-            <AnyValue/>
-        </AnySite>
-       </AttributeRule>
-       
-       <AttributeRule Name="urn:mace:dir:attribute-def:eduPersonOrgDN" Header="Shib-EP-OrgDN">
-        <AnySite>
-            <AnyValue/>
-        </AnySite>
-       </AttributeRule>
-
-       -->
-
-
-       <!--Examples of common LDAP-based attributes, uncomment to use these... -->
-       <!--
-       
-       <AttributeRule Name="urn:mace:dir:attribute-def:cn" Header="Shib-Person-commonName">
-               <AnySite>
-            <AnyValue/>
-        </AnySite>
-       </AttributeRule>
-       
-       <AttributeRule Name="urn:mace:dir:attribute-def:sn" Header="Shib-Person-surname">
-               <AnySite>
-            <AnyValue/>
-        </AnySite>
-       </AttributeRule>
-
-       <AttributeRule Name="urn:mace:dir:attribute-def:mail" Header="Shib-InetOrgPerson-mail">
-               <AnySite>
-            <AnyValue/>
-        </AnySite>
-       </AttributeRule>
-       
-       <AttributeRule Name="urn:mace:dir:attribute-def:telephoneNumber" Header="Shib-Person-telephoneNumber">
-               <AnySite>
-            <AnyValue/>
-        </AnySite>
-       </AttributeRule>
-       
-       <AttributeRule Name="urn:mace:dir:attribute-def:title" Header="Shib-OrgPerson-title">
-               <AnySite>
-            <AnyValue/>
-        </AnySite>
-       </AttributeRule>
-       
-       <AttributeRule Name="urn:mace:dir:attribute-def:initials" Header="Shib-InetOrgPerson-initials">
-               <AnySite>
-            <AnyValue/>
-        </AnySite>
-       </AttributeRule>
-       
-       <AttributeRule Name="urn:mace:dir:attribute-def:description" Header="Shib-Person-description">
-               <AnySite>
-            <AnyValue/>
-        </AnySite>
-       </AttributeRule>
-       
-       <AttributeRule Name="urn:mace:dir:attribute-def:carLicense" Header="Shib-InetOrgPerson-carLicense">
-               <AnySite>
-            <AnyValue/>
-        </AnySite>
-       </AttributeRule>
-       
-       <AttributeRule Name="urn:mace:dir:attribute-def:departmentNumber" Header="Shib-InetOrgPerson-deptNum">
-               <AnySite>
-            <AnyValue/>
-        </AnySite>
-       </AttributeRule>
-       
-       <AttributeRule Name="urn:mace:dir:attribute-def:displayName" Header="Shib-InetOrgPerson-displayName">
-               <AnySite>
-            <AnyValue/>
-        </AnySite>
-       </AttributeRule>
-       
-       <AttributeRule Name="urn:mace:dir:attribute-def:employeeNumber" Header="Shib-InetOrgPerson-employeeNum">
-               <AnySite>
-            <AnyValue/>
-        </AnySite>
-       </AttributeRule>
-       
-       <AttributeRule Name="urn:mace:dir:attribute-def:employeeType" Header="Shib-InetOrgPerson-employeeType">
-               <AnySite>
-            <AnyValue/>
-        </AnySite>
-       </AttributeRule>
-       
-       <AttributeRule Name="urn:mace:dir:attribute-def:preferredLanguage" Header="Shib-InetOrgPerson-prefLang">
-               <AnySite>
-            <AnyValue/>
-        </AnySite>
-       </AttributeRule>
-       
-       <AttributeRule Name="urn:mace:dir:attribute-def:manager" Header="Shib-InetOrgPerson-manager">
-               <AnySite>
-            <AnyValue/>
-        </AnySite>
-       </AttributeRule>
-       
-       <AttributeRule Name="urn:mace:dir:attribute-def:roomNumber" Header="Shib-InetOrgPerson-roomNum">
-               <AnySite>
-            <AnyValue/>
-        </AnySite>
-       </AttributeRule>
-       
-       <AttributeRule Name="urn:mace:dir:attribute-def:seeAlso" Header="Shib-OrgPerson-seeAlso">
-               <AnySite>
-            <AnyValue/>
-        </AnySite>
-       </AttributeRule>
-       
-       <AttributeRule Name="urn:mace:dir:attribute-def:facsimileTelephoneNumber" Header="Shib-OrgPerson-fax">
-               <AnySite>
-            <AnyValue/>
-        </AnySite>
-       </AttributeRule>
-       
-       <AttributeRule Name="urn:mace:dir:attribute-def:street" Header="Shib-OrgPerson-street">
-               <AnySite>
-            <AnyValue/>
-        </AnySite>
-       </AttributeRule>
-       
-       <AttributeRule Name="urn:mace:dir:attribute-def:postOfficeBox" Header="Shib-OrgPerson-POBox">
-               <AnySite>
-            <AnyValue/>
-        </AnySite>
-       </AttributeRule>
-       
-       <AttributeRule Name="urn:mace:dir:attribute-def:postalCode" Header="Shib-OrgPerson-postalCode">
-               <AnySite>
-            <AnyValue/>
-        </AnySite>
-       </AttributeRule>
-       
-       <AttributeRule Name="urn:mace:dir:attribute-def:st" Header="Shib-OrgPerson-state">
-               <AnySite>
-            <AnyValue/>
-        </AnySite>
-       </AttributeRule>
-       
-       <AttributeRule Name="urn:mace:dir:attribute-def:givenName" Header="Shib-InetOrgPerson-givenName">
-               <AnySite>
-            <AnyValue/>
-        </AnySite>
-       </AttributeRule>
-       
-       <AttributeRule Name="urn:mace:dir:attribute-def:l" Header="Shib-OrgPerson-locality">
-               <AnySite>
-            <AnyValue/>
-        </AnySite>
-       </AttributeRule>
-       
-       <AttributeRule Name="urn:mace:dir:attribute-def:businessCategory" Header="Shib-InetOrgPerson-businessCat">
-               <AnySite>
-            <AnyValue/>
-        </AnySite>
-       </AttributeRule>
-       
-       <AttributeRule Name="urn:mace:dir:attribute-def:ou" Header="Shib-OrgPerson-orgUnit">
-               <AnySite>
-            <AnyValue/>
-        </AnySite>
-       </AttributeRule>
-       
-       <AttributeRule Name="urn:mace:dir:attribute-def:physicalDeliveryOfficeName" Header="Shib-OrgPerson-OfficeName">
-               <AnySite>
-            <AnyValue/>
-        </AnySite>
-       </AttributeRule>
-       
-       -->
-
-</AttributeAcceptancePolicy>
index eeb0a6a..f403a34 100644 (file)
@@ -21,7 +21,7 @@ BUILTCONFIGFILES = \
        shibboleth.xml \
        native.logger \
        shibd.logger \
-       AAP.xml \
+       resolver-simple.xml \
        example-metadata.xml
 
 # While BUILTCONFIGFILES are processed, these are not; so we should pull
@@ -74,7 +74,7 @@ native.logger: ${srcdir}/native.logger.in Makefile ${top_builddir}/config.status
 shibboleth.xml: ${srcdir}/shibboleth.xml.in Makefile ${top_builddir}/config.status
        $(MAKE) do-build-file FILE=$@
 
-AAP.xml: ${srcdir}/AAP.xml.in Makefile ${top_builddir}/config.status
+resolver-simple.xml: ${srcdir}/resolver-simple.xml.in Makefile ${top_builddir}/config.status
        $(MAKE) do-build-file FILE=$@
 
 example-metadata.xml: ${srcdir}/example-metadata.xml.in Makefile ${top_builddir}/config.status
@@ -110,7 +110,7 @@ CLEANFILES = \
        shibd.logger \
        native.logger \
        shibboleth.xml \
-       AAP.xml \
+       resolver-simple.xml \
        example-metadata.xml
 
 EXTRA_DIST = .cvsignore \
@@ -128,7 +128,7 @@ EXTRA_DIST = .cvsignore \
        sessionError.html \
        metadataError.html \
        sslError.html \
-       AAP.xml.in \
+       resolver-simple.xml.in \
        example-metadata.xml.in \
        sp-example.key \
        sp-example.crt
diff --git a/configs/resolver-simple.xml.in b/configs/resolver-simple.xml.in
new file mode 100644 (file)
index 0000000..142a7d0
--- /dev/null
@@ -0,0 +1,78 @@
+<ar:AttributeResolver xmlns:ar="urn:mace:shibboleth:2.0:resolver:simple"
+       xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="urn:mace:shibboleth:2.0:resolver:simple @-PKGXMLDIR-@/shibboleth-2.0-simple-resolver.xsd"
+    allowQuery="true">
+
+       <!--
+       Built-in decoders that can extract SAML Attribute data.
+       Custom decoders can be configured here as well.
+       -->
+       <ar:AttributeDecoder id="Simple" type="Simple"/>
+       <ar:AttributeDecoder id="Scoped" type="Scoped"/>
+       <ar:AttributeDecoder id="NameID" type="NameID" formatter="$Name!!$NameQualifier!!$SPNameQualifier"/>
+       
+       <!--
+       The simple resolver just enumerates SAML Attribute elements, each one
+       referencing a specific Attribute by its name on the wire, and its local
+       "friendly" ID. All Attributes that should be visible to an application
+       should be listed, or they will be ignored by the resolver.
+       -->
+       
+       <!-- First some useful eduPerson attributes that many sites might use. -->
+       
+       <saml:Attribute Name="urn:mace:dir:attribute-def:eduPersonPrincipalName" FriendlyName="REMOTE_USER"     ar:decoderId="Scoped"/>
+       <saml:Attribute Name="urn:mace:dir:attribute-def:eduPersonScopedAffiliation" FriendlyName="affiliation" ar:decoderId="Scoped"/>
+       <saml:Attribute Name="urn:mace:dir:attribute-def:eduPersonAffiliation" FriendlyName="unscoped-affiliation" ar:decoderId="Simple"/>
+       <saml:Attribute Name="urn:mace:dir:attribute-def:eduPersonEntitlement" FriendlyName="entitlement" ar:decoderId="Simple"/>
+       
+       <!-- A persistent id attribute that supports personalized anonymous access. -->
+       
+       <!-- First, the deprecated version: -->
+       <saml:Attribute Name="urn:mace:dir:attribute-def:eduPersonTargetedID" FriendlyName="REMOTE_USER" ar:decoderId="Scoped"/>
+
+       <!-- Second, the new version (note the OID-style name): -->
+       <saml:Attribute Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10" FriendlyName="REMOTE_USER" ar:decoderId="NameID"/>
+
+       <!-- Third, the SAML 2.0 NameID Format: -->
+       <saml:Attribute Name="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" FriendlyName="REMOTE_USER" ar:decoderId="NameID"/>
+       
+       <!-- Some more eduPerson attributes, uncomment these to use them... -->
+       <!--
+       <saml:Attribute Name="urn:mace:dir:attribute-def:eduPersonNickname" FriendlyName="nickname" ar:decoderId="Simple"/>
+       <saml:Attribute Name="urn:mace:dir:attribute-def:eduPersonPrimaryAffiliation" FriendlyName="primary-affiliation" ar:decoderId="Simple"/>
+       <saml:Attribute Name="urn:mace:dir:attribute-def:eduPersonPrimaryOrgUnitDN" FriendlyName="primary-orgunit-dn" ar:decoderId="Simple"/>
+       <saml:Attribute Name="urn:mace:dir:attribute-def:eduPersonOrgUnitDN" FriendlyName="orgunit-dn" ar:decoderId="Simple"/>
+       <saml:Attribute Name="urn:mace:dir:attribute-def:eduPersonOrgDN" FriendlyName="org-dn" ar:decoderId="Simple"/>
+       -->
+
+       <!--Examples of LDAP-based attributes, uncomment to use these... -->
+       <!--
+       <saml:Attribute Name="urn:mace:dir:attribute-def:cn" FriendlyName="cn" ar:decoderId="Simple"/>
+       <saml:Attribute Name="urn:mace:dir:attribute-def:sn" FriendlyName="sn" ar:decoderId="Simple"/>
+       <saml:Attribute Name="urn:mace:dir:attribute-def:givenName" FriendlyName="givenName" ar:decoderId="Simple"/>
+       <saml:Attribute Name="urn:mace:dir:attribute-def:mail" FriendlyName="mail" ar:decoderId="Simple"/>
+       <saml:Attribute Name="urn:mace:dir:attribute-def:telephoneNumber" FriendlyName="telephoneNumber" ar:decoderId="Simple"/>
+       <saml:Attribute Name="urn:mace:dir:attribute-def:title" FriendlyName="title" ar:decoderId="Simple"/>
+       <saml:Attribute Name="urn:mace:dir:attribute-def:initials" FriendlyName="initials" ar:decoderId="Simple"/>
+       <saml:Attribute Name="urn:mace:dir:attribute-def:description" FriendlyName="description" ar:decoderId="Simple"/>
+       <saml:Attribute Name="urn:mace:dir:attribute-def:carLicense" FriendlyName="carLicense" ar:decoderId="Simple"/>
+       <saml:Attribute Name="urn:mace:dir:attribute-def:departmentNumber" FriendlyName="departmentNumber" ar:decoderId="Simple"/>
+       <saml:Attribute Name="urn:mace:dir:attribute-def:displayName" FriendlyName="displayName" ar:decoderId="Simple"/>
+       <saml:Attribute Name="urn:mace:dir:attribute-def:employeeNumber" FriendlyName="employeeNumber" ar:decoderId="Simple"/>
+       <saml:Attribute Name="urn:mace:dir:attribute-def:employeeType" FriendlyName="employeeType" ar:decoderId="Simple"/>
+       <saml:Attribute Name="urn:mace:dir:attribute-def:preferredLanguage" FriendlyName="preferredLanguage" ar:decoderId="Simple"/>
+       <saml:Attribute Name="urn:mace:dir:attribute-def:manager" FriendlyName="manager" ar:decoderId="Simple"/>
+       <saml:Attribute Name="urn:mace:dir:attribute-def:seeAlso" FriendlyName="seeAlso" ar:decoderId="Simple"/>
+       <saml:Attribute Name="urn:mace:dir:attribute-def:facsimileTelephoneNumber" FriendlyName="facsimileTelephoneNumber" ar:decoderId="Simple"/>
+       <saml:Attribute Name="urn:mace:dir:attribute-def:street" FriendlyName="street" ar:decoderId="Simple"/>
+       <saml:Attribute Name="urn:mace:dir:attribute-def:postOfficeBox" FriendlyName="postOfficeBox" ar:decoderId="Simple"/>
+       <saml:Attribute Name="urn:mace:dir:attribute-def:postalCode" FriendlyName="postalCode" ar:decoderId="Simple"/>
+       <saml:Attribute Name="urn:mace:dir:attribute-def:st" FriendlyName="st" ar:decoderId="Simple"/>
+       <saml:Attribute Name="urn:mace:dir:attribute-def:l" FriendlyName="l" ar:decoderId="Simple"/>
+       <saml:Attribute Name="urn:mace:dir:attribute-def:ou" FriendlyName="ou" ar:decoderId="Simple"/>
+       <saml:Attribute Name="urn:mace:dir:attribute-def:businessCategory" FriendlyName="businessCategory" ar:decoderId="Simple"/>
+       <saml:Attribute Name="urn:mace:dir:attribute-def:physicalDeliveryOfficeName" FriendlyName="physicalDeliveryOfficeName" ar:decoderId="Simple"/>
+       -->
+
+</ar::AttributeResolver>
index cae28ea..0eac855 100644 (file)
                        <TrustEngine type="PKIX"/>
                </TrustEngine>
 
+               <AttributeResolver type="Simple" path="@-PKGSYSCONFDIR-@/resolver-simple.xml"/>
        </Applications>
        
        <!-- Define all the private keys and certificates here that you reference from <CredentialUse>. -->
index 2e0ac6d..cf3710f 100644 (file)
     </element>
     <complexType name="AttributeResolverType">
         <sequence>
-            <element ref="saml:Attribute" minOccurs="0" maxOccurs="unbounded"/>
+            <element ref="resolver:AttributeDecoder" maxOccurs="unbounded"/>
+            <element ref="saml:Attribute" maxOccurs="unbounded"/>
         </sequence>
         <attribute name="allowQuery" type="boolean" default="true"/>
     </complexType>
 
+    <element name="AttributeDecoder">
+        <annotation>
+            <documentation>Instantiates decoders for use by Attribute definitions.</documentation>
+        </annotation>
+        <complexType>
+            <sequence>
+                <any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+            </sequence>
+            <attribute name="type" type="resolver:string" use="required"/>
+            <attribute name="id" type="ID" use="required"/>
+            <anyAttribute namespace="##any" processContents="lax"/>
+        </complexType>
+    </element>
+
     <simpleType name="string">
         <restriction base="string">
             <minLength value="1"/>
         </restriction>
     </simpleType>
 
-    <attribute name="decoderType" type="resolver:string"/>
+    <attribute name="decoderId" type="IDREF"/>
 </schema>
index ef03152..4040c10 100644 (file)
                                <element ref="saml:Audience" minOccurs="0" maxOccurs="unbounded"/>
                 <element name="MetadataProvider" type="conf:PluggableType"/>
                                <element name="TrustEngine" type="conf:PluggableType"/>\r
+                               <element name="AttributeResolver" type="conf:PluggableType"/>\r
                                <element ref="conf:Application" minOccurs="0" maxOccurs="unbounded"/>\r
                        </sequence>\r
                        <attribute name="id" type="conf:string" fixed="default"/>\r
                                <element ref="saml:Audience" minOccurs="0" maxOccurs="unbounded"/>\r
                                <element name="MetadataProvider" type="conf:PluggableType" minOccurs="0"/>\r
                                <element name="TrustEngine" type="conf:PluggableType" minOccurs="0"/>\r
+                               <element name="AttributeResolver" type="conf:PluggableType" minOccurs="0"/>\r
                        </sequence>\r
                        <attribute name="id" type="conf:string" use="required"/>\r
                        <attribute name="providerId" type="anyURI"/>\r
index 3d0632a..d7083d5 100644 (file)
@@ -119,9 +119,9 @@ int real_main(int preinit)
             (shar_checkonly ? (SPConfig::InProcess | SPConfig::RequestMapping) : SPConfig::Logging)\r
             );\r
         if (!shar_config)\r
-            shar_config=getenv("SHIBCONFIG");\r
+            shar_config=getenv("SHIBSP_CONFIG");\r
         if (!shar_schemadir)\r
-            shar_schemadir=getenv("SHIBSCHEMAS");\r
+            shar_schemadir=getenv("SHIBSP_SCHEMAS");\r
         if (!shar_schemadir)\r
             shar_schemadir=SHIBSP_SCHEMAS;\r
         if (!shar_config)\r
@@ -262,9 +262,9 @@ int main(int argc, char *argv[])
         usage(argv[0]);\r
 \r
     if (!shar_config)\r
-        shar_config=getenv("SHIBCONFIG");\r
+        shar_config=getenv("SHIBSP_CONFIG");\r
     if (!shar_schemadir)\r
-        shar_schemadir=getenv("SHIBSCHEMAS");\r
+        shar_schemadir=getenv("SHIBSP_SCHEMAS");\r
     if (!shar_schemadir)\r
         shar_schemadir=SHIBSP_SCHEMAS;\r
     if (!shar_config)\r
index eb90c61..89b31bb 100644 (file)
@@ -30,6 +30,7 @@
 
 namespace shibsp {
     
+    class SHIBSP_API AttributeResolver;
     class SHIBSP_API Handler;
     class SHIBSP_API ServiceProvider;
 
@@ -89,7 +90,14 @@ namespace shibsp {
          * @return  a TrustEngine instance, or NULL
          */
         virtual xmltooling::TrustEngine* getTrustEngine() const=0;
-        
+
+        /**
+         * Returns an AttributeResolver for use with this Application.
+         * 
+         * @return  an AttributeResolver, or NULL
+         */
+        virtual AttributeResolver* getAttributeResolver() const=0;
+
         /**
          * Returns configuration properties governing security interactions with a peer entity.
          * 
index 944a59c..e11ce75 100644 (file)
@@ -42,11 +42,15 @@ namespace shibsp {
         /**
          * Decodes an XMLObject into a resolved Attribute.
          * 
-         * @param id        ID of resolved attribute
-         * @param xmlObject XMLObject to decode
+         * @param id                ID of resolved attribute
+         * @param xmlObject         XMLObject to decode
+         * @param assertingParty    name of the party asserting the attribute
+         * @param relyingParty      name of the party relying on the attribute
          * @return a resolved Attribute
          */
-        virtual Attribute* decode(const char* id, const xmltooling::XMLObject* xmlObject) const=0;
+        virtual Attribute* decode(
+            const char* id, const xmltooling::XMLObject* xmlObject, const char* assertingParty=NULL, const char* relyingParty=NULL
+            ) const=0;
     };
 
     /** Decodes SimpleAttributes */
index c4885b1..76659c4 100644 (file)
@@ -44,11 +44,17 @@ namespace shibsp {
         NameIDAttributeDecoder(const DOMElement* e) : m_formatter(e ? e->getAttributeNS(NULL,formatter) : NULL) {}\r
         ~NameIDAttributeDecoder() {}\r
 \r
-        shibsp::Attribute* decode(const char* id, const XMLObject* xmlObject) const;\r
+        shibsp::Attribute* decode(\r
+            const char* id, const XMLObject* xmlObject, const char* assertingParty=NULL, const char* relyingParty=NULL\r
+            ) const;\r
 \r
     private:\r
-        void extract(const NameID* n, vector<NameIDAttribute::Value>& dest) const;\r
-        void extract(const NameIdentifier* n, vector<NameIDAttribute::Value>& dest) const;\r
+        void extract(\r
+            const NameIDType* n, vector<NameIDAttribute::Value>& dest, const char* assertingParty=NULL, const char* relyingParty=NULL\r
+            ) const;\r
+        void extract(\r
+            const NameIdentifier* n, vector<NameIDAttribute::Value>& dest, const char* assertingParty=NULL, const char* relyingParty=NULL\r
+            ) const;\r
         auto_ptr_char m_formatter;\r
     };\r
 \r
@@ -58,7 +64,9 @@ namespace shibsp {
     }\r
 };\r
 \r
-shibsp::Attribute* NameIDAttributeDecoder::decode(const char* id, const XMLObject* xmlObject) const\r
+shibsp::Attribute* NameIDAttributeDecoder::decode(\r
+    const char* id, const XMLObject* xmlObject, const char* assertingParty, const char* relyingParty\r
+    ) const\r
 {\r
     auto_ptr<NameIDAttribute> nameid(\r
         new NameIDAttribute(id, (m_formatter.get() && *m_formatter.get()) ? m_formatter.get() : DEFAULT_NAMEID_FORMATTER)\r
@@ -97,7 +105,7 @@ shibsp::Attribute* NameIDAttributeDecoder::decode(const char* id, const XMLObjec
         }\r
 \r
         for (; v!=stop; ++v) {\r
-            const NameID* n2 = dynamic_cast<const NameID*>(*v);\r
+            const NameIDType* n2 = dynamic_cast<const NameIDType*>(*v);\r
             if (n2)\r
                 extract(n2, dest);\r
             else {\r
@@ -107,7 +115,7 @@ shibsp::Attribute* NameIDAttributeDecoder::decode(const char* id, const XMLObjec
                 else if ((*v)->hasChildren()) {\r
                     const list<XMLObject*>& values = (*v)->getOrderedChildren();\r
                     for (list<XMLObject*>::const_iterator vv = values.begin(); vv!=values.end(); ++vv) {\r
-                        if (n2=dynamic_cast<const NameID*>(*vv))\r
+                        if (n2=dynamic_cast<const NameIDType*>(*vv))\r
                             extract(n2, dest);\r
                         else if (n1=dynamic_cast<const NameIdentifier*>(*vv))\r
                             extract(n1, dest);\r
@@ -121,7 +129,7 @@ shibsp::Attribute* NameIDAttributeDecoder::decode(const char* id, const XMLObjec
         return dest.empty() ? NULL : nameid.release();\r
     }\r
 \r
-    const NameID* saml2name = dynamic_cast<const NameID*>(xmlObject);\r
+    const NameIDType* saml2name = dynamic_cast<const NameIDType*>(xmlObject);\r
     if (saml2name) {\r
         if (log.isDebugEnabled()) {\r
             auto_ptr_char f(saml2name->getFormat());\r
@@ -147,7 +155,9 @@ shibsp::Attribute* NameIDAttributeDecoder::decode(const char* id, const XMLObjec
     return dest.empty() ? NULL : nameid.release();\r
 }\r
 \r
-void NameIDAttributeDecoder::extract(const NameID* n, vector<NameIDAttribute::Value>& dest) const\r
+void NameIDAttributeDecoder::extract(\r
+    const NameIDType* n, vector<NameIDAttribute::Value>& dest, const char* assertingParty, const char* relyingParty\r
+    ) const\r
 {\r
     char* name = toUTF8(n->getName());\r
     if (name && *name) {\r
@@ -159,16 +169,21 @@ void NameIDAttributeDecoder::extract(const NameID* n, vector<NameIDAttribute::Va
             val.m_Format = str;\r
             delete[] str;\r
         }\r
+        \r
         str = toUTF8(n->getNameQualifier());\r
-        if (str) {\r
+        if (str && *str)\r
             val.m_NameQualifier = str;\r
-            delete[] str;\r
-        }\r
+        else if (assertingParty)\r
+            val.m_NameQualifier = assertingParty;\r
+        delete[] str;\r
+        \r
         str = toUTF8(n->getSPNameQualifier());\r
-        if (str) {\r
+        if (str && *str)\r
             val.m_SPNameQualifier = str;\r
-            delete[] str;\r
-        }\r
+        else if (relyingParty)\r
+            val.m_SPNameQualifier = relyingParty;\r
+        delete[] str;\r
+        \r
         str = toUTF8(n->getSPProvidedID());\r
         if (str) {\r
             val.m_SPProvidedID = str;\r
@@ -178,7 +193,9 @@ void NameIDAttributeDecoder::extract(const NameID* n, vector<NameIDAttribute::Va
     delete[] name;\r
 }\r
 \r
-void NameIDAttributeDecoder::extract(const NameIdentifier* n, vector<NameIDAttribute::Value>& dest) const\r
+void NameIDAttributeDecoder::extract(\r
+    const NameIdentifier* n, vector<NameIDAttribute::Value>& dest, const char* assertingParty, const char* relyingParty\r
+    ) const\r
 {\r
     char* name = toUTF8(n->getName());\r
     if (name && *name) {\r
@@ -190,11 +207,16 @@ void NameIDAttributeDecoder::extract(const NameIdentifier* n, vector<NameIDAttri
             val.m_Format = str;\r
             delete[] str;\r
         }\r
+\r
         str = toUTF8(n->getNameQualifier());\r
-        if (str) {\r
+        if (str && *str)\r
             val.m_NameQualifier = str;\r
-            delete[] str;\r
-        }\r
+        else if (assertingParty)\r
+            val.m_NameQualifier = assertingParty;\r
+        delete[] str;\r
+        \r
+        if (relyingParty)\r
+            val.m_SPNameQualifier = relyingParty;\r
     }\r
     delete[] name;\r
 }\r
index a412d64..516474d 100644 (file)
@@ -42,7 +42,9 @@ namespace shibsp {
         ScopedAttributeDecoder(const DOMElement* e) {}\r
         ~ScopedAttributeDecoder() {}\r
 \r
-        shibsp::Attribute* decode(const char* id, const XMLObject* xmlObject) const;\r
+        shibsp::Attribute* decode(\r
+            const char* id, const XMLObject* xmlObject, const char* assertingParty=NULL, const char* relyingParty=NULL\r
+            ) const;\r
     };\r
 \r
     AttributeDecoder* SHIBSP_DLLLOCAL ScopedAttributeDecoderFactory(const DOMElement* const & e)\r
@@ -53,7 +55,9 @@ namespace shibsp {
     static const XMLCh Scope[] = UNICODE_LITERAL_5(S,c,o,p,e);\r
 };\r
 \r
-shibsp::Attribute* ScopedAttributeDecoder::decode(const char* id, const XMLObject* xmlObject) const\r
+shibsp::Attribute* ScopedAttributeDecoder::decode(\r
+    const char* id, const XMLObject* xmlObject, const char* assertingParty, const char* relyingParty\r
+    ) const\r
 {\r
     char* val;\r
     char* scope;\r
index 0dfc6c8..f781f38 100644 (file)
@@ -42,7 +42,9 @@ namespace shibsp {
         SimpleAttributeDecoder(const DOMElement* e) {}\r
         ~SimpleAttributeDecoder() {}\r
 \r
-        shibsp::Attribute* decode(const char* id, const XMLObject* xmlObject) const;\r
+        shibsp::Attribute* decode(\r
+            const char* id, const XMLObject* xmlObject, const char* assertingParty=NULL, const char* relyingParty=NULL\r
+            ) const;\r
     };\r
 \r
     AttributeDecoder* SHIBSP_DLLLOCAL SimpleAttributeDecoderFactory(const DOMElement* const & e)\r
@@ -51,7 +53,9 @@ namespace shibsp {
     }\r
 };\r
 \r
-shibsp::Attribute* SimpleAttributeDecoder::decode(const char* id, const XMLObject* xmlObject) const\r
+shibsp::Attribute* SimpleAttributeDecoder::decode(\r
+    const char* id, const XMLObject* xmlObject, const char* assertingParty, const char* relyingParty\r
+    ) const\r
 {\r
     char* val;\r
     auto_ptr<SimpleAttribute> simple(new SimpleAttribute(id));\r
index 294bc63..19f2e84 100644 (file)
@@ -226,9 +226,12 @@ namespace shibsp {
         chLatin_r, chLatin_e, chLatin_s, chLatin_o, chLatin_l, chLatin_v, chLatin_e, chLatin_r, chColon,\r
         chLatin_s, chLatin_i, chLatin_m, chLatin_p, chLatin_l, chLatin_e, chNull\r
     };\r
+    static const XMLCh _AttributeDecoder[] =    UNICODE_LITERAL_16(A,t,t,r,i,b,u,t,e,D,e,c,o,d,e,r);\r
     static const XMLCh _AttributeResolver[] =   UNICODE_LITERAL_17(A,t,t,r,i,b,u,t,e,R,e,s,o,l,v,e,r);\r
     static const XMLCh allowQuery[] =           UNICODE_LITERAL_10(a,l,l,o,w,Q,u,e,r,y);\r
-    static const XMLCh decoderType[] =          UNICODE_LITERAL_11(d,e,c,o,d,e,r,T,y,p,e);\r
+    static const XMLCh decoderId[] =            UNICODE_LITERAL_9(d,e,c,o,d,e,r,I,d);\r
+    static const XMLCh _id[] =                  UNICODE_LITERAL_2(i,d);\r
+    static const XMLCh _type[] =                UNICODE_LITERAL_4(t,y,p,e);\r
 };\r
 \r
 SimpleResolverImpl::SimpleResolverImpl(const DOMElement* e) : m_document(NULL), m_allowQuery(true)\r
@@ -246,42 +249,42 @@ SimpleResolverImpl::SimpleResolverImpl(const DOMElement* e) : m_document(NULL),
         log.info("SAML attribute queries disabled");\r
         m_allowQuery = false;\r
     }\r
+\r
+    DOMElement* child = XMLHelper::getFirstChildElement(e, SIMPLE_NS, _AttributeDecoder);\r
+    while (child) {\r
+        auto_ptr_char id(child->getAttributeNS(NULL, _id));\r
+        auto_ptr_char type(child->getAttributeNS(NULL, _type));\r
+        try {\r
+            log.info("building AttributeDecoder (%s) of type %s", id.get(), type.get());\r
+            m_decoderMap[id.get()] = SPConfig::getConfig().AttributeDecoderManager.newPlugin(type.get(), child);\r
+        }\r
+        catch (exception& ex) {\r
+            log.error("error building AttributeDecoder (%s): %s", id.get(), ex.what());\r
+        }\r
+        child = XMLHelper::getNextSiblingElement(child, SIMPLE_NS, _AttributeDecoder);\r
+    }\r
     \r
-    e = XMLHelper::getFirstChildElement(e, samlconstants::SAML20_NS, opensaml::saml2::Attribute::LOCAL_NAME);\r
-    while (e) {\r
+    child = XMLHelper::getFirstChildElement(e, samlconstants::SAML20_NS, opensaml::saml2::Attribute::LOCAL_NAME);\r
+    while (child) {\r
         // Check for missing Name.\r
-        const XMLCh* name = e->getAttributeNS(NULL, opensaml::saml2::Attribute::NAME_ATTRIB_NAME);\r
+        const XMLCh* name = child->getAttributeNS(NULL, opensaml::saml2::Attribute::NAME_ATTRIB_NAME);\r
         if (!name || !*name) {\r
             log.warn("skipping saml:Attribute declared with no Name");\r
-            e = XMLHelper::getNextSiblingElement(e, samlconstants::SAML20_NS, opensaml::saml2::Attribute::LOCAL_NAME);\r
+            child = XMLHelper::getNextSiblingElement(child, samlconstants::SAML20_NS, opensaml::saml2::Attribute::LOCAL_NAME);\r
             continue;\r
         }\r
 \r
-        auto_ptr_char id(e->getAttributeNS(NULL, opensaml::saml2::Attribute::FRIENDLYNAME_ATTRIB_NAME));\r
-        if (!id.get() || !*id.get()) {\r
-            log.warn("skipping saml:Attribute declared with no FriendlyName");\r
-            e = XMLHelper::getNextSiblingElement(e, samlconstants::SAML20_NS, opensaml::saml2::Attribute::LOCAL_NAME);\r
+        const AttributeDecoder* decoder=NULL;\r
+        auto_ptr_char id(child->getAttributeNS(NULL, opensaml::saml2::Attribute::FRIENDLYNAME_ATTRIB_NAME));\r
+        auto_ptr_char d(child->getAttributeNS(SIMPLE_NS, decoderId));\r
+        if (!id.get() || !*id.get() || !d.get() || !*d.get() || !(decoder=m_decoderMap[d.get()])) {\r
+            log.warn("skipping saml:Attribute declared with no FriendlyName or resolvable AttributeDecoder");\r
+            child = XMLHelper::getNextSiblingElement(child, samlconstants::SAML20_NS, opensaml::saml2::Attribute::LOCAL_NAME);\r
             continue;\r
         }\r
         \r
-        auto_ptr_char d(e->getAttributeNS(SIMPLE_NS, decoderType));\r
-        const char* dtype = d.get();\r
-        if (!dtype || !*dtype)\r
-            dtype = SIMPLE_ATTRIBUTE_DECODER;\r
-        AttributeDecoder*& decoder = m_decoderMap[dtype];\r
-        if (!decoder) {\r
-            try {\r
-                decoder = SPConfig::getConfig().AttributeDecoderManager.newPlugin(dtype, NULL);\r
-            }\r
-            catch (exception& ex) {\r
-                log.error("error building AttributeDecoder: %s", ex.what());\r
-                e = XMLHelper::getNextSiblingElement(e, samlconstants::SAML20_NS, opensaml::saml2::Attribute::LOCAL_NAME);\r
-                continue;\r
-            }\r
-        }\r
-                \r
         // Empty NameFormat implies the usual Shib URI naming defaults.\r
-        const XMLCh* format = e->getAttributeNS(NULL, opensaml::saml2::Attribute::NAMEFORMAT_ATTRIB_NAME);\r
+        const XMLCh* format = child->getAttributeNS(NULL, opensaml::saml2::Attribute::NAMEFORMAT_ATTRIB_NAME);\r
         if (!format || XMLString::equals(format, shibspconstants::SHIB1_ATTRIBUTE_NAMESPACE_URI) ||\r
                 XMLString::equals(format, opensaml::saml2::Attribute::URI_REFERENCE))\r
             format = &chNull;  // ignore default Format/Namespace values\r
@@ -296,7 +299,7 @@ SimpleResolverImpl::SimpleResolverImpl(const DOMElement* e) : m_document(NULL),
 #endif\r
         if (decl.first) {\r
             log.warn("skipping duplicate saml:Attribute declaration (same Name and NameFormat)");\r
-            e = XMLHelper::getNextSiblingElement(e, samlconstants::SAML20_NS, opensaml::saml2::Attribute::LOCAL_NAME);\r
+            child = XMLHelper::getNextSiblingElement(child, samlconstants::SAML20_NS, opensaml::saml2::Attribute::LOCAL_NAME);\r
             continue;\r
         }\r
 \r
@@ -305,13 +308,13 @@ SimpleResolverImpl::SimpleResolverImpl(const DOMElement* e) : m_document(NULL),
             auto_ptr_char n(name);\r
             auto_ptr_char f(format);\r
 #endif\r
-            log.debug("creating declaration for (Name=%s) %s%s)", n.get(), *f.get() ? "(Format/Namespace=" : "", f.get());\r
+            log.debug("creating declaration for Attribute %s%s%s", n.get(), *f.get() ? ", Format/Namespace:" : "", f.get());\r
         }\r
         \r
         decl.first = decoder;\r
         decl.second = id.get();\r
         \r
-        e = XMLHelper::getNextSiblingElement(e, samlconstants::SAML20_NS, opensaml::saml2::Attribute::LOCAL_NAME);\r
+        child = XMLHelper::getNextSiblingElement(child, samlconstants::SAML20_NS, opensaml::saml2::Attribute::LOCAL_NAME);\r
     }\r
 }\r
 \r
@@ -326,6 +329,9 @@ void SimpleResolverImpl::resolve(
 \r
     vector<shibsp::Attribute*>& resolved = ctx.getResolvedAttributes();\r
 \r
+    auto_ptr_char assertingParty(ctx.getEntityDescriptor() ? ctx.getEntityDescriptor()->getEntityID() : NULL);\r
+    const char* relyingParty = ctx.getApplication().getString("providerId").second;\r
+\r
 #ifdef HAVE_GOOD_STL\r
     map< pair<xstring,xstring>,pair<const AttributeDecoder*,string> >::const_iterator rule;\r
 #else\r
@@ -343,8 +349,13 @@ void SimpleResolverImpl::resolve(
         auto_ptr_char temp(format);\r
         if ((rule=m_attrMap.find(make_pair(temp.get(),string()))) != m_attrMap.end()) {\r
 #endif\r
-            if (aset.empty() || aset.count(rule->second.second))\r
-                resolved.push_back(rule->second.first->decode(rule->second.second.c_str(), &ctx.getNameID()));\r
+            if (aset.empty() || aset.count(rule->second.second)) {\r
+                resolved.push_back(\r
+                    rule->second.first->decode(\r
+                        rule->second.second.c_str(), &ctx.getNameID(), assertingParty.get(), relyingParty\r
+                        )\r
+                    );\r
+            }\r
         }\r
     }\r
 \r
@@ -365,8 +376,11 @@ void SimpleResolverImpl::resolve(
             auto_ptr_char temp2(format);\r
             if ((rule=m_attrMap.find(make_pair(temp1.get(),temp2.get()))) != m_attrMap.end()) {\r
 #endif\r
-            if (aset.empty() || aset.count(rule->second.second))\r
-                resolved.push_back(rule->second.first->decode(rule->second.second.c_str(), *a));\r
+                if (aset.empty() || aset.count(rule->second.second)) {\r
+                    resolved.push_back(\r
+                        rule->second.first->decode(rule->second.second.c_str(), *a, assertingParty.get(), relyingParty)\r
+                        );\r
+                }\r
             }\r
         }\r
     }\r
@@ -383,6 +397,9 @@ void SimpleResolverImpl::resolve(
 \r
     vector<shibsp::Attribute*>& resolved = ctx.getResolvedAttributes();\r
 \r
+    auto_ptr_char assertingParty(ctx.getEntityDescriptor() ? ctx.getEntityDescriptor()->getEntityID() : NULL);\r
+    const char* relyingParty = ctx.getApplication().getString("providerId").second;\r
+\r
 #ifdef HAVE_GOOD_STL\r
     map< pair<xstring,xstring>,pair<const AttributeDecoder*,string> >::const_iterator rule;\r
 #else\r
@@ -400,8 +417,13 @@ void SimpleResolverImpl::resolve(
         auto_ptr_char temp(format);\r
         if ((rule=m_attrMap.find(make_pair(temp.get(),string()))) != m_attrMap.end()) {\r
 #endif\r
-            if (aset.empty() || aset.count(rule->second.second))\r
-                resolved.push_back(rule->second.first->decode(rule->second.second.c_str(), &ctx.getNameID()));\r
+            if (aset.empty() || aset.count(rule->second.second)) {\r
+                resolved.push_back(\r
+                    rule->second.first->decode(\r
+                        rule->second.second.c_str(), &ctx.getNameID(), assertingParty.get(), relyingParty\r
+                        )\r
+                    );\r
+            }\r
         }\r
     }\r
 \r
@@ -422,8 +444,11 @@ void SimpleResolverImpl::resolve(
             auto_ptr_char temp2(format);\r
             if ((rule=m_attrMap.find(make_pair(temp1.get(),temp2.get()))) != m_attrMap.end()) {\r
 #endif\r
-            if (aset.empty() || aset.count(rule->second.second))\r
-                resolved.push_back(rule->second.first->decode(rule->second.second.c_str(), *a));\r
+                if (aset.empty() || aset.count(rule->second.second)) {\r
+                    resolved.push_back(\r
+                        rule->second.first->decode(rule->second.second.c_str(), *a, assertingParty.get(), relyingParty)\r
+                        );\r
+                }\r
             }\r
         }\r
     }\r
index e6d9da8..209b504 100644 (file)
@@ -31,7 +31,7 @@
 #include "SPConfig.h"\r
 #include "SPRequest.h"\r
 #include "TransactionLog.h"\r
-#include "attribute/Attribute.h"\r
+#include "attribute/resolver/AttributeResolver.h"\r
 #include "remoting/ListenerService.h"\r
 #include "security/PKIXTrustEngine.h"\r
 #include "util/DOMPropertySet.h"\r
@@ -93,14 +93,23 @@ namespace {
         pair<bool,const XMLCh*> getXMLString(const char* name, const char* ns=NULL) const;\r
         pair<bool,unsigned int> getUnsignedInt(const char* name, const char* ns=NULL) const;\r
         pair<bool,int> getInt(const char* name, const char* ns=NULL) const;\r
-        const PropertySet* getPropertySet(const char* name, const char* ns="urn:mace:shibboleth:target:config:1.0") const;\r
+        const PropertySet* getPropertySet(const char* name, const char* ns="urn:mace:shibboleth:sp:config:2.0") const;\r
 \r
         // Application\r
         const ServiceProvider& getServiceProvider() const {return *m_sp;}\r
         const char* getId() const {return getString("id").second;}\r
         const char* getHash() const {return m_hash.c_str();}\r
-        MetadataProvider* getMetadataProvider() const;\r
-        TrustEngine* getTrustEngine() const;\r
+\r
+        MetadataProvider* getMetadataProvider() const {\r
+            return (!m_metadata && m_base) ? m_base->getMetadataProvider() : m_metadata;\r
+        }\r
+        TrustEngine* getTrustEngine() const {\r
+            return (!m_trust && m_base) ? m_base->getTrustEngine() : m_trust;\r
+        }\r
+        AttributeResolver* getAttributeResolver() const {\r
+            return (!m_attrResolver && m_base) ? m_base->getAttributeResolver() : m_attrResolver;\r
+        }\r
+\r
         const PropertySet* getCredentialUse(const EntityDescriptor* provider) const;\r
 \r
         const Handler* getDefaultSessionInitiator() const;\r
@@ -110,13 +119,13 @@ namespace {
         const vector<const Handler*>& getAssertionConsumerServicesByBinding(const XMLCh* binding) const;\r
         const Handler* getHandler(const char* path) const;\r
 \r
-        const vector<const XMLCh*>& getAudiences() const;\r
+        const vector<const XMLCh*>& getAudiences() const {\r
+            return (m_audiences.empty() && m_base) ? m_base->getAudiences() : m_audiences;\r
+        }\r
         Validator* getTokenValidator(time_t ts=0, const opensaml::saml2md::RoleDescriptor* role=NULL) const {\r
             return new TokenValidator(*this, ts, role);\r
         }\r
 \r
-        void validator(const XMLObject* xmlObject) const;\r
-\r
         // Provides filter to exclude special config elements.\r
         short acceptNode(const DOMNode* node) const;\r
     \r
@@ -127,6 +136,7 @@ namespace {
         string m_hash;\r
         MetadataProvider* m_metadata;\r
         TrustEngine* m_trust;\r
+        AttributeResolver* m_attrResolver;\r
         vector<const XMLCh*> m_audiences;\r
 \r
         // manage handler objects\r
@@ -299,6 +309,7 @@ namespace {
 \r
     static const XMLCh _Application[] =         UNICODE_LITERAL_11(A,p,p,l,i,c,a,t,i,o,n);\r
     static const XMLCh Applications[] =         UNICODE_LITERAL_12(A,p,p,l,i,c,a,t,i,o,n,s);\r
+    static const XMLCh _AttributeResolver[] =   UNICODE_LITERAL_17(A,t,t,r,i,b,u,t,e,R,e,s,o,l,v,e,r);\r
     static const XMLCh Credentials[] =          UNICODE_LITERAL_11(C,r,e,d,e,n,t,i,a,l,s);\r
     static const XMLCh CredentialUse[] =        UNICODE_LITERAL_13(C,r,e,d,e,n,t,i,a,l,U,s,e);\r
     static const XMLCh fatal[] =                UNICODE_LITERAL_5(f,a,t,a,l);\r
@@ -465,7 +476,7 @@ XMLApplication::XMLApplication(
     const ServiceProvider* sp,\r
     const DOMElement* e,\r
     const XMLApplication* base\r
-    ) : m_sp(sp), m_base(base), m_metadata(NULL), m_trust(NULL),\r
+    ) : m_sp(sp), m_base(base), m_metadata(NULL), m_trust(NULL), m_attrResolver(NULL),\r
         m_credDefault(NULL), m_sessionInitDefault(NULL), m_acsDefault(NULL)\r
 {\r
 #ifdef _DEBUG\r
@@ -600,10 +611,6 @@ XMLApplication::XMLApplication(
         // Always include our own providerId as an audience.\r
         m_audiences.push_back(getXMLString("providerId").second);\r
 \r
-        if (conf.isEnabled(SPConfig::AttributeResolution)) {\r
-            // TODO\r
-        }\r
-\r
         if (conf.isEnabled(SPConfig::Metadata)) {\r
             child = XMLHelper::getFirstChildElement(e,_MetadataProvider);\r
             if (child) {\r
@@ -629,11 +636,25 @@ XMLApplication::XMLApplication(
                     m_trust = xmlConf.TrustEngineManager.newPlugin(type.get(),child);\r
                 }\r
                 catch (exception& ex) {\r
-                    log.crit("error building TrustEngine: %s",ex.what());\r
+                    log.crit("error building TrustEngine: %s", ex.what());\r
                 }\r
             }\r
         }\r
-        \r
+\r
+        if (conf.isEnabled(SPConfig::AttributeResolution)) {\r
+            child = XMLHelper::getFirstChildElement(e,_AttributeResolver);\r
+            if (child) {\r
+                auto_ptr_char type(child->getAttributeNS(NULL,_type));\r
+                log.info("building AttributeResolver of type %s...",type.get());\r
+                try {\r
+                    m_attrResolver = conf.AttributeResolverManager.newPlugin(type.get(),child);\r
+                }\r
+                catch (exception& ex) {\r
+                    log.crit("error building AttributeResolver: %s", ex.what());\r
+                }\r
+            }\r
+        }\r
+\r
         // Finally, load credential mappings.\r
         child = XMLHelper::getFirstChildElement(e,CredentialUse);\r
         if (child) {\r
@@ -676,6 +697,7 @@ void XMLApplication::cleanup()
     for_each(m_credMap.begin(),m_credMap.end(),cleanup_pair<const XMLCh*,PropertySet>());\r
 #endif\r
 \r
+    delete m_attrResolver;\r
     delete m_trust;\r
     delete m_metadata;\r
 }\r
@@ -695,7 +717,8 @@ short XMLApplication::acceptNode(const DOMNode* node) const
         XMLString::equals(name,CredentialUse) ||\r
         XMLString::equals(name,RelyingParty) ||\r
         XMLString::equals(name,_MetadataProvider) ||\r
-        XMLString::equals(name,_TrustEngine))\r
+        XMLString::equals(name,_TrustEngine) ||\r
+        XMLString::equals(name,_AttributeResolver))\r
         return FILTER_REJECT;\r
 \r
     return FILTER_ACCEPT;\r
@@ -749,21 +772,6 @@ const PropertySet* XMLApplication::getPropertySet(const char* name, const char*
     return m_base->getPropertySet(name,ns);\r
 }\r
 \r
-MetadataProvider* XMLApplication::getMetadataProvider() const\r
-{\r
-    return (!m_metadata && m_base) ? m_base->getMetadataProvider() : m_metadata;\r
-}\r
-\r
-TrustEngine* XMLApplication::getTrustEngine() const\r
-{\r
-    return (!m_trust && m_base) ? m_base->getTrustEngine() : m_trust;\r
-}\r
-\r
-const vector<const XMLCh*>& XMLApplication::getAudiences() const\r
-{\r
-    return (m_audiences.empty() && m_base) ? m_base->getAudiences() : m_audiences;\r
-}\r
-\r
 const PropertySet* XMLApplication::getCredentialUse(const EntityDescriptor* provider) const\r
 {\r
     if (!m_credDefault && m_base)\r