2 * Licensed to the University Corporation for Advanced Internet
3 * Development, Inc. (UCAID) under one or more contributor license
4 * agreements. See the NOTICE file distributed with this work for
5 * additional information regarding copyright ownership.
7 * UCAID licenses this file to you under the Apache License,
8 * Version 2.0 (the "License"); you may not use this file except
9 * in compliance with the License. You may obtain a copy of the
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
17 * either express or implied. See the License for the specific
18 * language governing permissions and limitations under the License.
22 * DelegationAttributeExtractor.cpp
24 * AttributeExtractor for DelegationRestriction information.
28 #include "Application.h"
29 #include "ServiceProvider.h"
30 #include "attribute/ExtensibleAttribute.h"
31 #include "attribute/resolver/AttributeExtractor.h"
32 #include "util/SPConstants.h"
34 #include <saml/saml2/core/Assertions.h>
35 #include <saml/saml2/metadata/Metadata.h>
36 #include <saml/saml2/metadata/MetadataCredentialCriteria.h>
37 #include <xmltooling/security/CredentialResolver.h>
38 #include <xmltooling/util/DateTime.h>
39 #include <xmltooling/util/XMLHelper.h>
40 #include <xercesc/util/XMLUniDefs.hpp>
42 using namespace shibsp;
43 using namespace opensaml::saml2md;
44 using namespace opensaml;
45 using namespace xmltooling;
50 #if defined (_MSC_VER)
51 #pragma warning( push )
52 #pragma warning( disable : 4250 )
55 class DelegationExtractor : public AttributeExtractor
58 DelegationExtractor(const DOMElement* e);
59 ~DelegationExtractor() {}
68 void extractAttributes(
69 const Application& application, const RoleDescriptor* issuer, const XMLObject& xmlObject, vector<Attribute*>& attributes
72 void getAttributeIds(std::vector<std::string>& attributes) const {
73 attributes.push_back(m_attributeId);
77 string m_attributeId,m_formatter;
80 #if defined (_MSC_VER)
81 #pragma warning( pop )
84 AttributeExtractor* SHIBSP_DLLLOCAL DelegationAttributeExtractorFactory(const DOMElement* const & e)
86 return new DelegationExtractor(e);
89 static const XMLCh attributeId[] = UNICODE_LITERAL_11(a,t,t,r,i,b,u,t,e,I,d);
90 static const XMLCh formatter[] = UNICODE_LITERAL_9(f,o,r,m,a,t,t,e,r);
93 DelegationExtractor::DelegationExtractor(const DOMElement* e)
94 : m_attributeId(XMLHelper::getAttrString(e, "delegate", attributeId)),
95 m_formatter(XMLHelper::getAttrString(e, "$Name", formatter))
99 void DelegationExtractor::extractAttributes(
100 const Application& application, const RoleDescriptor* issuer, const XMLObject& xmlObject, vector<Attribute*>& attributes
103 const saml2::Assertion* assertion = dynamic_cast<const saml2::Assertion*>(&xmlObject);
104 if (!assertion || !assertion->getConditions())
107 Category& log = Category::getInstance(SHIBSP_LOGCAT".AttributeExtractor.Delegation");
109 const vector<saml2::Condition*>& conditions = const_cast<const saml2::Conditions*>(assertion->getConditions())->getConditions();
110 for (vector<saml2::Condition*>::const_iterator c = conditions.begin(); c != conditions.end(); ++c) {
111 const saml2::DelegationRestrictionType* drt = dynamic_cast<const saml2::DelegationRestrictionType*>(*c);
113 auto_ptr<ExtensibleAttribute> attr(new ExtensibleAttribute(vector<string>(1,m_attributeId), m_formatter.c_str()));
115 const vector<saml2::Delegate*>& dels = drt->getDelegates();
116 for (vector<saml2::Delegate*>::const_iterator d = dels.begin(); d != dels.end(); ++d) {
117 if ((*d)->getBaseID()) {
118 log.error("delegate identified by saml:BaseID cannot be processed into an attribute value");
122 saml2::NameID* n = nullptr;
123 if ((*d)->getEncryptedID()) {
124 CredentialResolver* cr = application.getCredentialResolver();
126 log.warn("found encrypted Delegate, but no CredentialResolver was available");
130 const XMLCh* recipient = application.getRelyingParty(
131 issuer ? dynamic_cast<EntityDescriptor*>(issuer->getParent()) : nullptr
132 )->getXMLString("entityID").second;
133 Locker credlocker(cr);
135 MetadataCredentialCriteria mcc(*issuer);
136 auto_ptr<XMLObject> decrypted((*d)->getEncryptedID()->decrypt(*cr, recipient, &mcc));
137 n = dynamic_cast<saml2::NameID*>(decrypted.release());
140 auto_ptr<XMLObject> decrypted((*d)->getEncryptedID()->decrypt(*cr, recipient));
141 n = dynamic_cast<saml2::NameID*>(decrypted.release());
143 if (n && log.isDebugEnabled())
144 log.debugStream() << "decrypted Delegate: " << *n << logging::eol;
146 catch (exception& ex) {
147 log.error("caught exception decrypting Delegate: %s", ex.what());
151 n = (*d)->getNameID();
155 DDF val = DDF(nullptr).structure();
156 if ((*d)->getConfirmationMethod()) {
157 auto_ptr_char temp((*d)->getConfirmationMethod());
158 val.addmember("ConfirmationMethod").string(temp.get());
160 if ((*d)->getDelegationInstant()) {
161 auto_ptr_char temp((*d)->getDelegationInstant()->getRawData());
162 val.addmember("DelegationInstant").string(temp.get());
165 auto_arrayptr<char> name(toUTF8(n->getName()));
166 if (name.get() && *name.get()) {
167 val.addmember("Name").string(name.get());
168 char* str = toUTF8(n->getFormat());
170 val.addmember("Format").string(str);
173 str = toUTF8(n->getNameQualifier());
175 val.addmember("NameQualifier").string(str);
178 str = toUTF8(n->getSPNameQualifier());
180 val.addmember("SPNameQualifier").string(str);
183 str = toUTF8(n->getSPProvidedID());
185 val.addmember("SPProvidedID").string(str);
189 if (n != (*d)->getNameID())
193 attr->getValues().add(val);
199 attributes.push_back(attr.release());