Added class/decl support to authz plugins, also added reserved user rule to XML plugin.
[shibboleth/sp.git] / shibsp / impl / XMLAccessControl.cpp
index f134dee..f82d955 100644 (file)
@@ -50,7 +50,7 @@ namespace {
         Lockable* lock() {return this;}\r
         void unlock() {}\r
 \r
-        bool authorized(const SPRequest& request, const Session* session) const;\r
+        aclresult_t authorized(const SPRequest& request, const Session* session) const;\r
     \r
     private:\r
         string m_alias;\r
@@ -66,7 +66,7 @@ namespace {
         Lockable* lock() {return this;}\r
         void unlock() {}\r
 \r
-        bool authorized(const SPRequest& request, const Session* session) const;\r
+        aclresult_t authorized(const SPRequest& request, const Session* session) const;\r
         \r
     private:\r
         enum operator_t { OP_NOT, OP_AND, OP_OR } m_op;\r
@@ -82,7 +82,7 @@ namespace {
     {\r
     public:\r
         XMLAccessControl(const DOMElement* e)\r
-                : ReloadableXMLFile(e, log4cpp::Category::getInstance(SHIBSP_LOGCAT".AccessControl")), m_rootAuthz(NULL) {\r
+                : ReloadableXMLFile(e, Category::getInstance(SHIBSP_LOGCAT".AccessControl")), m_rootAuthz(NULL) {\r
             load(); // guarantees an exception or the policy is loaded\r
         }\r
         \r
@@ -90,7 +90,7 @@ namespace {
             delete m_rootAuthz;\r
         }\r
 \r
-        bool authorized(const SPRequest& request, const Session* session) const;\r
+        aclresult_t authorized(const SPRequest& request, const Session* session) const;\r
 \r
     protected:\r
         pair<bool,DOMElement*> load();\r
@@ -147,7 +147,7 @@ Rule::Rule(const DOMElement* e)
     }\r
 }\r
 \r
-bool Rule::authorized(const SPRequest& request, const Session* session) const\r
+AccessControl::aclresult_t Rule::authorized(const SPRequest& request, const Session* session) const\r
 {\r
     // We can make this more complex later using pluggable comparison functions,\r
     // but for now, just a straight port to the new Attribute API.\r
@@ -155,15 +155,45 @@ bool Rule::authorized(const SPRequest& request, const Session* session) const
     // Map alias in rule to the attribute.\r
     if (!session) {\r
         request.log(SPRequest::SPWarn, "AccessControl plugin not given a valid session to evaluate, are you using lazy sessions?");\r
-        return false;\r
+        return shib_acl_false;\r
     }\r
     \r
+    if (m_alias == "user") {\r
+        for (vector<string>::const_iterator i=m_vals.begin(); i!=m_vals.end(); ++i) {\r
+            if (*i == request.getRemoteUser()) {\r
+                request.log(SPRequest::SPDebug, string("AccessControl plugin expecting REMOTE_USER (") + *i + "), authz granted");\r
+                return shib_acl_true;\r
+            }\r
+        }\r
+        return shib_acl_false;\r
+    }\r
+    else if (m_alias == "authnContextClassRef") {\r
+        const char* ref = session->getAuthnContextClassRef();\r
+        for (vector<string>::const_iterator i=m_vals.begin(); ref && i!=m_vals.end(); ++i) {\r
+            if (!strcmp(i->c_str(),ref)) {\r
+                request.log(SPRequest::SPDebug, string("AccessControl plugin expecting authnContextClassRef (") + *i + "), authz granted");\r
+                return shib_acl_true;\r
+            }\r
+        }\r
+        return shib_acl_false;\r
+    }\r
+    else if (m_alias == "authnContextDeclRef") {\r
+        const char* ref = session->getAuthnContextDeclRef();\r
+        for (vector<string>::const_iterator i=m_vals.begin(); ref && i!=m_vals.end(); ++i) {\r
+            if (!strcmp(i->c_str(),ref)) {\r
+                request.log(SPRequest::SPDebug, string("AccessControl plugin expecting authnContextDeclRef (") + *i + "), authz granted");\r
+                return shib_acl_true;\r
+            }\r
+        }\r
+        return shib_acl_false;\r
+    }\r
+\r
     // Find the attribute(s) matching the require rule.\r
-    pair<multimap<string,Attribute*>::const_iterator, multimap<string,Attribute*>::const_iterator> attrs =\r
-        session->getAttributes().equal_range(m_alias);\r
+    pair<multimap<string,const Attribute*>::const_iterator, multimap<string,const Attribute*>::const_iterator> attrs =\r
+        session->getIndexedAttributes().equal_range(m_alias);\r
     if (attrs.first == attrs.second) {\r
         request.log(SPRequest::SPWarn, string("rule requires attribute (") + m_alias + "), not found in session");\r
-        return false;\r
+        return shib_acl_false;\r
     }\r
 \r
     for (; attrs.first != attrs.second; ++attrs.first) {\r
@@ -174,14 +204,14 @@ bool Rule::authorized(const SPRequest& request, const Session* session) const
         for (vector<string>::const_iterator i=m_vals.begin(); i!=m_vals.end(); ++i) {\r
             for (vector<string>::const_iterator j=vals.begin(); j!=vals.end(); ++j) {\r
                 if ((caseSensitive && *i == *j) || (!caseSensitive && !strcasecmp(i->c_str(),j->c_str()))) {\r
-                    request.log(SPRequest::SPDebug, string("AccessControl plugin expecting ") + *j + ", authz granted");\r
-                    return true;\r
+                    request.log(SPRequest::SPDebug, string("AccessControl plugin expecting (") + *j + "), authz granted");\r
+                    return shib_acl_true;\r
                 }\r
             }\r
         }\r
     }\r
 \r
-    return false;\r
+    return shib_acl_false;\r
 }\r
 \r
 Operator::Operator(const DOMElement* e)\r
@@ -225,32 +255,39 @@ Operator::~Operator()
     for_each(m_operands.begin(),m_operands.end(),xmltooling::cleanup<AccessControl>());\r
 }\r
 \r
-bool Operator::authorized(const SPRequest& request, const Session* session) const\r
+AccessControl::aclresult_t Operator::authorized(const SPRequest& request, const Session* session) const\r
 {\r
     switch (m_op) {\r
         case OP_NOT:\r
-            return !m_operands[0]->authorized(request,session);\r
+            switch (m_operands.front()->authorized(request,session)) {\r
+                case shib_acl_true:\r
+                    return shib_acl_false;\r
+                case shib_acl_false:\r
+                    return shib_acl_true;\r
+                default:\r
+                    return shib_acl_indeterminate;\r
+            }\r
         \r
         case OP_AND:\r
         {\r
             for (vector<AccessControl*>::const_iterator i=m_operands.begin(); i!=m_operands.end(); i++) {\r
-                if (!(*i)->authorized(request,session))\r
-                    return false;\r
+                if ((*i)->authorized(request,session) != shib_acl_true)\r
+                    return shib_acl_false;\r
             }\r
-            return true;\r
+            return shib_acl_true;\r
         }\r
         \r
         case OP_OR:\r
         {\r
             for (vector<AccessControl*>::const_iterator i=m_operands.begin(); i!=m_operands.end(); i++) {\r
-                if ((*i)->authorized(request,session))\r
-                    return true;\r
+                if ((*i)->authorized(request,session) == shib_acl_true)\r
+                    return shib_acl_true;\r
             }\r
-            return false;\r
+            return shib_acl_false;\r
         }\r
     }\r
     request.log(SPRequest::SPWarn,"unknown operation in access control policy, denying access");\r
-    return false;\r
+    return shib_acl_false;\r
 }\r
 \r
 pair<bool,DOMElement*> XMLAccessControl::load()\r
@@ -276,7 +313,7 @@ pair<bool,DOMElement*> XMLAccessControl::load()
     return make_pair(false,(DOMElement*)NULL);\r
 }\r
 \r
-bool XMLAccessControl::authorized(const SPRequest& request, const Session* session) const\r
+AccessControl::aclresult_t XMLAccessControl::authorized(const SPRequest& request, const Session* session) const\r
 {\r
-    return m_rootAuthz ? m_rootAuthz->authorized(request,session) : false;\r
+    return m_rootAuthz ? m_rootAuthz->authorized(request,session) : shib_acl_false;\r
 }\r