API consolidation around ShibTarget class
authorcantor <cantor@cb58f699-b61c-0410-a6fe-9272a202ed29>
Fri, 15 Apr 2005 04:22:04 +0000 (04:22 +0000)
committercantor <cantor@cb58f699-b61c-0410-a6fe-9272a202ed29>
Fri, 15 Apr 2005 04:22:04 +0000 (04:22 +0000)
git-svn-id: https://svn.middleware.georgetown.edu/cpp-sp/trunk@1528 cb58f699-b61c-0410-a6fe-9272a202ed29

apache/mod_apache.cpp
isapi_shib/isapi_shib.cpp
shib-mysql-ccache/shib-mysql-ccache.cpp
shib-target/XML.cpp
shib-target/XMLRequestMapper.cpp
shib-target/internal.h
shib-target/shib-config.cpp
shib-target/shib-ini.cpp
shib-target/shib-target.cpp
shib-target/shib-target.h

index 2e16f29..f1ab8fd 100644 (file)
@@ -100,7 +100,7 @@ struct shib_dir_config
     char* szAuthGrpFile;    // Auth GroupFile name
     int bRequireAll;        // all require directives must match, otherwise OR logic
 
-    // SHIRE Configuration
+    // Content Configuration
     int bBasicHijack;       // activate for AuthType Basic?
     int bRequireSession;    // require a session?
     int bExportAssertion;   // export SAML assertion to the environment?
@@ -167,72 +167,8 @@ extern "C" const char* shib_ap_set_file_slot(cmd_parms* parms,
 }
 
 /********************************************************************************/
-// Some other useful helper function(s)
-
-static SH_AP_TABLE* groups_for_user(request_rec* r, const char* user, char* grpfile)
-{
-    SH_AP_CONFIGFILE* f;
-    SH_AP_TABLE* grps=ap_make_table(r->pool,15);
-    char l[MAX_STRING_LEN];
-    const char *group_name, *ll, *w;
-
-#ifdef SHIB_APACHE_13
-    if (!(f=ap_pcfg_openfile(r->pool,grpfile))) {
-#else
-    if (ap_pcfg_openfile(&f,r->pool,grpfile) != APR_SUCCESS) {
-#endif
-        ap_log_rerror(APLOG_MARK,APLOG_DEBUG,SH_AP_R(r),"groups_for_user() could not open group file: %s\n",grpfile);
-        return NULL;
-    }
-
-    SH_AP_POOL* sp;
-#ifdef SHIB_APACHE_13
-    sp=ap_make_sub_pool(r->pool);
-#else
-    if (apr_pool_create(&sp,r->pool) != APR_SUCCESS) {
-        ap_log_rerror(APLOG_MARK,APLOG_ERR,0,r,
-            "groups_for_user() could not create a subpool");
-        return NULL;
-    }
-#endif
-
-    while (!(ap_cfg_getline(l,MAX_STRING_LEN,f))) {
-        if ((*l=='#') || (!*l))
-            continue;
-        ll = l;
-        ap_clear_pool(sp);
-
-        group_name=ap_getword(sp,&ll,':');
-
-        while (*ll) {
-            w=ap_getword_conf(sp,&ll);
-            if (!strcmp(w,user)) {
-                ap_table_setn(grps,ap_pstrdup(r->pool,group_name),"in");
-                break;
-            }
-        }
-    }
-    ap_cfg_closefile(f);
-    ap_destroy_pool(sp);
-    return grps;
-}
-
-/********************************************************************************/
 // Apache ShibTarget subclass(es) here.
 
-class HTGroupTableApache : public HTGroupTable
-{
-public:
-  HTGroupTableApache(request_rec* r, const char *user, char *grpfile) {
-    groups = groups_for_user(r, user, grpfile);
-    if (!groups)
-      throw ResourceAccessException("Unable to access group file ($1) for user ($2)",params(2,grpfile,user));
-  }
-  ~HTGroupTableApache() {}
-  bool lookup(const char *entry) { return (ap_table_get(groups, entry)!=NULL); }
-  SH_AP_TABLE* groups;
-};
-
 class ShibTargetApache : public ShibTarget
 {
 public:
@@ -324,60 +260,6 @@ public:
     }
     return string(auth_type);
   }
-  // Override this function because we want to add the Apache Directory override
-  virtual pair<bool,bool> getRequireSession(IRequestMapper::Settings &settings) {
-    pair<bool,bool> requireSession = settings.first->getBool("requireSession");
-    if (!requireSession.first || !requireSession.second)
-      if (m_dc->bRequireSession == 1)
-       requireSession.second=true;
-
-    return requireSession;
-  }
-
-  virtual HTAccessInfo* getAccessInfo(void) { 
-    int m = m_req->method_number;
-    const array_header* reqs_arr = ap_requires(m_req);
-    if (!reqs_arr)
-      return NULL;
-
-    require_line* reqs = (require_line*) reqs_arr->elts;
-
-    ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(m_req),
-                 "REQUIRE nelts: %d", reqs_arr->nelts);
-    ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(m_req),
-                 "REQUIRE all: %d", m_dc->bRequireAll);
-
-    HTAccessInfo* ht = new HTAccessInfo();
-    ht->requireAll = (m_dc->bRequireAll == 1);
-    ht->elements.reserve(reqs_arr->nelts);
-    for (int x = 0; x < reqs_arr->nelts; x++) {
-      HTAccessInfo::RequireLine* rline = new HTAccessInfo::RequireLine();
-      rline->use_line = (reqs[x].method_mask & (1 << m));
-      rline->tokens.reserve(6);        // No reason to reserve specifically 6 tokens
-      const char* t = reqs[x].requirement;
-      const char* w = ap_getword_white(m_req->pool, &t);
-      rline->tokens.push_back(w);
-      while (*t) {
-        w = ap_getword_conf(m_req->pool, &t);
-        rline->tokens.push_back(w);
-      }
-      ht->elements.push_back(rline);
-    }
-    return ht;
-  }
-  virtual HTGroupTable* getGroupTable(string& user) {
-    if (m_dc->szAuthGrpFile && !user.empty()) {
-      ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(m_req),
-                   "getGroupTable() using groups file: %s\n",
-                   m_dc->szAuthGrpFile);
-      try {
-        HTGroupTableApache *gt = new HTGroupTableApache(m_req, user.c_str(),
-                                                       m_dc->szAuthGrpFile);
-        return gt;
-      } catch (...) { }
-    }
-    return NULL;
-  }
 
   virtual void* sendPage(
     const string& msg,
@@ -423,12 +305,12 @@ extern "C" int shib_check_user(request_rec* r)
     ShibTargetApache sta(r);
 
     // Check user authentication, the set the handler bypass
-    pair<bool,void*> res = sta.doCheckAuthN((sta.m_dc->bRequireSession == 1), true);
+    pair<bool,void*> res = sta.doCheckAuthN(true);
     apr_pool_userdata_setn((const void*)42,g_UserDataKey,NULL,r->pool);
     if (res.first) return (int)res.second;
 
     // user auth was okay -- export the assertions now
-    res = sta.doExportAssertions((sta.m_dc->bExportAssertion == 1));
+    res = sta.doExportAssertions();
     if (res.first) return (int)res.second;
 
     // export happened successfully..  this user is ok.
@@ -512,622 +394,216 @@ extern "C" int shib_auth_checker(request_rec* r)
 #endif
 }
 
-#if 0
-static char* shib_get_targeturl(request_rec* r, const char* scheme=NULL)
+// Access control plugin that enforces htaccess rules
+class htAccessControl : virtual public IAccessControl
 {
-    // On 1.3, this is always canonical, but on 2.0, UseCanonicalName comes into play.
-    // However, we also have a setting to forcibly replace the scheme for esoteric cases.
-    if (scheme) {
-        unsigned port = ap_get_server_port(r);
-        if ((!strcmp(scheme,"http") && port==80) || (!strcmp(scheme,"https") && port==443)) {
-            return ap_pstrcat(r->pool, scheme, "://", ap_get_server_name(r), r->unparsed_uri, NULL);
-        }
-        return ap_psprintf(r->pool, "%s://%s:%u%s", scheme, ap_get_server_name(r), port, r->unparsed_uri);
-    }
-    return ap_construct_url(r->pool,r->unparsed_uri,r);
-}
+public:
+    htAccessControl() {}
+    ~htAccessControl() {}
+    void lock() {}
+    void unlock() {}
+    bool authorized(
+        ShibTarget* st,
+        const char* providerId,
+        const saml::SAMLAuthenticationStatement* authn,
+        const saml::SAMLResponse* attrs
+    ) const;
+};
 
-extern "C" int shib_check_user(request_rec* r)
+IPlugIn* htAccessFactory(const DOMElement* e)
 {
-    ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r),"shib_check_user: ENTER");
-    shib_dir_config* dc=(shib_dir_config*)ap_get_module_config(r->per_dir_config,&mod_shib);
-    shib_server_config* sc=(shib_server_config*)ap_get_module_config(r->server->module_config,&mod_shib);
-
-    ostringstream threadid;
-    threadid << "[" << getpid() << "] shib_check_user" << '\0';
-    saml::NDC ndc(threadid.str().c_str());
-
-    const char* targeturl=shib_get_targeturl(r,sc->szScheme);
+    return new htAccessControl();
+}
 
-    // We lock the configuration system for the duration.
-    IConfig* conf=g_Config->getINI();
-    Locker locker(conf);
-    
-    // Map request to application and content settings.
-    IRequestMapper* mapper=conf->getRequestMapper();
-    Locker locker2(mapper);
-    IRequestMapper::Settings settings=mapper->getSettingsFromParsedURL(
-        (sc-> szScheme ? sc-> szScheme : ap_http_method(r)), ap_get_server_name(r), ap_get_server_port(r), r->unparsed_uri
-        );
-    pair<bool,const char*> application_id=settings.first->getString("applicationId");
-    const IApplication* application=conf->getApplication(application_id.second);
-    if (!application) {
-        ap_log_rerror(APLOG_MARK,APLOG_ERR|APLOG_NOERRNO,SH_AP_R(r),
-           "shib_check_user: unable to map request to application settings, check configuration");
-        return SERVER_ERROR;
-    }
-    
-    // Declare SHIRE object for this request.
-    SHIRE shire(application);
-    
-    const char* shireURL=shire.getShireURL(targeturl);
-    if (!shireURL) {
-        ap_log_rerror(APLOG_MARK,APLOG_ERR|APLOG_NOERRNO,SH_AP_R(r),
-           "shib_check_user: unable to map request to proper shireURL setting, check configuration");
-        return SERVER_ERROR;
-    }
+class ApacheRequestMapper : public virtual IRequestMapper, public virtual IPropertySet
+{
+public:
+    struct ApacheRequestMapperSettings {
+        ApacheRequestMapperSettings(ShibTargetApache* sta, const IPropertySet* p) : m_sta(sta), m_props(p) {}
+        ShibTargetApache* m_sta;
+        const IPropertySet* m_props;
+    };
+
+    ApacheRequestMapper(const DOMElement* e);
+    ~ApacheRequestMapper() { delete m_mapper; delete m_htaccess; delete m_key; }
+    void lock() { m_mapper->lock(); }
+    void unlock() { delete (ApacheRequestMapperSettings*)(m_key->getData()); m_key->setData(NULL); m_mapper->unlock(); }
+    Settings getSettings(ShibTarget* st) const;
     
-    // Get location of this application's assertion consumer service and see if this is it.
-    if (strstr(targeturl,shireURL)) {
-        return shib_handler(r,application,shire);
-    }
-
-    // We can short circuit the handler if we run this...
-    apr_pool_userdata_setn((const void*)42,g_UserDataKey,NULL,r->pool);
-
-    // Regular access to arbitrary resource...check AuthType
-    const char *auth_type=ap_auth_type(r);
-    if (!auth_type)
-        return DECLINED;
-
-    if (strcasecmp(auth_type,"shibboleth")) {
-        if (!strcasecmp(auth_type,"basic") && dc->bBasicHijack==1) {
-            core_dir_config* conf=
-                (core_dir_config*)ap_get_module_config(r->per_dir_config,
-                    ap_find_linked_module("http_core.c"));
-            conf->ap_auth_type="shibboleth";
-        }
-        else
-            return DECLINED;
-    }
-
-    pair<bool,bool> requireSession = settings.first->getBool("requireSession");
-    if (!requireSession.first || !requireSession.second)
-        if (dc->bRequireSession==1)
-            requireSession.second=true;
-
-    ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r),"shib_check_user: session check for %s",targeturl);
-
-    pair<const char*,const char*> shib_cookie=shire.getCookieNameProps();   // always returns *something*
-
-    // We're in charge, so check for cookie.
-    const char* session_id=NULL;
-    const char* cookies=ap_table_get(r->headers_in,"Cookie");
-
-    if (cookies) {
-        ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r),"shib_check_user: cookies found: %s",cookies);
-        if (session_id=strstr(cookies,shib_cookie.first)) {
-            // Yep, we found a cookie -- pull it out (our session_id)
-            session_id+=strlen(shib_cookie.first) + 1; /* Skip over the '=' */
-            char* cookiebuf = ap_pstrdup(r->pool,session_id);
-            char* cookieend = strchr(cookiebuf,';');
-            if (cookieend)
-                *cookieend = '\0';    /* Ignore anyting after a ; */
-            session_id=cookiebuf;
-        }
-    }
-
-    if (!session_id || !*session_id) {
-        // If no session required, bail now.
-        if (!requireSession.second)
-            return OK;
-
-        // No acceptable cookie, and we require a session.  Generate an AuthnRequest.
-        ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r),"shib_check_user: no cookie found -- redirecting to WAYF");
-        ap_table_setn(r->headers_out,"Location",ap_pstrdup(r->pool,shire.getAuthnRequest(targeturl)));
-        return REDIRECT;
-    }
-
-    // Make sure this session is still valid.
-    RPCError* status = NULL;
-    ShibMLP markupProcessor;
-    markupProcessor.insert("requestURL", targeturl);
-
-    try {
-        status = shire.sessionIsValid(session_id, r->connection->remote_ip);
-    }
-    catch (ShibTargetException &e) {
-        ap_log_rerror(APLOG_MARK,APLOG_ERR|APLOG_NOERRNO,SH_AP_R(r),"shib_check_user(): %s", e.what());
-        markupProcessor.insert("errorType", "Session Processing Error");
-        markupProcessor.insert("errorText", e.what());
-        markupProcessor.insert("errorDesc", "An error occurred while processing your request.");
-        return shib_error_page(r, application, "shire", markupProcessor);
-    }
-#ifndef _DEBUG
-    catch (...) {
-        ap_log_rerror(APLOG_MARK,APLOG_ERR|APLOG_NOERRNO,SH_AP_R(r),"shib_check_user(): caught unexpected error");
-        markupProcessor.insert("errorType", "Session Processing Error");
-        markupProcessor.insert("errorText", "Unexpected Exception");
-        markupProcessor.insert("errorDesc", "An error occurred while processing your request.");
-        return shib_error_page(r, application, "shire", markupProcessor);
-    }
-#endif
-
-    // Check the status
-    if (status->isError()) {
-        ap_log_rerror(APLOG_MARK,APLOG_INFO|APLOG_NOERRNO,SH_AP_R(r),
-                     "shib_check_user() session invalid: %s", status->getText());
-
-        // If no session required, bail now.
-        if (!requireSession.second)
-            return OK; // XXX: Or should this be DECLINED?
-                        // Has to be OK because DECLINED will just cause Apache to fail when it can't locate
-                        // anything to process the AuthType. No session plus requireSession false means 
-                        // do not authenticate the user.
-        else if (status->isRetryable()) {
-            // Oops, session is invalid. Generate AuthnRequest.
-            ap_table_setn(r->headers_out,"Location",ap_pstrdup(r->pool,shire.getAuthnRequest(targeturl)));
-            delete status;
-            return REDIRECT;
-        }
-        else {
-            // return the error page to the user
-            markupProcessor.insert(*status);
-            delete status;
-            return shib_error_page(r, application, "shire", markupProcessor);
-        }
-    }
-
-    delete status;
-    // set the authtype
-#ifdef SHIB_APACHE_13
-    if (r->connection)
-        r->connection->ap_auth_type = "shibboleth";
-#else
-    r->ap_auth_type = "shibboleth";
-#endif
-    ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r),"shib_check_user: session successfully verified");
-
-    // This is code transferred in from the auth check to export the attributes.
-    // We could even combine the isSessionValid/getAssertions API...?
-
-    RM rm(application);
-    vector<SAMLAssertion*> assertions;
-    SAMLAuthenticationStatement* sso_statement=NULL;
-
-    try {
-        status = rm.getAssertions(session_id, r->connection->remote_ip, assertions, &sso_statement);
-    }
-    catch (ShibTargetException &e) {
-        ap_log_rerror(APLOG_MARK,APLOG_ERR|APLOG_NOERRNO,SH_AP_R(r),"shib_check_user(): %s", e.what());
-        markupProcessor.insert("errorType", "Attribute Processing Error");
-        markupProcessor.insert("errorText", e.what());
-        markupProcessor.insert("errorDesc", "An error occurred while processing your request.");
-        return shib_error_page(r, application, "rm", markupProcessor);
-    }
-#ifndef _DEBUG
-    catch (...) {
-        ap_log_rerror(APLOG_MARK,APLOG_ERR|APLOG_NOERRNO,SH_AP_R(r),"shib_check_user(): caught unexpected error");
-        markupProcessor.insert("errorType", "Attribute Processing Error");
-        markupProcessor.insert("errorText", "Unexpected Exception");
-        markupProcessor.insert("errorDesc", "An error occurred while processing your request.");
-        return shib_error_page(r, application, "rm", markupProcessor);
-    }
-#endif
+    pair<bool,bool> getBool(const char* name, const char* ns=NULL) const;
+    pair<bool,const char*> getString(const char* name, const char* ns=NULL) const;
+    pair<bool,const XMLCh*> getXMLString(const char* name, const char* ns=NULL) const;
+    pair<bool,unsigned int> getUnsignedInt(const char* name, const char* ns=NULL) const;
+    pair<bool,int> getInt(const char* name, const char* ns=NULL) const;
+    const IPropertySet* getPropertySet(const char* name, const char* ns="urn:mace:shibboleth:target:config:1.0") const;
+    const DOMElement* getElement() const;
+
+private:
+    IRequestMapper* m_mapper;
+    ThreadKey* m_key;
+    IAccessControl* m_htaccess;
+};
 
