Next integration phase, metadata and trust conversion.
[shibboleth/cpp-sp.git] / shib-target / shib-target.h
index 422ca4c..808f7ef 100644 (file)
@@ -1,50 +1,17 @@
 /*
- * The Shibboleth License, Version 1.
- * Copyright (c) 2002
- * University Corporation for Advanced Internet Development, Inc.
- * All rights reserved
+ *  Copyright 2001-2005 Internet2
  *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution, if any, must include
- * the following acknowledgment: "This product includes software developed by
- * the University Corporation for Advanced Internet Development
- * <http://www.ucaid.edu>Internet2 Project. Alternately, this acknowledegement
- * may appear in the software itself, if and wherever such third-party
- * acknowledgments normally appear.
- *
- * Neither the name of Shibboleth nor the names of its contributors, nor
- * Internet2, nor the University Corporation for Advanced Internet Development,
- * Inc., nor UCAID may be used to endorse or promote products derived from this
- * software without specific prior written permission. For written permission,
- * please contact shibboleth@shibboleth.org
- *
- * Products derived from this software may not be called Shibboleth, Internet2,
- * UCAID, or the University Corporation for Advanced Internet Development, nor
- * may Shibboleth appear in their name, without prior written permission of the
- * University Corporation for Advanced Internet Development.
- *
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
- * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK
- * OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY
- * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 /*
 #ifndef SHIB_TARGET_H
 #define SHIB_TARGET_H
 
-#ifdef __cplusplus
-# include <saml/saml.h>
-# include <shib/shib.h>
-#endif
+// New headers
+#include <shibsp/base.h>
+#include <shibsp/ListenerService.h>
+#include <shibsp/PropertySet.h>
+#include <saml/saml2/metadata/MetadataProvider.h>
+#include <xmltooling/security/TrustEngine.h>
+
+// Old headers
+#include <saml/saml.h>
+#include <shib/shib.h>
 
 #ifdef WIN32
 # ifndef SHIBTARGET_EXPORTS
 #  define SHIBTARGET_EXPORTS __declspec(dllimport)
 # endif
+# define SHIB_SCHEMAS "/opt/shibboleth-sp/share/xml/shibboleth"
+# define SHIB_CONFIG "/opt/shibboleth-sp/etc/shibboleth/shibboleth.xml"
 #else
+# include <shib-target/shib-paths.h>
 # define SHIBTARGET_EXPORTS
 #endif
 
-#include <shib-target/shibrpc.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef WIN32
-
-#include <winsock.h>
-typedef SOCKET ShibSocket;
-typedef u_short ShibSockName;
-#define SHIB_SHAR_SOCKET 12345  /* shar portnumber */
-
-#else  /* UNIX */
-
-typedef int ShibSocket;
-typedef char * ShibSockName;
-#define SHIB_SHAR_SOCKET "/tmp/shar-socket"
-
-#endif
-
-/* shib-rpcutil.c */
-
-/* Create an RPC Client handle for the _connected_ socket sock, attaching
- * the RPC program and version.
- *
- * returns a CLIENT on success, or NULL on error.  The caller can
- * call clnt_pcreateerror ("<string>") to output an error message from
- * the RPC library.
- */
-SHIBTARGET_EXPORTS CLIENT * shibrpc_client_create (ShibSocket sock, u_long program, u_long version);
-
-/* shib-sock.c */
-
-/* Create a new socket and put it into sock.
- *
- * Returns 0 on success, non-zero on error 
- */
-SHIBTARGET_EXPORTS int shib_sock_create (ShibSocket *sock);
-
-/*
- * bind the socket s to the "port" name.
- *
- * Returns 0 on success; non-zero on error.
- *
- * SIDE EFFECT: On error, the socket is closed!
- */
-SHIBTARGET_EXPORTS int shib_sock_bind (ShibSocket s, ShibSockName name);
-
-/*
- * connect the socket s to the "port" name on the local host.
- *
- * Returns 0 on success; non-zero on error.
- */
-SHIBTARGET_EXPORTS int shib_sock_connect (ShibSocket s, ShibSockName name);
-
-/*
- * accept a connection.  Returns 0 on success, non-zero on failure.
- */
-SHIBTARGET_EXPORTS int shib_sock_accept (ShibSocket listener, ShibSocket* s);
-
-/*
- * close the socket
- */
-SHIBTARGET_EXPORTS void shib_sock_close (ShibSocket s, ShibSockName name);
-
-/* shib-target.cpp */
+namespace shibtarget {
+  
+    // Abstract APIs for access to configuration information
+    
+    // Forward declaration
+    class SHIBTARGET_EXPORTS ShibTarget;
+
+    /**
+     * Interface to a protocol handler
+     * 
+     * Protocol handlers perform system functions such as processing SAML protocol
+     * messages to create and logout sessions or creating protocol requests.
+     */
+    struct SHIBTARGET_EXPORTS IHandler : public virtual saml::IPlugIn
+    {
+        IHandler() : m_props(NULL) {}
+        virtual ~IHandler() {}
+        virtual const shibsp::PropertySet* getProperties() const { return m_props; }
+        virtual void setProperties(const shibsp::PropertySet* properties) { m_props=properties; }
+        virtual std::pair<bool,void*> run(ShibTarget* st, bool isHandler=true) const=0;
+    private:
+        const shibsp::PropertySet* m_props;
+    };
+    
+    /**
+     * Interface to Shibboleth Applications, which exposes most of the functionality
+     * required to process web requests or security protocol messages for resources
+     * associated with them.
+     * 
+     * Applications are implementation-specific, but generally correspond to collections
+     * of resources related to one another in logical ways, such as a virtual host or
+     * a Java servlet context. Most complex configuration data is associated with an
+     * Application. Implementations should always expose an application named "default"
+     * as a last resort.
+     */
+    struct SHIBTARGET_EXPORTS IApplication : public virtual shibsp::PropertySet,
+        public virtual shibboleth::ShibBrowserProfile::ITokenValidator
+    {
+        virtual const char* getId() const=0;
+        virtual const char* getHash() const=0;
+        
+        virtual saml::Iterator<saml::SAMLAttributeDesignator*> getAttributeDesignators() const=0;
+        virtual saml::Iterator<shibboleth::IAAP*> getAAPProviders() const=0;
+        virtual opensaml::saml2md::MetadataProvider* getMetadataProvider() const=0;
+        virtual xmltooling::TrustEngine* getTrustEngine() const=0;
+        virtual saml::Iterator<const XMLCh*> getAudiences() const=0;
+        virtual const shibsp::PropertySet* getCredentialUse(const opensaml::saml2md::EntityDescriptor* provider) const=0;
+
+        // caller is borrowing object, must use within scope of config lock
+        virtual const saml::SAMLBrowserProfile* getBrowserProfile() const=0;
+        virtual const saml::SAMLBinding* getBinding(const XMLCh* binding) const=0;
+
+        // caller is given ownership of object, must use and delete within scope of config lock
+        virtual saml::SAMLBrowserProfile::ArtifactMapper* getArtifactMapper() const=0;
+
+        // general token validation based on conditions, signatures, etc.
+        virtual void validateToken(
+            saml::SAMLAssertion* token,
+            time_t t=0,
+            const opensaml::saml2md::RoleDescriptor* role=NULL,
+            const xmltooling::TrustEngine* trust=NULL
+            ) const=0;
+
+        // Used to locate a default or designated session initiator for automatic sessions
+        virtual const IHandler* getDefaultSessionInitiator() const=0;
+        virtual const IHandler* getSessionInitiatorById(const char* id) const=0;
+        
+        // Used by session initiators to get endpoint to forward to IdP/WAYF
+        virtual const IHandler* getDefaultAssertionConsumerService() const=0;
+        virtual const IHandler* getAssertionConsumerServiceByIndex(unsigned short index) const=0;
+        virtual saml::Iterator<const IHandler*> getAssertionConsumerServicesByBinding(const XMLCh* binding) const=0;
+        
+        // Used by dispatcher to locate the handler for a request
+        virtual const IHandler* getHandler(const char* path) const=0;
+
+        virtual ~IApplication() {}
+    };
 
-/* application names */
-#define SHIBTARGET_GENERAL  "general"
-#define SHIBTARGET_SHAR     "shar"
-#define SHIBTARGET_SHIRE    "shire"
-#define SHIBTARGET_RM       "rm"
-#define SHIBTARGET_POLICIES "policies"
+    /**
+     * OpenSAML binding hook
+     *
+     * Instead of wrapping the binding to deal with mutual authentication, we
+     * just use the HTTP hook functionality offered by OpenSAML. The hook will
+     * register "itself" as a globalCtx pointer with the SAML binding and the caller
+     * will declare and pass the embedded struct as callCtx for use by the hook.
+     */
+    class ShibHTTPHook : virtual public saml::SAMLSOAPHTTPBinding::HTTPHook
+    {
+    public:
+        ShibHTTPHook(const xmltooling::TrustEngine* trust, const saml::Iterator<shibboleth::ICredentials*>& creds)
+            : m_trust(trust), m_creds(creds) {}
+        virtual ~ShibHTTPHook() {}
+        
+        // Only hook we need here is for outgoing connection to server.
+        virtual bool outgoing(saml::HTTPClient* conn, void* globalCtx=NULL, void* callCtx=NULL);
+
+        // Client declares a context object and pass as callCtx to send() method.
+        class ShibHTTPHookCallContext {
+        public:
+            ShibHTTPHookCallContext(const shibsp::PropertySet* credUse, const opensaml::saml2md::RoleDescriptor* role)
+                : m_credUse(credUse), m_role(role), m_hook(NULL), m_authenticated(false) {}
+            const ShibHTTPHook* getHook() {return m_hook;}
+            const shibsp::PropertySet* getCredentialUse() {return m_credUse;}
+            const opensaml::saml2md::RoleDescriptor* getRoleDescriptor() {return m_role;}
+            bool isAuthenticated() const {return m_authenticated;}
+            void setAuthenticated() {m_authenticated=true;}
+            
+        private:
+            const shibsp::PropertySet* m_credUse;
+            const opensaml::saml2md::RoleDescriptor* m_role;
+            ShibHTTPHook* m_hook;
+            bool m_authenticated;
+            friend class ShibHTTPHook;
+        };
+        
+        const xmltooling::TrustEngine* getTrustEngine() const {return m_trust;}
+        const saml::Iterator<shibboleth::ICredentials*>& getCredentialProviders() const {return m_creds;}
+    private:
+        const xmltooling::TrustEngine* m_trust;
+        saml::Iterator<shibboleth::ICredentials*> m_creds;
+    };
 
-/* configuration tags */
-#define SHIBTARGET_TAG_LOGGER   "logger"
-#define SHIBTARGET_TAG_SCHEMAS  "schemadir"
-#define SHIBTARGET_TAG_CERTFILE "certfile"
-#define SHIBTARGET_TAG_KEYFILE  "keyfile"
-#define SHIBTARGET_TAG_KEYPASS  "keypass"
-#define SHIBTARGET_TAG_CALIST   "calist"
+    /**
+     * Interface to a cached user session.
+     * 
+     * Cache entries provide implementations with access to the raw SAML information they
+     * need to publish or provide access to the data for applications to use. All creation
+     * or access to entries is through the ISessionCache interface, and callers must unlock
+     * the entry when finished using it, rather than explicitly freeing them.
+     */
+    struct SHIBTARGET_EXPORTS ISessionCacheEntry : public virtual saml::ILockable
+    {
+        virtual const char* getClientAddress() const=0;
+        virtual const char* getProviderId() const=0;
+        virtual std::pair<const char*,const saml::SAMLSubject*> getSubject(bool xml=true, bool obj=false) const=0;
+        virtual const char* getAuthnContext() const=0;
+        virtual std::pair<const char*,const saml::SAMLResponse*> getTokens(bool xml=true, bool obj=false) const=0;
+        virtual std::pair<const char*,const saml::SAMLResponse*> getFilteredTokens(bool xml=true, bool obj=false) const=0;
+        virtual ~ISessionCacheEntry() {}
+    };
 
-#define SHIBTARGET_TAG_AATIMEOUT    "AATimeout"
-#define SHIBTARGET_TAG_AACONNECTTO  "AAConnectTimeout"
-#define SHIBTARGET_TAG_SAMLCOMPAT   "SAMLCompat"
+    /**
+     * Interface to a sink for session cache events.
+     *
+     * All caches support registration of a backing store that can be informed
+     * of significant events in the lifecycle of a cache entry.
+     */
+    struct SHIBTARGET_EXPORTS ISessionCacheStore
+    {
+        virtual HRESULT onCreate(
+            const char* key,
+            const IApplication* application,
+            const ISessionCacheEntry* entry,
+            int majorVersion,
+            int minorVersion,
+            time_t created
+            )=0;
+        virtual HRESULT onRead(
+            const char* key,
+            std::string& applicationId,
+            std::string& clientAddress,
+            std::string& providerId,
+            std::string& subject,
+            std::string& authnContext,
+            std::string& tokens,
+            int& majorVersion,
+            int& minorVersion,
+            time_t& created,
+            time_t& accessed
+            )=0;
+        virtual HRESULT onRead(const char* key, time_t& accessed)=0;
+        virtual HRESULT onRead(const char* key, std::string& tokens)=0;
+        virtual HRESULT onUpdate(const char* key, const char* tokens=NULL, time_t lastAccess=0)=0;
+        virtual HRESULT onDelete(const char* key)=0;
+        virtual ~ISessionCacheStore() {}
+    };
 
-#define SHIBTARGET_TAG_METADATA "metadata"
+    /**
+     * Interface to the session cache.
+     * 
+     * The session cache abstracts a persistent (meaning across requests) cache of
+     * instances of the ISessionCacheEntry interface. Creation of new entries and entry
+     * lookup are confined to this interface to enable implementations to flexibly
+     * remote and/or optimize calls by implementing custom versions of the
+     * ISessionCacheEntry interface as required.
+     */
+    struct SHIBTARGET_EXPORTS ISessionCache : public virtual saml::IPlugIn
+    {
+        virtual std::string insert(
+            const IApplication* application,
+            const opensaml::saml2md::RoleDescriptor* source,
+            const char* client_addr,
+            const saml::SAMLSubject* subject,
+            const char* authnContext,
+            const saml::SAMLResponse* tokens
+            )=0;
+        virtual ISessionCacheEntry* find(
+            const char* key, const IApplication* application, const char* client_addr
+            )=0;
+        virtual void remove(
+            const char* key, const IApplication* application, const char* client_addr
+            )=0;
+
+        virtual bool setBackingStore(ISessionCacheStore* store)=0;
+        virtual ~ISessionCache() {}
+    };
 
-#define SHIBTARGET_TAG_DEFAULTLIFE  "defaultLife"
+    /**
+     * Interface to an access control plugin
+     * 
+     * Access control plugins return authorization decisions based on the intersection
+     * of the resource request and the active session. They can be implemented through
+     * cross-platform or platform-specific mechanisms.
+     */
+    struct SHIBTARGET_EXPORTS IAccessControl : public virtual saml::ILockable, public virtual saml::IPlugIn
+    {
+        virtual bool authorized(ShibTarget* st, ISessionCacheEntry* entry) const=0;
+        virtual ~IAccessControl() {}
+    };
 
-#define SHIBTARGET_TAG_CACHETYPE    "cacheType"
-#define SHIBTARGET_TAG_CACHECLEAN   "cacheClean"
-#define SHIBTARGET_TAG_CACHETIMEOUT "cacheTimeout"
+    /**
+     * Interface to a request mapping plugin
+     * 
+     * Request mapping plugins return configuration settings that apply to resource requests.
+     * They can be implemented through cross-platform or platform-specific mechanisms.
+     */
+    struct SHIBTARGET_EXPORTS IRequestMapper : public virtual saml::ILockable, public virtual saml::IPlugIn
+    {
+        typedef std::pair<const shibsp::PropertySet*,IAccessControl*> Settings;
+        virtual Settings getSettings(ShibTarget* st) const=0;
+        virtual ~IRequestMapper() {}
+    };
+    
+    struct SHIBTARGET_EXPORTS IConfig : public virtual saml::ILockable, public virtual shibsp::PropertySet, public virtual saml::IPlugIn
+    {
+        // loads initial configuration
+        virtual void init()=0;
+
+        virtual shibsp::ListenerService* getListener() const=0;
+        virtual ISessionCache* getSessionCache() const=0;
+        virtual saml::IReplayCache* getReplayCache() const=0;
+        virtual IRequestMapper* getRequestMapper() const=0;
+        virtual const IApplication* getApplication(const char* applicationId) const=0;
+        virtual saml::Iterator<shibboleth::ICredentials*> getCredentialsProviders() const=0;
+        virtual ~IConfig() {}
+    };
 
-#define SHIBTARGET_TAG_REQATTRS     "requestAttributes"
+    class SHIBTARGET_EXPORTS ShibTargetConfig
+    {
+    public:
+        ShibTargetConfig() : m_ini(NULL) {}
+        virtual ~ShibTargetConfig() {}
+        
+        virtual bool init(const char* schemadir) = 0;
+        virtual bool load(const char* config) = 0;
+        virtual void shutdown() = 0;
 
-/* initialize and finalize the target library (return 0 on success, 1 on failure) */
-SHIBTARGET_EXPORTS int shib_target_initialize (const char* application, const char* ini_file);
-SHIBTARGET_EXPORTS void shib_target_finalize (void);
-SHIBTARGET_EXPORTS ShibSockName shib_target_sockname(void);
+        virtual IConfig* getINI() const {return m_ini;}
 
-#ifdef __cplusplus
-}
+        static ShibTargetConfig& getConfig();
 
+    protected:
+        IConfig* m_ini;
+    };
 
