From 244e807edf8af453022d11d1357e04b5d53db8af Mon Sep 17 00:00:00 2001 From: Scott Cantor Date: Thu, 4 Jan 2007 03:19:39 +0000 Subject: [PATCH] New base class for ACL files. --- xmlproviders/XML.cpp | 22 ------ xmlproviders/XMLAccessControl.cpp | 142 ++++++++++++++++++-------------------- xmlproviders/internal.h | 12 +--- 3 files changed, 68 insertions(+), 108 deletions(-) diff --git a/xmlproviders/XML.cpp b/xmlproviders/XML.cpp index 0b95544..bf2284f 100644 --- a/xmlproviders/XML.cpp +++ b/xmlproviders/XML.cpp @@ -105,25 +105,3 @@ const XMLCh XML::Literals::regexp[] = const XMLCh XML::Literals::xpath[] = { chLatin_x, chLatin_p, chLatin_a, chLatin_t, chLatin_h, chNull }; - -const XMLCh XML::Literals::url[] = { chLatin_u, chLatin_r, chLatin_l, chNull }; - -const XMLCh XML::Literals::AccessControl[] = -{ chLatin_A, chLatin_c, chLatin_c, chLatin_e, chLatin_s, chLatin_s, - chLatin_C, chLatin_o, chLatin_n, chLatin_t, chLatin_r, chLatin_o, chLatin_l, chNull -}; - -const XMLCh XML::Literals::AND[] = -{ chLatin_A, chLatin_N, chLatin_D, chNull }; - -const XMLCh XML::Literals::NOT[] = -{ chLatin_N, chLatin_O, chLatin_T, chNull }; - -const XMLCh XML::Literals::OR[] = -{ chLatin_O, chLatin_R, chNull }; - -const XMLCh XML::Literals::require[] = -{ chLatin_r, chLatin_e, chLatin_q, chLatin_u, chLatin_i, chLatin_r, chLatin_e, chNull }; - -const XMLCh XML::Literals::Rule[] = -{ chLatin_R, chLatin_u, chLatin_l, chLatin_e, chNull }; diff --git a/xmlproviders/XMLAccessControl.cpp b/xmlproviders/XMLAccessControl.cpp index e7d8e13..d623e41 100644 --- a/xmlproviders/XMLAccessControl.cpp +++ b/xmlproviders/XMLAccessControl.cpp @@ -25,17 +25,19 @@ #include #include -#include +#include +#include #ifndef HAVE_STRCASECMP # define strcasecmp _stricmp #endif +using namespace shibsp; +using namespace shibtarget; using namespace saml; using namespace shibboleth; -using namespace shibtarget; +using namespace xmltooling; using namespace std; -using namespace log4cpp; namespace { struct IAuthz { @@ -67,46 +69,56 @@ namespace { vector m_operands; }; - class XMLAccessControlImpl : public ReloadableXMLFileImpl - { - public: - XMLAccessControlImpl(const char* pathname) : ReloadableXMLFileImpl(pathname) { init(); } - XMLAccessControlImpl(const DOMElement* e) : ReloadableXMLFileImpl(e) { init(); } - void init(); - ~XMLAccessControlImpl() {delete m_rootAuthz;} - - IAuthz* m_rootAuthz; - }; +#if defined (_MSC_VER) + #pragma warning( push ) + #pragma warning( disable : 4250 ) +#endif - class XMLAccessControl : public IAccessControl, public ReloadableXMLFile + class XMLAccessControl : public IAccessControl, public xmltooling::ReloadableXMLFile { public: - XMLAccessControl(const DOMElement* e) : ReloadableXMLFile(e) {} - ~XMLAccessControl() {} + XMLAccessControl(const DOMElement* e) : xmltooling::ReloadableXMLFile(e), m_rootAuthz(NULL) { + load(); // guarantees an exception or the policy is loaded + } + + ~XMLAccessControl() { + delete m_rootAuthz; + } - virtual bool authorized(ShibTarget* st, ISessionCacheEntry* entry) const; + bool authorized(ShibTarget* st, ISessionCacheEntry* entry) const; protected: - virtual ReloadableXMLFileImpl* newImplementation(const char* pathname, bool first=true) const; - virtual ReloadableXMLFileImpl* newImplementation(const DOMElement* e, bool first=true) const; + pair load(); + + private: + IAuthz* m_rootAuthz; }; + +#if defined (_MSC_VER) + #pragma warning( pop ) +#endif + + static const XMLCh AccessControl[] = UNICODE_LITERAL_13(A,c,c,e,s,s,C,o,n,t,r,o,l); + static const XMLCh require[] = UNICODE_LITERAL_7(r,e,q,u,i,r,e); + static const XMLCh NOT[] = UNICODE_LITERAL_3(N,O,T); + static const XMLCh AND[] = UNICODE_LITERAL_3(A,N,D); + static const XMLCh OR[] = UNICODE_LITERAL_2(O,R); + static const XMLCh _Rule[] = UNICODE_LITERAL_4(R,u,l,e); } IPlugIn* XMLAccessControlFactory(const DOMElement* e) { - auto_ptr a(new XMLAccessControl(e)); - a->getImplementation(); - return a.release(); + return new XMLAccessControl(e); } Rule::Rule(const DOMElement* e) { - auto_ptr_char req(e->getAttributeNS(NULL,SHIB_L(require))); + xmltooling::auto_ptr_char req(e->getAttributeNS(NULL,require)); if (!req.get() || !*req.get()) - throw MalformedException("Access control rule missing require attribute"); + throw ConfigurationException("Access control rule missing require attribute"); m_alias=req.get(); - auto_ptr_char vals(e->hasChildNodes() ? e->getFirstChild()->getNodeValue() : NULL); + xmltooling::auto_ptr_char vals(e->hasChildNodes() ? e->getFirstChild()->getNodeValue() : NULL); #ifdef HAVE_STRTOK_R char* pos=NULL; const char* token=strtok_r(const_cast(vals.get()),"/",&pos); @@ -176,18 +188,18 @@ bool Rule::authorized(ShibTarget* st, ISessionCacheEntry* entry) const Operator::Operator(const DOMElement* e) { - if (saml::XML::isElementNamed(e,shibtarget::XML::SHIBTARGET_NS,SHIB_L(NOT))) + if (XMLString::equals(e->getLocalName(),NOT)) m_op=OP_NOT; - else if (saml::XML::isElementNamed(e,shibtarget::XML::SHIBTARGET_NS,SHIB_L(AND))) + else if (XMLString::equals(e->getLocalName(),AND)) m_op=OP_AND; - else if (saml::XML::isElementNamed(e,shibtarget::XML::SHIBTARGET_NS,SHIB_L(OR))) + else if (XMLString::equals(e->getLocalName(),OR)) m_op=OP_OR; else - throw MalformedException("Unrecognized operator in access control rule"); + throw ConfigurationException("Unrecognized operator in access control rule"); try { - e=saml::XML::getFirstChildElement(e); - if (saml::XML::isElementNamed(e,shibtarget::XML::SHIBTARGET_NS,SHIB_L(Rule))) + e=XMLHelper::getFirstChildElement(e); + if (XMLString::equals(e->getLocalName(),_Rule)) m_operands.push_back(new Rule(e)); else m_operands.push_back(new Operator(e)); @@ -195,17 +207,17 @@ Operator::Operator(const DOMElement* e) if (m_op==OP_NOT) return; - e=saml::XML::getNextSiblingElement(e); + e=XMLHelper::getNextSiblingElement(e); while (e) { - if (saml::XML::isElementNamed(e,shibtarget::XML::SHIBTARGET_NS,SHIB_L(Rule))) + if (XMLString::equals(e->getLocalName(),_Rule)) m_operands.push_back(new Rule(e)); else m_operands.push_back(new Operator(e)); - e=saml::XML::getNextSiblingElement(e); + e=XMLHelper::getNextSiblingElement(e); } } - catch (SAMLException&) { - this->~Operator(); + catch (exception&) { + for_each(m_operands.begin(),m_operands.end(),xmltooling::cleanup()); throw; } } @@ -243,50 +255,30 @@ bool Operator::authorized(ShibTarget* st, ISessionCacheEntry* entry) const return false; } -void XMLAccessControlImpl::init() +pair XMLAccessControl::load() { -#ifdef _DEBUG - xmltooling::NDC ndc("init"); -#endif - Category* log=&Category::getInstance(XMLPROVIDERS_LOGCAT".AccessControl"); - - try { - // We need to move below the AccessControl root element if the policy is in a separate file. - // Unlike most of the plugins, an inline policy will end up handing us the first inline - // content element, and not the outer wrapper. - const DOMElement* rootElement=ReloadableXMLFileImpl::m_root; - if (saml::XML::isElementNamed(rootElement,shibtarget::XML::SHIBTARGET_NS,SHIB_L(AccessControl))) - rootElement = saml::XML::getFirstChildElement(rootElement); - - if (saml::XML::isElementNamed(rootElement,shibtarget::XML::SHIBTARGET_NS,SHIB_L(Rule))) - m_rootAuthz=new Rule(rootElement); - else - m_rootAuthz=new Operator(rootElement); - } - catch (SAMLException& e) { - log->errorStream() << "Error while parsing access control configuration: " << e.what() << CategoryStream::ENDLINE; - throw; - } -#ifndef _DEBUG - catch (...) - { - log->error("Unexpected error while parsing access control configuration"); - throw; - } -#endif -} + // Load from source using base class. + pair raw = ReloadableXMLFile::load(); + + // If we own it, wrap it. + XercesJanitor docjanitor(raw.first ? raw.second->getOwnerDocument() : NULL); -ReloadableXMLFileImpl* XMLAccessControl::newImplementation(const char* pathname, bool first) const -{ - return new XMLAccessControlImpl(pathname); -} + // Check for AccessControl wrapper and drop a level. + if (XMLString::equals(raw.second->getLocalName(),AccessControl)) + raw.second = XMLHelper::getFirstChildElement(raw.second); + + IAuthz* authz; + if (XMLString::equals(raw.second->getLocalName(),_Rule)) + authz=new Rule(raw.second); + else + authz=new Operator(raw.second); -ReloadableXMLFileImpl* XMLAccessControl::newImplementation(const DOMElement* e, bool first) const -{ - return new XMLAccessControlImpl(e); + delete m_rootAuthz; + m_rootAuthz = authz; + return make_pair(false,(DOMElement*)NULL); } bool XMLAccessControl::authorized(ShibTarget* st, ISessionCacheEntry* entry) const { - return static_cast(getImplementation())->m_rootAuthz->authorized(st,entry); + return m_rootAuthz ? m_rootAuthz->authorized(st,entry) : false; } diff --git a/xmlproviders/internal.h b/xmlproviders/internal.h index 2667472..9452348 100644 --- a/xmlproviders/internal.h +++ b/xmlproviders/internal.h @@ -38,7 +38,7 @@ #endif #include -#include +#include #include #define XMLPROVIDERS_LOGCAT "XMLProviders" @@ -77,16 +77,6 @@ public: static const XMLCh literal[]; static const XMLCh regexp[]; static const XMLCh xpath[]; - - static const XMLCh url[]; - - // access control constants - static const XMLCh AccessControl[]; - static const XMLCh AND[]; - static const XMLCh NOT[]; - static const XMLCh OR[]; - static const XMLCh require[]; - static const XMLCh Rule[]; }; }; -- 2.1.4