-    if (status->isError()) {
-        ap_log_rerror(APLOG_MARK,APLOG_ERR|APLOG_NOERRNO,SH_AP_R(r),
-            "shib_check_user() getAssertions failed: %s", status->getText());
+IPlugIn* ApacheRequestMapFactory(const DOMElement* e)
+{
+    return new ApacheRequestMapper(e);
+}
 
-        markupProcessor.insert(*status);
-        delete status;
-        return shib_error_page(r, application, "rm", markupProcessor);
-    }
-    delete status;
-
-    // Do we have an access control plugin?
-    if (settings.second) {
-        Locker acllock(settings.second);
-        if (!settings.second->authorized(*sso_statement,assertions)) {
-            for (int k = 0; k < assertions.size(); k++)
-                delete assertions[k];
-            delete sso_statement;
-            ap_log_rerror(APLOG_MARK,APLOG_ERR|APLOG_NOERRNO,SH_AP_R(r),"shib_check_user(): access control provider denied access");
-            return shib_error_page(r, application, "access", markupProcessor);
-        }
+ApacheRequestMapper::ApacheRequestMapper(const DOMElement* e) : m_mapper(NULL), m_htaccess(NULL), m_key(NULL)
+{
+    IPlugIn* p=SAMLConfig::getConfig().getPlugMgr().newPlugin(
+        "edu.internet2.middleware.shibboleth.sp.provider.XMLRequestMapProvider", e
+        );
+    m_mapper=dynamic_cast<IRequestMapper*>(p);
+    if (!m_mapper) {
+        delete p;
+        throw UnsupportedExtensionException("Embedded request mapper plugin was not of correct type.");
     }
+    m_htaccess=new htAccessControl();
+    m_key=ThreadKey::create(NULL);
+}
 
-    // Get the AAP providers, which contain the attribute policy info.
-    Iterator<IAAP*> provs=application->getAAPProviders();
-
-    // Clear out the list of mapped attributes
-    while (provs.hasNext()) {
-        IAAP* aap=provs.next();
-        aap->lock();
-        try {
-            Iterator<const IAttributeRule*> rules=aap->getAttributeRules();
-            while (rules.hasNext()) {
-                const char* header=rules.next()->getHeader();
-                if (header)
-                    ap_table_unset(r->headers_in,header);
-            }
-        }
-        catch(...) {
-            aap->unlock();
-            for (int k = 0; k < assertions.size(); k++)
-                delete assertions[k];
-            delete sso_statement;
-            ap_log_rerror(APLOG_MARK,APLOG_ERR|APLOG_NOERRNO,SH_AP_R(r),
-                "shib_check_user(): caught unexpected error while clearing headers");
-            markupProcessor.insert("errorType", "Attribute Processing Error");
-            markupProcessor.insert("errorText", "Unexpected Exception");
-            markupProcessor.insert("errorDesc", "An error occurred while processing your request.");
-            return shib_error_page(r, application, "rm", markupProcessor);
-        }
-        aap->unlock();
-    }
-    provs.reset();
-    
-    // Maybe export the first assertion.
-    ap_table_unset(r->headers_in,"Shib-Attributes");
-    pair<bool,bool> exp=settings.first->getBool("exportAssertion");
-    if (!exp.first || !exp.second)
-        if (dc->bExportAssertion==1)
-            exp.second=true;
-    if (exp.second && assertions.size()) {
-        string assertion;
-        RM::serialize(*(assertions[0]), assertion);
-        ap_table_set(r->headers_in,"Shib-Attributes", assertion.c_str());
-    }
+IRequestMapper::Settings ApacheRequestMapper::getSettings(ShibTarget* st) const
+{
+    Settings s=m_mapper->getSettings(st);
+    m_key->setData(new ApacheRequestMapperSettings(dynamic_cast<ShibTargetApache*>(st),s.first));
+    return pair<const IPropertySet*,IAccessControl*>(this,s.second ? s.second : m_htaccess);
+}
 
-    // Export the SAML AuthnMethod and the origin site name, and possibly the NameIdentifier.
-    ap_table_unset(r->headers_in,"Shib-Origin-Site");
-    ap_table_unset(r->headers_in,"Shib-Authentication-Method");
-    ap_table_unset(r->headers_in,"Shib-NameIdentifier-Format");
-    auto_ptr_char os(sso_statement->getSubject()->getNameIdentifier()->getNameQualifier());
-    auto_ptr_char am(sso_statement->getAuthMethod());
-    ap_table_set(r->headers_in,"Shib-Origin-Site", os.get());
-    ap_table_set(r->headers_in,"Shib-Authentication-Method", am.get());
-    
-    // Export NameID?
-    AAP wrapper(provs,sso_statement->getSubject()->getNameIdentifier()->getFormat(),Constants::SHIB_ATTRIBUTE_NAMESPACE_URI);
-    if (!wrapper.fail() && wrapper->getHeader()) {
-        auto_ptr_char form(sso_statement->getSubject()->getNameIdentifier()->getFormat());
-        auto_ptr_char nameid(sso_statement->getSubject()->getNameIdentifier()->getName());
-        ap_table_set(r->headers_in,"Shib-NameIdentifier-Format",form.get());
-        if (!strcmp(wrapper->getHeader(),"REMOTE_USER"))
-            SH_AP_USER(r)=ap_pstrdup(r->pool,nameid.get());
-        else
-            ap_table_set(r->headers_in,wrapper->getHeader(),nameid.get());
-    }
-    
-    ap_table_unset(r->headers_in,"Shib-Application-ID");
-    ap_table_set(r->headers_in,"Shib-Application-ID",application_id.second);
-
-    // Export the attributes.
-    Iterator<SAMLAssertion*> a_iter(assertions);
-    while (a_iter.hasNext()) {
-        SAMLAssertion* assert=a_iter.next();
-        Iterator<SAMLStatement*> statements=assert->getStatements();
-        while (statements.hasNext()) {
-            SAMLAttributeStatement* astate=dynamic_cast<SAMLAttributeStatement*>(statements.next());
-            if (!astate)
-                continue;
-            Iterator<SAMLAttribute*> attrs=astate->getAttributes();
-            while (attrs.hasNext()) {
-                SAMLAttribute* attr=attrs.next();
-        
-                // Are we supposed to export it?
-                AAP wrapper(provs,attr->getName(),attr->getNamespace());
-                if (wrapper.fail() || !wrapper->getHeader())
-                    continue;
-                
-                Iterator<string> vals=attr->getSingleByteValues();
-                if (!strcmp(wrapper->getHeader(),"REMOTE_USER") && vals.hasNext())
-                    SH_AP_USER(r)=ap_pstrdup(r->pool,vals.next().c_str());
-                else {
-                    int it=0;
-                    char* header = (char*)ap_table_get(r->headers_in, wrapper->getHeader());
-                    if (header) {
-                        header=ap_pstrdup(r->pool, header);
-                        it++;
-                    }
-                    else
-                        header = ap_pstrdup(r->pool, "");
-                    for (; vals.hasNext(); it++) {
-                        string value = vals.next();
-                        for (string::size_type pos = value.find_first_of(";", string::size_type(0));
-                                pos != string::npos;
-                                pos = value.find_first_of(";", pos)) {
-                            value.insert(pos, "\\");
-                            pos += 2;
-                        }
-                        header=ap_pstrcat(r->pool, header, (it ? ";" : ""), value.c_str(), NULL);
-                    }
-                    ap_table_setn(r->headers_in, wrapper->getHeader(), header);
-               }
-            }
+pair<bool,bool> ApacheRequestMapper::getBool(const char* name, const char* ns) const
+{
+    ApacheRequestMapperSettings* arms=(ApacheRequestMapperSettings*)m_key->getData();
+    if (arms) {
+        if (!ns) {
+            // Override Apache-settable boolean properties.
+            if (name && !strcmp(name,"requireSession") && arms->m_sta->m_dc->bRequireSession==1)
+                return make_pair(true,true);
+            else if (name && !strcmp(name,"exportAssertion") && arms->m_sta->m_dc->bExportAssertion==1)
+                return make_pair(true,true);
         }
+        return arms->m_props->getBool(name,ns);
     }
-
-    // clean up memory
-    for (int k = 0; k < assertions.size(); k++)
-        delete assertions[k];
-    delete sso_statement;
-
-    return OK;
+    return make_pair(false,false);
 }
 
-extern "C" int shib_post_handler(request_rec* r)
+pair<bool,const char*> ApacheRequestMapper::getString(const char* name, const char* ns) const
 {
-    ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r),
-               "shib_post_handler(%d): ENTER", (int)getpid());
-    shib_server_config* sc=(shib_server_config*)ap_get_module_config(r->server->module_config,&mod_shib);
-
-#ifndef SHIB_APACHE_13
-    // With 2.x, this handler always runs, though last.
-    // We check if shib_check_user ran, because it will detect a SHIRE request
-    // and dispatch it directly.
-    void* data;
-    apr_pool_userdata_get(&data,g_UserDataKey,r->pool);
-    if (data==(const void*)42) {
-        ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r),"shib_post_handler skipped since check_user ran");
-        return DECLINED;
-    }
-#endif
-    
-    ostringstream threadid;
-    threadid << "[" << getpid() << "] shib_post_handler" << '\0';
-    saml::NDC ndc(threadid.str().c_str());
+    ApacheRequestMapperSettings* arms=(ApacheRequestMapperSettings*)m_key->getData();
+    return arms ? arms->m_props->getString(name,ns) : pair<bool,const char*>(false,NULL);
+}
 
