https://bugs.internet2.edu/jira/browse/SSPCPP-293
authorcantor <cantor@cb58f699-b61c-0410-a6fe-9272a202ed29>
Thu, 27 May 2010 21:59:52 +0000 (21:59 +0000)
committercantor <cantor@cb58f699-b61c-0410-a6fe-9272a202ed29>
Thu, 27 May 2010 21:59:52 +0000 (21:59 +0000)
git-svn-id: https://svn.middleware.georgetown.edu/cpp-sp/branches/REL_2@3258 cb58f699-b61c-0410-a6fe-9272a202ed29

16 files changed:
adfs/adfs.cpp
schemas/shibboleth-2.0-native-sp-config.xsd
shibsp/Makefile.am
shibsp/SPConfig.cpp
shibsp/SPConfig.h
shibsp/ServiceProvider.cpp
shibsp/ServiceProvider.h
shibsp/handler/AssertionConsumerService.h
shibsp/handler/impl/AssertionConsumerService.cpp
shibsp/handler/impl/SAML1Consumer.cpp
shibsp/handler/impl/SAML2Consumer.cpp
shibsp/impl/XMLSecurityPolicyProvider.cpp [new file with mode: 0644]
shibsp/impl/XMLServiceProvider.cpp
shibsp/security/SecurityPolicyProvider.h [new file with mode: 0644]
shibsp/shibsp.vcxproj
shibsp/shibsp.vcxproj.filters

index 0c9f242..c957c19 100644 (file)
@@ -179,7 +179,7 @@ namespace {
             const HTTPRequest& httpRequest,
             HTTPResponse& httpResponse,
             SecurityPolicy& policy,
-            const PropertySet* settings,
+            const PropertySet*,
             const XMLObject& xmlObject
             ) const;
 #endif
@@ -595,7 +595,7 @@ void ADFSConsumer::implementProtocol(
     const HTTPRequest& httpRequest,
     HTTPResponse& httpResponse,
     SecurityPolicy& policy,
-    const PropertySet* settings,
+    const PropertySet*,
     const XMLObject& xmlObject
     ) const
 {
index 02a4140..2e89fe9 100644 (file)
     <anyAttribute namespace="##any" processContents="lax"/>
   </complexType>
 
-  <complexType name="SecurityPoliciesType">
-    <annotation>
-      <documentation>Container for specifying sets of policy rules to apply to incoming messages</documentation>
-    </annotation>
-    <sequence>
-      <element name="Policy" minOccurs="1" maxOccurs="unbounded">
-        <annotation>
-          <documentation>Specifies a set of SecurityPolicyRule plugins</documentation>
-        </annotation>
-        <complexType>
-          <choice>
-            <element name="Rule" type="conf:PluggableType" minOccurs="1" maxOccurs="unbounded"/>
-            <element name="PolicyRule" type="conf:PluggableType" minOccurs="1" maxOccurs="unbounded"/>
-          </choice>
-          <attribute name="id" type="conf:string" use="required"/>
-          <attribute name="validate" type="boolean"/>
-          <anyAttribute namespace="##any" processContents="lax"/>
-        </complexType>
-      </element>
-      <choice minOccurs="0">
-        <element name="AlgorithmWhitelist" type="conf:listOfURIs"/>
-        <element name="AlgorithmBlacklist" type="conf:listOfURIs"/>
-      </choice>
-    </sequence>
-  </complexType>
+  <element name="SecurityPolicies">
+    <complexType>
+      <annotation>
+        <documentation>Container for specifying sets of policy rules to apply to incoming messages</documentation>
+      </annotation>
+      <sequence>
+        <element name="Policy" minOccurs="1" maxOccurs="unbounded">
+          <annotation>
+            <documentation>Specifies a set of SecurityPolicyRule plugins</documentation>
+          </annotation>
+          <complexType>
+            <choice>
+              <element name="Rule" type="conf:PluggableType" minOccurs="1" maxOccurs="unbounded"/>
+              <element name="PolicyRule" type="conf:PluggableType" minOccurs="1" maxOccurs="unbounded"/>
+            </choice>
+            <attribute name="id" type="conf:string" use="required"/>
+            <attribute name="validate" type="boolean"/>
+            <anyAttribute namespace="##any" processContents="lax"/>
+          </complexType>
+        </element>
+        <choice minOccurs="0">
+          <element name="AlgorithmWhitelist" type="conf:listOfURIs"/>
+          <element name="AlgorithmBlacklist" type="conf:listOfURIs"/>
+        </choice>
+      </sequence>
+    </complexType>
+  </element>
 
   <element name="TransportOption">
     <annotation>
         <element name="ArtifactMap" type="conf:ArtifactMapType" minOccurs="0"/>
         <element name="RequestMapper" type="conf:PluggableType" minOccurs="0"/>
         <element name="ApplicationDefaults" type="conf:ApplicationDefaultsType"/>
-        <element name="SecurityPolicies" type="conf:SecurityPoliciesType"/>
+        <choice>
+          <element name="SecurityPolicyProvider" type="conf:PluggableType"/>
+          <element ref="conf:SecurityPolicies"/> <!-- deprecated -->
+        </choice>
         <element ref="conf:TransportOption" minOccurs="0" maxOccurs="unbounded"/>
         <element ref="ds:Signature" minOccurs="0"/>
       </sequence>
index 334f513..7184a59 100644 (file)
@@ -87,7 +87,8 @@ reminclude_HEADERS = \
        
 secinclude_HEADERS = \
        security/PKIXTrustEngine.h \
-       security/SecurityPolicy.h
+       security/SecurityPolicy.h \
+       security/SecurityPolicyProvider.h
 
 utilinclude_HEADERS = \
        util/CGIParser.h \
@@ -197,6 +198,7 @@ libshibsp_la_SOURCES = \
        attribute/resolver/impl/XMLAttributeExtractor.cpp \
        binding/impl/ArtifactResolver.cpp \
        binding/impl/SOAPClient.cpp \
+       impl/XMLSecurityPolicyProvider.cpp \
        metadata/DynamicMetadataProvider.cpp \
        metadata/MetadataExtImpl.cpp \
        metadata/MetadataExtSchemaValidators.cpp \
index 7a4585b..f89ee17 100644 (file)
@@ -55,6 +55,7 @@
 # include "binding/ArtifactResolver.h"
 # include "metadata/MetadataExt.h"
 # include "security/PKIXTrustEngine.h"
+# include "security/SecurityPolicyProvider.h"
 # include <saml/SAMLConfig.h>
 #endif
 
@@ -251,6 +252,7 @@ bool SPConfig::init(const char* catalog_path, const char* inst_prefix)
         registerAttributeFilters();
         registerMatchFunctors();
     }
