Adjust logging/error-handling, schema fixes, failed message handling.
authorcantor <cantor@cb58f699-b61c-0410-a6fe-9272a202ed29>
Sat, 10 Mar 2007 21:07:59 +0000 (21:07 +0000)
committercantor <cantor@cb58f699-b61c-0410-a6fe-9272a202ed29>
Sat, 10 Mar 2007 21:07:59 +0000 (21:07 +0000)
git-svn-id: https://svn.middleware.georgetown.edu/cpp-sp/trunk@2191 cb58f699-b61c-0410-a6fe-9272a202ed29

apache/mod_apache.cpp
configs/shibboleth.xml.in
isapi_shib/isapi_shib.cpp
nsapi_shib/nsapi_shib.cpp
schemas/shibboleth-spconfig-2.0.xsd
shibsp/ServiceProvider.cpp
shibsp/attribute/resolver/impl/SimpleAttributeResolver.cpp
shibsp/handler/impl/AssertionConsumerService.cpp
shibsp/impl/RemotedSessionCache.cpp
shibsp/impl/XMLServiceProvider.cpp

index 1494e5e..df67456 100644 (file)
@@ -321,15 +321,19 @@ public:
   }
   const char* getQueryString() const { return m_req->args; }
   const char* getRequestBody() const {
-    if (m_gotBody)
+    if (m_gotBody || m_req->method_number==M_GET)
         return m_body.c_str();
     // Read the posted data
-    if (ap_setup_client_block(m_req, REQUEST_CHUNKED_ERROR))
-        throw opensaml::BindingException("Apache function (setup_client_block) failed while reading POST request body.");
-    if (!ap_should_client_block(m_req))
-        throw opensaml::BindingException("Apache function (should_client_block) failed while reading POST request body.");
+    if (ap_setup_client_block(m_req, REQUEST_CHUNKED_DECHUNK)) {
+        m_gotBody=true;
+        log(SPError, "Apache function (setup_client_block) failed while reading request body.");
+    }
+    if (!ap_should_client_block(m_req)) {
+        m_gotBody=true;
+        log(SPError, "Apache function (should_client_block) failed while reading request body.");
+    }
     if (m_req->remaining > 1024*1024)
-        throw opensaml::BindingException("Blocked POST request body larger than size limit.");
+        throw opensaml::SecurityPolicyException("Blocked request body larger than 1M size limit.");
     m_gotBody=true;
     char buff[HUGE_STRING_LEN];
     ap_hard_timeout("[mod_shib] getRequestBody", m_req);
@@ -1014,6 +1018,7 @@ extern "C" void shib_child_init(apr_pool_t* p, server_rec* s)
     g_Config=&SPConfig::getConfig();
     g_Config->setFeatures(
         SPConfig::Listener |
+        SPConfig::Caching |
         SPConfig::Metadata |
         SPConfig::RequestMapping |
         SPConfig::InProcess |
@@ -1114,8 +1119,10 @@ typedef const char* (*config_fn_t)(void);
 static command_rec shire_cmds[] = {
   {"ShibConfig", (config_fn_t)ap_set_global_string_slot, &g_szSHIBConfig,
    RSRC_CONF, TAKE1, "Path to shibboleth.xml config file"},
+  {"ShibCatalogs", (config_fn_t)ap_set_global_string_slot, &g_szSchemaDir,
+   RSRC_CONF, TAKE1, "Paths of XML schema catalogs"},
   {"ShibSchemaDir", (config_fn_t)ap_set_global_string_slot, &g_szSchemaDir,
-   RSRC_CONF, TAKE1, "Path to Shibboleth XML schema directory"},
+   RSRC_CONF, TAKE1, "Paths of XML schema catalogs (deprecated in favor of ShibCatalogs)"},
 
   {"ShibURLScheme", (config_fn_t)shib_set_server_string_slot,
    (void *) XtOffsetOf (shib_server_config, szScheme),
@@ -1208,9 +1215,12 @@ static command_rec shib_cmds[] = {
   AP_INIT_TAKE1("ShibConfig",
                (config_fn_t)ap_set_global_string_slot, &g_szSHIBConfig,
                RSRC_CONF, "Path to shibboleth.xml config file"),
+  AP_INIT_TAKE1("ShibCatalogs",
+     (config_fn_t)ap_set_global_string_slot, &g_szSchemaDir,
+      RSRC_CONF, "Paths of XML schema catalogs"),
   AP_INIT_TAKE1("ShibSchemaDir",
      (config_fn_t)ap_set_global_string_slot, &g_szSchemaDir,
-      RSRC_CONF, "Path to Shibboleth XML schema directory"),
+      RSRC_CONF, "Paths of XML schema catalogs (deprecated in favor of ShibCatalogs)"),
 
   AP_INIT_TAKE1("ShibURLScheme",
      (config_fn_t)shib_set_server_string_slot,
index 918ced7..38989a5 100644 (file)
@@ -44,7 +44,7 @@
        </OutOfProcess>
     
        <!-- The InProcess section pertains to components that support transient process pools like most web servers. -->
-       <InProcess logger="@-PKGSYSCONFDIR-@/native.logger" localRelayState="true">
+       <InProcess logger="@-PKGSYSCONFDIR-@/native.logger">
                <!--
                To customize behavior, map hostnames and path components to applicationId and other settings.
                The following provider types are available with the delivered code:
index efe5aac..0e8f191 100644 (file)
@@ -144,15 +144,16 @@ extern "C" BOOL WINAPI GetFilterVersion(PHTTP_FILTER_VERSION pVer)
         return TRUE;
     }
 
-    LPCSTR schemadir=getenv("SHIBSCHEMAS");
+    LPCSTR schemadir=getenv("SHIBSP_SCHEMAS");
     if (!schemadir)
         schemadir=SHIBSP_SCHEMAS;
-    LPCSTR config=getenv("SHIBCONFIG");
+    LPCSTR config=getenv("SHIBSP_CONFIG");
     if (!config)
         config=SHIBSP_CONFIG;
     g_Config=&SPConfig::getConfig();
     g_Config->setFeatures(
         SPConfig::Listener |
+        SPConfig::Caching |
         SPConfig::Metadata |
         SPConfig::RequestMapping |
         SPConfig::InProcess |
@@ -754,8 +755,8 @@ public:
     if (m_gotBody)
         return m_body.c_str();
     if (m_lpECB->cbTotalBytes > 1024*1024) // 1MB?
-        throw opensaml::BindingException("Size of POST request body exceeded limit.");
-    else if (m_lpECB->cbTotalBytes != m_lpECB->cbAvailable) {
+        throw opensaml::SecurityPolicyException("Size of request body exceeded 1M size limit.");
+    else if (m_lpECB->cbTotalBytes > m_lpECB->cbAvailable) {
       m_gotBody=true;
       char buf[8192];
       DWORD datalen=m_lpECB->cbTotalBytes;
@@ -763,12 +764,12 @@ public:
         DWORD buflen=8192;
         BOOL ret = m_lpECB->ReadClient(m_lpECB->ConnID, buf, &buflen);
         if (!ret || !buflen)
-            throw IOException("Error reading POST request body from browser.");
+            throw IOException("Error reading request body from browser.");
         m_body.append(buf, buflen);
         datalen-=buflen;
       }
     }
-    else {
+    else if (m_lpECB->cbAvailable) {
         m_gotBody=true;
         m_body.assign(reinterpret_cast<char*>(m_lpECB->lpbData),m_lpECB->cbAvailable);
     }
index 5d45aac..d529afe 100644 (file)
@@ -116,17 +116,18 @@ extern "C" NSAPI_PUBLIC int nsapi_shib_init(pblock* pb, ::Session* sn, Request*
 
     const char* schemadir=pblock_findval("shib-schemas",pb);
     if (!schemadir)
-        schemadir=getenv("SHIBSCHEMAS");
+        schemadir=getenv("SHIBSP_SCHEMAS");
     if (!schemadir)
         schemadir=SHIBSP_SCHEMAS;
     const char* config=pblock_findval("shib-config",pb);
     if (!config)
-        config=getenv("SHIBCONFIG");
+        config=getenv("SHIBSP_CONFIG");
     if (!config)
         config=SHIBSP_CONFIG;
     g_Config=&SPConfig::getConfig();
     g_Config->setFeatures(
         SPConfig::Listener |
+        SPConfig::Caching |
         SPConfig::Metadata |
         SPConfig::RequestMapping |
         SPConfig::InProcess |
@@ -264,9 +265,8 @@ public:
     if (m_gotBody)
         return m_body.c_str();
     char* content_length=NULL;
-    if (request_header("content-length", &content_length, m_sn, m_rq)!=REQ_PROCEED ||
-         atoi(content_length) > 1024*1024) // 1MB?
-      throw opensaml::BindingException("Blocked POST request body exceeding size limit.");
+    if (request_header("content-length", &content_length, m_sn, m_rq)!=REQ_PROCEED || atoi(content_length) > 1024*1024) // 1MB?
+      throw opensaml::SecurityPolicyException("Blocked request body exceeding 1M size limit.");
     else {
       char ch=IO_EOF+1;
       int cl=atoi(content_length);
@@ -280,7 +280,7 @@ public:
         cl--;
       }
       if (cl)
-        throw opensaml::BindingException("Error reading POST request body from browser.");
+        throw IOException("Error reading request body from browser.");
       return m_body.c_str();
     }
   }
index c2699db..2824f84 100644 (file)
                <annotation>\r
                        <documentation>Ties ReplayCache to a custom StorageService</documentation>\r
                </annotation>\r
-               <sequence/>\r
-               <attribute name="StorageService" type="IDREF" use="required"/>\r
+               <complexType>\r
+                       <sequence/>
+                       <attribute name="StorageService" type="IDREF" use="required"/>\r
+               </complexType>\r
        </element>
        \r
        <element name="ArtifactMap">
                <annotation>\r
                        <documentation>Customizes an ArtifactMap</documentation>\r
                </annotation>\r
-               <sequence/>
-               <attribute name="StorageService" type="IDREF"/>
-               <attribute name="context" type="conf:string"/>
-               <attribute name="artifactTTL" type="unsignedInt" default="180"/>
+               <complexType>\r
+                       <sequence/>
+                       <attribute name="StorageService" type="IDREF"/>
+                       <attribute name="context" type="conf:string"/>
+                       <attribute name="artifactTTL" type="unsignedInt" default="180"/>\r
+               </complexType>
        </element>\r
        \r
        <element name="OutOfProcess">\r
                <complexType>\r
                        <sequence>
                                <element ref="conf:Extensions" minOccurs="0"/>
+                               <element ref="conf:SessionCache" minOccurs="0"/>\r
                                <element name="RequestMapper" type="conf:PluggableType"/>
                                <element name="Implementation" minOccurs="0">
                                        <complexType>
                                <any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
                        </sequence>
                        <attribute name="logger" type="anyURI"/>
-                       <attribute name="localRelayState" type="boolean" default="false"/>
                        <anyAttribute namespace="##other" processContents="lax"/>\r
                </complexType>\r
        </element>\r
index 4ed5939..a9fd473 100644 (file)
@@ -451,13 +451,13 @@ pair<bool,long> ServiceProvider::doHandler(SPRequest& request) const
       
         // Make sure this is SSL, if it should be
         if ((!handlerSSL.first || handlerSSL.second) && !request.isSecure())
-            throw FatalProfileException("Blocked non-SSL access to Shibboleth handler.");
+            throw SecurityPolicyException("Blocked non-SSL access to Shibboleth handler.");
 
         // We dispatch based on our path info. We know the request URL begins with or equals the handler URL,
         // so the path info is the next character (or null).
         const Handler* handler=app->getHandler(targetURL.c_str() + strlen(handlerURL));
         if (!handler)
-            throw BindingException("Shibboleth handler invoked at an unconfigured location.");
+            throw ConfigurationException("Shibboleth handler invoked at an unconfigured location.");
 
         pair<bool,long> hret=handler->run(request);
 
@@ -465,7 +465,7 @@ pair<bool,long> ServiceProvider::doHandler(SPRequest& request) const
         if (hret.first)
             return hret;
        
-        throw BindingException("Configured Shibboleth handler failed to process the request.");
+        throw ConfigurationException("Configured Shibboleth handler failed to process the request.");
     }
     catch (MetadataException& e) {
         TemplateParameters tp(&e);
index 268677f..43a2c6c 100644 (file)
@@ -74,7 +74,8 @@ namespace shibsp {
             const EntityDescriptor* issuer,\r
             const NameID& nameid,\r
             const vector<const opensaml::Assertion*>* tokens=NULL\r
-            ) : m_app(application), m_session(NULL), m_client_addr(client_addr), m_entity(issuer), m_nameid(nameid), m_tokens(tokens) {\r
+            ) : m_app(application), m_session(NULL), m_client_addr(client_addr), m_metadata(NULL), m_entity(issuer),\r
+                m_nameid(nameid), m_tokens(tokens) {\r
         }\r
         \r
         ~SimpleContext() {\r
@@ -297,12 +298,12 @@ SimpleResolverImpl::SimpleResolverImpl(const DOMElement* e) : m_document(NULL),
             continue;\r
         }\r
 \r
-        if (log.isDebugEnabled()) {\r
+        if (log.isInfoEnabled()) {\r
 #ifdef HAVE_GOOD_STL\r
             auto_ptr_char n(name);\r
             auto_ptr_char f(format);\r
 #endif\r
-            log.debug("creating declaration for Attribute %s%s%s", n.get(), *f.get() ? ", Format/Namespace:" : "", f.get());\r
+            log.info("creating declaration for Attribute %s%s%s", n.get(), *f.get() ? ", Format/Namespace:" : "", f.get());\r
         }\r
         \r
         decl.first = decoder;\r
index 1498faa..891dbe9 100644 (file)
@@ -42,7 +42,7 @@ using namespace log4cpp;
 using namespace std;
 
 AssertionConsumerService::AssertionConsumerService(const DOMElement* e, Category& log)
-    : AbstractHandler(e, log), m_configNS(SHIB2SPCONFIG_NS),
+    : AbstractHandler(e, log), m_decoder(NULL), m_configNS(SHIB2SPCONFIG_NS),
         m_role(samlconstants::SAML20MD_NS, opensaml::saml2md::IDPSSODescriptor::LOCAL_NAME)
 {
     if (SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess))
@@ -174,6 +174,8 @@ string AssertionConsumerService::processMessage(
     
     // Decode the message and process it in a protocol-specific way.
     auto_ptr<XMLObject> msg(m_decoder->decode(relayState, httpRequest, policy));
+    if (!msg.get())
+        throw BindingException("Failed to decode an SSO protocol response.");
     recoverRelayState(httpRequest, relayState);
     string key = implementProtocol(application, httpRequest, policy, settings, *msg.get());
 
index 474f2a5..a64222d 100644 (file)
@@ -607,17 +607,16 @@ void RemotedCache::cleanup()
     xmltooling::NDC ndc("cleanup");\r
 #endif\r
 \r
-    int rerun_timer = 0;\r
     Mutex* mutex = Mutex::create();\r
   \r
     // Load our configuration details...\r
     static const XMLCh cleanupInterval[] = UNICODE_LITERAL_15(c,l,e,a,n,u,p,I,n,t,e,r,v,a,l);\r
-    const XMLCh* tag=m_root->getAttributeNS(NULL,cleanupInterval);\r
+    const XMLCh* tag=m_root ? m_root->getAttributeNS(NULL,cleanupInterval) : NULL;\r
+    int rerun_timer = 900;\r
     if (tag && *tag)\r
         rerun_timer = XMLString::parseInt(tag);\r
-\r
     if (rerun_timer <= 0)\r
-        rerun_timer = 900;        // rerun every 5 minutes\r
+        rerun_timer = 900;\r
 \r
     mutex->lock();\r
 \r
index b7d6f39..e67dfa8 100644 (file)
@@ -943,8 +943,16 @@ XMLConfigImpl::XMLConfigImpl(const DOMElement* e, bool first, const XMLConfig* o
                     }\r
                 }\r
                 else {\r
-                    log.info("building in-process SessionCache of type %s...",REMOTED_SESSION_CACHE);\r
-                    m_outer->m_sessionCache=conf.SessionCacheManager.newPlugin(REMOTED_SESSION_CACHE,NULL);\r
+                    child=XMLHelper::getFirstChildElement(SHIRE,_SessionCache);\r
+                    if (child) {\r
+                        auto_ptr_char type(child->getAttributeNS(NULL,_type));\r
+                        log.info("building SessionCache of type %s...",type.get());\r
+                        m_outer->m_sessionCache=conf.SessionCacheManager.newPlugin(type.get(),child);\r
+                    }\r
+                    else {\r
+                        log.warn("SessionCache unspecified, building SessionCache of type %s...",REMOTED_SESSION_CACHE);\r
+                        m_outer->m_sessionCache=conf.SessionCacheManager.newPlugin(REMOTED_SESSION_CACHE,child);\r
+                    }\r
                 }\r
             }\r
         } // end of first-time-only stuff\r