-    // We lock the configuration system for the duration.
-    IConfig* conf=g_Config->getINI();
-    Locker locker(conf);
-    
-    // Map request to application and content settings.
-    IRequestMapper* mapper=conf->getRequestMapper();
-    Locker locker2(mapper);
-    IRequestMapper::Settings settings=mapper->getSettingsFromParsedURL(
-        (sc->szScheme ? sc->szScheme : ap_http_method(r)), ap_get_server_name(r), ap_get_server_port(r), r->unparsed_uri
-        );
-    pair<bool,const char*> application_id=settings.first->getString("applicationId");
-    const IApplication* application=conf->getApplication(application_id.second);
-    if (!application) {
-        ap_log_rerror(APLOG_MARK,APLOG_ERR|APLOG_NOERRNO,SH_AP_R(r),
-           "shib_post_handler: unable to map request to application settings, check configuration");
-        return SERVER_ERROR;
-    }
-    
-    // Declare SHIRE object for this request.
-    SHIRE shire(application);
-    
-    return shib_handler(r, application, shire);
+pair<bool,const XMLCh*> ApacheRequestMapper::getXMLString(const char* name, const char* ns) const
+{
+    ApacheRequestMapperSettings* arms=(ApacheRequestMapperSettings*)m_key->getData();
+    return arms ? arms->m_props->getXMLString(name,ns) : pair<bool,const XMLCh*>(false,NULL);
 }
 
-int shib_handler(request_rec* r, const IApplication* application, SHIRE& shire)
+pair<bool,unsigned int> ApacheRequestMapper::getUnsignedInt(const char* name, const char* ns) const
 {
-    shib_server_config* sc=(shib_server_config*)ap_get_module_config(r->server->module_config,&mod_shib);
+    ApacheRequestMapperSettings* arms=(ApacheRequestMapperSettings*)m_key->getData();
+    return arms ? arms->m_props->getUnsignedInt(name,ns) : make_pair(false,0);
+}
 
-    const char* targeturl=shib_get_targeturl(r,sc->szScheme);
+pair<bool,int> ApacheRequestMapper::getInt(const char* name, const char* ns) const
+{
+    ApacheRequestMapperSettings* arms=(ApacheRequestMapperSettings*)m_key->getData();
+    return arms ? arms->m_props->getInt(name,ns) : make_pair(false,0);
+}
 
-    const char* shireURL=shire.getShireURL(targeturl);
-    if (!shireURL) {
-        ap_log_rerror(APLOG_MARK,APLOG_ERR|APLOG_NOERRNO,SH_AP_R(r),
-           "shib_post_handler: unable to map request to proper shireURL setting, check configuration");
-        return SERVER_ERROR;
-    }
+const IPropertySet* ApacheRequestMapper::getPropertySet(const char* name, const char* ns) const
+{
+    ApacheRequestMapperSettings* arms=(ApacheRequestMapperSettings*)m_key->getData();
+    return arms ? arms->m_props->getPropertySet(name,ns) : NULL;
+}
 
-    // Make sure we only process the SHIRE requests.
-    if (!strstr(targeturl,shireURL))
-        return DECLINED;
+const DOMElement* ApacheRequestMapper::getElement() const
+{
+    ApacheRequestMapperSettings* arms=(ApacheRequestMapperSettings*)m_key->getData();
+    return arms ? arms->m_props->getElement() : NULL;
+}
 
-    ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r),"shib_handler() running");
+static SH_AP_TABLE* groups_for_user(request_rec* r, const char* user, char* grpfile)
+{
+    SH_AP_CONFIGFILE* f;
+    SH_AP_TABLE* grps=ap_make_table(r->pool,15);
+    char l[MAX_STRING_LEN];
+    const char *group_name, *ll, *w;
 
-    const IPropertySet* sessionProps=application->getPropertySet("Sessions");
-    if (!sessionProps) {
-        ap_log_rerror(APLOG_MARK,APLOG_ERR|APLOG_NOERRNO,SH_AP_R(r),
-           "shib_post_handler: unable to map request to application session settings, check configuration");
-        return SERVER_ERROR;
+#ifdef SHIB_APACHE_13
+    if (!(f=ap_pcfg_openfile(r->pool,grpfile))) {
+#else
+    if (ap_pcfg_openfile(&f,r->pool,grpfile) != APR_SUCCESS) {
+#endif
+        ap_log_rerror(APLOG_MARK,APLOG_DEBUG,SH_AP_R(r),"groups_for_user() could not open group file: %s\n",grpfile);
+        return NULL;
     }
 
-    pair<const char*,const char*> shib_cookie=shire.getCookieNameProps();   // always returns something
-
-    ShibMLP markupProcessor;
-    markupProcessor.insert("requestURL", targeturl);
-
-    // Process SHIRE request
-    ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r), "shib_handler() Beginning SHIRE processing");
-      
-    try {
-        pair<bool,bool> shireSSL=sessionProps->getBool("shireSSL");
-      
-        // Make sure this is SSL, if it should be
-        if ((!shireSSL.first || shireSSL.second) && strcmp(ap_http_method(r),"https"))
-            throw ShibTargetException(SHIBRPC_OK, "blocked non-SSL access to session creation service");
-
-        // If this is a GET, we manufacture an AuthnRequest.
-        if (!strcasecmp(r->method,"GET")) {
-            const char* areq=r->args ? shire.getLazyAuthnRequest(r->args) : NULL;
-            if (!areq)
-                throw ShibTargetException(SHIBRPC_OK, "malformed arguments to request a new session");
-            ap_table_setn(r->headers_out, "Location", ap_pstrdup(r->pool,areq));
-            return REDIRECT;
-        }
-        else if (strcasecmp(r->method,"POST")) {
-            throw ShibTargetException(SHIBRPC_OK, "blocked non-POST to SHIRE POST processor");
-        }
-
-        // Sure sure this POST is an appropriate content type
-        const char *ct = ap_table_get(r->headers_in, "Content-type");
-        if (!ct || strcasecmp(ct, "application/x-www-form-urlencoded"))
-            throw ShibTargetException(SHIBRPC_OK,
-                                     ap_psprintf(r->pool, "blocked bad content-type to SHIRE POST processor: %s", (ct ? ct : "")));
-
-        // Read the posted data
-        if (ap_setup_client_block(r, REQUEST_CHUNKED_ERROR))
-            throw ShibTargetException(SHIBRPC_OK, "CGI setup_client_block failed");
-        if (!ap_should_client_block(r))
-            throw ShibTargetException(SHIBRPC_OK, "CGI should_client_block failed");
-        if (r->remaining > 1024*1024)
-            throw ShibTargetException (SHIBRPC_OK, "CGI length too long...");
-
-        string cgistr;
-        char buff[HUGE_STRING_LEN];
-        ap_hard_timeout("[mod_shib] CGI Parser", r);
-        memset(buff, 0, sizeof(buff));
-        while (ap_get_client_block(r, buff, sizeof(buff)-1) > 0) {
-            ap_reset_timeout(r);
-            cgistr += buff;
-            memset(buff, 0, sizeof(buff));
-        }
-        ap_kill_timeout(r);
-
-        // Parse the submission.
-        pair<const char*,const char*> elements=shire.getFormSubmission(cgistr.c_str(),cgistr.length());
-    
-        // Make sure the SAML Response parameter exists
-        if (!elements.first || !*elements.first)
-            throw ShibTargetException(SHIBRPC_OK, "SHIRE POST failed to find SAMLResponse form element");
-    
-        // Make sure the target parameter exists
-        if (!elements.second || !*elements.second)
-            throw ShibTargetException(SHIBRPC_OK, "SHIRE POST failed to find TARGET form element");
-    
-        ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r),
-            "shib_handler() Processing POST for target: %s", elements.second);
-
-        // process the post
-        string cookie;
-        RPCError* status = shire.sessionCreate(elements.first, r->connection->remote_ip, cookie);
-
-        if (status->isError()) {
-            ap_log_rerror(APLOG_MARK,APLOG_ERR|APLOG_NOERRNO,SH_AP_R(r),
-                   "shib_handler() POST process failed (%d): %s", status->getCode(), status->getText());
-
-            if (status->isRetryable()) {
-                delete status;
-                ap_log_rerror(APLOG_MARK,APLOG_INFO|APLOG_NOERRNO,SH_AP_R(r),
-                       "shib_handler() retryable error, generating new AuthnRequest");
-                ap_table_setn(r->headers_out,"Location",ap_pstrdup(r->pool,shire.getAuthnRequest(elements.second)));
-                return REDIRECT;
-            }
-
-            // return this error to the user.
-            markupProcessor.insert(*status);
-            delete status;
-            return shib_error_page(r, application, "shire", markupProcessor);
-        }
-        delete status;
-
-        ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r),
-                 "shib_handler() POST process succeeded.  New session: %s", cookie.c_str());
-
-        // We've got a good session, set the cookie...
-        char* val = ap_psprintf(r->pool,"%s=%s%s",shib_cookie.first,cookie.c_str(),shib_cookie.second);
-        ap_table_setn(r->err_headers_out, "Set-Cookie", val);
-        ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r), "shib_handler() setting cookie: %s", val);
-
-        // ... and redirect to the target
-        ap_table_setn(r->headers_out, "Location", ap_pstrdup(r->pool,elements.second));
-        return REDIRECT;
-    }
-    catch (ShibTargetException &e) {
-        ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r), "shib_handler() caught exception: %s", e.what());
-        markupProcessor.insert("errorType", "Session Creation Service Error");
-        markupProcessor.insert("errorText", e.what());
-        markupProcessor.insert("errorDesc", "An error occurred while processing your request.");
-        return shib_error_page(r, application, "shire", markupProcessor);
-    }
-#ifndef _DEBUG
-    catch (...) {
-        ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r),"shib_handler(): unexpected exception");
-        markupProcessor.insert("errorType", "Session Creation Service Error");
-        markupProcessor.insert("errorText", "Unknown Exception");
-        markupProcessor.insert("errorDesc", "An error occurred while processing your request.");
-        return shib_error_page(r, application, "shire", markupProcessor);
+    SH_AP_POOL* sp;
+#ifdef SHIB_APACHE_13
+    sp=ap_make_sub_pool(r->pool);
+#else
+    if (apr_pool_create(&sp,r->pool) != APR_SUCCESS) {
+        ap_log_rerror(APLOG_MARK,APLOG_ERR,0,r,
+            "groups_for_user() could not create a subpool");
+        return NULL;
     }
 #endif
 
-    ap_log_rerror(APLOG_MARK,APLOG_ERR|APLOG_NOERRNO,SH_AP_R(r),"shib_handler() server error");
-    return SERVER_ERROR;
-}
+    while (!(ap_cfg_getline(l,MAX_STRING_LEN,f))) {
+        if ((*l=='#') || (!*l))
+            continue;
+        ll = l;
+        ap_clear_pool(sp);
 
-static int shib_error_page(request_rec* r, const IApplication* app, const char* page, ShibMLP& mlp)
-{
-    const IPropertySet* props=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) {
-                    r->content_type = ap_psprintf(r->pool, "text/html");
-                    ap_send_http_header(r);
-                    ap_rprintf(r, res);
-                    return DONE;
-                }
+        group_name=ap_getword(sp,&ll,':');
+
+        while (*ll) {
+            w=ap_getword_conf(sp,&ll);
+            if (!strcmp(w,user)) {
+                ap_table_setn(grps,ap_pstrdup(r->pool,group_name),"in");
+                break;
             }
         }
     }
-
-    ap_log_rerror(APLOG_MARK,APLOG_ERR,SH_AP_R(r),
-        "shib_error_page() could not process shire error template for application %s",app->getId());
-    return SERVER_ERROR;
+    ap_cfg_closefile(f);
+    ap_destroy_pool(sp);
+    return grps;
 }
 
-/*
- * shib_auth_checker() -- a simple resource manager to
- * process the .htaccess settings and copy attributes
- * into the HTTP headers.
- */
-extern "C" int shib_auth_checker(request_rec* r)
+bool htAccessControl::authorized(
+    ShibTarget* st,
+    const char* providerId,
+    const saml::SAMLAuthenticationStatement* authn,
+    const saml::SAMLResponse* attrs
+) const
 {
-    shib_dir_config* dc=
-        (shib_dir_config*)ap_get_module_config(r->per_dir_config,&mod_shib);
-
-    ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r),"shib_auth_checker() executing");
-
-    // Regular access to arbitrary resource...check AuthType
-    const char* auth_type=ap_auth_type(r);
-    if (!auth_type || strcasecmp(auth_type,"shibboleth"))
-        return DECLINED;
-
-    ostringstream threadid;
-    threadid << "[" << getpid() << "] shibrm" << '\0';
-    saml::NDC ndc(threadid.str().c_str());
-
-    // We lock the configuration system for the duration.
-    IConfig* conf=g_Config->getINI();
-    Locker locker(conf);
-    
-    const char* application_id=ap_table_get(r->headers_in,"Shib-Application-ID");
-    const IApplication* application=NULL;
-    if (application_id)
-        application = conf->getApplication(application_id);
+    // Make sure the object is our type.
+    ShibTargetApache* sta=dynamic_cast<ShibTargetApache*>(st);
+    if (!sta)
+        throw ConfigurationException("Request wrapper object was not of correct type.");
 
     // mod_auth clone
 
-    int m=r->method_number;
+    int m=sta->m_req->method_number;
     bool method_restricted=false;
     const char *t, *w;
     
-    const array_header* reqs_arr=ap_requires(r);
+    const array_header* reqs_arr=ap_requires(sta->m_req);
     if (!reqs_arr)
-        return OK;
+        return true;
 
     require_line* reqs=(require_line*)reqs_arr->elts;
-
-    ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r),"REQUIRE nelts: %d", reqs_arr->nelts);
-    ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r),"REQUIRE all: %d", dc->bRequireAll);
+    
+    ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(sta->m_req),"REQUIRE nelts: %d", reqs_arr->nelts);
+    ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(sta->m_req),"REQUIRE all: %d", sta->m_dc->bRequireAll);
 
     vector<bool> auth_OK(reqs_arr->nelts,false);
 
