Some API refactoring
authorcantor <cantor@cb58f699-b61c-0410-a6fe-9272a202ed29>
Thu, 14 Apr 2005 05:55:16 +0000 (05:55 +0000)
committercantor <cantor@cb58f699-b61c-0410-a6fe-9272a202ed29>
Thu, 14 Apr 2005 05:55:16 +0000 (05:55 +0000)
git-svn-id: https://svn.middleware.georgetown.edu/cpp-sp/trunk@1525 cb58f699-b61c-0410-a6fe-9272a202ed29

apache/mod_apache.cpp
isapi_shib/isapi_shib.cpp
shar/shar.cpp
shar/test-client.cpp
shib-target/XMLRequestMapper.cpp
shib-target/internal.h
shib-target/shib-config.cpp
shib-target/shib-target.cpp
shib-target/shib-target.h
test/shibtest.cpp

index c202f7c..2e16f29 100644 (file)
@@ -243,7 +243,6 @@ public:
     m_dc = (shib_dir_config*)ap_get_module_config(req->per_dir_config, &mod_shib);
 
     init(
-        g_Config,
         m_sc->szScheme ? m_sc->szScheme : ap_http_method(req),
            ap_get_server_name(req),
         (int)ap_get_server_port(req),
@@ -1389,7 +1388,7 @@ extern "C" void shib_child_init(apr_pool_t* p, server_rec* s)
             ShibTargetConfig::LocalExtensions |
             ShibTargetConfig::Logging
             );
-        if (!g_Config->init(g_szSchemaDir,g_szSHIBConfig)) {
+        if (!g_Config->init(g_szSchemaDir) || !g_Config->load(g_szSHIBConfig)) {
             ap_log_error(APLOG_MARK,APLOG_CRIT|APLOG_NOERRNO,SH_AP_R(s),"shib_child_init() failed to initialize SHIB Target");
             exit(1);
         }
index 1881ff8..5b5a10e 100644 (file)
@@ -195,7 +195,7 @@ extern "C" BOOL WINAPI GetFilterVersion(PHTTP_FILTER_VERSION pVer)
             ShibTargetConfig::LocalExtensions |
             ShibTargetConfig::Logging
             );
-        if (!g_Config->init(schemadir,config)) {
+        if (!g_Config->init(schemadir) || !g_Config->load(config)) {
             g_Config=NULL;
             LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL,
                     "Filter startup failed during initialization, check shire log for help.");
@@ -410,7 +410,7 @@ public:
     if (site.m_name!=host && site.m_aliases.find(host)==site.m_aliases.end())
         host=site.m_name.c_str();
 
-    init(g_Config, scheme, host, atoi(port), url, content_type, remote_addr, method); 
+    init(scheme, host, atoi(port), url, content_type, remote_addr, method); 
 
     m_pfc = pfc;
     m_pn = pn;
@@ -1126,7 +1126,7 @@ public:
         fullurl+='?';
         fullurl+=lpECB->lpszQueryString;
     }
-    init(g_Config, scheme, host, atoi(port), fullurl.c_str(), lpECB->lpszContentType, remote_addr, lpECB->lpszMethod);
+    init(scheme, host, atoi(port), fullurl.c_str(), lpECB->lpszContentType, remote_addr, lpECB->lpszMethod);
 
     m_lpECB = lpECB;
   }
index 3d9b73f..cf1d51d 100644 (file)
@@ -179,7 +179,7 @@ int real_main(int preinit)
             shar_schemadir=SHIB_SCHEMAS;
         if (!shar_config)
             shar_config=SHIB_CONFIG;
-        if (!conf.init(shar_schemadir,shar_config)) {
+        if (!conf.init(shar_schemadir) || !conf.load(shar_config)) {
             fprintf(stderr, "configuration is invalid, see console for specific problems\n");
             return -2;
         }
@@ -338,7 +338,7 @@ int main(int argc, char *argv[])
         ShibTargetConfig::GlobalExtensions |
         (shar_checkonly ? (ShibTargetConfig::LocalExtensions | ShibTargetConfig::RequestMapper) : ShibTargetConfig::Logging)
         );