+    registerSecurityPolicyProviders();
 #endif
 
     if (isEnabled(Listener))
@@ -301,6 +303,7 @@ void SPConfig::term()
     Attribute::deregisterFactories();
 
 #ifndef SHIBSP_LITE
+    SecurityPolicyProviderManager.deregisterFactories();
     if (isEnabled(AttributeResolution)) {
         MatchFunctorManager.deregisterFactories();
         AttributeFilterManager.deregisterFactories();
index e8afff6..ed3ddb5 100644 (file)
@@ -55,6 +55,7 @@ namespace shibsp {
     class SHIBSP_API AttributeResolver;
     class SHIBSP_API FilterPolicyContext;
     class SHIBSP_API MatchFunctor;
+    class SHIBSP_API SecurityPolicyProvider;
 #endif
 
 #if defined (_MSC_VER)
@@ -212,6 +213,11 @@ namespace shibsp {
          * Manages factories for MatchFunctor plugins.
          */
         xmltooling::PluginManager< MatchFunctor,xmltooling::QName,std::pair<const FilterPolicyContext*,const xercesc::DOMElement*> > MatchFunctorManager;
+
+        /**
+         * Manages factories for SecurityPolicyProvider plugins.
+         */
+        xmltooling::PluginManager<SecurityPolicyProvider,std::string,const xercesc::DOMElement*> SecurityPolicyProviderManager;
 #endif
 
         /**
index e166771..9c2487b 100644 (file)
@@ -168,6 +168,15 @@ ServiceProvider::~ServiceProvider()
 {
 }
 
+#ifndef SHIBSP_LITE
+SecurityPolicyProvider* ServiceProvider::getSecurityPolicyProvider(bool required) const
+{
+    if (required)
+        throw ConfigurationException("No SecurityPolicyProvider available.");
+    return NULL;
+}
+#endif
+
 pair<bool,long> ServiceProvider::doAuthentication(SPRequest& request, bool handler) const
 {
 #ifdef _DEBUG
index 2a4e4b7..15658fe 100644 (file)
@@ -48,6 +48,7 @@ namespace shibsp {
     class SHIBSP_API SPRequest;
     class SHIBSP_API TemplateParameters;
 #ifndef SHIBSP_LITE
+    class SHIBSP_API SecurityPolicyProvider;
     class SHIBSP_API TransactionLog;
 #endif
 
@@ -109,6 +110,15 @@ namespace shibsp {
         
 #ifndef SHIBSP_LITE
         /**
+         * Returns a SecurityPolicyProvider instance.
+         *
+         * @param required true iff an exception should be thrown if no SecurityPolicyProvider is available
+         * @return  a SecurityPolicyProvider
+         */
+        virtual SecurityPolicyProvider* getSecurityPolicyProvider(bool required=true) const;
+
+        /**
+         * @deprecated
                 * Returns the security policy settings for an identified policy.
          *
                 * @param id    identifies the policy to return
@@ -117,6 +127,7 @@ namespace shibsp {
         virtual const PropertySet* getPolicySettings(const char* id) const=0;
 
         /**
+         * @deprecated
                 * Returns the security policy rules for an identified policy.
          *
                 * @param id    identifies the policy to return
index bbdafd4..a7618fb 100644 (file)
@@ -94,6 +94,7 @@ namespace shibsp {
         void generateMetadata(opensaml::saml2md::SPSSODescriptor& role, const char* handlerURL) const;
         
         /**
+         * @deprecated
          * Returns a SecurityPolicy instance to use for an incoming request.
          *
          * <p>Allows handlers to customize the type of policy object their policy rules might require.
@@ -121,7 +122,7 @@ namespace shibsp {
          * @param httpRequest   client request that included message
          * @param httpResponse  response to client
          * @param policy        the SecurityPolicy in effect, after having evaluated the message
-         * @param settings      policy configuration settings in effect
+         * @param reserved      ignore this parameter
          * @param xmlObject     a protocol-specific message object
          */
         virtual void implementProtocol(
@@ -129,7 +130,7 @@ namespace shibsp {
             const xmltooling::HTTPRequest& httpRequest,
             xmltooling::HTTPResponse& httpResponse,
             opensaml::SecurityPolicy& policy,
-            const PropertySet* settings,
+            const PropertySet* reserved,
             const xmltooling::XMLObject& xmlObject
             ) const=0;
 
index 1c1160b..b35cd5c 100644 (file)
@@ -38,6 +38,7 @@
 # include "attribute/resolver/ResolutionContext.h"
 # include "metadata/MetadataProviderCriteria.h"
 # include "security/SecurityPolicy.h"
+# include "security/SecurityPolicyProvider.h"
 # include <saml/exceptions.h>
 # include <saml/SAMLConfig.h>
 # include <saml/saml1/core/Assertions.h>
@@ -143,16 +144,12 @@ pair<bool,long> AssertionConsumerService::processMessage(
     if (!policyId.first)
         policyId = application.getString("policyId");   // unqualified in Application(s) element
 
-    // Access policy properties.
-    const PropertySet* settings = application.getServiceProvider().getPolicySettings(policyId.second);
-    pair<bool,bool> validate = settings->getBool("validate");
-
     // Lock metadata for use by policy.
     Locker metadataLocker(application.getMetadataProvider());
 
     // Create the policy.
     auto_ptr<opensaml::SecurityPolicy> policy(
-        createSecurityPolicy(application, &m_role, validate.first && validate.second, policyId.second)
+        application.getServiceProvider().getSecurityPolicyProvider()->createSecurityPolicy(application, &m_role, policyId.second)
         );
 
     string relayState;
@@ -164,7 +161,7 @@ pair<bool,long> AssertionConsumerService::processMessage(
         DDF postData = recoverPostData(application, httpRequest, httpResponse, relayState.c_str());
         DDFJanitor postjan(postData);
         recoverRelayState(application, httpRequest, httpResponse, relayState);
-        implementProtocol(application, httpRequest, httpResponse, *(policy.get()), settings, *msg.get());
+        implementProtocol(application, httpRequest, httpResponse, *(policy.get()), NULL, *msg.get());
 
         auto_ptr_char issuer(policy->getIssuer() ? policy->getIssuer()->getName() : nullptr);
 
@@ -187,8 +184,8 @@ pair<bool,long> AssertionConsumerService::processMessage(
         // Check for isPassive error condition.
         const char* sc2 = ex.getProperty("statusCode2");
         if (sc2 && !strcmp(sc2, "urn:oasis:names:tc:SAML:2.0:status:NoPassive")) {
-            validate = getBool("ignoreNoPassive", m_configNS.get());  // namespace-qualified if inside handler element
-            if (validate.first && validate.second && !relayState.empty()) {
+            pair<bool,bool> ignore = getBool("ignoreNoPassive", m_configNS.get());  // namespace-qualified if inside handler element
+            if (ignore.first && ignore.second && !relayState.empty()) {
                 m_log.debug("ignoring SAML status of NoPassive and redirecting to resource...");
                 return make_pair(true, httpResponse.sendRedirect(relayState.c_str()));
             }
index b098aab..78cd49a 100644 (file)
@@ -91,7 +91,7 @@ namespace shibsp {
             const HTTPRequest& httpRequest,
             HTTPResponse& httpResponse,
             SecurityPolicy& policy,
-            const PropertySet* settings,
+            const PropertySet*,
             const XMLObject& xmlObject
             ) const;
 
@@ -130,7 +130,7 @@ void SAML1Consumer::implementProtocol(
     const HTTPRequest& httpRequest,
     HTTPResponse& httpResponse,
     SecurityPolicy& policy,
-    const PropertySet* settings,
+    const PropertySet*,
     const XMLObject& xmlObject
     ) const
 {
index c22f4a2..e67297e 100644 (file)
@@ -87,7 +87,7 @@ namespace shibsp {
             const HTTPRequest& httpRequest,
             HTTPResponse& httpResponse,
             SecurityPolicy& policy,
-            const PropertySet* settings,
+            const PropertySet*,
             const XMLObject& xmlObject
             ) const;
 
@@ -125,7 +125,7 @@ void SAML2Consumer::implementProtocol(
     const HTTPRequest& httpRequest,
     HTTPResponse& httpResponse,
     SecurityPolicy& policy,
-    const PropertySet* settings,
+    const PropertySet*,
     const XMLObject& xmlObject
     ) const
 {
diff --git a/shibsp/impl/XMLSecurityPolicyProvider.cpp b/shibsp/impl/XMLSecurityPolicyProvider.cpp
new file mode 100644 (file)
index 0000000..5f0fdb0
--- /dev/null
@@ -0,0 +1,295 @@
+/*\r
+ *  Copyright 2010 Internet2\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+/**\r
+ * XMLSecurityPolicyProvider.cpp\r
+ *\r
+ * XML-based security policy provider.\r
+ */\r
+\r
+#include "internal.h"\r
+#include "exceptions.h"\r
+#include "Application.h"\r
+#include "security/SecurityPolicy.h"\r
+#include "security/SecurityPolicyProvider.h"\r
+#include "util/DOMPropertySet.h"\r
+#include "util/SPConstants.h"\r
+\r
+#include <map>\r
+#include <saml/SAMLConfig.h>\r
+#include <saml/binding/SecurityPolicyRule.h>\r
+#include <xmltooling/io/HTTPResponse.h>\r
+#include <xmltooling/util/NDC.h>\r
+#include <xmltooling/util/ReloadableXMLFile.h>\r
+#include <xmltooling/util/Threads.h>\r
+#include <xmltooling/util/XMLHelper.h>\r
+#include <xercesc/util/XMLStringTokenizer.hpp>\r
+#include <xercesc/util/XMLUniDefs.hpp>\r
+\r
+using shibspconstants::SHIB2SPCONFIG_NS;\r
+using opensaml::SAMLConfig;\r
+using opensaml::SecurityPolicyRule;\r
+using namespace shibsp;\r
+using namespace xmltooling;\r
+using namespace std;\r
+\r
+namespace shibsp {\r
+\r
+#if defined (_MSC_VER)\r
+    #pragma warning( push )\r
+    #pragma warning( disable : 4250 )\r
+#endif\r
+\r
+    class SHIBSP_DLLLOCAL XMLSecurityPolicyProviderImpl\r
+    {\r
+    public:\r
+        XMLSecurityPolicyProviderImpl(const DOMElement* e, Category& log);\r
+        ~XMLSecurityPolicyProviderImpl() {\r
+            for (map< string,pair<PropertySet*,vector<const SecurityPolicyRule*> > >::iterator i = m_policyMap.begin(); i != m_policyMap.end(); ++i) {\r
+                delete i->second.first;\r
+                for_each(i->second.second.begin(), i->second.second.end(), xmltooling::cleanup<SecurityPolicyRule>());\r
+            }\r
+            if (m_document)\r
+                m_document->release();\r
+        }\r
+\r
+        void setDocument(DOMDocument* doc) {\r
+            m_document = doc;\r
+        }\r
+\r
+    private:\r
+        DOMDocument* m_document;\r
+        vector<xstring> m_whitelist,m_blacklist;\r
+        map< string,pair< PropertySet*,vector<const SecurityPolicyRule*> > > m_policyMap;\r
+\r
+        friend class SHIBSP_DLLLOCAL XMLSecurityPolicyProvider;\r
+    };\r
+\r
+    class XMLSecurityPolicyProvider : public SecurityPolicyProvider, public ReloadableXMLFile\r
+    {\r
+    public:\r
+        XMLSecurityPolicyProvider(const DOMElement* e)\r
+                : ReloadableXMLFile(e, Category::getInstance(SHIBSP_LOGCAT".SecurityPolicyProvider.XML")), m_impl(nullptr) {\r
+            background_load(); // guarantees an exception or the policy is loaded\r
+        }\r
+\r
+        ~XMLSecurityPolicyProvider() {\r
+            shutdown();\r
+            delete m_impl;\r
+        }\r
+\r
+        const PropertySet* getPolicySettings(const char* id) const {\r
+            map<string,pair<PropertySet*,vector<const SecurityPolicyRule*> > >::const_iterator i = m_impl->m_policyMap.find(id);\r
+            if (i != m_impl->m_policyMap.end())\r
+                return i->second.first;\r
+            throw ConfigurationException("Security Policy ($1) not found, check <SecurityPolicies> element.", params(1,id));\r
+        }\r
+\r
+        const vector<const SecurityPolicyRule*>& getPolicyRules(const char* id) const {\r
+            map<string,pair<PropertySet*,vector<const SecurityPolicyRule*> > >::const_iterator i = m_impl->m_policyMap.find(id);\r
+            if (i != m_impl->m_policyMap.end())\r
+                return i->second.second;\r
+            throw ConfigurationException("Security Policy ($1) not found, check <SecurityPolicies> element.", params(1,id));\r
+        }\r
+        const vector<xstring>& getAlgorithmBlacklist() const {\r
+            return m_impl->m_blacklist;\r
+        }\r
+        const vector<xstring>& getAlgorithmWhitelist() const {\r
+            return m_impl->m_whitelist;\r
+        }\r
+        \r
+    protected:\r
+        pair<bool,DOMElement*> load(bool backup);\r
+        pair<bool,DOMElement*> background_load();\r
+\r
+    private:\r
+        XMLSecurityPolicyProviderImpl* m_impl;\r
+    };\r
+\r
+#if defined (_MSC_VER)\r
+    #pragma warning( pop )\r
+#endif\r
+\r
+    SecurityPolicyProvider* SHIBSP_DLLLOCAL XMLSecurityPolicyProviderFactory(const DOMElement* const & e)\r
+    {\r
+        return new XMLSecurityPolicyProvider(e);\r
+    }\r
+\r
+    class SHIBSP_DLLLOCAL PolicyNodeFilter : public DOMNodeFilter\r
+    {\r
+    public:\r
+#ifdef SHIBSP_XERCESC_SHORT_ACCEPTNODE\r
+        short\r
+#else\r
+        FilterAction\r
+#endif\r
+        acceptNode(const DOMNode* node) const {\r
+            return FILTER_REJECT;\r
+        }\r
+    };\r
+\r
+    static const XMLCh _id[] =                  UNICODE_LITERAL_2(i,d);\r
+    static const XMLCh _type[] =                UNICODE_LITERAL_4(t,y,p,e);\r
+    static const XMLCh AlgorithmBlacklist[] =   UNICODE_LITERAL_18(A,l,g,o,r,i,t,h,m,B,l,a,c,k,l,i,s,t);\r
+    static const XMLCh AlgorithmWhitelist[] =   UNICODE_LITERAL_18(A,l,g,o,r,i,t,h,m,W,h,i,t,e,l,i,s,t);\r
+    static const XMLCh Policy[] =               UNICODE_LITERAL_6(P,o,l,i,c,y);\r
+    static const XMLCh PolicyRule[] =           UNICODE_LITERAL_10(P,o,l,i,c,y,R,u,l,e);\r
+    static const XMLCh Rule[] =                 UNICODE_LITERAL_4(R,u,l,e);\r
+    static const XMLCh SecurityPolicies[] =     UNICODE_LITERAL_16(S,e,c,u,r,i,t,y,P,o,l,i,c,i,e,s);\r
+}\r
+\r
+void SHIBSP_API shibsp::registerSecurityPolicyProviders()\r
+{\r
+    SPConfig::getConfig().SecurityPolicyProviderManager.registerFactory(XML_SECURITYPOLICY_PROVIDER, XMLSecurityPolicyProviderFactory);\r
+}\r
+\r
+SecurityPolicyProvider::SecurityPolicyProvider()\r
+{\r
+}\r
+\r
+SecurityPolicyProvider::~SecurityPolicyProvider()\r
+{\r
+}\r
+\r
+opensaml::SecurityPolicy* SecurityPolicyProvider::createSecurityPolicy(\r
+    const Application& application, const xmltooling::QName* role, const char* policyId\r
+    ) const\r
+{\r
+    pair<bool,bool> validate = getPolicySettings(policyId ? policyId : application.getString("policyId").second)->getBool("validate");\r
+    return new SecurityPolicy(application, role, (validate.first && validate.second), policyId);\r
+}\r
+\r
+XMLSecurityPolicyProviderImpl::XMLSecurityPolicyProviderImpl(const DOMElement* e, Category& log) : m_document(nullptr)\r
+{\r
+#ifdef _DEBUG\r
+    xmltooling::NDC ndc("XMLSecurityPolicyProviderImpl");\r
+#endif\r
+\r
+    if (!XMLHelper::isNodeNamed(e, SHIB2SPCONFIG_NS, SecurityPolicies))\r
+        throw ConfigurationException("XML SecurityPolicyProvider requires conf:SecurityPolicies at root of configuration.");\r
+\r
+    const XMLCh* algs = nullptr;\r
+    const DOMElement* alglist = XMLHelper::getLastChildElement(e, AlgorithmBlacklist);\r
+    if (alglist && alglist->hasChildNodes()) {\r
+        algs = alglist->getFirstChild()->getNodeValue();\r
+    }\r
+    else if ((alglist = XMLHelper::getLastChildElement(e, AlgorithmWhitelist)) && alglist->hasChildNodes()) {\r
+        algs = alglist->getFirstChild()->getNodeValue();\r
+    }\r
+    if (algs) {\r
+        const XMLCh* token;\r
+        XMLStringTokenizer tokenizer(algs);\r
+        while (tokenizer.hasMoreTokens()) {\r
+            token = tokenizer.nextToken();\r
+            if (token) {\r
+                if (XMLString::equals(alglist->getLocalName(), AlgorithmBlacklist))\r
+                    m_blacklist.push_back(token);\r
+                else\r
+                    m_whitelist.push_back(token);\r
+            }\r
+        }\r
+    }\r
+\r
+    PolicyNodeFilter filter;\r
+    SAMLConfig& samlConf = SAMLConfig::getConfig();\r
+    e = XMLHelper::getFirstChildElement(e, Policy);\r
+    while (e) {\r
+        auto_ptr_char id(e->getAttributeNS(nullptr, _id));\r
+        pair< PropertySet*,vector<const SecurityPolicyRule*> >& rules = m_policyMap[id.get()];\r
+        rules.first = nullptr;\r
+        auto_ptr<DOMPropertySet> settings(new DOMPropertySet());\r
+        settings->load(e, nullptr, &filter);\r
+        rules.first = settings.release();\r
+\r
+        // Process PolicyRule elements.\r
+        const DOMElement* rule = XMLHelper::getFirstChildElement(e, PolicyRule);\r
+        while (rule) {\r
+            auto_ptr_char type(rule->getAttributeNS(nullptr, _type));\r
+            try {\r
+                rules.second.push_back(samlConf.SecurityPolicyRuleManager.newPlugin(type.get(), rule));\r
+            }\r
+            catch (exception& ex) {\r
+                log.crit("error instantiating policy rule (%s) in policy (%s): %s", type.get(), id.get(), ex.what());\r
+            }\r
+            rule = XMLHelper::getNextSiblingElement(rule, PolicyRule);\r
+        }\r
+\r
+        if (rules.second.size() == 0) {\r
+            // Process Rule elements.\r
+            log.warn("detected legacy Policy configuration, please convert to new PolicyRule syntax");\r
+            rule = XMLHelper::getFirstChildElement(e, Rule);\r
+            while (rule) {\r
+                auto_ptr_char type(rule->getAttributeNS(nullptr, _type));\r
+                try {\r
+                    rules.second.push_back(samlConf.SecurityPolicyRuleManager.newPlugin(type.get(), rule));\r
+                }\r
+                catch (exception& ex) {\r
+                    log.crit("error instantiating policy rule (%s) in policy (%s): %s", type.get(), id.get(), ex.what());\r
+                }\r
+                rule = XMLHelper::getNextSiblingElement(rule, Rule);\r
+            }\r
+\r
+            // Manually add a basic Conditions rule.\r
+            log.info("installing a default Conditions rule in policy (%s) for compatibility with legacy configuration", id.get());\r
+            rules.second.push_back(samlConf.SecurityPolicyRuleManager.newPlugin(CONDITIONS_POLICY_RULE, nullptr));\r
+        }\r
+\r
+        e = XMLHelper::getNextSiblingElement(e, Policy);\r
+    }\r
+}\r
+\r
+pair<bool,DOMElement*> XMLSecurityPolicyProvider::load(bool backup)\r
+{\r
+    // Load from source using base class.\r
+    pair<bool,DOMElement*> raw = ReloadableXMLFile::load(backup);\r
+\r
+    // If we own it, wrap it.\r
+    XercesJanitor<DOMDocument> docjanitor(raw.first ? raw.second->getOwnerDocument() : nullptr);\r
+\r
+    XMLSecurityPolicyProviderImpl* impl = new XMLSecurityPolicyProviderImpl(raw.second, m_log);\r
+\r
+    // If we held the document, transfer it to the impl. If we didn't, it's a no-op.\r
+    impl->setDocument(docjanitor.release());\r
+\r
+    // Perform the swap inside a lock.\r
+    if (m_lock)\r
+        m_lock->wrlock();\r
+    SharedLock locker(m_lock, false);\r
+    delete m_impl;\r
+    m_impl = impl;\r
+\r
+\r
+    return make_pair(false,(DOMElement*)nullptr);\r
+}\r
+\r
+pair<bool,DOMElement*> XMLSecurityPolicyProvider::background_load()\r
+{\r
+    try {\r
+        return load(false);\r
+    }\r
+    catch (long& ex) {\r
+        if (ex == HTTPResponse::XMLTOOLING_HTTP_STATUS_NOTMODIFIED)\r
+            m_log.info("remote resource (%s) unchanged", m_source.c_str());\r
+        if (!m_loaded && !m_backing.empty())\r
+            return load(true);\r
+        throw;\r
+    }\r
+    catch (exception&) {\r
+        if (!m_loaded && !m_backing.empty())\r
+            return load(true);\r
+        throw;\r
+    }\r
+}\r
index d052a9e..231039f 100644 (file)
 # include "attribute/resolver/AttributeExtractor.h"
 # include "attribute/resolver/AttributeResolver.h"
 # include "security/PKIXTrustEngine.h"
+# include "security/SecurityPolicyProvider.h"
 # include <saml/SAMLConfig.h>
 # include <saml/version.h>
 # include <saml/binding/ArtifactMap.h>
 # include <saml/binding/SAMLArtifact.h>
-# include <saml/binding/SecurityPolicyRule.h>
 # include <saml/saml1/core/Assertions.h>
 # include <saml/saml2/core/Assertions.h>
 # include <saml/saml2/binding/SAML2ArtifactType0004.h>
@@ -74,7 +74,6 @@
 # include <xmltooling/security/TrustEngine.h>
 # include <xmltooling/util/ReplayCache.h>
 # include <xmltooling/util/StorageService.h>
-# include <xercesc/util/XMLStringTokenizer.hpp>
 # include <xsec/utils/XSECPlatformUtils.hpp>
 using namespace opensaml::saml2;
 using namespace opensaml::saml2p;
@@ -254,7 +253,7 @@ namespace {
         RequestMapper* m_requestMapper;
         map<string,Application*> m_appmap;
 #ifndef SHIBSP_LITE
-        map< string,pair< PropertySet*,vector<const SecurityPolicyRule*> > > m_policyMap;
+        SecurityPolicyProvider* m_policy;
         vector< pair< string, pair<string,string> > > m_transportOptions;
 #endif
 
@@ -309,6 +308,21 @@ namespace {
 #endif
         }
 
+#ifndef SHIBSP_LITE
+        // Lockable
+        Lockable* lock() {
+            ReloadableXMLFile::lock();
+            if (m_impl->m_policy)
+                m_impl->m_policy->lock();
+            return this;
+        }
+        void unlock() {
+            if (m_impl->m_policy)
+                m_impl->m_policy->unlock();
+            ReloadableXMLFile::unlock();
+        }
+#endif
+
         // PropertySet
         const PropertySet* getParent() const { return m_impl->getParent(); }
         void setParent(const PropertySet* parent) {return m_impl->setParent(parent);}
@@ -366,18 +380,18 @@ namespace {
         }
 
 #ifndef SHIBSP_LITE
+        SecurityPolicyProvider* getSecurityPolicyProvider(bool required=true) const {
+            if (required && !m_impl->m_policy)
+                throw ConfigurationException("No SecurityPolicyProvider available.");
+            return m_impl->m_policy;
+        }
+
         const PropertySet* getPolicySettings(const char* id) const {
-            map<string,pair<PropertySet*,vector<const SecurityPolicyRule*> > >::const_iterator i = m_impl->m_policyMap.find(id);
-            if (i!=m_impl->m_policyMap.end())
-                return i->second.first;
-            throw ConfigurationException("Security Policy ($1) not found, check <SecurityPolicies> element.", params(1,id));
+            return getSecurityPolicyProvider()->getPolicySettings(id);
         }
 
         const vector<const SecurityPolicyRule*>& getPolicyRules(const char* id) const {
-            map<string,pair<PropertySet*,vector<const SecurityPolicyRule*> > >::const_iterator i = m_impl->m_policyMap.find(id);
-            if (i!=m_impl->m_policyMap.end())
-                return i->second.second;
-            throw ConfigurationException("Security Policy ($1) not found, check <SecurityPolicies> element.", params(1,id));
+            return getSecurityPolicyProvider()->getPolicyRules(id);
         }
 
         bool setTransportOptions(SOAPTransport& transport) const {
@@ -411,8 +425,6 @@ namespace {
     #pragma warning( pop )
 #endif
 
-    static const XMLCh AlgorithmBlacklist[] =   UNICODE_LITERAL_18(A,l,g,o,r,i,t,h,m,B,l,a,c,k,l,i,s,t);
-    static const XMLCh AlgorithmWhitelist[] =   UNICODE_LITERAL_18(A,l,g,o,r,i,t,h,m,W,h,i,t,e,l,i,s,t);
     static const XMLCh ApplicationOverride[] =  UNICODE_LITERAL_19(A,p,p,l,i,c,a,t,i,o,n,O,v,e,r,r,i,d,e);
     static const XMLCh ApplicationDefaults[] =  UNICODE_LITERAL_19(A,p,p,l,i,c,a,t,i,o,n,D,e,f,a,u,l,t,s);
     static const XMLCh _ArtifactMap[] =         UNICODE_LITERAL_11(A,r,t,i,f,a,c,t,M,a,p);
@@ -441,14 +453,12 @@ namespace {
     static const XMLCh _option[] =              UNICODE_LITERAL_6(o,p,t,i,o,n);
     static const XMLCh OutOfProcess[] =         UNICODE_LITERAL_12(O,u,t,O,f,P,r,o,c,e,s,s);
     static const XMLCh _path[] =                UNICODE_LITERAL_4(p,a,t,h);
-    static const XMLCh Policy[] =               UNICODE_LITERAL_6(P,o,l,i,c,y);
-    static const XMLCh PolicyRule[] =           UNICODE_LITERAL_10(P,o,l,i,c,y,R,u,l,e);
     static const XMLCh _provider[] =            UNICODE_LITERAL_8(p,r,o,v,i,d,e,r);
     static const XMLCh RelyingParty[] =         UNICODE_LITERAL_12(R,e,l,y,i,n,g,P,a,r,t,y);
     static const XMLCh _ReplayCache[] =         UNICODE_LITERAL_11(R,e,p,l,a,y,C,a,c,h,e);
     static const XMLCh _RequestMapper[] =       UNICODE_LITERAL_13(R,e,q,u,e,s,t,M,a,p,p,e,r);
-    static const XMLCh Rule[] =                 UNICODE_LITERAL_4(R,u,l,e);
     static const XMLCh SecurityPolicies[] =     UNICODE_LITERAL_16(S,e,c,u,r,i,t,y,P,o,l,i,c,i,e,s);
+    static const XMLCh SecurityPolicyProvider[] = UNICODE_LITERAL_22(S,e,c,u,r,i,t,y,P,o,l,i,c,y,P,r,o,v,i,d,e,r);
     static const XMLCh _SessionCache[] =        UNICODE_LITERAL_12(S,e,s,s,i,o,n,C,a,c,h,e);
     static const XMLCh _SessionInitiator[] =    UNICODE_LITERAL_16(S,e,s,s,i,o,n,I,n,i,t,i,a,t,o,r);
     static const XMLCh _SingleLogoutService[] = UNICODE_LITERAL_19(S,i,n,g,l,e,L,o,g,o,u,t,S,e,r,v,i,c,e);
@@ -459,21 +469,6 @@ namespace {
     static const XMLCh _TrustEngine[] =         UNICODE_LITERAL_11(T,r,u,s,t,E,n,g,i,n,e);
     static const XMLCh _type[] =                UNICODE_LITERAL_4(t,y,p,e);
     static const XMLCh UnixListener[] =         UNICODE_LITERAL_12(U,n,i,x,L,i,s,t,e,n,e,r);
-
-#ifndef SHIBSP_LITE
-    class SHIBSP_DLLLOCAL PolicyNodeFilter : public DOMNodeFilter
-    {
-    public:
-#ifdef SHIBSP_XERCESC_SHORT_ACCEPTNODE
-        short
-#else
-        FilterAction
-#endif
-        acceptNode(const DOMNode* node) const {
-            return FILTER_REJECT;
-        }
-    };
-#endif
 };
 
 namespace shibsp {
@@ -1225,6 +1220,7 @@ XMLConfigImpl::acceptNode(const DOMNode* node) const
         XMLString::equals(name,_RequestMapper) ||
         XMLString::equals(name,_ReplayCache) ||
         XMLString::equals(name,SecurityPolicies) ||
+        XMLString::equals(name,SecurityPolicyProvider) ||
         XMLString::equals(name,_SessionCache) ||
         XMLString::equals(name,Site) ||
         XMLString::equals(name,_StorageService) ||
@@ -1266,7 +1262,11 @@ void XMLConfigImpl::doExtensions(const DOMElement* e, const char* label, Categor
 }
 
 XMLConfigImpl::XMLConfigImpl(const DOMElement* e, bool first, const XMLConfig* outer, Category& log)
-    : m_requestMapper(nullptr), m_outer(outer), m_document(nullptr)
+    : m_requestMapper(nullptr),
+#ifndef SHIBSP_LITE
+        m_policy(nullptr),
+#endif
+        m_outer(outer), m_document(nullptr)
 {
 #ifdef _DEBUG
     xmltooling::NDC ndc("XMLConfigImpl");
@@ -1320,7 +1320,7 @@ XMLConfigImpl::XMLConfigImpl(const DOMElement* e, bool first, const XMLConfig* o
         // First load any property sets.
         load(e,nullptr,this);
 
-        const DOMElement* child;
+        DOMElement* child;
         string plugtype;
 
         // Much of the processing can only occur on the first instantiation.
@@ -1456,44 +1456,11 @@ XMLConfigImpl::XMLConfigImpl(const DOMElement* e, bool first, const XMLConfig* o
                     throw ConfigurationException("Can't build SessionCache, missing conf:SessionCache element?");
                 }
             }
-
-#ifndef SHIBSP_LITE
-            child = XMLHelper::getLastChildElement(e, SecurityPolicies);
-            if (child) {
-                const XMLCh* algs = nullptr;
-                const DOMElement* alglist = XMLHelper::getLastChildElement(child, AlgorithmBlacklist);
-                if (alglist && alglist->hasChildNodes()) {
-                    algs = alglist->getFirstChild()->getNodeValue();
-                }
-                else if ((alglist = XMLHelper::getLastChildElement(child, AlgorithmWhitelist)) && alglist->hasChildNodes()) {
-                    algs = alglist->getFirstChild()->getNodeValue();
-                }
-                if (algs) {
-#ifdef SHIBSP_XMLSEC_WHITELISTING
-                    const XMLCh* token;
-                    XMLStringTokenizer tokenizer(algs);
-                    while (tokenizer.hasMoreTokens()) {
-                        token = tokenizer.nextToken();
-                        if (token) {
-                            if (XMLString::equals(alglist->getLocalName(), AlgorithmBlacklist))
-                                XSECPlatformUtils::blacklistAlgorithm(token);
-                            else
-                                XSECPlatformUtils::whitelistAlgorithm(token);
-                        }
-                    }
-#else
-                    log.fatal("XML-Security-C library prior to 1.6.0 does not support algorithm white/blacklists");
-                    throw ConfigurationException("XML-Security-C library prior to 1.6.0 does not support algorithm white/blacklists.");
-#endif
-                }
-            }
-#endif
         } // end of first-time-only stuff
 
         // Back to the fully dynamic stuff...next up is the RequestMapper.
         if (conf.isEnabled(SPConfig::RequestMapping)) {
-            child=XMLHelper::getFirstChildElement(e,_RequestMapper);
-            if (child) {
+            if (child = XMLHelper::getFirstChildElement(e,_RequestMapper)) {
                 auto_ptr_char type(child->getAttributeNS(nullptr,_type));
                 log.info("building RequestMapper of type %s...",type.get());
                 m_requestMapper=conf.RequestMapperManager.newPlugin(type.get(),child);
@@ -1506,53 +1473,38 @@ XMLConfigImpl::XMLConfigImpl(const DOMElement* e, bool first, const XMLConfig* o
 
 #ifndef SHIBSP_LITE
         // Load security policies.
-        child = XMLHelper::getLastChildElement(e,SecurityPolicies);
-        if (child) {
-            PolicyNodeFilter filter;
-            child = XMLHelper::getFirstChildElement(child,Policy);
-            while (child) {
-                auto_ptr_char id(child->getAttributeNS(nullptr,_id));
-                pair< PropertySet*,vector<const SecurityPolicyRule*> >& rules = m_policyMap[id.get()];
-                rules.first = nullptr;
-                auto_ptr<DOMPropertySet> settings(new DOMPropertySet());
-                settings->load(child, nullptr, &filter);
-                rules.first = settings.release();
-
-                // Process PolicyRule elements.
-                const DOMElement* rule = XMLHelper::getFirstChildElement(child,PolicyRule);
-                while (rule) {
-                    auto_ptr_char type(rule->getAttributeNS(nullptr,_type));
-                    try {
-                        rules.second.push_back(samlConf.SecurityPolicyRuleManager.newPlugin(type.get(),rule));
-                    }
-                    catch (exception& ex) {
-                        log.crit("error instantiating policy rule (%s) in policy (%s): %s", type.get(), id.get(), ex.what());
-                    }
-                    rule = XMLHelper::getNextSiblingElement(rule,PolicyRule);
-                }
-
-                if (rules.second.size() == 0) {
-                    // Process Rule elements.
-                    log.warn("detected legacy Policy configuration, please convert to new PolicyRule syntax");
-                    rule = XMLHelper::getFirstChildElement(child,Rule);
-                    while (rule) {
-                        auto_ptr_char type(rule->getAttributeNS(nullptr,_type));
-                        try {
-                            rules.second.push_back(samlConf.SecurityPolicyRuleManager.newPlugin(type.get(),rule));
-                        }
-                        catch (exception& ex) {
-                            log.crit("error instantiating policy rule (%s) in policy (%s): %s", type.get(), id.get(), ex.what());
-                        }
-                        rule = XMLHelper::getNextSiblingElement(rule,Rule);
-                    }
-
-                    // Manually add a basic Conditions rule.
-                    log.info("installing a default Conditions rule in policy (%s) for compatibility with legacy configuration", id.get());
-                    rules.second.push_back(samlConf.SecurityPolicyRuleManager.newPlugin(CONDITIONS_POLICY_RULE, nullptr));
-                }
+        if (child = XMLHelper::getLastChildElement(e, SecurityPolicyProvider)) {
+            auto_ptr_char type(child->getAttributeNS(nullptr, _type));
+            log.info("building SecurityPolicyProvider of type %s...", type.get());
+            m_policy = conf.SecurityPolicyProviderManager.newPlugin(type.get(), child);
+        }
+        else if (child = XMLHelper::getLastChildElement(e, SecurityPolicies)) {
+            // For backward compatibility, wrap in a plugin element.
+            DOMElement* polwrapper = e->getOwnerDocument()->createElementNS(nullptr, SecurityPolicyProvider);
+            polwrapper->appendChild(child);
+            log.info("building SecurityPolicyProvider of type %s...", XML_SECURITYPOLICY_PROVIDER);
+            m_policy = conf.SecurityPolicyProviderManager.newPlugin(XML_SECURITYPOLICY_PROVIDER, polwrapper);
+        }
+        else {
+            log.fatal("can't build SecurityPolicyProvider, missing conf:SecurityPolicyProvider element?");
+            throw ConfigurationException("Can't build SecurityPolicyProvider, missing conf:SecurityPolicyProvider element?");
+        }
 
-                child = XMLHelper::getNextSiblingElement(child,Policy);
+        if (first) {
+#ifdef SHIBSP_XMLSEC_WHITELISTING
+            vector<xstring>::const_iterator alg;
+            if (!m_policy->getAlgorithmBlacklist().empty()) {
+                for (alg = m_policy->getAlgorithmBlacklist().begin(); alg != m_policy->getAlgorithmBlacklist().end(); ++alg)
+                    XSECPlatformUtils::blacklistAlgorithm(alg->c_str());
+            }
+            else if (!m_policy->getAlgorithmWhitelist().empty()) {
+                for (alg = m_policy->getAlgorithmWhitelist().begin(); alg != m_policy->getAlgorithmWhitelist().end(); ++alg)
+                    XSECPlatformUtils::whitelistAlgorithm(alg->c_str());
             }
+#else
+            log.fatal("XML-Security-C library prior to 1.6.0 does not support algorithm white/blacklists");
+            throw ConfigurationException("XML-Security-C library prior to 1.6.0 does not support algorithm white/blacklists.");
+#endif
         }
 
         // Process TransportOption elements.
@@ -1609,11 +1561,8 @@ void XMLConfigImpl::cleanup()
     for_each(m_appmap.begin(),m_appmap.end(),cleanup_pair<string,Application>());
     m_appmap.clear();
 #ifndef SHIBSP_LITE
-    for (map< string,pair<PropertySet*,vector<const SecurityPolicyRule*> > >::iterator i=m_policyMap.begin(); i!=m_policyMap.end(); ++i) {
-        delete i->second.first;
-        for_each(i->second.second.begin(), i->second.second.end(), xmltooling::cleanup<SecurityPolicyRule>());
-    }
-    m_policyMap.clear();
+    delete m_policy;
+    m_policy = nullptr;
 #endif
     delete m_requestMapper;
     m_requestMapper = nullptr;
diff --git a/shibsp/security/SecurityPolicyProvider.h b/shibsp/security/SecurityPolicyProvider.h
new file mode 100644 (file)
index 0000000..32734f9
--- /dev/null
@@ -0,0 +1,116 @@
+/*\r
+ *  Copyright 2010 Internet2\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+/**\r
+ * @file shibsp/security/SecurityPolicyProvider.h\r
+ * \r
+ * Interface to a source of security policy settings and rules.\r
+ */\r
+\r
+#ifndef __shibsp_policyfactory_h__\r
+#define __shibsp_policyfactory_h__\r
+\r
+#ifndef SHIBSP_LITE\r
+\r
+#include <shibsp/base.h>\r
+\r
+#include <vector>\r
+#include <xmltooling/Lockable.h>\r
+#include <xmltooling/unicode.h>\r
+\r
+namespace xmltooling {\r
+    class XMLTOOL_API QName;\r
+};\r
+\r
+namespace opensaml {\r
+    class SAML_API SecurityPolicy;\r
+    class SAML_API SecurityPolicyRule;\r
+};\r
+\r
+namespace shibsp {\r
+\r
+    class SHIBSP_API Application;\r
+    class SHIBSP_API PropertySet;\r
+\r
+    /**\r
+     * Interface to a source of security policy settings and rules.\r
+     */\r
+       class SHIBSP_API SecurityPolicyProvider : public virtual xmltooling::Lockable\r
+    {\r
+        MAKE_NONCOPYABLE(SecurityPolicyProvider);\r
+    protected:\r
+        SecurityPolicyProvider();\r
+    public:\r
+        virtual ~SecurityPolicyProvider();\r
+        \r
+        /**\r
+                * Returns the security policy settings for an identified policy.\r
+         *\r
+                * @param id    identifies the policy to return\r
+         * @return a PropertySet\r
+                */\r
+        virtual const PropertySet* getPolicySettings(const char* id) const=0;\r
+\r
+        /**\r
+                * Returns the security policy rules for an identified policy.\r
+         *\r
+                * @param id    identifies the policy to return\r
+         * @return an array of policy rules\r
+                */\r
+        virtual const std::vector<const opensaml::SecurityPolicyRule*>& getPolicyRules(const char* id) const=0;\r
+\r
+        /**\r
+         * Returns a set of XML Signature/Encryption algorithm identifiers to block.\r
+         *\r
+         * @return  an array of algorithm URIs to block\r
+         */\r
+        virtual const std::vector<xmltooling::xstring>& getAlgorithmBlacklist() const=0;\r
+\r
+        /**\r
+         * Returns a set of XML Signature/Encryption algorithm identifiers to permit.\r
+         *\r
+         * @return  an array of algorithm URIs to permit\r
+         */\r
+        virtual const std::vector<xmltooling::xstring>& getAlgorithmWhitelist() const=0;\r
+\r
+        /**\r
+         * Returns a SecurityPolicy applicable to an application and/or policy identifier.\r
+         *\r
+         * <p>The caller <strong>MUST</strong> lock the application's MetadataProvider for the life\r
+         * of the returned object.\r
+         *\r
+         * @param application   reference to application applying policy\r
+         * @param role          identifies the role (generally IdP or SP) of the policy peer\r
+         * @param policyId      identifies policy, defaults to the application's default\r
+         * @return  a new policy instance, which the caller is responsible for freeing\r
+         */\r
+        virtual opensaml::SecurityPolicy* createSecurityPolicy(\r
+            const Application& application, const xmltooling::QName* role, const char* policyId=nullptr\r
+            ) const;\r
+    };\r
+\r
+    /**\r
+     * Registers SecurityPolicyProvider classes into the runtime.\r
+     */\r
+    void SHIBSP_API registerSecurityPolicyProviders();\r
+\r
+    /** SecurityPolicyProvider based on an XML configuration format. */\r
+    #define XML_SECURITYPOLICY_PROVIDER "XML"\r
+};\r
+\r
+#endif\r
+\r
+#endif /* __shibsp_policyfactory_h__ */\r
index 990b70f..c8906f5 100644 (file)
   <ItemGroup>\r
     <ClCompile Include="AbstractSPRequest.cpp" />\r
     <ClCompile Include="Application.cpp" />\r
+    <ClCompile Include="impl\XMLSecurityPolicyProvider.cpp" />\r
     <ClCompile Include="ServiceProvider.cpp" />\r
     <ClCompile Include="SPConfig.cpp" />\r
     <ClCompile Include="util\CGIParser.cpp" />\r
     <ClInclude Include="internal.h" />\r
     <ClInclude Include="RequestMapper.h" />\r
     <ClInclude Include="resource.h" />\r
+    <ClInclude Include="security\SecurityPolicyProvider.h" />\r
     <ClInclude Include="ServiceProvider.h" />\r
     <ClInclude Include="SessionCache.h" />\r
     <ClInclude Include="SessionCacheEx.h" />\r
index 0c89b89..47af548 100644 (file)
     <ClCompile Include="handler\impl\WAYFSessionInitiator.cpp">\r
       <Filter>Source Files\handler\impl</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="impl\XMLSecurityPolicyProvider.cpp">\r
+      <Filter>Source Files\impl</Filter>\r
+    </ClCompile>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ClInclude Include="remoting\impl\SocketListener.h">\r
     <ClInclude Include="metadata\MetadataProviderCriteria.h">\r
       <Filter>Header Files\metadata</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="security\SecurityPolicyProvider.h">\r
+      <Filter>Header Files\security</Filter>\r
+    </ClInclude>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ResourceCompile Include="shibsp.rc">\r