-#define SHIB_AP_CHECK_IS_OK {       \
-     if (dc->bRequireAll < 1)    \
-         return OK;      \
-     auth_OK[x] = true;      \
-     continue;           \
+#define SHIB_AP_CHECK_IS_OK {           \
+     if (sta->m_dc->bRequireAll < 1)    \
+         return true;                   \
+     auth_OK[x] = true;                 \
+     continue;                          \
 }
 
     for (int x=0; x<reqs_arr->nelts; x++) {
@@ -1135,23 +611,24 @@ extern "C" int shib_auth_checker(request_rec* r)
         if (!(reqs[x].method_mask & (1 << m)))
             continue;
         method_restricted=true;
+        string remote_user = st->getRemoteUser();
 
         t = reqs[x].requirement;
-        w = ap_getword_white(r->pool, &t);
+        w = ap_getword_white(sta->m_req->pool, &t);
 
         if (!strcasecmp(w,"Shibboleth")) {
             // This is a dummy rule needed because Apache conflates authn and authz.
             // Without some require rule, AuthType is ignored and no check_user hooks run.
             SHIB_AP_CHECK_IS_OK;
         }
-        else if (!strcmp(w,"valid-user") && application_id) {
-            ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r),"shib_auth_checker() accepting valid-user");
+        else if (!strcmp(w,"valid-user")) {
+            st->log(ShibTarget::LogLevelDebug,"htAccessControl plugin accepting valid-user");
             SHIB_AP_CHECK_IS_OK;
         }
-        else if (!strcmp(w,"user") && SH_AP_USER(r)) {
+        else if (!strcmp(w,"user") && !remote_user.empty()) {
             bool regexp=false;
             while (*t) {
-                w=ap_getword_conf(r->pool,&t);
+                w=ap_getword_conf(sta->m_req->pool,&t);
                 if (*w=='~') {
                     regexp=true;
                     continue;
@@ -1162,54 +639,53 @@ extern "C" int shib_auth_checker(request_rec* r)
                         // To do regex matching, we have to convert from UTF-8.
                         auto_ptr<XMLCh> trans(fromUTF8(w));
                         RegularExpression re(trans.get());
-                        auto_ptr<XMLCh> trans2(fromUTF8(SH_AP_USER(r)));
+                        auto_ptr<XMLCh> trans2(fromUTF8(remote_user.c_str()));
                         if (re.matches(trans2.get())) {
-                            ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r),"shib_auth_checker() accepting user: %s",w);
+                            st->log(ShibTarget::LogLevelDebug, string("htAccessControl plugin accepting user (") + w + ")");
                             SHIB_AP_CHECK_IS_OK;
                         }
                     }
                     catch (XMLException& ex) {
                         auto_ptr_char tmp(ex.getMessage());
-                        ap_log_rerror(APLOG_MARK,APLOG_ERR|APLOG_NOERRNO,SH_AP_R(r),
-                                        "shib_auth_checker caught exception while parsing regular expression (%s): %s",w,tmp.get());
+                        st->log(ShibTarget::LogLevelError,
+                            string("htAccessControl plugin caught exception while parsing regular expression (") + w + "): " + tmp.get());
                     }
                 }
-                else if (!strcmp(SH_AP_USER(r),w)) {
-                    ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r),"shib_auth_checker() accepting user: %s",w);
+                else if (remote_user==w) {
+                    st->log(ShibTarget::LogLevelDebug, string("htAccessControl plugin accepting user (") + w + ")");
                     SHIB_AP_CHECK_IS_OK;
                 }
             }
         }
         else if (!strcmp(w,"group")) {
             SH_AP_TABLE* grpstatus=NULL;
-            if (dc->szAuthGrpFile && SH_AP_USER(r)) {
-                ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r),"shib_auth_checker() using groups file: %s\n",dc->szAuthGrpFile);
-                grpstatus=groups_for_user(r,SH_AP_USER(r),dc->szAuthGrpFile);
+            if (sta->m_dc->szAuthGrpFile && !remote_user.empty()) {
+                st->log(ShibTarget::LogLevelDebug,string("htAccessControl plugin using groups file: ") + sta->m_dc->szAuthGrpFile);
+                grpstatus=groups_for_user(sta->m_req,remote_user.c_str(),sta->m_dc->szAuthGrpFile);
             }
             if (!grpstatus)
-                return DECLINED;
+                return false;
     
             while (*t) {
-                w=ap_getword_conf(r->pool,&t);
+                w=ap_getword_conf(sta->m_req->pool,&t);
                 if (ap_table_get(grpstatus,w)) {
-                    ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r),"shib_auth_checker() accepting group: %s",w);
+                    st->log(ShibTarget::LogLevelDebug, string("htAccessControl plugin accepting group (") + w + ")");
                     SHIB_AP_CHECK_IS_OK;
                 }
             }
         }
         else {
-            Iterator<IAAP*> provs=application ? application->getAAPProviders() : EMPTY(IAAP*);
+            Iterator<IAAP*> provs=st->getApplication()->getAAPProviders();
             AAP wrapper(provs,w);
             if (wrapper.fail()) {
-                ap_log_rerror(APLOG_MARK,APLOG_WARNING|APLOG_NOERRNO,SH_AP_R(r),
-                    "shib_auth_checker() didn't recognize require rule: %s\n",w);
+                st->log(ShibTarget::LogLevelWarn, string("htAccessControl plugin didn't recognize require rule: ") + w);
                 continue;
             }
 
             bool regexp=false;
-            const char* vals=ap_table_get(r->headers_in,wrapper->getHeader());
+            const char* vals=ap_table_get(sta->m_req->headers_in,wrapper->getHeader());
             while (*t && vals) {
-                w=ap_getword_conf(r->pool,&t);
+                w=ap_getword_conf(sta->m_req->pool,&t);
                 if (*w=='~') {
                     regexp=true;
                     continue;
@@ -1229,9 +705,9 @@ extern "C" int shib_auth_checker(request_rec* r)
                     for (int i = 0;  i < vals_str.length();  i++) {
                         if (vals_str.at(i) == ';') {
                             if (i == 0) {
-                                ap_log_rerror(APLOG_MARK,APLOG_WARNING|APLOG_NOERRNO,SH_AP_R(r),
-                                                "shib_auth_checker() invalid header encoding %s: starts with semicolon", vals);
-                                return SERVER_ERROR;
+                                st->log(ShibTarget::LogLevelError, string("htAccessControl plugin found invalid header encoding (") +
+                                    vals + "): starts with a semicolon");
+                                throw SAMLException("Invalid information supplied to authorization plugin.");
                             }
 
                             if (vals_str.at(i-1) == '\\') {
@@ -1245,19 +721,19 @@ extern "C" int shib_auth_checker(request_rec* r)
                             if (regexp) {
                                 auto_ptr<XMLCh> trans(fromUTF8(val.c_str()));
                                 if (re->matches(trans.get())) {
-                                    ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r),
-                                                    "shib_auth_checker() expecting %s, got %s: authorization granted", w, val.c_str());
+                                    st->log(ShibTarget::LogLevelDebug, string("htAccessControl plugin expecting ") + w +
+                                       ", got " + val + ": authorization granted");
                                     SHIB_AP_CHECK_IS_OK;
                                 }
                             }
                             else if ((wrapper->getCaseSensitive() && val==w) || (!wrapper->getCaseSensitive() && !strcasecmp(val.c_str(),w))) {
-                                ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r),
-                                                "shib_auth_checker() expecting %s, got %s: authorization granted", w, val.c_str());
+                                st->log(ShibTarget::LogLevelDebug, string("htAccessControl plugin expecting ") + w +
+                                    ", got " + val + ": authorization granted.");
                                 SHIB_AP_CHECK_IS_OK;
                             }
                             else {
-                                ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r),
-                                                "shib_auth_checker() expecting %s, got %s: authorization not granted", w, val.c_str());
+                                st->log(ShibTarget::LogLevelDebug, string("htAccessControl plugin expecting ") + w +
+                                    ", got " + val + ": authoritzation not granted.");
                             }
                         }
                     }
@@ -1266,25 +742,25 @@ extern "C" int shib_auth_checker(request_rec* r)
                     if (regexp) {
                         auto_ptr<XMLCh> trans(fromUTF8(val.c_str()));
                         if (re->matches(trans.get())) {
-                            ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r),
-                                            "shib_auth_checker() expecting %s, got %s: authorization granted", w, val.c_str());
+                            st->log(ShibTarget::LogLevelDebug, string("htAccessControl plugin expecting ") + w +
+                                ", got " + val + ": authorization granted.");
                             SHIB_AP_CHECK_IS_OK;
                         }
                     }
                     else if ((wrapper->getCaseSensitive() && val==w) || (!wrapper->getCaseSensitive() && !strcasecmp(val.c_str(),w))) {
-                        ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r),
-                                        "shib_auth_checker() expecting %s, got %s: authorization granted", w, val.c_str());
+                        st->log(ShibTarget::LogLevelDebug, string("htAccessControl plugin expecting ") + w +
+                            ", got " + val + ": authorization granted");
                         SHIB_AP_CHECK_IS_OK;
                     }
                     else {
-                        ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r),
-                                        "shib_auth_checker() expecting %s, got %s: authorization not granted", w, val.c_str());
+                            st->log(ShibTarget::LogLevelDebug, string("htAccessControl plugin expecting ") + w +
+                                ", got " + val + ": authorization not granted");
                     }
                 }
                 catch (XMLException& ex) {
                     auto_ptr_char tmp(ex.getMessage());
-                    ap_log_rerror(APLOG_MARK,APLOG_ERR|APLOG_NOERRNO,SH_AP_R(r),
-                                    "shib_auth_checker caught exception while parsing regular expression (%s): %s",w,tmp.get());
+                    st->log(ShibTarget::LogLevelError, string("htAccessControl plugin caught exception while parsing regular expression (")
+                        + w + "): " + tmp.get());
                 }
             }
         }
@@ -1295,28 +771,11 @@ extern "C" int shib_auth_checker(request_rec* r)
     for (int i= 0; i<reqs_arr->nelts; i++) {
         auth_all_OK &= auth_OK[i];
     }
-    if (auth_all_OK)
-        return OK;
-
-    if (!method_restricted)
-        return OK;
-
-    if (!application_id) {
-        ap_log_rerror(APLOG_MARK,APLOG_ERR|APLOG_NOERRNO,SH_AP_R(r),
-           "shib_auth_checker: Shib-Application-ID header not found in request");
-        return HTTP_FORBIDDEN;
-    }
-    else if (!application) {
-        ap_log_rerror(APLOG_MARK,APLOG_ERR|APLOG_NOERRNO,SH_AP_R(r),
-           "shib_auth_checker: unable to map request to application settings, check configuration");
-        return HTTP_FORBIDDEN;
-    }
+    if (auth_all_OK || !method_restricted)
+        return true;
 
-    ShibMLP markupProcessor;
-    markupProcessor.insert("requestURL", ap_construct_url(r->pool,r->unparsed_uri,r));
-    return shib_error_page(r, application, "access", markupProcessor);
+    return false;
 }