-    if (!conf.init(shar_schemadir,shar_config)) {
+    if (!conf.init(shar_schemadir) || !conf.load(shar_config)) {
         fprintf(stderr, "configuration is invalid, check console for specific problems\n");
         return -2;
     }
index 72ab5d6..226f734 100644 (file)
@@ -18,7 +18,7 @@ int main (int argc, char *argv[])
 
   ShibTargetConfig& conf=ShibTargetConfig::getConfig();
   conf.setFeatures(ShibTargetConfig::Listener);
-  if (!conf.init(schemadir,config))
+  if (!conf.init(schemadir) || conf.load(config))
       return -10;
 
   IListener::ShibSocket sock;
index 034f70c..66e2dd1 100644 (file)
@@ -119,9 +119,9 @@ namespace shibtarget {
         XMLRequestMapper(const DOMElement* e) : ReloadableXMLFile(e) {}
         ~XMLRequestMapper() {}
 
-        virtual Settings getSettingsFromURL(const char* url) const;
+        virtual Settings getSettingsFromURL(const char* url, ShibTarget* st) const;
         virtual Settings getSettingsFromParsedURL(
-            const char* scheme, const char* hostname, unsigned int port, const char* path=NULL
+            const char* scheme, const char* hostname, unsigned int port, const char* path, ShibTarget* st
             ) const;
 
     protected:
@@ -312,8 +312,10 @@ const Override* Override::locate(const char* path) const
 
 void XMLRequestMapperImpl::init()
 {
+#ifdef _DEBUG
     NDC ndc("init");
-    log=&Category::getInstance("shibtarget.XMLRequestMapper");
+#endif
+    log=&Category::getInstance("shibtarget.RequestMapper");
 
     try {
         if (!saml::XML::isElementNamed(ReloadableXMLFileImpl::m_root,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(RequestMap))) {
@@ -498,7 +500,7 @@ ReloadableXMLFileImpl* XMLRequestMapper::newImplementation(const DOMElement* e,
     return new XMLRequestMapperImpl(e);
 }
 
-IRequestMapper::Settings XMLRequestMapper::getSettingsFromURL(const char* url) const
+IRequestMapper::Settings XMLRequestMapper::getSettingsFromURL(const char* url, ShibTarget* st) const
 {
     string vhost;
     const char* path=split_url(url,vhost);
@@ -516,7 +518,7 @@ IRequestMapper::Settings XMLRequestMapper::getSettingsFromURL(const char* url) c
 }
 
 IRequestMapper::Settings XMLRequestMapper::getSettingsFromParsedURL(
-    const char* scheme, const char* hostname, unsigned int port, const char* path
+    const char* scheme, const char* hostname, unsigned int port, const char* path, ShibTarget* st
     ) const
 {
     char buf[21];
index 6d00dfe..07b1d63 100644 (file)
@@ -198,6 +198,43 @@ namespace shibtarget {
         shibboleth::Metadata m_metadata;    // scopes lock around use of role descriptor by hook context
         shibboleth::ShibHTTPHook::ShibHTTPHookCallContext* m_ctx;
     };
+
+    // Error template class
+    class ShibMLPPriv;
+    class ShibMLP {
+    public:
+        ShibMLP();
+        ~ShibMLP();
+
+        void insert (const std::string& key, const std::string& value);
+        void insert (const std::string& key, const char* value) {
+          std::string v = value;
+          insert (key, v);
+        }
+        void insert (const char* key, const std::string& value) {
+          std::string k = key;
+          insert (k, value);
+        }
+        void insert (const char* key, const char* value) {
+          std::string k = key, v = value;
+          insert(k,v);
+        }
+        void insert (saml::SAMLException& e);
+
+        void clear () { m_map.clear(); }
+
+        const char* run (std::istream& s, const IPropertySet* props=NULL, std::string* output=NULL);
+        const char* run (const std::string& input, const IPropertySet* props=NULL, std::string* output=NULL);
+        const char* run (const char* input, const IPropertySet* props=NULL, std::string* output=NULL) {
+            std::string i = input;
+            return run(i,props,output);
+        }
+
+    private:
+        ShibMLPPriv *m_priv;
+        std::map<std::string,std::string> m_map;
+        std::string m_generated;
+    };
     
     class STConfig : public ShibTargetConfig
     {
@@ -205,7 +242,8 @@ namespace shibtarget {
         STConfig() : m_tranLog(NULL), m_tranLogLock(NULL), m_rpcpool(NULL) {}
         ~STConfig() {}
         
-        bool init(const char* schemadir, const char* config);
+        bool init(const char* schemadir);
+        bool load(const char* config);
         void shutdown();
         
         RPCHandlePool& getRPCHandlePool() {return *m_rpcpool;}
index 6aa5e46..e8dbaf9 100644 (file)
@@ -95,7 +95,7 @@ ShibTargetConfig& ShibTargetConfig::getConfig()
     return g_Config;
 }
 
-bool STConfig::init(const char* schemadir, const char* config)
+bool STConfig::init(const char* schemadir)
 {
     // With new build of log4cpp, we need to establish a "default"
     // logging appender to stderr up front.
@@ -126,10 +126,10 @@ bool STConfig::init(const char* schemadir, const char* config)
 #ifdef _DEBUG
     saml::NDC ndc("init");
 #endif
-    Category& log = Category::getInstance("shibtarget.STConfig");
+    Category& log = Category::getInstance("shibtarget.Config");
 
-    if (!schemadir || !config) {
-        log.fatal("schema directory or config file not supplied");
+    if (!schemadir) {
+        log.fatal("XML schema directory not supplied");
         return false;
     }
 
@@ -163,24 +163,41 @@ bool STConfig::init(const char* schemadir, const char* config)
         return false;
     }
 
-    try {
-        // Register plugin types.
-        REGISTER_EXCEPTION_FACTORY(ListenerException);
-        REGISTER_EXCEPTION_FACTORY(ConfigurationException);
+    // Register built-in plugin types.
+    REGISTER_EXCEPTION_FACTORY(ListenerException);
+    REGISTER_EXCEPTION_FACTORY(ConfigurationException);
 #ifndef WIN32
-        samlConf.getPlugMgr().regFactory(shibtarget::XML::UnixListenerType,&UnixListenerFactory);
+    samlConf.getPlugMgr().regFactory(shibtarget::XML::UnixListenerType,&UnixListenerFactory);
 #endif
-        samlConf.getPlugMgr().regFactory(shibtarget::XML::TCPListenerType,&TCPListenerFactory);
-        samlConf.getPlugMgr().regFactory(shibtarget::XML::MemorySessionCacheType,&MemoryCacheFactory);
-        samlConf.getPlugMgr().regFactory(shibtarget::XML::LegacyRequestMapType,&XMLRequestMapFactory);
-        samlConf.getPlugMgr().regFactory(shibtarget::XML::RequestMapType,&XMLRequestMapFactory);
-        //shibConf.getPlugMgr().regFactory(shibtarget::XML::htaccessType,&htaccessFactory);
-        
-        saml::XML::registerSchema(ShibTargetConfig::SHIBTARGET_NS,shibtarget::XML::SHIBTARGET_SCHEMA_ID);
-        saml::XML::registerSchema(shibtarget::XML::SAML2META_NS,shibtarget::XML::SAML2META_SCHEMA_ID);
-        saml::XML::registerSchema(shibtarget::XML::SAML2ASSERT_NS,shibtarget::XML::SAML2ASSERT_SCHEMA_ID);
-        saml::XML::registerSchema(shibtarget::XML::XMLENC_NS,shibtarget::XML::XMLENC_SCHEMA_ID);
-        
+    samlConf.getPlugMgr().regFactory(shibtarget::XML::TCPListenerType,&TCPListenerFactory);
+    samlConf.getPlugMgr().regFactory(shibtarget::XML::MemorySessionCacheType,&MemoryCacheFactory);
+    samlConf.getPlugMgr().regFactory(shibtarget::XML::LegacyRequestMapType,&XMLRequestMapFactory);
+    samlConf.getPlugMgr().regFactory(shibtarget::XML::RequestMapType,&XMLRequestMapFactory);
+    //shibConf.getPlugMgr().regFactory(shibtarget::XML::htaccessType,&htaccessFactory);
+    
+    saml::XML::registerSchema(ShibTargetConfig::SHIBTARGET_NS,shibtarget::XML::SHIBTARGET_SCHEMA_ID);
+    saml::XML::registerSchema(shibtarget::XML::SAML2META_NS,shibtarget::XML::SAML2META_SCHEMA_ID);
+    saml::XML::registerSchema(shibtarget::XML::SAML2ASSERT_NS,shibtarget::XML::SAML2ASSERT_SCHEMA_ID);
+    saml::XML::registerSchema(shibtarget::XML::XMLENC_NS,shibtarget::XML::XMLENC_SCHEMA_ID);
+    
+    log.info("finished initializing");
+    return true;
+}
+
+bool STConfig::load(const char* config)
+{
+#ifdef _DEBUG
+    saml::NDC ndc("load");
+#endif
+    Category& log = Category::getInstance("shibtarget.Config");
+
+    if (!config) {
+        log.fatal("path to configuration file not supplied");
+        shutdown();
+        return false;
+    }
+
+    try {
         log.info("loading configuration file: %s", config);
         static const XMLCh uri[] = { chLatin_u, chLatin_r, chLatin_i, chNull };
         DOMImplementation* impl=DOMImplementationRegistry::getDOMImplementation(NULL);
@@ -192,7 +209,7 @@ bool STConfig::init(const char* schemadir, const char* config)
         dummydoc->release();
         
         pair<bool,unsigned int> skew=m_ini->getUnsignedInt("clockSkew");
-        samlConf.clock_skew_secs=skew.first ? skew.second : 180;
+        SAMLConfig::getConfig().clock_skew_secs=skew.first ? skew.second : 180;
         
         m_tranLog=new FixedContextCategory(SHIBTRAN_LOGCAT);
         m_tranLog->info("opened transaction log");
@@ -212,9 +229,8 @@ bool STConfig::init(const char* schemadir, const char* config)
         return false;
     }
 #endif
-  
-    log.info("finished initializing");
 
+    log.info("finished loading configuration");
     return true;
 }
 
@@ -223,7 +239,7 @@ void STConfig::shutdown()
 #ifdef _DEBUG
     saml::NDC ndc("shutdown");
 #endif
-    Category& log = Category::getInstance("shibtarget.STConfig");
+    Category& log = Category::getInstance("shibtarget.Config");
     log.info("shutting down the library");
     delete m_rpcpool;
     m_rpcpool = NULL;
index b4a73dc..a4a175c 100644 (file)
@@ -108,10 +108,11 @@ namespace shibtarget {
     ~ShibTargetPriv();
 
     // Helper functions
-    void get_application(const string& protocol, const string& hostname, int port, const string& uri);
+    void get_application(ShibTarget* st, const string& protocol, const string& hostname, int port, const string& uri);
     const char* getCookie(ShibTarget* st, const string& name) const;
     pair<string,const char*> getCookieNameProps(const char* prefix) const;
     const char* getHandlerURL(const char* resource) const;
+    void* sendError(ShibTarget* st, const char* page, ShibMLP &mlp);
     
     // Handlers do the real Shibboleth work
     pair<bool,void*> doSessionInitiator(ShibTarget* st, const IPropertySet* handler, bool isHandler=true) const;
@@ -140,13 +141,6 @@ namespace shibtarget {
     SAMLResponse* m_pre_response;
     SAMLResponse* m_post_response;
     
-    // These are the actual request parameters set via the init method.
-    string m_url;
-    string m_method;
-    string m_protocol;
-    string m_content_type;
-    string m_remote_addr;
-
     ShibTargetConfig* m_Config;
 
     IConfig* m_conf;
@@ -176,13 +170,12 @@ ShibTarget::~ShibTarget(void)
 }
 
 void ShibTarget::init(
-    ShibTargetConfig *config,
     const char* protocol,
     const char* hostname,
     int port,
     const char* uri,
     const char* content_type,
-    const char* remote_host,
+    const char* remote_addr,
     const char* method
     )
 {
@@ -192,15 +185,16 @@ void ShibTarget::init(
 
   if (m_priv->m_app)
     throw SAMLException("Request initialization occurred twice!");
-  if (!config)
-    throw SAMLException("SP configuration not supplied.");
-
-  if (protocol) m_priv->m_protocol = protocol;
-  if (content_type) m_priv->m_content_type = content_type;
-  if (remote_host) m_priv->m_remote_addr = remote_host;
-  if (method) m_priv->m_method = method;
-  m_priv->m_Config = config;
-  m_priv->get_application(protocol, hostname, port, uri);
+
+  if (method) m_method = method;
+  if (protocol) m_protocol = protocol;
+  if (hostname) m_hostname = hostname;
+  if (uri) m_uri = uri;
+  if (content_type) m_content_type = content_type;
+  if (remote_addr) m_remote_addr = remote_addr;
+  m_port = port;
+  m_priv->m_Config = &ShibTargetConfig::getConfig();
+  m_priv->get_application(this, protocol, hostname, port, uri);
 }
 
 
@@ -214,8 +208,8 @@ pair<bool,void*> ShibTarget::doCheckAuthN(bool requireSessionFlag, bool handler)
     saml::NDC ndc("doCheckAuthN");
 #endif
 
-    const char *procState = "Request Processing Error";
-    const char *targetURL = m_priv->m_url.c_str();
+    const charprocState = "Request Processing Error";
+    const char* targetURL = m_url.c_str();
     ShibMLP mlp;
 
     try {
@@ -264,7 +258,7 @@ pair<bool,void*> ShibTarget::doCheckAuthN(bool requireSessionFlag, bool handler)
             // Localized exception throw if the session isn't valid.
             sessionGet(
                 session_id,
-                m_priv->m_remote_addr.c_str(),
+                m_remote_addr.c_str(),
                 m_priv->m_sso_profile,
                 m_priv->m_provider_id,
                 &m_priv->m_sso_statement,
@@ -317,9 +311,9 @@ pair<bool,void*> ShibTarget::doCheckAuthN(bool requireSessionFlag, bool handler)
     // If we get here then we've got an error.
     mlp.insert("errorType", procState);
     if (targetURL)
-        mlp.insert("requestURL", m_priv->m_url.substr(0,m_priv->m_url.find('?')));
+        mlp.insert("requestURL", m_url.substr(0,m_url.find('?')));
 
-    return pair<bool,void*>(true,sendError("session", mlp));
+    return pair<bool,void*>(true,m_priv->sendError(this,"session", mlp));
 }
 
 pair<bool,void*> ShibTarget::doHandler(void)
@@ -328,8 +322,8 @@ pair<bool,void*> ShibTarget::doHandler(void)
     saml::NDC ndc("doHandler");
 #endif
 
-    const char *procState = "Shibboleth Handler Error";
-    const char* targetURL = m_priv->m_url.c_str();
+    const charprocState = "Shibboleth Handler Error";
+    const char* targetURL = m_url.c_str();
     ShibMLP mlp;
 
     try {
@@ -352,7 +346,7 @@ pair<bool,void*> ShibTarget::doHandler(void)
         pair<bool,bool> handlerSSL=sessionProps->getBool("handlerSSL");
       
         // Make sure this is SSL, if it should be
-        if ((!handlerSSL.first || handlerSSL.second) && m_priv->m_protocol != "https")
+        if ((!handlerSSL.first || handlerSSL.second) && m_protocol != "https")
             throw FatalProfileException("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,
@@ -381,7 +375,7 @@ pair<bool,void*> ShibTarget::doHandler(void)
         // This is a legacy direct execution of the handler (the old shireURL).
         // If this is a GET, we see if it's a lazy session request, otherwise
         // assume it's a SAML 1.x POST profile response and process it.
-        if (!strcasecmp(m_priv->m_method.c_str(), "GET")) {
+        if (!strcasecmp(m_method.c_str(), "GET")) {
             procState = "Session Initiator Error";
             return m_priv->doSessionInitiator(this, sessionProps);
         }
@@ -399,7 +393,7 @@ pair<bool,void*> ShibTarget::doHandler(void)
                 mlp.insert("errorType", procState);
                 if (targetURL)
                     mlp.insert("requestURL", targetURL);
-                return pair<bool,void*>(true,sendError("metadata", mlp));
+                return make_pair(true,m_priv->sendError(this,"metadata", mlp));
             }
         }
     }
@@ -416,9 +410,9 @@ pair<bool,void*> ShibTarget::doHandler(void)
     mlp.insert("errorType", procState);
 
     if (targetURL)
-        mlp.insert("requestURL", m_priv->m_url.substr(0,m_priv->m_url.find('?')));
+        mlp.insert("requestURL", m_url.substr(0,m_url.find('?')));
 
-    return pair<bool,void*>(true,sendError("session", mlp));
+    return make_pair(true,m_priv->sendError(this,"session", mlp));
 }
 
 pair<bool,void*> ShibTarget::doCheckAuthZ(void)
@@ -428,8 +422,8 @@ pair<bool,void*> ShibTarget::doCheckAuthZ(void)
 #endif
 
     ShibMLP mlp;
-    const char *procState = "Authorization Processing Error";
-    const char *targetURL = m_priv->m_url.c_str();
+    const charprocState = "Authorization Processing Error";
+    const char* targetURL = m_url.c_str();
 
     try {
         if (!m_priv->m_app)
@@ -438,12 +432,11 @@ pair<bool,void*> ShibTarget::doCheckAuthZ(void)
         // Do we have an access control plugin?
         if (m_priv->m_settings.second) {
             Locker acllock(m_priv->m_settings.second);
-            if (!m_priv->m_settings.second->authorized(*m_priv->m_sso_statement,
-                m_priv->m_post_response ? m_priv->m_post_response->getAssertions() : EMPTY(SAMLAssertion*))) {
+            if (!m_priv->m_settings.second->authorized(m_priv->m_provider_id.c_str(), m_priv->m_sso_statement, m_priv->m_post_response, this)) {
                 log(LogLevelWarn, "doCheckAuthZ() access control provider denied access");
                 if (targetURL)
                     mlp.insert("requestURL", targetURL);
-                return pair<bool,void*>(true,sendError("access", mlp));
+                return make_pair(true,m_priv->sendError(this, "access", mlp));
             }
         }
 
@@ -650,9 +643,9 @@ pair<bool,void*> ShibTarget::doCheckAuthZ(void)
     mlp.insert("errorType", procState);
 
     if (targetURL)
-        mlp.insert("requestURL", m_priv->m_url.substr(0,m_priv->m_url.find('?')));
+        mlp.insert("requestURL", m_url.substr(0,m_url.find('?')));
 
-    return pair<bool,void*>(true,sendError("access", mlp));
+    return make_pair(true,m_priv->sendError(this, "access", mlp));
 }
 
 pair<bool,void*> ShibTarget::doExportAssertions(bool exportAssertion)
@@ -662,8 +655,8 @@ pair<bool,void*> ShibTarget::doExportAssertions(bool exportAssertion)
 #endif
 
     ShibMLP mlp;
-    const char *procState = "Attribute Processing Error";
-    const char *targetURL = m_priv->m_url.c_str();
+    const charprocState = "Attribute Processing Error";
+    const char* targetURL = m_url.c_str();
 
     try {
         if (!m_priv->m_app)
@@ -677,7 +670,7 @@ pair<bool,void*> ShibTarget::doExportAssertions(bool exportAssertion)
             // if the call to doCheckAuthn doesn't happen in the same object lifetime.
             sessionGet(
                 session_id,
-                m_priv->m_remote_addr.c_str(),
+                m_remote_addr.c_str(),
                 m_priv->m_sso_profile,
                 m_priv->m_provider_id,
                 &m_priv->m_sso_statement,
@@ -815,9 +808,9 @@ pair<bool,void*> ShibTarget::doExportAssertions(bool exportAssertion)
     mlp.insert("errorType", procState);
 
     if (targetURL)
-        mlp.insert("requestURL", m_priv->m_url.substr(0,m_priv->m_url.find('?')));
+        mlp.insert("requestURL", m_url.substr(0,m_url.find('?')));
 
-    return pair<bool,void*>(true,sendError("rm", mlp));
+    return make_pair(true,m_priv->sendError(this, "rm", mlp));
 }
 
 
@@ -1154,34 +1147,6 @@ void ShibTarget::sessionEnd(const char* cookie) const
     }
 }
 
-void* ShibTarget::sendError(const char* page, ShibMLP &mlp)
-{
-    header_t hdrs[] = {
-        header_t("Expires","01-Jan-1997 12:00:00 GMT"), header_t("Cache-Control","private,no-store,no-cache")
-        };
-    
-    const IPropertySet* props=m_priv->m_app->getPropertySet("Errors");
-    if (props) {
-        pair<bool,const char*> p=props->getString(page);
-        if (p.first) {
-            ifstream infile(p.second);
-            if (!infile.fail()) {
-                const char* res = mlp.run(infile,props);
-                if (res)
-                    return sendPage(res, 200, "text/html", ArrayIterator<header_t>(hdrs,2));
-            }
-        }
-        else if (!strcmp(page,"access"))
-            return sendPage("Access Denied", 403, "text/html", ArrayIterator<header_t>(hdrs,2));
-    }
-
-    string errstr = string("sendError could not process error template (") + page + ") for application (";
-    errstr += m_priv->m_app->getId();
-    errstr += ")";
-    log(ShibTarget::LogLevelError, errstr);
-    return sendPage("Internal Server Error. Please contact the site administrator.", 500, "text/html", ArrayIterator<header_t>(hdrs,2));
-}
-
 /*************************************************************************
  * Shib Target Private implementation
  */
@@ -1212,7 +1177,7 @@ ShibTargetPriv::~ShibTargetPriv()
   m_Config = NULL;
 }
 
-void ShibTargetPriv::get_application(const string& protocol, const string& hostname, int port, const string& uri)
+void ShibTargetPriv::get_application(ShibTarget* st, const string& protocol, const string& hostname, int port, const string& uri)
 {
   if (m_app)
     return;
@@ -1229,9 +1194,7 @@ void ShibTargetPriv::get_application(const string& protocol, const string& hostn
   m_mapper->lock();
 
   // Obtain the application settings from the parsed URL
-  m_settings = m_mapper->getSettingsFromParsedURL(protocol.c_str(),
-                                                 hostname.c_str(),
-                                                 port, uri.c_str());
+  m_settings = m_mapper->getSettingsFromParsedURL(protocol.c_str(),hostname.c_str(),port,uri.c_str(),st);
 
   // Now find the application from the URL settings
   pair<bool,const char*> application_id=m_settings.first->getString("applicationId");
@@ -1248,10 +1211,41 @@ void ShibTargetPriv::get_application(const string& protocol, const string& hostn
   m_app = application;
 
   // Compute the target URL
-  m_url = protocol + "://" + hostname;
+  st->m_url = protocol + "://" + hostname;
   if ((protocol == "http" && port != 80) || (protocol == "https" && port != 443))
-    m_url += ":" + port;
-  m_url += uri;
+    st->m_url += ":" + port;
+  st->m_url += uri;
+}
+
+void* ShibTargetPriv::sendError(ShibTarget* st, const char* page, ShibMLP &mlp)
+{
+    ShibTarget::header_t hdrs[] = {
+        ShibTarget::header_t("Expires","01-Jan-1997 12:00:00 GMT"),
+        ShibTarget::header_t("Cache-Control","private,no-store,no-cache")
+        };
+    
+    const IPropertySet* props=m_app->getPropertySet("Errors");
+    if (props) {
+        pair<bool,const char*> p=props->getString(page);
+        if (p.first) {
+            ifstream infile(p.second);
+            if (!infile.fail()) {
+                const char* res = mlp.run(infile,props);
+                if (res)
+                    return st->sendPage(res, 200, "text/html", ArrayIterator<ShibTarget::header_t>(hdrs,2));
+            }
+        }
+        else if (!strcmp(page,"access"))
+            return st->sendPage("Access Denied", 403, "text/html", ArrayIterator<ShibTarget::header_t>(hdrs,2));
+    }
+
+    string errstr = string("sendError could not process error template (") + page + ") for application (";
+    errstr += m_app->getId();
+    errstr += ")";
+    st->log(ShibTarget::LogLevelError, errstr);
+    return st->sendPage(
+        "Internal Server Error. Please contact the site administrator.", 500, "text/html", ArrayIterator<ShibTarget::header_t>(hdrs,2)
+        );
 }
 
 const char* ShibTargetPriv::getCookie(ShibTarget* st, const string& name) const
@@ -1453,7 +1447,7 @@ pair<bool,void*> ShibTargetPriv::doSessionInitiator(ShibTarget* st, const IPrope
     else {
         // We're running as a "virtual handler" from within the filter.
         // The target resource is the current one and everything else is defaulted.
-        resource=m_url.c_str();
+        resource=st->m_url.c_str();
     }
     
     if (!ACS) ACS=m_app->getDefaultAssertionConsumerService();
@@ -1532,22 +1526,22 @@ pair<bool,void*> ShibTargetPriv::doAssertionConsumer(ShibTarget* st, const IProp
     // Right now, this only handles SAML 1.1.
     pair<bool,const XMLCh*> binding=handler->getXMLString("Binding");
     if (!binding.first || !XMLString::compareString(binding.second,SAMLBrowserProfile::BROWSER_POST)) {
-        if (strcasecmp(m_method.c_str(), "POST"))
+        if (strcasecmp(st->m_method.c_str(), "POST"))
             throw FatalProfileException(
-                "SAML 1.1 Browser/POST handler does not support HTTP method ($1).", params(1,m_method.c_str())
+                "SAML 1.1 Browser/POST handler does not support HTTP method ($1).", params(1,st->m_method.c_str())
                 );
         
-        if (m_content_type.empty() || strcasecmp(m_content_type.c_str(),"application/x-www-form-urlencoded"))
+        if (st->m_content_type.empty() || strcasecmp(st->m_content_type.c_str(),"application/x-www-form-urlencoded"))
             throw FatalProfileException(
-                "Blocked invalid content-type ($1) submitted to SAML 1.1 Browser/POST handler.", params(1,m_content_type.c_str())
+                "Blocked invalid content-type ($1) submitted to SAML 1.1 Browser/POST handler.", params(1,st->m_content_type.c_str())
                 );
         input=st->getPostData();
         profile|=SAML11_POST;
     }
     else if (!XMLString::compareString(binding.second,SAMLBrowserProfile::BROWSER_ARTIFACT)) {
-        if (strcasecmp(m_method.c_str(), "GET"))
+        if (strcasecmp(st->m_method.c_str(), "GET"))
             throw FatalProfileException(
-                "SAML 1.1 Browser/Artifact handler does not support HTTP method ($1).", params(1,m_method.c_str())
+                "SAML 1.1 Browser/Artifact handler does not support HTTP method ($1).", params(1,st->m_method.c_str())
                 );
         input=st->getArgs();
         profile|=SAML11_ARTIFACT;
@@ -1561,7 +1555,7 @@ pair<bool,void*> ShibTargetPriv::doAssertionConsumer(ShibTarget* st, const IProp
         profile,
         loc.first ? m_handlerURL + loc.second : m_handlerURL,
         input.c_str(),
-        m_remote_addr.c_str(),
+        st->m_remote_addr.c_str(),
         target,
         cookie,
         providerId
index be9a185..e74e239 100644 (file)
@@ -110,10 +110,14 @@ namespace shibtarget {
         virtual ~IListener() {}
     };
 
+    class SHIBTARGET_EXPORTS ShibTarget;
     struct SHIBTARGET_EXPORTS IAccessControl : public virtual saml::ILockable, public virtual saml::IPlugIn
     {
         virtual bool authorized(
-            const saml::SAMLAuthenticationStatement& authn, const saml::Iterator<saml::SAMLAssertion*>& attrs
+            const char* providerId,
+            const saml::SAMLAuthenticationStatement* authn,
+            const saml::SAMLResponse* attrs,
+            ShibTarget* st
             ) const=0;
         virtual ~IAccessControl() {}
     };
@@ -121,9 +125,9 @@ namespace shibtarget {
     struct SHIBTARGET_EXPORTS IRequestMapper : public virtual saml::ILockable, public virtual saml::IPlugIn
     {
         typedef std::pair<const IPropertySet*,IAccessControl*> Settings;
-        virtual Settings getSettingsFromURL(const char* url) const=0;
+        virtual Settings getSettingsFromURL(const char* url, ShibTarget* st) const=0;
         virtual Settings getSettingsFromParsedURL(
-            const char* scheme, const char* hostname, unsigned int port, const char* path=NULL
+            const char* scheme, const char* hostname, unsigned int port, const char* path, ShibTarget* st
             ) const=0;
         virtual ~IRequestMapper() {}
     };
@@ -219,8 +223,9 @@ namespace shibtarget {
     public:
         ShibTargetConfig() : m_ini(NULL), m_features(0) {}
         virtual ~ShibTargetConfig() {}
-
-        virtual bool init(const char* schemadir, const char* config) = 0;
+        
+        virtual bool init(const char* schemadir) = 0;
+        virtual bool load(const char* config) = 0;
         virtual void shutdown() = 0;
 
         enum components_t {
@@ -249,57 +254,19 @@ namespace shibtarget {
         unsigned long m_features;
     };
 
-    class ShibMLPPriv;
-    class SHIBTARGET_EXPORTS ShibMLP {
-    public:
-        ShibMLP();
-        ~ShibMLP();
-
-        void insert (const std::string& key, const std::string& value);
-        void insert (const std::string& key, const char* value) {
-          std::string v = value;
-          insert (key, v);
-        }
-        void insert (const char* key, const std::string& value) {
-          std::string k = key;
-          insert (k, value);
-        }
-        void insert (const char* key, const char* value) {
-          std::string k = key, v = value;
-          insert(k,v);
-        }
-        void insert (saml::SAMLException& e);
-
-        void clear () { m_map.clear(); }
-
-        const char* run (std::istream& s, const IPropertySet* props=NULL, std::string* output=NULL);
-        const char* run (const std::string& input, const IPropertySet* props=NULL, std::string* output=NULL);
-        const char* run (const char* input, const IPropertySet* props=NULL, std::string* output=NULL) {
-            std::string i = input;
-            return run(i,props,output);
-        }
-
-    private:
-        ShibMLPPriv *m_priv;
-        std::map<std::string,std::string> m_map;
-        std::string m_generated;
-    };
-
   class HTAccessInfo {
   public:
-    class RequireLine {
-    public:
-      bool use_line;
-      std::vector<std::string> tokens;
-    };
-
     HTAccessInfo() {}
     ~HTAccessInfo() {
       for (int k = 0; k < elements.size(); k++)
-       delete elements[k];
+        delete elements[k];
       elements.resize(0);
     }
 
+    struct RequireLine {
+      bool use_line;
+      std::vector<std::string> tokens;
+    };
     std::vector<RequireLine*> elements;
     bool requireAll;
   };
@@ -312,7 +279,6 @@ namespace shibtarget {
     HTGroupTable() {}
   };
 
-  // This usurps the existing SHIRE and RM apis into a single class.
   class ShibTargetPriv;
   class SHIBTARGET_EXPORTS ShibTarget {
   public:
@@ -333,7 +299,7 @@ namespace shibtarget {
     //
     // Note: subclasses MUST implement ALL of these virtual methods
     //
-
+    
     // Send a message to the Webserver log
     virtual void log(ShibLogLevel level, const std::string &msg)=0;
 
@@ -423,7 +389,6 @@ namespace shibtarget {
       return sendPage(m);
     }
     virtual void* sendRedirect(const std::string& url)=0;
-    virtual void* sendError(const char* page, ShibMLP &mlp);
     
     // These next two APIs are used to obtain the module-specific "OK"
     // and "Decline" results.  OK means "we believe that this request
@@ -488,6 +453,16 @@ namespace shibtarget {
 
     void sessionEnd(const char* cookie) const;
 
+    // Basic request access in case any plugins need the info
+    const char* getRequestMethod() const {return m_method.c_str();}
+    const char* getProtocol() const {return m_protocol.c_str();}
+    const char* getHostname() const {return m_hostname.c_str();}
+    int getPort() const {return m_port;}
+    const char* getRequestURI() const {return m_uri.c_str();}
+    const char* getContentType() const {return m_content_type.c_str();}
+    const char* getRemoteAddr() const {return m_remote_addr.c_str();}
+    const char* getRequestURL() const {return m_url.c_str();}
+
   protected:
     ShibTarget();
 
@@ -500,18 +475,21 @@ namespace shibtarget {
     // uri == resource path
     // method == GET, POST, etc.
     void init(
-        ShibTargetConfig *config,
         const char* protocol,
         const char* hostname,
         int port,
         const char* uri,
         const char* content_type,
-        const char* remote_host,
+        const char* remote_addr,
         const char* method
         );
 
+    std::string m_url, m_method, m_protocol, m_hostname, m_uri, m_content_type, m_remote_addr;
+    int m_port;
+
   private:
-    mutable ShibTargetPriv *m_priv;
+    mutable ShibTargetPriv* m_priv;
+    friend class ShibTargetPriv;
   };
 }
 
index d47fd18..36fde0e 100644 (file)
@@ -104,7 +104,7 @@ int main(int argc,char* argv[])
         ShibTargetConfig::GlobalExtensions |
         ShibTargetConfig::Caching
         );
-    if (!conf.init(path,config))
+    if (!conf.init(path) || !conf.load(config))
         return -10;
 
     try {