From: cantor Date: Tue, 8 May 2007 02:28:49 +0000 (+0000) Subject: Genericize string values and scopes, add value/scope functors. X-Git-Tag: 2.4~946 X-Git-Url: http://www.project-moonshot.org/gitweb/?p=shibboleth%2Fsp.git;a=commitdiff_plain;h=d30673a03fe633dfb952bb6644657574f81a8ffa Genericize string values and scopes, add value/scope functors. git-svn-id: https://svn.middleware.georgetown.edu/cpp-sp/trunk@2238 cb58f699-b61c-0410-a6fe-9272a202ed29 --- diff --git a/schemas/shibboleth-2.0-afp-mf-basic.xsd b/schemas/shibboleth-2.0-afp-mf-basic.xsd index d178261..885f6f0 100644 --- a/schemas/shibboleth-2.0-afp-mf-basic.xsd +++ b/schemas/shibboleth-2.0-afp-mf-basic.xsd @@ -166,7 +166,7 @@ - + diff --git a/shibsp/Makefile.am b/shibsp/Makefile.am index 58956b4..ea038e9 100644 --- a/shibsp/Makefile.am +++ b/shibsp/Makefile.am @@ -109,6 +109,8 @@ libshibsp_la_SOURCES = \ attribute/filtering/OrMatchFunctor.cpp \ attribute/filtering/AttributeIssuerStringFunctor.cpp \ attribute/filtering/AttributeRequesterStringFunctor.cpp \ + attribute/filtering/AttributeScopeStringFunctor.cpp \ + attribute/filtering/AttributeValueStringFunctor.cpp \ attribute/filtering/AuthenticationMethodStringFunctor.cpp \ attribute/resolver/impl/ChainingAttributeResolver.cpp \ attribute/resolver/impl/QueryAttributeResolver.cpp \ diff --git a/shibsp/attribute/Attribute.h b/shibsp/attribute/Attribute.h index 401749f..4b0e474 100644 --- a/shibsp/attribute/Attribute.h +++ b/shibsp/attribute/Attribute.h @@ -142,6 +142,26 @@ namespace shibsp { virtual void clearSerializedValues()=0; /** + * Gets the string equivalent of the value at the specified position (starting from zero). + * + * @param index position of value + * @return the specified value in its "string" form, or NULL if undefined + */ + virtual const char* getString(size_t index) const { + return m_serialized[index].c_str(); + } + + /** + * Gets the "scope" of the value at the specified position (starting from zero). + * + * @param index position of value + * @return the specified value's "scope", or NULL if attribute is unscoped + */ + virtual const char* getScope(size_t index) const { + return NULL; + } + + /** * Removes the value at the specified position (starting from zero). * * @param index position of value to remove diff --git a/shibsp/attribute/NameIDAttribute.h b/shibsp/attribute/NameIDAttribute.h index 0ba4ab7..3b674aa 100644 --- a/shibsp/attribute/NameIDAttribute.h +++ b/shibsp/attribute/NameIDAttribute.h @@ -117,6 +117,14 @@ namespace shibsp { m_serialized.clear(); } + const char* getString(size_t index) const { + return m_values[index].m_Name.c_str(); + } + + const char* getScope(size_t index) const { + return m_values[index].m_NameQualifier.c_str(); + } + void removeValue(size_t index) { Attribute::removeValue(index); if (index < m_values.size()) diff --git a/shibsp/attribute/ScopedAttribute.h b/shibsp/attribute/ScopedAttribute.h index 9fb81e2..0e79398 100644 --- a/shibsp/attribute/ScopedAttribute.h +++ b/shibsp/attribute/ScopedAttribute.h @@ -90,6 +90,14 @@ namespace shibsp { m_serialized.clear(); } + const char* getString(size_t index) const { + return m_values[index].first.c_str(); + } + + const char* getScope(size_t index) const { + return m_values[index].second.c_str(); + } + void removeValue(size_t index) { Attribute::removeValue(index); if (index < m_values.size()) diff --git a/shibsp/attribute/filtering/BasicFilteringContext.h b/shibsp/attribute/filtering/BasicFilteringContext.h index 39518c1..b05f555 100644 --- a/shibsp/attribute/filtering/BasicFilteringContext.h +++ b/shibsp/attribute/filtering/BasicFilteringContext.h @@ -33,17 +33,19 @@ namespace shibsp { /** * Constructor. * - * @param app reference to Application - * @param role metadata role of attribute issuer, if any + * @param app reference to Application + * @param attributes attributes being filtered + * @param role metadata role of Attribute issuer, if any * @param authncontext_class method/category of authentication event, if known - * @param authncontext_decl specifics of authentication event, if known + * @param authncontext_decl specifics of authentication event, if known */ BasicFilteringContext( const Application& app, + const std::multimap& attributes, const opensaml::saml2md::RoleDescriptor* role=NULL, const char* authncontext_class=NULL, const char* authncontext_decl=NULL - ) : m_app(app), m_role(role), m_issuer(NULL), m_class(authncontext_class), m_decl(authncontext_decl) { + ) : m_app(app), m_attributes(attributes), m_role(role), m_issuer(NULL), m_class(authncontext_class), m_decl(authncontext_decl) { if (role) m_issuer = dynamic_cast(role->getParent())->getEntityID(); } @@ -71,9 +73,13 @@ namespace shibsp { const opensaml::saml2md::RoleDescriptor* getAttributeIssuerMetadata() const { return m_role; } + const std::multimap& getAttributes() const { + return m_attributes; + } private: const Application& m_app; + const std::multimap& m_attributes; const opensaml::saml2md::RoleDescriptor* m_role; const XMLCh* m_issuer; const char* m_class; diff --git a/shibsp/attribute/filtering/FilteringContext.h b/shibsp/attribute/filtering/FilteringContext.h index 4f67a96..6d3b59c 100644 --- a/shibsp/attribute/filtering/FilteringContext.h +++ b/shibsp/attribute/filtering/FilteringContext.h @@ -93,6 +93,17 @@ namespace shibsp { * @return SAML metadata for the attribute issuing role, or NULL */ virtual const opensaml::saml2md::RoleDescriptor* getAttributeIssuerMetadata() const=0; + + /** + * Returns the set of Attributes being filtered. + * + *