-#endif /* 0 */
 
 #ifndef SHIB_APACHE_13
 /*
@@ -1388,14 +847,24 @@ extern "C" void shib_child_init(apr_pool_t* p, server_rec* s)
             ShibTargetConfig::LocalExtensions |
             ShibTargetConfig::Logging
             );
-        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");
+        if (!g_Config->init(g_szSchemaDir)) {
+            ap_log_error(APLOG_MARK,APLOG_CRIT|APLOG_NOERRNO,SH_AP_R(s),"shib_child_init() failed to initialize libraries");
+            exit(1);
+        }
+        SAMLConfig::getConfig().getPlugMgr().regFactory(shibtarget::XML::htAccessControlType,&htAccessFactory);
+        SAMLConfig::getConfig().getPlugMgr().regFactory(shibtarget::XML::ApacheRequestMapType,&ApacheRequestMapFactory);
+        
+        // We hijack the legacy type so that 1.2 config files will load this plugin instead of the basic plugin.
+        SAMLConfig::getConfig().getPlugMgr().regFactory(shibtarget::XML::LegacyRequestMapType,&ApacheRequestMapFactory);
+        
+        if (!g_Config->load(g_szSHIBConfig)) {
+            ap_log_error(APLOG_MARK,APLOG_CRIT|APLOG_NOERRNO,SH_AP_R(s),"shib_child_init() failed to load configuration");
             exit(1);
         }
     }
     catch (...) {
-        ap_log_error(APLOG_MARK,APLOG_CRIT|APLOG_NOERRNO,SH_AP_R(s),"shib_child_init() failed to initialize SHIB Target");
-        exit (1);
+        ap_log_error(APLOG_MARK,APLOG_CRIT|APLOG_NOERRNO,SH_AP_R(s),"shib_child_init() failed to initialize system");
+        exit(1);
     }
 
     // Set the cleanup handler
index 5b5a10e..778d740 100644 (file)
@@ -105,7 +105,7 @@ namespace {
             if (s.get()) m_scheme=s.get();
             if (p.get()) m_port=p.get();
             if (p2.get()) m_sslport=p2.get();
-            DOMNodeList* nlist=e->getElementsByTagNameNS(ShibTargetConfig::SHIBTARGET_NS,Alias);
+            DOMNodeList* nlist=e->getElementsByTagNameNS(shibtarget::XML::SHIBTARGET_NS,Alias);
             for (int i=0; nlist && i<nlist->getLength(); i++) {
                 if (nlist->item(i)->hasChildNodes()) {
                     auto_ptr_char alias(nlist->item(i)->getFirstChild()->getNodeValue());
@@ -208,17 +208,17 @@ extern "C" BOOL WINAPI GetFilterVersion(PHTTP_FILTER_VERSION pVer)
         const IPropertySet* props=conf->getPropertySet("Local");
         if (props) {
             const DOMElement* impl=saml::XML::getFirstChildElement(
-                props->getElement(),ShibTargetConfig::SHIBTARGET_NS,Implementation
+                props->getElement(),shibtarget::XML::SHIBTARGET_NS,Implementation
                 );
-            if (impl && (impl=saml::XML::getFirstChildElement(impl,ShibTargetConfig::SHIBTARGET_NS,ISAPI))) {
+            if (impl && (impl=saml::XML::getFirstChildElement(impl,shibtarget::XML::SHIBTARGET_NS,ISAPI))) {
                 const XMLCh* flag=impl->getAttributeNS(NULL,normalizeRequest);
                 g_bNormalizeRequest=(!flag || !*flag || *flag==chDigit_1 || *flag==chLatin_t);
-                impl=saml::XML::getFirstChildElement(impl,ShibTargetConfig::SHIBTARGET_NS,Site);
+                impl=saml::XML::getFirstChildElement(impl,shibtarget::XML::SHIBTARGET_NS,Site);
                 while (impl) {
                     auto_ptr_char id(impl->getAttributeNS(NULL,id));
                     if (id.get())
                         g_Sites.insert(pair<string,site_t>(id.get(),site_t(impl)));
-                    impl=saml::XML::getNextSiblingElement(impl,ShibTargetConfig::SHIBTARGET_NS,Site);
+                    impl=saml::XML::getNextSiblingElement(impl,shibtarget::XML::SHIBTARGET_NS,Site);
                 }
             }
         }
index 542e765..4994800 100644 (file)
@@ -710,12 +710,12 @@ void mysqlInit(const DOMElement* e, Category& log)
   arg_array.push_back("shibboleth");
 
   // grab any MySQL parameters from the config file
-  e=saml::XML::getFirstChildElement(e,ShibTargetConfig::SHIBTARGET_NS,Argument);
+  e=saml::XML::getFirstChildElement(e,shibtarget::XML::SHIBTARGET_NS,Argument);
   while (e) {
       auto_ptr_char arg(e->getFirstChild()->getNodeValue());
       if (arg.get())
           arg_array.push_back(arg.get());
-      e=saml::XML::getNextSiblingElement(e,ShibTargetConfig::SHIBTARGET_NS,Argument);
+      e=saml::XML::getNextSiblingElement(e,shibtarget::XML::SHIBTARGET_NS,Argument);
   }
 
   // Compute the argument array
index 3be166f..2b60a70 100644 (file)
 
 using namespace shibtarget;
 
-const char XML::htaccessType[] =            "edu.internet2.middleware.shibboleth.sp.provider.htaccess";
 const char XML::MemorySessionCacheType[] =  "edu.internet2.middleware.shibboleth.sp.provider.MemorySessionCacheProvider";
 const char XML::MySQLSessionCacheType[] =   "edu.internet2.middleware.shibboleth.sp.provider.MySQLSessionCacheProvider";
+
 const char XML::MySQLReplayCacheType[] =    "edu.internet2.middleware.shibboleth.sp.provider.MySQLReplayCacheProvider";
+
+const char XML::XMLRequestMapType[] =       "edu.internet2.middleware.shibboleth.sp.provider.XMLRequestMapProvider";
+const char XML::ApacheRequestMapType[] =    "edu.internet2.middleware.shibboleth.sp.apache.provider.ApacheRequestMapProvider";
 const char XML::LegacyRequestMapType[] =    "edu.internet2.middleware.shibboleth.target.provider.XMLRequestMap";
-const char XML::RequestMapType[] =          "edu.internet2.middleware.shibboleth.sp.provider.XMLRequestMapProvider";
+
+const char XML::htAccessControlType[] =     "edu.internet2.middleware.shibboleth.sp.apache.provider.htAccessControl";
+const char XML::XMLAccessControlType[] =    "edu.internet2.middleware.shibboleth.sp.provider.XMLAccessControl";
+
 const char XML::TCPListenerType[] =         "edu.internet2.middleware.shibboleth.sp.provider.TCPListener";
 const char XML::UnixListenerType[] =        "edu.internet2.middleware.shibboleth.sp.provider.UnixListener";
 
+const XMLCh XML::SHIBTARGET_NS[] = // urn:mace:shibboleth:target:config:1.0
+{ chLatin_u, chLatin_r, chLatin_n, chColon, chLatin_m, chLatin_a, chLatin_c, chLatin_e, chColon,
+  chLatin_s, chLatin_h, chLatin_i, chLatin_b, chLatin_b, chLatin_o, chLatin_l, chLatin_e, chLatin_t, chLatin_h, chColon,
+  chLatin_t, chLatin_a, chLatin_r, chLatin_g, chLatin_e, chLatin_t, chColon,
+  chLatin_c, chLatin_o, chLatin_n, chLatin_f, chLatin_i, chLatin_g, chColon,
+  chDigit_1, chPeriod, chDigit_0, chNull
+};
+
 const XMLCh XML::SHIBTARGET_SCHEMA_ID[] = // shibboleth-targetconfig-1.0.xsd
 { chLatin_s, chLatin_h, chLatin_i, chLatin_b, chLatin_b, chLatin_o, chLatin_l, chLatin_e, chLatin_t, chLatin_h, chDash,
   chLatin_t, chLatin_a, chLatin_r, chLatin_g, chLatin_e, chLatin_t, chLatin_c, chLatin_o, chLatin_n, chLatin_f, chLatin_i, chLatin_g, chDash,
@@ -124,6 +138,11 @@ const XMLCh XML::Literals::AccessControlProvider[] =
   chLatin_P, chLatin_r, chLatin_o, chLatin_v, chLatin_i, chLatin_d, chLatin_e, chLatin_r, 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::applicationId[] =
 { chLatin_a, chLatin_p, chLatin_p, chLatin_l, chLatin_i, chLatin_c, chLatin_a, chLatin_t, chLatin_i, chLatin_o, chLatin_n,
   chLatin_I, chLatin_d, chNull
index 66e2dd1..d17570c 100644 (file)
@@ -119,10 +119,7 @@ namespace shibtarget {
         XMLRequestMapper(const DOMElement* e) : ReloadableXMLFile(e) {}
         ~XMLRequestMapper() {}
 
-        virtual Settings getSettingsFromURL(const char* url, ShibTarget* st) const;
-        virtual Settings getSettingsFromParsedURL(
-            const char* scheme, const char* hostname, unsigned int port, const char* path, ShibTarget* st
-            ) const;
+        virtual Settings getSettings(ShibTarget* st) const;
 
     protected:
         virtual ReloadableXMLFileImpl* newImplementation(const char* pathname, bool first=true) const;
@@ -139,7 +136,7 @@ IPlugIn* XMLRequestMapFactory(const DOMElement* e)
 
 short Override::acceptNode(const DOMNode* node) const
 {
-    if (XMLString::compareString(node->getNamespaceURI(),ShibTargetConfig::SHIBTARGET_NS))
+    if (XMLString::compareString(node->getNamespaceURI(),shibtarget::XML::SHIBTARGET_NS))
         return FILTER_ACCEPT;
     const XMLCh* name=node->getLocalName();
     if (XMLString::compareString(name,SHIBT_L(AccessControlProvider)) ||
@@ -153,17 +150,24 @@ short Override::acceptNode(const DOMNode* node) const
 void Override::loadACL(const DOMElement* e, Category& log)
 {
     IPlugIn* plugin=NULL;
-    const DOMElement* acl=saml::XML::getFirstChildElement(e,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(htaccess));
+    const DOMElement* acl=saml::XML::getFirstChildElement(e,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(htaccess));
     if (acl) {
-        log.info("building htaccess provider...");
-        plugin=SAMLConfig::getConfig().getPlugMgr().newPlugin(shibtarget::XML::htaccessType,acl);
+        log.info("building Apache htaccess provider...");
+        plugin=SAMLConfig::getConfig().getPlugMgr().newPlugin(shibtarget::XML::htAccessControlType,acl);
     }
     else {
-        acl=saml::XML::getFirstChildElement(e,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(AccessControlProvider));
+        acl=saml::XML::getFirstChildElement(e,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(AccessControl));
         if (acl) {
-            auto_ptr_char type(acl->getAttributeNS(NULL,SHIBT_L(type)));
-            log.info("building Access Control provider of type %s...",type.get());
-            plugin=SAMLConfig::getConfig().getPlugMgr().newPlugin(type.get(),acl);
+            log.info("building XML-based Access Control provider...");
+            plugin=SAMLConfig::getConfig().getPlugMgr().newPlugin(shibtarget::XML::XMLAccessControlType,acl);
+        }
+        else {
+            acl=saml::XML::getFirstChildElement(e,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(AccessControlProvider));
+            if (acl) {
+                auto_ptr_char type(acl->getAttributeNS(NULL,SHIBT_L(type)));
+                log.info("building Access Control provider of type %s...",type.get());
+                plugin=SAMLConfig::getConfig().getPlugMgr().newPlugin(type.get(),acl);
+            }
         }
     }
     if (plugin) {
@@ -188,7 +192,7 @@ Override::Override(const DOMElement* e, Category& log, const Override* base) : m
         loadACL(e,log);
     
         // Handle nested Paths.
-        DOMNodeList* nlist=e->getElementsByTagNameNS(ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(Path));
+        DOMNodeList* nlist=e->getElementsByTagNameNS(shibtarget::XML::SHIBTARGET_NS,SHIBT_L(Path));
         for (int i=0; nlist && i<nlist->getLength(); i++) {
             DOMElement* path=static_cast<DOMElement*>(nlist->item(i));
             const XMLCh* n=path->getAttributeNS(NULL,SHIBT_L(name));
@@ -318,7 +322,7 @@ void XMLRequestMapperImpl::init()
     log=&Category::getInstance("shibtarget.RequestMapper");
 
     try {
-        if (!saml::XML::isElementNamed(ReloadableXMLFileImpl::m_root,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(RequestMap))) {
+        if (!saml::XML::isElementNamed(ReloadableXMLFileImpl::m_root,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(RequestMap))) {
             log->error("Construction requires a valid request mapping file: (conf:RequestMap as root element)");
             throw MalformedException("Construction requires a valid request mapping file: (conf:RequestMap as root element)");
         }
@@ -330,7 +334,7 @@ void XMLRequestMapperImpl::init()
         loadACL(ReloadableXMLFileImpl::m_root,*log);
     
         // Loop over the Host elements.
-        DOMNodeList* nlist = ReloadableXMLFileImpl::m_root->getElementsByTagNameNS(ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(Host));
+        DOMNodeList* nlist = ReloadableXMLFileImpl::m_root->getElementsByTagNameNS(shibtarget::XML::SHIBTARGET_NS,SHIBT_L(Host));
         for (int i=0; nlist && i<nlist->getLength(); i++) {
             DOMElement* host=static_cast<DOMElement*>(nlist->item(i));
             const XMLCh* n=host->getAttributeNS(NULL,SHIBT_L(name));
@@ -471,25 +475,6 @@ const Override* XMLRequestMapperImpl::findOverride(const char* vhost, const char
     return o ? o->locate(path) : this;
 }
 
-const char* split_url(const char* url, string& vhost)
-{
-    const char* path=NULL;
-    const char* slash=strchr(url,'/');
-    if (slash)
-    {
-        slash=strchr(slash,'/');
-        if (slash)
-        {
-            path=strchr(slash,'/');
-            if (path)
-                vhost.append(url,path-url);
-            else
-                vhost=url;
-        }
-    }
-    return path;
-}
-
 ReloadableXMLFileImpl* XMLRequestMapper::newImplementation(const char* pathname, bool first) const
 {
     return new XMLRequestMapperImpl(pathname);
@@ -500,45 +485,20 @@ ReloadableXMLFileImpl* XMLRequestMapper::newImplementation(const DOMElement* e,
     return new XMLRequestMapperImpl(e);
 }
 
-IRequestMapper::Settings XMLRequestMapper::getSettingsFromURL(const char* url, ShibTarget* st) const
+IRequestMapper::Settings XMLRequestMapper::getSettings(ShibTarget* st) const
 {
-    string vhost;
-    const char* path=split_url(url,vhost);
+    ostringstream vhost;
+    vhost << st->getProtocol() << "://" << st->getHostname() << ':' << st->getPort();
 
     XMLRequestMapperImpl* impl=static_cast<XMLRequestMapperImpl*>(getImplementation());
-    const Override* o=impl->findOverride(vhost.c_str(), path);
+    const Override* o=impl->findOverride(vhost.str().c_str(), st->getRequestURI());
 
     if (impl->log->isDebugEnabled()) {
-        saml::NDC ndc("getApplicationFromURL");
-        pair<bool,const char*> ret=o->getString("applicationId");
-        impl->log->debug("mapped %s to %s", url, ret.second);
-    }
-
-    return Settings(o,o->m_acl);
-}
-
-IRequestMapper::Settings XMLRequestMapper::getSettingsFromParsedURL(
-    const char* scheme, const char* hostname, unsigned int port, const char* path, ShibTarget* st
-    ) const
-{
-    char buf[21];
-    string vhost(scheme);
-    vhost=vhost + "://" + hostname + ':';
-#ifdef WIN32
-    _snprintf(buf,20,"%u",port);
-#else
-    snprintf(buf,20,"%u",port);
+#ifdef _DEBUG
+        saml::NDC ndc("getSettings");
 #endif
-    vhost+=buf;
-
-    XMLRequestMapperImpl* impl=static_cast<XMLRequestMapperImpl*>(getImplementation());
-    const Override* o=impl->findOverride(vhost.c_str(), path);
-
-    if (impl->log->isDebugEnabled())
-    {
-        saml::NDC ndc("getApplicationFromParsedURL");
         pair<bool,const char*> ret=o->getString("applicationId");
-        impl->log->debug("mapped %s%s to %s", vhost.c_str(), path ? path : "", ret.second);
+        impl->log->debug("mapped %s%s to %s", vhost.str().c_str(), st->getRequestURI() ? st->getRequestURI() : "", ret.second);
     }
 
     return Settings(o,o->m_acl);
index 07b1d63..5df255c 100644 (file)
@@ -255,83 +255,6 @@ namespace shibtarget {
         shibboleth::Mutex* m_tranLogLock;
         static IConfig* ShibTargetConfigFactory(const DOMElement* e);
     };
-
-    class XML
-    {
-    public:
-        static const XMLCh SHIBTARGET_SCHEMA_ID[];
-        static const XMLCh SAML2ASSERT_NS[];
-        static const XMLCh SAML2ASSERT_SCHEMA_ID[];
-        static const XMLCh SAML2META_NS[];
-        static const XMLCh SAML2META_SCHEMA_ID[];
-        static const XMLCh XMLENC_NS[];
-        static const XMLCh XMLENC_SCHEMA_ID[];
-    
-        static const char htaccessType[];
-        static const char MemorySessionCacheType[];
-        static const char MySQLSessionCacheType[];
-        static const char MemoryReplayCacheType[];
-        static const char MySQLReplayCacheType[];
-        static const char LegacyRequestMapType[];
-        static const char RequestMapType[];
-        static const char TCPListenerType[];
-        static const char UnixListenerType[];
-    
-        struct Literals
-        {
-            static const XMLCh AAPProvider[];
-            static const XMLCh AccessControlProvider[];
-            static const XMLCh AND[];
-            static const XMLCh applicationId[];
-            static const XMLCh Application[];
-            static const XMLCh Applications[];
-            static const XMLCh AssertionConsumerService[];
-            static const XMLCh CredentialsProvider[];
-            static const XMLCh CredentialUse[];
-            static const XMLCh Extensions[];
-            static const XMLCh fatal[];
-            static const XMLCh FederationProvider[];
-            static const XMLCh Global[];
-            static const XMLCh Host[];
-            static const XMLCh htaccess[];
-            static const XMLCh Implementation[];
-            static const XMLCh index[];
-            static const XMLCh isDefault[];
-            static const XMLCh Library[];
-            static const XMLCh Listener[];
-            static const XMLCh Local[];
-            static const XMLCh logger[];
-            static const XMLCh MemorySessionCache[];
-            static const XMLCh MetadataProvider[];
-            static const XMLCh MySQLReplayCache[];
-            static const XMLCh MySQLSessionCache[];
-            static const XMLCh name[];
-            static const XMLCh Name[];
-            static const XMLCh NOT[];
-            static const XMLCh OR[];
-            static const XMLCh Path[];
-            static const XMLCh path[];
-            static const XMLCh RelyingParty[];
-            static const XMLCh ReplayCache[];
-            static const XMLCh RequestMap[];
-            static const XMLCh RequestMapProvider[];
-            static const XMLCh require[];
-            static const XMLCh Rule[];
-            static const XMLCh SessionCache[];
-            static const XMLCh SessionInitiator[];
-            static const XMLCh SHAR[];
-            static const XMLCh ShibbolethTargetConfig[];
-            static const XMLCh SHIRE[];
-            static const XMLCh Signing[];
-            static const XMLCh SingleLogoutService[];
-            static const XMLCh SPConfig[];
-            static const XMLCh TCPListener[];
-            static const XMLCh TLS[];
-            static const XMLCh TrustProvider[];
-            static const XMLCh type[];
-            static const XMLCh UnixListener[];
-        };
-    };
 }
 
 #endif
index e8dbaf9..29ccbdf 100644 (file)
@@ -69,14 +69,6 @@ namespace {
     STConfig g_Config;
 }
 
-const XMLCh ShibTargetConfig::SHIBTARGET_NS[] = // urn:mace:shibboleth:target:config:1.0
-{ chLatin_u, chLatin_r, chLatin_n, chColon, chLatin_m, chLatin_a, chLatin_c, chLatin_e, chColon,
-  chLatin_s, chLatin_h, chLatin_i, chLatin_b, chLatin_b, chLatin_o, chLatin_l, chLatin_e, chLatin_t, chLatin_h, chColon,
-  chLatin_t, chLatin_a, chLatin_r, chLatin_g, chLatin_e, chLatin_t, chColon,
-  chLatin_c, chLatin_o, chLatin_n, chLatin_f, chLatin_i, chLatin_g, chColon,
-  chDigit_1, chPeriod, chDigit_0, chNull
-};
-
 // Factories for built-in plugins we can manufacture. Actual definitions
 // will be with the actual object implementation.
 #ifndef WIN32
@@ -172,10 +164,9 @@ bool STConfig::init(const char* schemadir)
     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);
+    samlConf.getPlugMgr().regFactory(shibtarget::XML::XMLRequestMapType,&XMLRequestMapFactory);
     
-    saml::XML::registerSchema(ShibTargetConfig::SHIBTARGET_NS,shibtarget::XML::SHIBTARGET_SCHEMA_ID);
+    saml::XML::registerSchema(shibtarget::XML::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);
index b5fb98a..a4de79e 100644 (file)
@@ -440,7 +440,7 @@ XMLApplication::XMLApplication(
                             m_acsDefault=hprops;
                     }
                 }
-                else if (saml::XML::isElementNamed(handler,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(SessionInitiator))) {
+                else if (saml::XML::isElementNamed(handler,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(SessionInitiator))) {
                     pair<bool,const char*> si_id=hprops->getString("id");
                     if (si_id.first && si_id.second)
                         m_sessionInitMap[si_id.second]=hprops;
@@ -474,7 +474,7 @@ XMLApplication::XMLApplication(
         m_audiences.push_back(getXMLString("providerId").second);
 
         if (conf.isEnabled(ShibTargetConfig::AAP)) {
-            nlist=e->getElementsByTagNameNS(ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(AAPProvider));
+            nlist=e->getElementsByTagNameNS(shibtarget::XML::SHIBTARGET_NS,SHIBT_L(AAPProvider));
             for (i=0; nlist && i<nlist->getLength(); i++) {
                 auto_ptr_char type(static_cast<DOMElement*>(nlist->item(i))->getAttributeNS(NULL,SHIBT_L(type)));
                 log.info("building AAP provider of type %s...",type.get());
@@ -491,7 +491,7 @@ XMLApplication::XMLApplication(
         }
 
         if (conf.isEnabled(ShibTargetConfig::Metadata)) {
-            nlist=e->getElementsByTagNameNS(ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(MetadataProvider));
+            nlist=e->getElementsByTagNameNS(shibtarget::XML::SHIBTARGET_NS,SHIBT_L(MetadataProvider));
             for (i=0; nlist && i<nlist->getLength(); i++) {
                 auto_ptr_char type(static_cast<DOMElement*>(nlist->item(i))->getAttributeNS(NULL,SHIBT_L(type)));
                 log.info("building metadata provider of type %s...",type.get());
@@ -505,7 +505,7 @@ XMLApplication::XMLApplication(
                     throw UnsupportedExtensionException("plugin was not a metadata provider");
                 }
             }
-            nlist=e->getElementsByTagNameNS(ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(FederationProvider));
+            nlist=e->getElementsByTagNameNS(shibtarget::XML::SHIBTARGET_NS,SHIBT_L(FederationProvider));
             for (i=0; nlist && i<nlist->getLength(); i++) {
                 auto_ptr_char type(static_cast<DOMElement*>(nlist->item(i))->getAttributeNS(NULL,SHIBT_L(type)));
                 log.info("building metadata provider of type %s...",type.get());
@@ -522,7 +522,7 @@ XMLApplication::XMLApplication(
         }
 
         if (conf.isEnabled(ShibTargetConfig::Trust)) {
-            nlist=e->getElementsByTagNameNS(ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(TrustProvider));
+            nlist=e->getElementsByTagNameNS(shibtarget::XML::SHIBTARGET_NS,SHIBT_L(TrustProvider));
             for (i=0; nlist && i<nlist->getLength(); i++) {
                 auto_ptr_char type(static_cast<DOMElement*>(nlist->item(i))->getAttributeNS(NULL,SHIBT_L(type)));
                 log.info("building trust provider of type %s...",type.get());
@@ -539,16 +539,16 @@ XMLApplication::XMLApplication(
         }
         
         // Finally, load credential mappings.
-        const DOMElement* cu=saml::XML::getFirstChildElement(e,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(CredentialUse));
+        const DOMElement* cu=saml::XML::getFirstChildElement(e,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(CredentialUse));
         if (cu) {
             m_credDefault=new XMLPropertySet();
             m_credDefault->load(cu,log,this);
-            cu=saml::XML::getFirstChildElement(cu,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(RelyingParty));
+            cu=saml::XML::getFirstChildElement(cu,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(RelyingParty));
             while (cu) {
                 XMLPropertySet* rp=new XMLPropertySet();
                 rp->load(cu,log,this);
                 m_credMap[cu->getAttributeNS(NULL,SHIBT_L(Name))]=rp;
-                cu=saml::XML::getNextSiblingElement(cu,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(RelyingParty));
+                cu=saml::XML::getNextSiblingElement(cu,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(RelyingParty));
             }
         }
         
@@ -792,7 +792,7 @@ ReloadableXMLFileImpl* XMLConfig::newImplementation(const DOMElement* e, bool fi
 
 short XMLConfigImpl::acceptNode(const DOMNode* node) const
 {
-    if (XMLString::compareString(node->getNamespaceURI(),ShibTargetConfig::SHIBTARGET_NS))
+    if (XMLString::compareString(node->getNamespaceURI(),shibtarget::XML::SHIBTARGET_NS))
         return FILTER_ACCEPT;
     const XMLCh* name=node->getLocalName();
     if (!XMLString::compareString(name,SHIBT_L(Applications)) ||
@@ -819,23 +819,23 @@ void XMLConfigImpl::init(bool first)
 #ifdef _DEBUG
     saml::NDC ndc("init");
 #endif
-    Category& log=Category::getInstance("shibtarget.XMLConfig");
+    Category& log=Category::getInstance("shibtarget.Config");
 
     try {
-        if (!saml::XML::isElementNamed(ReloadableXMLFileImpl::m_root,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(ShibbolethTargetConfig)) &&
-            !saml::XML::isElementNamed(ReloadableXMLFileImpl::m_root,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(SPConfig))) {
+        if (!saml::XML::isElementNamed(ReloadableXMLFileImpl::m_root,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(ShibbolethTargetConfig)) &&
+            !saml::XML::isElementNamed(ReloadableXMLFileImpl::m_root,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(SPConfig))) {
             log.error("Construction requires a valid configuration file: (conf:SPConfig as root element)");
             throw ConfigurationException("Construction requires a valid configuration file: (conf:SPConfig as root element)");
         }
 
         SAMLConfig& shibConf=SAMLConfig::getConfig();
         ShibTargetConfig& conf=ShibTargetConfig::getConfig();
-        const DOMElement* SHAR=saml::XML::getFirstChildElement(ReloadableXMLFileImpl::m_root,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(SHAR));
+        const DOMElement* SHAR=saml::XML::getFirstChildElement(ReloadableXMLFileImpl::m_root,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(SHAR));
         if (!SHAR)
-            SHAR=saml::XML::getFirstChildElement(ReloadableXMLFileImpl::m_root,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(Global));
-        const DOMElement* SHIRE=saml::XML::getFirstChildElement(ReloadableXMLFileImpl::m_root,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(SHIRE));
+            SHAR=saml::XML::getFirstChildElement(ReloadableXMLFileImpl::m_root,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(Global));
+        const DOMElement* SHIRE=saml::XML::getFirstChildElement(ReloadableXMLFileImpl::m_root,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(SHIRE));
         if (!SHIRE)
-            SHIRE=saml::XML::getFirstChildElement(ReloadableXMLFileImpl::m_root,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(Local));
+            SHIRE=saml::XML::getFirstChildElement(ReloadableXMLFileImpl::m_root,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(Local));
 
         // Initialize log4cpp manually in order to redirect log messages as soon as possible.
         if (conf.isEnabled(ShibTargetConfig::Logging)) {
@@ -869,9 +869,9 @@ void XMLConfigImpl::init(bool first)
         if (first) {
             // Now load any extensions to insure any needed plugins are registered.
             DOMElement* exts=
-                saml::XML::getFirstChildElement(ReloadableXMLFileImpl::m_root,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(Extensions));
+                saml::XML::getFirstChildElement(ReloadableXMLFileImpl::m_root,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(Extensions));
             if (exts) {
-                exts=saml::XML::getFirstChildElement(exts,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(Library));
+                exts=saml::XML::getFirstChildElement(exts,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(Library));
                 while (exts) {
                     auto_ptr_char path(exts->getAttributeNS(NULL,SHIBT_L(path)));
                     try {
@@ -887,14 +887,14 @@ void XMLConfigImpl::init(bool first)
                         else
                             log.crit("unable to load optional global extension library %s: %s", path.get(), e.what());
                     }
-                    exts=saml::XML::getNextSiblingElement(exts,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(Library));
+                    exts=saml::XML::getNextSiblingElement(exts,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(Library));
                 }
             }
             
             if (conf.isEnabled(ShibTargetConfig::GlobalExtensions)) {
-                exts=saml::XML::getFirstChildElement(SHAR,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(Extensions));
+                exts=saml::XML::getFirstChildElement(SHAR,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(Extensions));
                 if (exts) {
-                    exts=saml::XML::getFirstChildElement(exts,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(Library));
+                    exts=saml::XML::getFirstChildElement(exts,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(Library));
                     while (exts) {
                         auto_ptr_char path(exts->getAttributeNS(NULL,SHIBT_L(path)));
                         try {
@@ -910,15 +910,15 @@ void XMLConfigImpl::init(bool first)
                             else
                                 log.crit("unable to load optional Global extension library %s: %s", path.get(), e.what());
                         }
-                        exts=saml::XML::getNextSiblingElement(exts,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(Library));
+                        exts=saml::XML::getNextSiblingElement(exts,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(Library));
                     }
                 }
             }
 
             if (conf.isEnabled(ShibTargetConfig::LocalExtensions)) {
-                exts=saml::XML::getFirstChildElement(SHIRE,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(Extensions));
+                exts=saml::XML::getFirstChildElement(SHIRE,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(Extensions));
                 if (exts) {
-                    exts=saml::XML::getFirstChildElement(exts,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(Library));
+                    exts=saml::XML::getFirstChildElement(exts,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(Library));
                     while (exts) {
                         auto_ptr_char path(exts->getAttributeNS(NULL,SHIBT_L(path)));
                         try {
@@ -934,7 +934,7 @@ void XMLConfigImpl::init(bool first)
                             else
                                 log.crit("unable to load optional Local extension library %s: %s", path.get(), e.what());
                         }
-                        exts=saml::XML::getNextSiblingElement(exts,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(Library));
+                        exts=saml::XML::getNextSiblingElement(exts,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(Library));
                     }
                 }
             }
@@ -942,19 +942,19 @@ void XMLConfigImpl::init(bool first)
             // Instantiate the Listener and SessionCache objects.
             if (conf.isEnabled(ShibTargetConfig::Listener)) {
                 IPlugIn* plugin=NULL;
-                exts=saml::XML::getFirstChildElement(SHAR,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(UnixListener));
+                exts=saml::XML::getFirstChildElement(SHAR,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(UnixListener));
                 if (exts) {
                     log.info("building Listener of type %s...",shibtarget::XML::UnixListenerType);
                     plugin=shibConf.getPlugMgr().newPlugin(shibtarget::XML::UnixListenerType,exts);
                 }
                 else {
-                    exts=saml::XML::getFirstChildElement(SHAR,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(TCPListener));
+                    exts=saml::XML::getFirstChildElement(SHAR,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(TCPListener));
                     if (exts) {
                         log.info("building Listener of type %s...",shibtarget::XML::TCPListenerType);
                         plugin=shibConf.getPlugMgr().newPlugin(shibtarget::XML::TCPListenerType,exts);
                     }
                     else {
-                        exts=saml::XML::getFirstChildElement(SHAR,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(Listener));
+                        exts=saml::XML::getFirstChildElement(SHAR,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(Listener));
                         if (exts) {
                             auto_ptr_char type(exts->getAttributeNS(NULL,SHIBT_L(type)));
                             log.info("building Listener of type %s...",type.get());
@@ -980,19 +980,19 @@ void XMLConfigImpl::init(bool first)
 
             if (conf.isEnabled(ShibTargetConfig::Caching)) {
                 IPlugIn* plugin=NULL;
-                exts=saml::XML::getFirstChildElement(SHAR,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(MemorySessionCache));
+                exts=saml::XML::getFirstChildElement(SHAR,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(MemorySessionCache));
                 if (exts) {
                     log.info("building Session Cache of type %s...",shibtarget::XML::MemorySessionCacheType);
                     plugin=shibConf.getPlugMgr().newPlugin(shibtarget::XML::MemorySessionCacheType,exts);
                 }
                 else {
-                    exts=saml::XML::getFirstChildElement(SHAR,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(MySQLSessionCache));
+                    exts=saml::XML::getFirstChildElement(SHAR,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(MySQLSessionCache));
                     if (exts) {
                         log.info("building Session Cache of type %s...",shibtarget::XML::MySQLSessionCacheType);
                         plugin=shibConf.getPlugMgr().newPlugin(shibtarget::XML::MySQLSessionCacheType,exts);
                     }
                     else {
-                        exts=saml::XML::getFirstChildElement(SHAR,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(SessionCache));
+                        exts=saml::XML::getFirstChildElement(SHAR,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(SessionCache));
                         if (exts) {
                             auto_ptr_char type(exts->getAttributeNS(NULL,SHIBT_L(type)));
                             log.info("building Session Cache of type %s...",type.get());
@@ -1016,13 +1016,13 @@ void XMLConfigImpl::init(bool first)
                 }
                 
                 // Replay cache.
-                exts=saml::XML::getFirstChildElement(SHAR,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(MySQLReplayCache));
+                exts=saml::XML::getFirstChildElement(SHAR,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(MySQLReplayCache));
                 if (exts) {
                     log.info("building Replay Cache of type %s...",shibtarget::XML::MySQLReplayCacheType);
                     m_outer->m_replayCache=IReplayCache::getInstance(shibtarget::XML::MySQLSessionCacheType,exts);
                 }
                 else {
-                    exts=saml::XML::getFirstChildElement(SHAR,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(ReplayCache));
+                    exts=saml::XML::getFirstChildElement(SHAR,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(ReplayCache));
                     if (exts) {
                         auto_ptr_char type(exts->getAttributeNS(NULL,SHIBT_L(type)));
                         log.info("building Replay Cache of type %s...",type.get());
@@ -1039,7 +1039,7 @@ void XMLConfigImpl::init(bool first)
         
         // Back to the fully dynamic stuff...next up is the Request Mapper.
         if (conf.isEnabled(ShibTargetConfig::RequestMapper)) {
-            const DOMElement* child=saml::XML::getFirstChildElement(SHIRE,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(RequestMapProvider));
+            const DOMElement* child=saml::XML::getFirstChildElement(SHIRE,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(RequestMapProvider));
             if (child) {
                 auto_ptr_char type(child->getAttributeNS(NULL,SHIBT_L(type)));
                 log.info("building Request Mapper of type %s...",type.get());
@@ -1064,9 +1064,7 @@ void XMLConfigImpl::init(bool first)
         // Now we load any credentials providers.
         DOMNodeList* nlist;
         if (conf.isEnabled(ShibTargetConfig::Credentials)) {
-            nlist=ReloadableXMLFileImpl::m_root->getElementsByTagNameNS(
-                ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(CredentialsProvider)
-                );
+            nlist=ReloadableXMLFileImpl::m_root->getElementsByTagNameNS(shibtarget::XML::SHIBTARGET_NS,SHIBT_L(CredentialsProvider));
             for (int i=0; nlist && i<nlist->getLength(); i++) {
                 auto_ptr_char type(static_cast<DOMElement*>(nlist->item(i))->getAttributeNS(NULL,SHIBT_L(type)));
                 log.info("building Credentials provider of type %s...",type.get());
@@ -1086,7 +1084,7 @@ void XMLConfigImpl::init(bool first)
 
         // Load the default application. This actually has a fixed ID of "default". ;-)
         const DOMElement* app=saml::XML::getFirstChildElement(
-            ReloadableXMLFileImpl::m_root,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(Applications)
+            ReloadableXMLFileImpl::m_root,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(Applications)
             );
         if (!app) {
             log.fatal("can't build default Application object, missing conf:Applications element?");
@@ -1096,7 +1094,7 @@ void XMLConfigImpl::init(bool first)
         m_appmap[defapp->getId()]=defapp;
         
         // Load any overrides.
-        nlist=app->getElementsByTagNameNS(ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(Application));
+        nlist=app->getElementsByTagNameNS(shibtarget::XML::SHIBTARGET_NS,SHIBT_L(Application));
         for (int i=0; nlist && i<nlist->getLength(); i++) {
             XMLApplication* iapp=new XMLApplication(m_outer,m_creds,static_cast<DOMElement*>(nlist->item(i)),defapp);
             if (m_appmap.find(iapp->getId())!=m_appmap.end()) {
index a4a175c..83ed5c1 100644 (file)
@@ -202,7 +202,7 @@ void ShibTarget::init(
 // The web server modules implement a subclass and then call into 
 // these methods once they instantiate their request object.
 
-pair<bool,void*> ShibTarget::doCheckAuthN(bool requireSessionFlag, bool handler)
+pair<bool,void*> ShibTarget::doCheckAuthN(bool handler)
 {
 #ifdef _DEBUG
     saml::NDC ndc("doCheckAuthN");
@@ -234,17 +234,12 @@ pair<bool,void*> ShibTarget::doCheckAuthN(bool requireSessionFlag, bool handler)
             return pair<bool,void*>(true,returnDecline());
 
         pair<bool,bool> requireSession = m_priv->m_settings.first->getBool("requireSession");
-        if (!requireSession.first || !requireSession.second) {
-            // Web server might override.
-            if (requireSessionFlag)
-                requireSession.second=true;
-        }
 
         pair<string,const char*> shib_cookie = m_priv->getCookieNameProps("_shibsession_");
         const char* session_id = m_priv->getCookie(this,shib_cookie.first);
         if (!session_id || !*session_id) {
             // No session.  Maybe that's acceptable?
-            if (!requireSession.second)
+            if (!requireSession.first || !requireSession.second)
                 return pair<bool,void*>(true,returnOK());
 
             // No cookie, but we require a session. Initiate a new session using the default method.
@@ -270,7 +265,7 @@ pair<bool,void*> ShibTarget::doCheckAuthN(bool requireSessionFlag, bool handler)
             log(LogLevelError, string("session processing failed: ") + e.what());
 
             // If no session is required, bail now.
-            if (!requireSession.second)
+            if (!requireSession.first || !requireSession.second)
                 // Has to be OK because DECLINED will just cause Apache
                 // to fail when it can't locate anything to process the
                 // AuthType.  No session plus requireSession false means
@@ -357,7 +352,7 @@ pair<bool,void*> ShibTarget::doHandler(void)
                 procState = "Session Creation Error";
                 return m_priv->doAssertionConsumer(this,handler);
             }
-            else if (saml::XML::isElementNamed(handler->getElement(),ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(SessionInitiator))) {
+            else if (saml::XML::isElementNamed(handler->getElement(),shibtarget::XML::SHIBTARGET_NS,SHIBT_L(SessionInitiator))) {
                 procState = "Session Initiator Error";
                 return m_priv->doSessionInitiator(this,handler);
             }
@@ -429,206 +424,27 @@ pair<bool,void*> ShibTarget::doCheckAuthZ(void)
         if (!m_priv->m_app)
             throw ConfigurationException("System uninitialized, application did not supply request information.");
 
+        string auth_type = getAuthType();
+        if (strcasecmp(auth_type.c_str(),"shibboleth"))
+            return make_pair(true,returnDecline());
+
         // 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_provider_id.c_str(), m_priv->m_sso_statement, m_priv->m_post_response, this)) {
-                log(LogLevelWarn, "doCheckAuthZ() access control provider denied access");
+            if (m_priv->m_settings.second->authorized(this,m_priv->m_provider_id.c_str(), m_priv->m_sso_statement, m_priv->m_post_response)) {
+                // Let the caller decide how to proceed.
+                log(LogLevelDebug, "doCheckAuthZ: access control provider granted access");
+                return pair<bool,void*>(false,NULL);
+            }
+            else {
+                log(LogLevelWarn, "doCheckAuthZ: access control provider denied access");
                 if (targetURL)
                     mlp.insert("requestURL", targetURL);
                 return make_pair(true,m_priv->sendError(this, "access", mlp));
             }
         }
-
-        // Perform HTAccess Checks
-        auto_ptr<HTAccessInfo> ht(getAccessInfo());
-
-        // No Info means OK.  Just return
-        if (!ht.get())
-            return pair<bool,void*>(false, NULL);
-
-        vector<bool> auth_OK(ht->elements.size(), false);
-        bool method_restricted=false;
-        string remote_user = getRemoteUser();
-
-#define CHECK_OK \
-    do { \
-        if (!ht->requireAll) { \
-            return pair<bool,void*>(false, NULL); \
-        } \
-        auth_OK[x] = true; \
-        continue; \
-    } while (0)
-
-        for (int x = 0; x < ht->elements.size(); x++) {
-            auth_OK[x] = false;
-            HTAccessInfo::RequireLine *line = ht->elements[x];
-            if (! line->use_line)
-                continue;
-            method_restricted = true;
-
-            const char *w = line->tokens[0].c_str();
-
-            if (!strcasecmp(w,"Shibboleth")) {
-                // This is a dummy rule needed because Apache conflates authn and authz.
-                // Without some require rule, AuthType is ignored and no check_user hooks run.
-                CHECK_OK;
-            }
-            else if (!strcmp(w,"valid-user")) {
-                log(LogLevelDebug, "doCheckAuthZ accepting valid-user");
-                CHECK_OK;
-            }
-            else if (!strcmp(w,"user") && !remote_user.empty()) {
-                bool regexp=false;
-                for (int i = 1; i < line->tokens.size(); i++) {
-                    w = line->tokens[i].c_str();
-                    if (*w == '~') {
-                        regexp = true;
-                        continue;
-                    }
-                
-                    if (regexp) {
-                        try {
-                            // To do regex matching, we have to convert from UTF-8.
-                            auto_ptr<XMLCh> trans(fromUTF8(w));
-                            RegularExpression re(trans.get());
-                            auto_ptr<XMLCh> trans2(fromUTF8(remote_user.c_str()));
-                            if (re.matches(trans2.get())) {
-                                log(LogLevelDebug, string("doCheckAuthZ accepting user: ") + w);
-                                CHECK_OK;
-                            }
-                        }
-                        catch (XMLException& ex) {
-                            auto_ptr_char tmp(ex.getMessage());
-                            log(LogLevelError, string("doCheckAuthZ caught exception while parsing regular expression (")
-                              + w + "): " + tmp.get());
-                        }
-                    }
-                    else if (!strcmp(remote_user.c_str(), w)) {
-                        log(LogLevelDebug, string("doCheckAuthZ accepting user: ") + w);
-                        CHECK_OK;
-                    }
-                }
-            }
-            else if (!strcmp(w,"group")) {
-                auto_ptr<HTGroupTable> grpstatus(getGroupTable(remote_user));
-                if (!grpstatus.get()) {
-                    return pair<bool,void*>(true, returnDecline());
-                }
-    
-                for (int i = 1; i < line->tokens.size(); i++) {
-                    w = line->tokens[i].c_str();
-                    if (grpstatus->lookup(w)) {
-                        log(LogLevelDebug, string("doCheckAuthZ accepting group: ") + w);
-                        CHECK_OK;
-                    }
-                }
-            }
-            else {
-                Iterator<IAAP*> provs = m_priv->m_app->getAAPProviders();
-                AAP wrapper(provs, w);
-                if (wrapper.fail()) {
-                    log(LogLevelWarn, string("doCheckAuthZ didn't recognize require rule: ") + w);
-                    continue;
-                }
-
-                bool regexp = false;
-                string vals = getHeader(wrapper->getHeader());
-                for (int i = 1; i < line->tokens.size() && !vals.empty(); i++) {
-                    w = line->tokens[i].c_str();
-                    if (*w == '~') {
-                        regexp = true;
-                        continue;
-                    }
-
-                    try {
-                        auto_ptr<RegularExpression> re;
-                        if (regexp) {
-                            delete re.release();
-                            auto_ptr<XMLCh> trans(fromUTF8(w));
-                            auto_ptr<RegularExpression> temp(new RegularExpression(trans.get()));
-                            re=temp;
-                        }
-                    
-                        string vals_str(vals);
-                        int j = 0;
-                        for (int i = 0;  i < vals_str.length();  i++) {
-                            if (vals_str.at(i) == ';') {
-                                if (i == 0) {
-                                    log(LogLevelError, string("doCheckAuthZ invalid header encoding") +
-                                        vals + ": starts with a semicolon");
-                                    throw SAMLException("Invalid information supplied to authorization module.");
-                                }
-
-                                if (vals_str.at(i-1) == '\\') {
-                                    vals_str.erase(i-1, 1);
-                                    i--;
-                                    continue;
-                                }
-
-                                string val = vals_str.substr(j, i-j);
-                                j = i+1;
-                                if (regexp) {
-                                    auto_ptr<XMLCh> trans(fromUTF8(val.c_str()));
-                                    if (re->matches(trans.get())) {
-                                        log(LogLevelDebug, string("doCheckAuthZ expecting ") + w +
-                                          ", got " + val + ": authorization granted");
-                                        CHECK_OK;
-                                    }
-                                }
-                                else if ((wrapper->getCaseSensitive() && val==w) ||
-                                        (!wrapper->getCaseSensitive() && !strcasecmp(val.c_str(),w))) {
-                                    log(LogLevelDebug, string("doCheckAuthZ expecting ") + w +
-                                        ", got " + val + ": authorization granted.");
-                                    CHECK_OK;
-                                }
-                                else {
-                                    log(LogLevelDebug, string("doCheckAuthZ expecting ") + w +
-                                        ", got " + val + ": authoritzation not granted.");
-                                }
-                            }
-                        }
-    
-                        string val = vals_str.substr(j, vals_str.length()-j);
-                        if (regexp) {
-                            auto_ptr<XMLCh> trans(fromUTF8(val.c_str()));
-                            if (re->matches(trans.get())) {
-                                log(LogLevelDebug, string("doCheckAuthZ expecting ") + w +
-                                    ", got " + val + ": authorization granted.");
-                                CHECK_OK;
-                            }
-                        }
-                        else if ((wrapper->getCaseSensitive() && val==w) ||
-                                (!wrapper->getCaseSensitive() && !strcasecmp(val.c_str(),w))) {
-                            log(LogLevelDebug, string("doCheckAuthZ expecting ") + w +
-                                ", got " + val + ": authorization granted");
-                            CHECK_OK;
-                        }
-                        else {
-                            log(LogLevelDebug, string("doCheckAuthZ expecting ") + w +
-                                ", got " + val + ": authorization not granted");
-                        }
-                    }
-                    catch (XMLException& ex) {
-                        auto_ptr_char tmp(ex.getMessage());
-                            log(LogLevelError, string("doCheckAuthZ caught exception while parsing regular expression (")
-                                + w + "): " + tmp.get());
-                    }
-                }
-            }
-        } // for x
-
-
-        // check if all require directives are true
-        bool auth_all_OK = true;
-        for (int i = 0; i < ht->elements.size(); i++) {
-            auth_all_OK &= auth_OK[i];
-        }
-
-        if (auth_all_OK || !method_restricted)
-            return pair<bool,void*>(false, NULL);
-
-        // If we get here there's an access error, so just fall through
+        else
+            return make_pair(true,returnDecline());
     }
     catch (SAMLException& e) {
         mlp.insert(e);
@@ -648,7 +464,7 @@ pair<bool,void*> ShibTarget::doCheckAuthZ(void)
     return make_pair(true,m_priv->sendError(this, "access", mlp));
 }
 
-pair<bool,void*> ShibTarget::doExportAssertions(bool exportAssertion)
+pair<bool,void*> ShibTarget::doExportAssertions()
 {
 #ifdef _DEBUG
     saml::NDC ndc("doExportAssertions");
@@ -697,10 +513,7 @@ pair<bool,void*> ShibTarget::doExportAssertions(bool exportAssertion)
         // Maybe export the first assertion.
         clearHeader("Shib-Attributes");
         pair<bool,bool> exp=m_priv->m_settings.first->getBool("exportAssertion");
-        if (!exp.first || !exp.second)
-            if (exportAssertion)
-                exp.second=true;
-        if (exp.second && m_priv->m_pre_response) {
+        if (exp.first && exp.second && m_priv->m_pre_response) {
             ostringstream os;
             os << *(m_priv->m_pre_response);
             unsigned int outlen;
@@ -1194,23 +1007,20 @@ void ShibTargetPriv::get_application(ShibTarget* st, const string& protocol, con
   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(),st);
+  m_settings = m_mapper->getSettings(st);
 
   // Now find the application from the URL settings
   pair<bool,const char*> application_id=m_settings.first->getString("applicationId");
-  const IApplication* application=m_conf->getApplication(application_id.second);
-  if (!application) {
+  m_app=m_conf->getApplication(application_id.second);
+  if (!m_app) {
     m_mapper->unlock();
     m_mapper = NULL;
     m_conf->unlock();
     m_conf = NULL;
-    throw SAMLException("Unable to map request to application settings, check configuration.");
+    throw ConfigurationException("Unable to map request to application settings, check configuration.");
   }
 
-  // Store the application for later use
-  m_app = application;
-
-  // Compute the target URL
+  // Compute the full target URL
   st->m_url = protocol + "://" + hostname;
   if ((protocol == "http" && port != 80) || (protocol == "https" && port != 443))
     st->m_url += ":" + port;
@@ -1808,25 +1618,21 @@ string CgiParse::url_encode(const char* s)
     return ret;
 }
 // Subclasses may not need to override these particular virtual methods.
+const IApplication* ShibTarget::getApplication() const
+{
+    return m_priv->m_app;
+}
 string ShibTarget::getAuthType(void)
 {
-  return string("shibboleth");
+    return string("shibboleth");
 }
 void* ShibTarget::returnDecline(void)
 {
-  return NULL;
+    return NULL;
 }
 void* ShibTarget::returnOK(void)
 {
-  return NULL;
-}
-HTAccessInfo* ShibTarget::getAccessInfo(void)
-{
-  return NULL;
-}
-HTGroupTable* ShibTarget::getGroupTable(string &user)
-{
-  return NULL;
+    return NULL;
 }
 
 // CDC implementation
index e74e239..4eacf38 100644 (file)
@@ -114,10 +114,10 @@ namespace shibtarget {
     struct SHIBTARGET_EXPORTS IAccessControl : public virtual saml::ILockable, public virtual saml::IPlugIn
     {
         virtual bool authorized(
+            ShibTarget* st,
             const char* providerId,
             const saml::SAMLAuthenticationStatement* authn,
-            const saml::SAMLResponse* attrs,
-            ShibTarget* st
+            const saml::SAMLResponse* attrs
             ) const=0;
         virtual ~IAccessControl() {}
     };
@@ -125,10 +125,7 @@ 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, ShibTarget* st) const=0;
-        virtual Settings getSettingsFromParsedURL(
-            const char* scheme, const char* hostname, unsigned int port, const char* path, ShibTarget* st
-            ) const=0;
+        virtual Settings getSettings(ShibTarget* st) const=0;
         virtual ~IRequestMapper() {}
     };
     
@@ -244,7 +241,6 @@ namespace shibtarget {
         bool isEnabled(components_t feature) {return (m_features & feature)>0;}
         virtual IConfig* getINI() const {return m_ini;}
 
-        static const XMLCh SHIBTARGET_NS[];
         static ShibTargetConfig& getConfig();
 
     protected:
@@ -254,31 +250,6 @@ namespace shibtarget {
         unsigned long m_features;
     };
 
-  class HTAccessInfo {
-  public:
-    HTAccessInfo() {}
-    ~HTAccessInfo() {
-      for (int k = 0; k < elements.size(); k++)
-        delete elements[k];
-      elements.resize(0);
-    }
-
-    struct RequireLine {
-      bool use_line;
-      std::vector<std::string> tokens;
-    };
-    std::vector<RequireLine*> elements;
-    bool requireAll;
-  };
-
-  class HTGroupTable {
-  public:
-    virtual ~HTGroupTable() {}
-    virtual bool lookup(const char *entry) = 0;
-  protected:
-    HTGroupTable() {}
-  };
-
   class ShibTargetPriv;
   class SHIBTARGET_EXPORTS ShibTarget {
   public:
@@ -369,12 +340,6 @@ namespace shibtarget {
     // implementation always returns "shibboleth".
     virtual std::string getAuthType(void);
 
-    // Note: we still need to define exactly what kind of data in contained
-    // in the HTAccessInfo -- perhaps we can stub it out so non-htaccess
-    // systems have something they can plug in?
-    virtual HTAccessInfo* getAccessInfo(void);
-    virtual HTGroupTable* getGroupTable(std::string &user);
-
     // We're done.  Finish up.  Send specific result content or a redirect.
     // If there are no headers supplied assume the content-type is text/html
     typedef std::pair<std::string, std::string> header_t;
@@ -416,18 +381,14 @@ namespace shibtarget {
     //   is not valid, and the caller should continue processing (the API Call
     //   finished successfully).
     //
-    //   The arguments are all overrides..  The requireSession and
-    //   exportAssertion values passed in here are only used if the
-    //   settings resource is negative.
-    //
     //   The handleProfile argument declares whether doCheckAuthN() should
     //   automatically call doHandlePOST() when it encounters a request for
     //   the ShireURL;  if false it will call returnOK() instead.
     //
-    std::pair<bool,void*> doCheckAuthN(bool requireSession = false, bool handler = false);
+    std::pair<bool,void*> doCheckAuthN(bool handler = false);
     std::pair<bool,void*> doHandler();
     std::pair<bool,void*> doCheckAuthZ();
-    std::pair<bool,void*> doExportAssertions(bool exportAssertion = false);
+    std::pair<bool,void*> doExportAssertions();
 
     // Currently wraps remoted interface.
     // TODO: Move this functionality behind IListener
@@ -454,6 +415,7 @@ namespace shibtarget {
     void sessionEnd(const char* cookie) const;
 
     // Basic request access in case any plugins need the info
+    virtual const IApplication* getApplication() const;
     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();}
@@ -491,6 +453,95 @@ namespace shibtarget {
     mutable ShibTargetPriv* m_priv;
     friend class ShibTargetPriv;
   };
+
+    struct SHIBTARGET_EXPORTS XML
+    {
+        static const XMLCh SHIBTARGET_NS[];
+        static const XMLCh SHIBTARGET_SCHEMA_ID[];
+        static const XMLCh SAML2ASSERT_NS[];
+        static const XMLCh SAML2ASSERT_SCHEMA_ID[];
+        static const XMLCh SAML2META_NS[];
+        static const XMLCh SAML2META_SCHEMA_ID[];
+        static const XMLCh XMLENC_NS[];
+        static const XMLCh XMLENC_SCHEMA_ID[];
+    
+        // Session cache implementations
+        static const char MemorySessionCacheType[];
+        static const char MySQLSessionCacheType[];
+        
+        // Replay cache implementations
+        static const char MySQLReplayCacheType[];
+        
+        // Request mapping/settings implementations
+        static const char XMLRequestMapType[];      // portable XML-based map
+        static const char ApacheRequestMapType[];   // Apache command override of XML-based map
+        static const char LegacyRequestMapType[];   // older designation of XML map, hijacked by Apache
+        
+        // Access control implementations
+        static const char htAccessControlType[];    // Apache-specific .htaccess authz module
+        static const char XMLAccessControlType[];   // Proprietary but portable XML authz syntax
+
+        // Out of process listener implementations
+        static const char TCPListenerType[];        // ONC RPC via TCP socket
+        static const char UnixListenerType[];       // ONC RPC via domain socker
+        static const char NullListenerType[];       // "faked" in-process marshalling
+    
+        struct SHIBTARGET_EXPORTS Literals
+        {
+            static const XMLCh AAPProvider[];
+            static const XMLCh AccessControl[];
+            static const XMLCh AccessControlProvider[];
+            static const XMLCh AND[];
+            static const XMLCh applicationId[];
+            static const XMLCh Application[];
+            static const XMLCh Applications[];
+            static const XMLCh AssertionConsumerService[];
+            static const XMLCh CredentialsProvider[];
+            static const XMLCh CredentialUse[];
+            static const XMLCh Extensions[];
+            static const XMLCh fatal[];
+            static const XMLCh FederationProvider[];
+            static const XMLCh Global[];
+            static const XMLCh Host[];
+            static const XMLCh htaccess[];
+            static const XMLCh Implementation[];
+            static const XMLCh index[];
+            static const XMLCh isDefault[];
+            static const XMLCh Library[];
+            static const XMLCh Listener[];
+            static const XMLCh Local[];
+            static const XMLCh logger[];
+            static const XMLCh MemorySessionCache[];
+            static const XMLCh MetadataProvider[];
+            static const XMLCh MySQLReplayCache[];
+            static const XMLCh MySQLSessionCache[];
+            static const XMLCh name[];
+            static const XMLCh Name[];
+            static const XMLCh NOT[];
+            static const XMLCh OR[];
+            static const XMLCh Path[];
+            static const XMLCh path[];
+            static const XMLCh RelyingParty[];
+            static const XMLCh ReplayCache[];
+            static const XMLCh RequestMap[];
+            static const XMLCh RequestMapProvider[];
+            static const XMLCh require[];
+            static const XMLCh Rule[];
+            static const XMLCh SessionCache[];
+            static const XMLCh SessionInitiator[];
+            static const XMLCh SHAR[];
+            static const XMLCh ShibbolethTargetConfig[];
+            static const XMLCh SHIRE[];
+            static const XMLCh Signing[];
+            static const XMLCh SingleLogoutService[];
+            static const XMLCh SPConfig[];
+            static const XMLCh TCPListener[];
+            static const XMLCh TLS[];
+            static const XMLCh TrustProvider[];
+            static const XMLCh type[];
+            static const XMLCh UnixListener[];
+        };
+    };
 }
 
 #endif /* SHIB_TARGET_H */