2 * Copyright 2009-2010 Internet2
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 * DelegationAttributeExtractor.cpp
20 * AttributeExtractor for DelegationRestriction information.
24 #include "Application.h"
25 #include "ServiceProvider.h"
26 #include "attribute/ExtensibleAttribute.h"
27 #include "attribute/resolver/AttributeExtractor.h"
28 #include "util/SPConstants.h"
30 #include <saml/saml2/core/Assertions.h>
31 #include <saml/saml2/metadata/Metadata.h>
32 #include <saml/saml2/metadata/MetadataCredentialCriteria.h>
33 #include <xmltooling/security/CredentialResolver.h>
34 #include <xmltooling/util/DateTime.h>
35 #include <xmltooling/util/XMLHelper.h>
36 #include <xercesc/util/XMLUniDefs.hpp>
38 using namespace shibsp;
39 using namespace opensaml::saml2md;
40 using namespace opensaml;
41 using namespace xmltooling;
46 #if defined (_MSC_VER)
47 #pragma warning( push )
48 #pragma warning( disable : 4250 )
51 class DelegationExtractor : public AttributeExtractor
54 DelegationExtractor(const DOMElement* e);
55 ~DelegationExtractor() {}
64 void extractAttributes(
65 const Application& application, const RoleDescriptor* issuer, const XMLObject& xmlObject, vector<Attribute*>& attributes
68 void getAttributeIds(std::vector<std::string>& attributes) const {
69 attributes.push_back(m_attributeId);
73 string m_attributeId,m_formatter;
76 #if defined (_MSC_VER)
77 #pragma warning( pop )
80 AttributeExtractor* SHIBSP_DLLLOCAL DelegationAttributeExtractorFactory(const DOMElement* const & e)
82 return new DelegationExtractor(e);
85 static const XMLCh attributeId[] = UNICODE_LITERAL_11(a,t,t,r,i,b,u,t,e,I,d);
86 static const XMLCh formatter[] = UNICODE_LITERAL_9(f,o,r,m,a,t,t,e,r);
89 DelegationExtractor::DelegationExtractor(const DOMElement* e) : m_attributeId("delegate"), m_formatter("$Name")
92 const XMLCh* a = e->getAttributeNS(nullptr, attributeId);
94 auto_ptr_char temp(a);
95 m_attributeId = temp.get();
97 a = e->getAttributeNS(nullptr, formatter);
99 auto_ptr_char temp(a);
100 m_formatter = temp.get();
105 void DelegationExtractor::extractAttributes(
106 const Application& application, const RoleDescriptor* issuer, const XMLObject& xmlObject, vector<Attribute*>& attributes
109 const saml2::Assertion* assertion = dynamic_cast<const saml2::Assertion*>(&xmlObject);
110 if (!assertion || !assertion->getConditions())
113 Category& log = Category::getInstance(SHIBSP_LOGCAT".AttributeExtractor.Delegation");
115 const vector<saml2::Condition*>& conditions = const_cast<const saml2::Conditions*>(assertion->getConditions())->getConditions();
116 for (vector<saml2::Condition*>::const_iterator c = conditions.begin(); c != conditions.end(); ++c) {
117 const saml2::DelegationRestrictionType* drt = dynamic_cast<const saml2::DelegationRestrictionType*>(*c);
119 auto_ptr<ExtensibleAttribute> attr(new ExtensibleAttribute(vector<string>(1,m_attributeId), m_formatter.c_str()));
121 const vector<saml2::Delegate*>& dels = drt->getDelegates();
122 for (vector<saml2::Delegate*>::const_iterator d = dels.begin(); d != dels.end(); ++d) {
123 if ((*d)->getBaseID()) {
124 log.error("delegate identified by saml:BaseID cannot be processed into an attribute value");
128 saml2::NameID* n = nullptr;
129 if ((*d)->getEncryptedID()) {
130 CredentialResolver* cr = application.getCredentialResolver();
132 log.warn("found encrypted Delegate, but no CredentialResolver was available");
136 const XMLCh* recipient = application.getRelyingParty(
137 issuer ? dynamic_cast<EntityDescriptor*>(issuer->getParent()) : nullptr
138 )->getXMLString("entityID").second;
139 Locker credlocker(cr);
141 MetadataCredentialCriteria mcc(*issuer);
142 auto_ptr<XMLObject> decrypted((*d)->getEncryptedID()->decrypt(*cr, recipient, &mcc));
143 n = dynamic_cast<saml2::NameID*>(decrypted.release());
146 auto_ptr<XMLObject> decrypted((*d)->getEncryptedID()->decrypt(*cr, recipient));
147 n = dynamic_cast<saml2::NameID*>(decrypted.release());
149 if (n && log.isDebugEnabled())
150 log.debugStream() << "decrypted Delegate: " << *n << logging::eol;
152 catch (exception& ex) {
153 log.error("caught exception decrypting Delegate: %s", ex.what());
157 n = (*d)->getNameID();
161 DDF val = DDF(nullptr).structure();
162 if ((*d)->getConfirmationMethod()) {
163 auto_ptr_char temp((*d)->getConfirmationMethod());
164 val.addmember("ConfirmationMethod").string(temp.get());
166 if ((*d)->getDelegationInstant()) {
167 auto_ptr_char temp((*d)->getDelegationInstant()->getRawData());
168 val.addmember("DelegationInstant").string(temp.get());
171 auto_arrayptr<char> name(toUTF8(n->getName()));
172 if (name.get() && *name.get()) {
173 val.addmember("Name").string(name.get());
174 char* str = toUTF8(n->getFormat());
176 val.addmember("Format").string(str);
179 str = toUTF8(n->getNameQualifier());
181 val.addmember("NameQualifier").string(str);
184 str = toUTF8(n->getSPNameQualifier());
186 val.addmember("SPNameQualifier").string(str);
189 str = toUTF8(n->getSPProvidedID());
191 val.addmember("SPProvidedID").string(str);
195 if (n != (*d)->getNameID())
199 attr->getValues().add(val);
205 attributes.push_back(attr.release());