2 * The Shibboleth License, Version 1.
4 * University Corporation for Advanced Internet Development, Inc.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
11 * Redistributions of source code must retain the above copyright notice, this
12 * list of conditions and the following disclaimer.
14 * Redistributions in binary form must reproduce the above copyright notice,
15 * this list of conditions and the following disclaimer in the documentation
16 * and/or other materials provided with the distribution, if any, must include
17 * the following acknowledgment: "This product includes software developed by
18 * the University Corporation for Advanced Internet Development
19 * <http://www.ucaid.edu>Internet2 Project. Alternately, this acknowledegement
20 * may appear in the software itself, if and wherever such third-party
21 * acknowledgments normally appear.
23 * Neither the name of Shibboleth nor the names of its contributors, nor
24 * Internet2, nor the University Corporation for Advanced Internet Development,
25 * Inc., nor UCAID may be used to endorse or promote products derived from this
26 * software without specific prior written permission. For written permission,
27 * please contact shibboleth@shibboleth.org
29 * Products derived from this software may not be called Shibboleth, Internet2,
30 * UCAID, or the University Corporation for Advanced Internet Development, nor
31 * may Shibboleth appear in their name, without prior written permission of the
32 * University Corporation for Advanced Internet Development.
35 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
36 * AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
38 * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK
39 * OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE.
40 * IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY
41 * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. BE LIABLE FOR ANY DIRECT,
42 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
43 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
44 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
47 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50 /* ArtifactMapper.cpp - a ShibTarget-aware SAML artifact->binding mapper
60 #include <log4cpp/Category.hh>
63 using namespace log4cpp;
65 using namespace shibboleth;
66 using namespace shibtarget;
68 SAMLBrowserProfile::ArtifactMapper::ArtifactMapperResponse STArtifactMapper::map(const SAMLArtifact* artifact)
70 Category& log=Category::getInstance("shibtarget.ArtifactMapper");
72 // First do a search for the issuer.
73 const IEntityDescriptor* entity=m_metadata.lookup(artifact);
76 "metadata lookup failed, unable to determine issuer of artifact (0x%s)",
77 SAMLArtifact::toHex(artifact->getBytes()).c_str()
79 throw MetadataException("ArtifactMapper::map() metadata lookup failed, unable to determine artifact issuer");
82 SAMLBrowserProfile::ArtifactMapper::ArtifactMapperResponse amr;
83 auto_ptr_char issuer(entity->getId());
84 log.info("lookup succeeded, artifact issued by (%s)", issuer.get());
85 amr.source=issuer.get();
87 const IPropertySet* credUse=m_app->getCredentialUse(entity);
89 // Depends on type of artifact.
90 const SAMLArtifactType0001* type1=dynamic_cast<const SAMLArtifactType0001*>(artifact);
92 // With type 01, any endpoint will do. Try SAML 1.1 first.
93 const IIDPSSODescriptor* idp=entity->getIDPSSODescriptor(saml::XML::SAML11_PROTOCOL_ENUM);
95 const IEndpointManager* mgr=idp->getArtifactResolutionServiceManager();
96 Iterator<const IEndpoint*> eps=mgr ? mgr->getEndpoints() : EMPTY(const IEndpoint*);
97 while (eps.hasNext()) {
98 const IEndpoint* ep=eps.next();
99 amr.binding = m_app->getBinding(ep->getBinding());
101 auto_ptr_char loc(ep->getLocation());
102 amr.endpoint = loc.get();
103 amr.callCtx = new ShibHTTPHook::ShibHTTPHookCallContext(credUse ? credUse->getString("TLS").second : NULL,idp);
109 // No compatible 1.1 binding, try 1.0...
110 idp=entity->getIDPSSODescriptor(saml::XML::SAML10_PROTOCOL_ENUM);
112 const IEndpointManager* mgr=idp->getArtifactResolutionServiceManager();
113 Iterator<const IEndpoint*> eps=mgr ? mgr->getEndpoints() : EMPTY(const IEndpoint*);
114 while (eps.hasNext()) {
115 const IEndpoint* ep=eps.next();
116 amr.binding = m_app->getBinding(ep->getBinding());
118 auto_ptr_char loc(ep->getLocation());
119 amr.endpoint = loc.get();
120 amr.callCtx = new ShibHTTPHook::ShibHTTPHookCallContext(credUse ? credUse->getString("TLS").second : NULL,idp);
127 const SAMLArtifactType0002* type2=dynamic_cast<const SAMLArtifactType0002*>(artifact);
129 // With type 02, we have to find the matching location. Try SAML 1.1 first.
130 const IIDPSSODescriptor* idp=entity->getIDPSSODescriptor(saml::XML::SAML11_PROTOCOL_ENUM);
132 const IEndpointManager* mgr=idp->getArtifactResolutionServiceManager();
133 Iterator<const IEndpoint*> eps=mgr ? mgr->getEndpoints() : EMPTY(const IEndpoint*);
134 while (eps.hasNext()) {
135 const IEndpoint* ep=eps.next();
136 auto_ptr_char loc(ep->getLocation());
137 if (!strcmp(loc.get(),type2->getSourceLocation())) {
138 amr.binding = m_app->getBinding(ep->getBinding());
140 amr.endpoint = loc.get();
141 amr.callCtx = new ShibHTTPHook::ShibHTTPHookCallContext(credUse ? credUse->getString("TLS").second : NULL,idp);
148 // No match for 1.1, try 1.0...
149 idp=entity->getIDPSSODescriptor(saml::XML::SAML10_PROTOCOL_ENUM);
151 const IEndpointManager* mgr=idp->getArtifactResolutionServiceManager();
152 Iterator<const IEndpoint*> eps=mgr ? mgr->getEndpoints() : EMPTY(const IEndpoint*);
153 while (eps.hasNext()) {
154 const IEndpoint* ep=eps.next();
155 auto_ptr_char loc(ep->getLocation());
156 if (!strcmp(loc.get(),type2->getSourceLocation())) {
157 amr.binding = m_app->getBinding(ep->getBinding());
159 amr.endpoint = loc.get();
160 amr.callCtx = new ShibHTTPHook::ShibHTTPHookCallContext(credUse ? credUse->getString("TLS").second : NULL,idp);
168 log.error("unrecognized artifact type (0x%s)", SAMLArtifact::toHex(artifact->getTypeCode()).c_str());
169 throw UnsupportedExtensionException(
170 string("ArtifactMapper::map() unrecognized artifact type (0x") + SAMLArtifact::toHex(artifact->getTypeCode()) + ")"
175 log.error("unable to locate acceptable binding endpoint to resolve artifact");
176 MetadataException ex("Unable to locate acceptable binding endpoint to resolve artifact.");
177 annotateException(ex,entity,false);