-namespace shibtarget {
-  class ResourcePriv;
-  class SHIBTARGET_EXPORTS Resource
-  {
-  public:
-    Resource(const char* resource_url);
-    Resource(std::string resource_url);
-    ~Resource();
-
-    const char* getResource() const;
-    const char* getURL() const;
-    bool equals(Resource*) const;
-    saml::Iterator<saml::SAMLAttribute*> getDesignators() const;
-
-  private:
-    ResourcePriv *m_priv;
-  };
-
-  class RPCHandleInternal;
-  class SHIBTARGET_EXPORTS RPCHandle
-  {
-  public:
-    RPCHandle(ShibSockName shar, u_long program, u_long version);
-    ~RPCHandle();
-
-    CLIENT *   connect(void);  /* locks the HANDLE and returns the CLIENT */
-    void       release(void);  /* unlocks the HANDLE */
-    void       disconnect(void); /* disconnects */
-
-  private:
-    RPCHandleInternal *m_priv;
-  };
-
-  class SHIBTARGET_EXPORTS ShibTargetException : public std::exception
-  {
-  public:
-    explicit ShibTargetException() { m_code = SHIBRPC_OK; }
-    explicit ShibTargetException(ShibRpcStatus code, const char* msg,
-                                const XMLCh* origin = NULL)
-       { m_code = code; if (msg) m_msg=msg; if (origin) m_origin = origin; }
-    explicit ShibTargetException(ShibRpcStatus code, const std::string& msg,
-                                const XMLCh* origin = NULL) : m_msg(msg)
-       { m_code=code; if(origin) m_origin = origin; }
-    virtual ~ShibTargetException() throw () {}
-    virtual const char* what() const throw () { return (m_msg.c_str()); }
-    virtual ShibRpcStatus which() const throw () { return (m_code); }
-    virtual const XMLCh* where() const throw () { return m_origin.c_str(); }
-
-  private:
-    ShibRpcStatus      m_code;
-    std::string                m_msg;
-    saml::xstring      m_origin;
-  };
-
-  class RPCErrorPriv;
-  class SHIBTARGET_EXPORTS RPCError
-  {
-  public:
-    RPCError() { init(0, "", NULL); }
-    RPCError(ShibRpcError* error);
-    RPCError(int s, char const* st, const XMLCh* orig = NULL) { init (s,st,orig); }
-    RPCError(ShibTargetException &exp) { init(exp.which(), exp.what(), exp.where()); }
-    ~RPCError();
-
-    bool       isError();
-    bool       isRetryable();
-
-    // Return a set of strings that corresponds to the type, text, and desc
-    const char* getType();
-    const char* getText();
-    const char* getDesc();
-    std::string getOriginErrorURL();
-    std::string getOriginContactName();
-    std::string getOriginContactEmail();
-    int getCode();
-
-  private:
-    void init(int stat, char const* msg, const XMLCh* origin);
-    RPCErrorPriv* m_priv;
-  };
-
-  class SHIBTARGET_EXPORTS SHIREConfig
-  {
-  public:
-    bool       checkIPAddress;
-    time_t     lifetime;
-    time_t     timeout;
-  };
-
-  class SHIREPriv;
-  class SHIBTARGET_EXPORTS SHIRE
-  {
-  public:
-    SHIRE(RPCHandle *rpc, SHIREConfig config, std::string shire_url);
-    ~SHIRE();
-
-    RPCError* sessionIsValid(const char* cookie, const char* ip, const char* url);
-    RPCError* sessionCreate(const char* post, const char* ip,
-                            std::string &cookie);
-  private:
-    SHIREPriv *m_priv;
-  };
-
-  class SHIBTARGET_EXPORTS RMConfig
-  {
-  public:
-    bool       checkIPAddress;
-  };
-
-  class RMPriv;
-  class SHIBTARGET_EXPORTS RM
-  {
-  public:
-    RM(RPCHandle *rpc, RMConfig config);
-    ~RM();
-
-    RPCError* getAssertions(const char* cookie, const char* ip,
-                           const char* url,
-                           std::vector<saml::SAMLAssertion*> &assertions,
-                           saml::SAMLAuthenticationStatement **statement = NULL);
-    static void serialize(saml::SAMLAssertion &assertion, std::string &result);
-    static saml::Iterator<saml::SAMLAttribute*> getAttributes(saml::SAMLAssertion &assertion);
-  private:
-    RMPriv *m_priv;
-  };
-
-  class ShibINIPriv;
-  class SHIBTARGET_EXPORTS ShibINI {
-  public:
-    ShibINI (std::string& file, bool case_sensitive = true) { init(file,case_sensitive); }
-    ShibINI (const char *file, bool case_sensitive = true) {
-      std::string f = file;
-      init(f, case_sensitive);
-    }
-    ~ShibINI ();
-
-    void refresh(void);
-
-    const std::string get (const std::string& header, const std::string& tag);
-    const std::string get (const char* header, const char* tag) {
-      std::string h = header, t = tag;
-      return get(h,t);
-    }
-
-    const std::string operator() (const std::string& header, const std::string& tag)  {
-      return get(header,tag);
-    }
-    const std::string operator() (const char* header, const char* tag) {
-      std::string h = header, t = tag;
-      return get(h,t);
-    }
-
-    bool exists(const std::string& header);
-    bool exists(const std::string& header, const std::string& tag);
-
-    bool exists(const char* header) {
-      std::string s = header;
-      return exists(s);
-    }
-    bool exists(const char* header, const char* tag) {
-      std::string h = header, t = tag;
-      return exists(h,t);
-    }
-
-    // Special method to look for a tag in one header and maybe in the
-    // 'SHIBTARGET_GENERAL' header
-    bool get_tag(std::string& header, std::string& tag, bool try_general,
-                std::string* result);
-
-    bool get_tag(std::string& header, const char* tag, bool try_general,
-                std::string* result) {
-      std::string t = tag;
-      return get_tag (header,t,try_general,result);
-    }
-
-    bool get_tag(const char* header, const char* tag, bool try_general,
-                std::string* result) {
-      std::string h = header, t = tag;
-      return get_tag (h,t,try_general,result);
-    }
-
-    // Dump out the inifile to the output stream
-    void dump(std::ostream& os);
-
-    // Iterators
-
-    // The begin() functions reset the iterator and return the first element
-    // (or 0 if there are no elements.)
-    // The next() functions return the next element, or 0 if there are no
-    // elements left.
-    //
-    // Example:
-    // for (const foo* current = begin(); current; current = next()) {
-    //   ...
-    // }
-    //
-    // NOTE: Holding an Iterator will lock the INI file and cause it to
-    // stop updating itself.  You should destroy the iterator as soon as
-    // you are done with it.
-    //
-    // ALSO NOTE: the string* returned from the Iterator is only valid
-    // while you hold the iterator.  You should copy the de-reference
-    // of the pointer to your own copy if you want to keep the string.
-
-    class SHIBTARGET_EXPORTS Iterator {
+    class ShibTargetPriv;
+    class SHIBTARGET_EXPORTS ShibTarget {
     public:
-      virtual ~Iterator() {}
-      virtual const std::string* begin() = 0;
-      virtual const std::string* next() = 0;
+        ShibTarget(const IApplication* app);
+        virtual ~ShibTarget(void);
+
+        // These are defined here so the subclass does not need to specifically
+        // depend on log4cpp.  We could use log4cpp::Priority::PriorityLevel
+        // but this is just as easy, IMHO.  It's just a case statement in the
+        // implementation to handle the event level.
+        enum ShibLogLevel {
+          LogLevelDebug,
+          LogLevelInfo,
+          LogLevelWarn,
+          LogLevelError
+        };
+
+        //
+        // Note: subclasses MUST implement ALL of these virtual methods
+        //
+        
+        // Send a message to the Webserver log
+        virtual void log(ShibLogLevel level, const std::string &msg)=0;
+
+        void log(ShibLogLevel level, const char* msg) {
+          std::string s = msg;
+          log(level, s);
+        }
+
+        // Get/Set a cookie for this request
+        virtual std::string getCookies() const=0;
+        virtual void setCookie(const std::string& name, const std::string& value)=0;
+        virtual const char* getCookie(const std::string& name) const;
+        void setCookie(const char* name, const char* value) {
+          std::string ns = name;
+          std::string vs = value;
+          setCookie(ns, vs);
+        }
+        void setCookie(const char* name, const std::string& value) {
+          std::string ns = name;
+          setCookie(ns, value);
+        }
+
+        // Get any URL-encoded arguments or the raw POST body from the server
+        virtual const char* getQueryString() const=0;
+        virtual const char* getRequestBody() const=0;
+        virtual const char* getRequestParameter(const char* param, size_t index=0) const;
+
+        // Clear a header, set a header
+        // These APIs are used for exporting the Assertions into the
+        // Headers.  It will clear some well-known headers first to make
+        // sure none remain.  Then it will process the set of assertions
+        // and export them via setHeader().
+        virtual void clearHeader(const std::string& name)=0;
+        virtual void setHeader(const std::string& name, const std::string& value)=0;
+        virtual std::string getHeader(const std::string& name)=0;
+        virtual void setRemoteUser(const std::string& user)=0;
+        virtual std::string getRemoteUser()=0;
+
+        void clearHeader(const char* n) {
+          std::string s = n;
+          clearHeader(s);
+        }
+        void setHeader(const char* n, const char* v) {
+          std::string ns = n;
+          std::string vs = v;
+          setHeader(ns, vs);
+        }
+        void setHeader(const std::string& n, const char* v) {
+          std::string vs = v;
+          setHeader(n, vs);
+        }
+        void setHeader(const char* n, const std::string& v) {
+          std::string ns = n;
+          setHeader(ns, v);
+        }
+        std::string getHeader(const char* n) {
+          std::string s = n;
+          return getHeader(s);
+        }
+        void setRemoteUser(const char* n) {
+          std::string s = n;
+          setRemoteUser(s);
+        }
+
+        // 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;
+        virtual void* sendPage(
+            const std::string& msg,
+            int code = 200,
+            const std::string& content_type = "text/html",
+            const saml::Iterator<header_t>& headers = EMPTY(header_t)
+            )=0;
+        void* sendPage(const char* msg) {
+          std::string m = msg;
+          return sendPage(m);
+        }
+        virtual void* sendRedirect(const std::string& url)=0;
+        
+        // These next two APIs are used to obtain the module-specific "OK"
+        // and "Decline" results.  OK means "we believe that this request
+        // should be accepted".  Declined means "we believe that this is
+        // not a shibbolized request so we have no comment".
+
+        virtual void* returnDecline();
+        virtual void* returnOK();
+
+        //
+        // Note:  Subclasses need not implement anything below this line
+        //
+
+        // These functions implement the server-agnostic shibboleth engine
+        // The web server modules implement a subclass and then call into 
+        // these methods once they instantiate their request object.
+        // 
+        // Return value:
+        //   these APIs will always return the result of sendPage(), sendRedirect(),
+        //   returnDecline(), or returnOK() in the void* portion of the return code.
+        //   Exactly what those values are is module- (subclass-) implementation
+        //   specific.  The 'bool' part of the return value declares whether the
+        //   void* is valid or not.  If the bool is true then the void* is valid.
+        //   If the bool is false then the API did not call any callback, the void*
+        //   is not valid, and the caller should continue processing (the API Call
+        //   finished successfully).
+        //
+        //   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 handler = false);
+        std::pair<bool,void*> doHandler();
+        std::pair<bool,void*> doCheckAuthZ();
+        std::pair<bool,void*> doExportAssertions(bool requireSession = true);
+
+        // Basic request access in case any plugins need the info
+        virtual const IConfig* getConfig() const;
+        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();}
+        int getPort() const {return m_port;}
+        const char* getRequestURI() const {return m_uri.c_str();}
+        const char* getContentType() const {return m_content_type.c_str();}
+        const char* getRemoteAddr() const {return m_remote_addr.c_str();}
+        const char* getRequestURL() const {return m_url.c_str();}
+        
+        // Advanced methods useful to profile handlers implemented outside core
+        
+        // Get per-application session and state cookie name and properties
+        virtual std::pair<std::string,const char*> getCookieNameProps(const char* prefix) const;
+        
+        // Determine the effective handler URL based on the resource URL
+        virtual std::string getHandlerURL(const char* resource) const;
+
+    protected:
+        ShibTarget();
+
+        // Internal APIs
+
+        // Initialize the request from the parsed URL
+        // protocol == http, https, etc
+        // hostname == server name
+        // port == server port
+        // uri == resource path
+        // method == GET, POST, etc.
+        void init(
+            const char* protocol,
+            const char* hostname,
+            int port,
+            const char* uri,
+            const char* content_type,
+            const char* remote_addr,
+            const char* method
+            );
+
+        std::string m_url, m_method, m_protocol, m_hostname, m_uri, m_content_type, m_remote_addr;
+        int m_port;
+
+    private:
+        mutable ShibTargetPriv* m_priv;
+        friend class ShibTargetPriv;
     };
 
-    Iterator* header_iterator();
-    Iterator* tag_iterator(const std::string& header);
-
-    static bool boolean(std::string& value);
-
-  private:
-    ShibINIPriv *m_priv;
-    void init(std::string& file, bool case_sensitive);
-  };
-
-  class ShibMLPPriv;
-  class SHIBTARGET_EXPORTS ShibMLP {
-  public:
-    ShibMLP();
-    ~ShibMLP();
-
-    void insert (const std::string& key, const std::string& value);
-    void insert (const std::string& key, const char* value) {
-      std::string v = value;
-      insert (key, v);
-    }
-    void insert (const char* key, const std::string& value) {
-      std::string k = key;
-      insert (k, value);
-    }
-    void insert (const char* key, const char* value) {
-      std::string k = key, v = value;
-      insert(k,v);
-    }
-    void insert (RPCError& e);
-
-    void clear () { m_map.clear(); }
-
-    std::string run (std::istream& s) const;
-    std::string run (const std::string& input) const;
-    std::string run (const char* input) const {
-      std::string i = input;
-      return run(i);
-    }
-
-  private:
-    ShibMLPPriv *m_priv;
-    std::map<std::string,std::string> m_map;
-  };
-
-  class SHIBTARGET_EXPORTS ShibTargetConfig
-  {
-  public:
-    static void preinit();
-    static ShibTargetConfig& init(const char* app_name, const char* inifile);
-    static ShibTargetConfig& getConfig();
-    virtual void init() = 0;
-    virtual void shutdown() = 0;
-    virtual ~ShibTargetConfig();
-    virtual ShibINI& getINI() = 0;
-    virtual saml::Iterator<const XMLCh*> getPolicies() = 0;
+    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[];
     
-    ShibSockName m_SocketName;
-  };
-
-} // namespace
-#endif
+        // Session cache implementations
+        static const char MemorySessionCacheType[];
+        static const char MySQLSessionCacheType[];
+        static const char ODBCSessionCacheType[];
+        
+        // Replay cache implementations
+        static const char MySQLReplayCacheType[];
+        static const char ODBCReplayCacheType[];
+        
+        // Request mapping/settings implementations
+        static const char XMLRequestMapType[];      // portable XML-based map
+        static const char NativeRequestMapType[];   // Native web server command override of XML-based map
+        static const char LegacyRequestMapType[];   // older designation of XML map, hijacked by web server
+        
+        // Access control implementations
+        static const char htAccessControlType[];    // Apache-specific .htaccess authz module
+        static const char XMLAccessControlType[];   // Proprietary but portable XML authz syntax
+
+        struct SHIBTARGET_EXPORTS Literals
+        {
+            static const XMLCh AAPProvider[];
+            static const XMLCh AccessControl[];
+            static const XMLCh AccessControlProvider[];
+            static const XMLCh acl[];
+            static const XMLCh AND[];
+            static const XMLCh applicationId[];
+            static const XMLCh Application[];
+            static const XMLCh Applications[];
+            static const XMLCh AssertionConsumerService[];
+            static const XMLCh AttributeFactory[];
+            static const XMLCh config[];
+            static const XMLCh CredentialsProvider[];
+            static const XMLCh CredentialUse[];
+            static const XMLCh DiagnosticService[];
+            static const XMLCh echo[];
+            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 InProcess[];
+            static const XMLCh isDefault[];
+            static const XMLCh Library[];
+            static const XMLCh Listener[];
+            static const XMLCh Local[];
+            static const XMLCh log[];
+            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 ODBCReplayCache[];
+            static const XMLCh ODBCSessionCache[];
+            static const XMLCh OR[];
+            static const XMLCh OutOfProcess[];
+            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 */