No modifications should be performed, access is provided only for use by + * MatchFunctors based on the presence of Attribute data. + * + * @return an immutable map of Attributes. + */ + virtual const std::multimap& getAttributes() const=0; + }; }; diff --git a/shibsp/attribute/filtering/MatchFunctor.h b/shibsp/attribute/filtering/MatchFunctor.h index a3be664..7390b8c 100644 --- a/shibsp/attribute/filtering/MatchFunctor.h +++ b/shibsp/attribute/filtering/MatchFunctor.h @@ -85,6 +85,12 @@ namespace shibsp { /** Matches the principal's authentication method/class or context reference. */ extern SHIBSP_API xmltooling::QName AuthenticationMethodStringType; + /** Matches an attribute's string value. */ + extern SHIBSP_API xmltooling::QName AttributeValueStringType; + + /** Matches an attribute's "scope". */ + extern SHIBSP_API xmltooling::QName AttributeScopeStringType; + /** * Registers MatchFunctor classes into the runtime. */ diff --git a/shibsp/attribute/filtering/impl/AttributeScopeStringFunctor.cpp b/shibsp/attribute/filtering/impl/AttributeScopeStringFunctor.cpp new file mode 100644 index 0000000..70a252f --- /dev/null +++ b/shibsp/attribute/filtering/impl/AttributeScopeStringFunctor.cpp @@ -0,0 +1,87 @@ +/* + * Copyright 2001-2007 Internet2 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * AttributeScopeStringFunctor.cpp + * + * A match function that matches the scope of an attribute value against the specified value. + */ + +#include "internal.h" +#include "exceptions.h" +#include "attribute/Attribute.h" +#include "attribute/filtering/FilteringContext.h" +#include "attribute/filtering/FilterPolicyContext.h" + +using namespace shibsp; +using namespace std; + +namespace shibsp { + + static const XMLCh attributeID[] = UNICODE_LITERAL_11(a,t,t,r,i,b,u,t,e,I,D); + static const XMLCh value[] = UNICODE_LITERAL_5(v,a,l,u,e); + + /** + * A match function that matches the scope of an attribute value against the specified value. + */ + class SHIBSP_DLLLOCAL AttributeScopeStringFunctor : public MatchFunctor + { + xmltooling::auto_ptr_char m_value; + xmltooling::auto_ptr_char m_attributeID; + + bool hasScope(const FilteringContext& filterContext) const; + + public: + AttributeScopeStringFunctor(const DOMElement* e) + : m_value(e ? e->getAttributeNS(NULL,value) : NULL), m_attributeID(e ? e->getAttributeNS(NULL,attributeID) : NULL) { + if (!m_value.get() || !*m_value.get()) + throw ConfigurationException("AttributeScopeString MatchFunctor requires non-empty value attribute."); + } + + bool evaluatePolicyRequirement(const FilteringContext& filterContext) const { + if (!m_attributeID.get() || !*m_attributeID.get()) + throw AttributeFilteringException("No attributeID specified."); + return hasScope(filterContext); + } + + bool evaluatePermitValue(const FilteringContext& filterContext, const Attribute& attribute, size_t index) const { + if (!XMLString::equals(m_attributeID.get(), attribute.getId())) + return hasScope(filterContext); + return XMLString::equals(attribute.getScope(index), m_value.get()); + } + }; + + MatchFunctor* SHIBSP_DLLLOCAL AttributeScopeStringFactory(const std::pair& p) + { + return new AttributeScopeStringFunctor(p.second); + } + +}; + +bool AttributeScopeStringFunctor::hasScope(const FilteringContext& filterContext) const +{ + size_t count; + pair::const_iterator,multimap::const_iterator> attrs = + filterContext.getAttributes().equal_range(m_attributeID.get()); + for (; attrs.first != attrs.second; ++attrs.first) { + count = attrs.first->second->valueCount(); + for (size_t index = 0; index < count; ++index) { + if (XMLString::equals(attrs.first->second->getScope(index), m_value.get())) + return true; + } + } + return false; +} diff --git a/shibsp/attribute/filtering/impl/AttributeValueStringFunctor.cpp b/shibsp/attribute/filtering/impl/AttributeValueStringFunctor.cpp new file mode 100644 index 0000000..c969ac5 --- /dev/null +++ b/shibsp/attribute/filtering/impl/AttributeValueStringFunctor.cpp @@ -0,0 +1,103 @@ +/* + * Copyright 2001-2007 Internet2 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * AttributeValueStringFunctor.cpp + * + * A match function that matches the value of an attribute against the specified value. + */ + +#include "internal.h" +#include "exceptions.h" +#include "attribute/Attribute.h" +#include "attribute/filtering/FilteringContext.h" +#include "attribute/filtering/FilterPolicyContext.h" + +using namespace shibsp; +using namespace std; + +namespace shibsp { + + static const XMLCh attributeID[] = UNICODE_LITERAL_11(a,t,t,r,i,b,u,t,e,I,D); + static const XMLCh value[] = UNICODE_LITERAL_5(v,a,l,u,e); + + /** + * A match function that matches the value of an attribute against the specified value. + */ + class SHIBSP_DLLLOCAL AttributeValueStringFunctor : public MatchFunctor + { + xmltooling::auto_ptr_char m_value; + xmltooling::auto_ptr_char m_attributeID; + + bool hasValue(const FilteringContext& filterContext) const; + bool matches(const Attribute& attribute, size_t index) const; + + public: + AttributeValueStringFunctor(const DOMElement* e) + : m_value(e ? e->getAttributeNS(NULL,value) : NULL), m_attributeID(e ? e->getAttributeNS(NULL,attributeID) : NULL) { + if (!m_value.get() || !*m_value.get()) + throw ConfigurationException("AttributeValueString MatchFunctor requires non-empty value attribute."); + } + + bool evaluatePolicyRequirement(const FilteringContext& filterContext) const { + if (!m_attributeID.get() || !*m_attributeID.get()) + throw AttributeFilteringException("No attributeID specified."); + return hasValue(filterContext); + } + + bool evaluatePermitValue(const FilteringContext& filterContext, const Attribute& attribute, size_t index) const { + if (!XMLString::equals(m_attributeID.get(), attribute.getId())) + return hasValue(filterContext); + return matches(attribute, index); + } + }; + + MatchFunctor* SHIBSP_DLLLOCAL AttributeValueStringFactory(const std::pair& p) + { + return new AttributeValueStringFunctor(p.second); + } + +}; + +bool AttributeValueStringFunctor::hasValue(const FilteringContext& filterContext) const +{ + size_t count; + pair::const_iterator,multimap::const_iterator> attrs = + filterContext.getAttributes().equal_range(m_attributeID.get()); + for (; attrs.first != attrs.second; ++attrs.first) { + count = attrs.first->second->valueCount(); + for (size_t index = 0; index < count; ++index) { + if (matches(*(attrs.first->second), index)) + return true; + } + } + return false; +} + +bool AttributeValueStringFunctor::matches(const Attribute& attribute, size_t index) const +{ + const char* val = attribute.getString(index); + if (!val) + return false; + if (attribute.isCaseSensitive()) + return !strcmp(m_value.get(), val); + +#ifdef HAVE_STRCASECMP + return !strcasecmp(m_value.get(), val); +#else + return !stricmp(m_value.get(), val); +#endif +} diff --git a/shibsp/attribute/filtering/impl/MatchFunctor.cpp b/shibsp/attribute/filtering/impl/MatchFunctor.cpp index 385b996..428668a 100644 --- a/shibsp/attribute/filtering/impl/MatchFunctor.cpp +++ b/shibsp/attribute/filtering/impl/MatchFunctor.cpp @@ -47,6 +47,8 @@ namespace shibsp { DECL_FACTORY(AttributeRequesterString); DECL_FACTORY(AttributeIssuerString); DECL_FACTORY(AuthenticationMethodString); + DECL_FACTORY(AttributeValueString); + DECL_FACTORY(AttributeScopeString); static const XMLCh ANY[] = UNICODE_LITERAL_3(A,N,Y); static const XMLCh AND[] = UNICODE_LITERAL_3(A,N,D); @@ -55,6 +57,8 @@ namespace shibsp { static const XMLCh AttributeRequesterString[] = UNICODE_LITERAL_24(A,t,t,r,i,b,u,t,e,R,e,q,u,e,s,t,e,r,S,t,r,i,n,g); static const XMLCh AttributeIssuerString[] = UNICODE_LITERAL_21(A,t,t,r,i,b,u,t,e,I,s,s,u,e,r,S,t,r,i,n,g); static const XMLCh AuthenticationMethodString[] = UNICODE_LITERAL_26(A,u,t,h,e,n,t,i,c,a,t,i,o,n,M,e,t,h,o,d,S,t,r,i,n,g); + static const XMLCh AttributeValueString[] = UNICODE_LITERAL_20(A,t,t,r,i,b,u,t,e,V,a,l,u,e,S,t,r,i,n,g); + static const XMLCh AttributeScopeString[] = UNICODE_LITERAL_20(A,t,t,r,i,b,u,t,e,S,c,o,p,e,S,t,r,i,n,g); }; DECL_BASIC_QNAME(AnyMatchFunctor, ANY); @@ -64,6 +68,8 @@ DECL_BASIC_QNAME(NotMatchFunctor, NOT); DECL_BASIC_QNAME(AttributeRequesterString, AttributeRequesterString); DECL_BASIC_QNAME(AttributeIssuerString, AttributeIssuerString); DECL_BASIC_QNAME(AuthenticationMethodString, AuthenticationMethodString); +DECL_BASIC_QNAME(AttributeValueString, AttributeValueString); +DECL_BASIC_QNAME(AttributeScopeString, AttributeScopeString); void SHIBSP_API shibsp::registerMatchFunctors() { @@ -76,4 +82,6 @@ void SHIBSP_API shibsp::registerMatchFunctors() REGISTER_FACTORY(AttributeRequesterString); REGISTER_FACTORY(AttributeIssuerString); REGISTER_FACTORY(AuthenticationMethodString); + REGISTER_FACTORY(AttributeValueString); + REGISTER_FACTORY(AttributeScopeString); } diff --git a/shibsp/attribute/resolver/impl/QueryAttributeResolver.cpp b/shibsp/attribute/resolver/impl/QueryAttributeResolver.cpp index 98ebb77..52bb845 100644 --- a/shibsp/attribute/resolver/impl/QueryAttributeResolver.cpp +++ b/shibsp/attribute/resolver/impl/QueryAttributeResolver.cpp @@ -339,7 +339,7 @@ bool QueryResolver::SAML1Query(QueryContext& ctx) const AttributeFilter* filter = ctx.getApplication().getAttributeFilter(); if (filter) { - BasicFilteringContext fc(ctx.getApplication(), AA, ctx.getClassRef(), ctx.getDeclRef()); + BasicFilteringContext fc(ctx.getApplication(), ctx.getResolvedAttributes(), AA, ctx.getClassRef(), ctx.getDeclRef()); Locker filtlocker(filter); filter->filterAttributes(fc, ctx.getResolvedAttributes()); } @@ -450,7 +450,7 @@ bool QueryResolver::SAML2Query(QueryContext& ctx) const AttributeFilter* filter = ctx.getApplication().getAttributeFilter(); if (filter) { - BasicFilteringContext fc(ctx.getApplication(), AA, ctx.getClassRef(), ctx.getDeclRef()); + BasicFilteringContext fc(ctx.getApplication(), ctx.getResolvedAttributes(), AA, ctx.getClassRef(), ctx.getDeclRef()); Locker filtlocker(filter); filter->filterAttributes(fc, ctx.getResolvedAttributes()); } diff --git a/shibsp/handler/impl/SAML1Consumer.cpp b/shibsp/handler/impl/SAML1Consumer.cpp index 2efa16c..478adf5 100644 --- a/shibsp/handler/impl/SAML1Consumer.cpp +++ b/shibsp/handler/impl/SAML1Consumer.cpp @@ -188,6 +188,18 @@ string SAML1Consumer::implementProtocol( NameIdentifier* n = ssoStatement->getSubject()->getNameIdentifier(); + // Now we have to extract the authentication details for attribute and session setup. + + // Session expiration for SAML 1.x is purely SP-driven, and the method is mapped to a ctx class. + const PropertySet* sessionProps = application.getPropertySet("Sessions"); + pair lifetime = sessionProps ? sessionProps->getUnsignedInt("lifetime") : make_pair(true,28800); + if (!lifetime.first) + lifetime.second = 28800; + auto_ptr_char authnInstant( + ssoStatement->getAuthenticationInstant() ? ssoStatement->getAuthenticationInstant()->getRawData() : NULL + ); + auto_ptr_char authnMethod(ssoStatement->getAuthenticationMethod()); + // We've successfully "accepted" at least one SSO token, along with any additional valid tokens. // To complete processing, we need to extract and resolve attributes and then create the session. multimap resolvedAttributes; @@ -214,7 +226,7 @@ string SAML1Consumer::implementProtocol( AttributeFilter* filter = application.getAttributeFilter(); if (filter && !resolvedAttributes.empty()) { - BasicFilteringContext fc(application, policy.getIssuerMetadata()); + BasicFilteringContext fc(application, resolvedAttributes, policy.getIssuerMetadata(), authnMethod.get()); Locker filtlocker(filter); try { filter->filterAttributes(fc, resolvedAttributes); @@ -228,7 +240,7 @@ string SAML1Consumer::implementProtocol( } } - // First, normalize the SAML 1.x NameIdentifier... + // Normalize the SAML 1.x NameIdentifier... auto_ptr nameid(n ? NameIDBuilder::buildNameID() : NULL); if (n) { nameid->setName(n->getName()); @@ -236,18 +248,6 @@ string SAML1Consumer::implementProtocol( nameid->setNameQualifier(n->getNameQualifier()); } - // Now we have to extract the authentication details for session setup. - - // Session expiration for SAML 1.x is purely SP-driven, and the method is mapped to a ctx class. - const PropertySet* sessionProps = application.getPropertySet("Sessions"); - pair lifetime = sessionProps ? sessionProps->getUnsignedInt("lifetime") : make_pair(true,28800); - if (!lifetime.first) - lifetime.second = 28800; - auto_ptr_char authnInstant( - ssoStatement->getAuthenticationInstant() ? ssoStatement->getAuthenticationInstant()->getRawData() : NULL - ); - auto_ptr_char authnMethod(ssoStatement->getAuthenticationMethod()); - const EntityDescriptor* issuerMetadata = policy.getIssuerMetadata() ? dynamic_cast(policy.getIssuerMetadata()->getParent()) : NULL; auto_ptr ctx( diff --git a/shibsp/handler/impl/SAML2Consumer.cpp b/shibsp/handler/impl/SAML2Consumer.cpp index a0063ce..5d544ec 100644 --- a/shibsp/handler/impl/SAML2Consumer.cpp +++ b/shibsp/handler/impl/SAML2Consumer.cpp @@ -314,6 +314,28 @@ string SAML2Consumer::implementProtocol( // We've successfully "accepted" at least one SSO token, along with any additional valid tokens. // To complete processing, we need to extract and resolve attributes and then create the session. + // Now we have to extract the authentication details for session setup. + + // Session expiration for SAML 2.0 is jointly IdP- and SP-driven. + time_t sessionExp = ssoStatement->getSessionNotOnOrAfter() ? ssoStatement->getSessionNotOnOrAfterEpoch() : 0; + const PropertySet* sessionProps = application.getPropertySet("Sessions"); + pair lifetime = sessionProps ? sessionProps->getUnsignedInt("lifetime") : make_pair(true,28800); + if (!lifetime.first) + lifetime.second = 28800; + if (lifetime.second != 0) { + if (sessionExp == 0) + sessionExp = now + lifetime.second; // IdP says nothing, calulate based on SP. + else + sessionExp = min(sessionExp, now + lifetime.second); // Use the lowest. + } + + // Other details... + const AuthnContext* authnContext = ssoStatement->getAuthnContext(); + auto_ptr_char authnClass((authnContext && authnContext->getAuthnContextClassRef()) ? authnContext->getAuthnContextClassRef()->getReference() : NULL); + auto_ptr_char authnDecl((authnContext && authnContext->getAuthnContextDeclRef()) ? authnContext->getAuthnContextDeclRef()->getReference() : NULL); + auto_ptr_char index(ssoStatement->getSessionIndex()); + auto_ptr_char authnInstant(ssoStatement->getAuthnInstant() ? ssoStatement->getAuthnInstant()->getRawData() : NULL); + multimap resolvedAttributes; AttributeExtractor* extractor = application.getAttributeExtractor(); if (extractor) { @@ -337,7 +359,7 @@ string SAML2Consumer::implementProtocol( AttributeFilter* filter = application.getAttributeFilter(); if (filter && !resolvedAttributes.empty()) { - BasicFilteringContext fc(application, policy.getIssuerMetadata()); + BasicFilteringContext fc(application, resolvedAttributes, policy.getIssuerMetadata(), authnClass.get(), authnDecl.get()); Locker filtlocker(filter); try { filter->filterAttributes(fc, resolvedAttributes); @@ -351,28 +373,6 @@ string SAML2Consumer::implementProtocol( } try { - // Now we have to extract the authentication details for session setup. - - // Session expiration for SAML 2.0 is jointly IdP- and SP-driven. - time_t sessionExp = ssoStatement->getSessionNotOnOrAfter() ? ssoStatement->getSessionNotOnOrAfterEpoch() : 0; - const PropertySet* sessionProps = application.getPropertySet("Sessions"); - pair lifetime = sessionProps ? sessionProps->getUnsignedInt("lifetime") : make_pair(true,28800); - if (!lifetime.first) - lifetime.second = 28800; - if (lifetime.second != 0) { - if (sessionExp == 0) - sessionExp = now + lifetime.second; // IdP says nothing, calulate based on SP. - else - sessionExp = min(sessionExp, now + lifetime.second); // Use the lowest. - } - - // Other details... - const AuthnContext* authnContext = ssoStatement->getAuthnContext(); - auto_ptr_char authnClass((authnContext && authnContext->getAuthnContextClassRef()) ? authnContext->getAuthnContextClassRef()->getReference() : NULL); - auto_ptr_char authnDecl((authnContext && authnContext->getAuthnContextDeclRef()) ? authnContext->getAuthnContextDeclRef()->getReference() : NULL); - auto_ptr_char index(ssoStatement->getSessionIndex()); - auto_ptr_char authnInstant(ssoStatement->getAuthnInstant() ? ssoStatement->getAuthnInstant()->getRawData() : NULL); - const EntityDescriptor* issuerMetadata = policy.getIssuerMetadata() ? dynamic_cast(policy.getIssuerMetadata()->getParent()) : NULL; auto_ptr ctx( diff --git a/shibsp/shibsp.vcproj b/shibsp/shibsp.vcproj index 5a2c683..a269849 100644 --- a/shibsp/shibsp.vcproj +++ b/shibsp/shibsp.vcproj @@ -211,6 +211,14 @@ > + + + +