Moved remoting layer to new library.
authorcantor <cantor@cb58f699-b61c-0410-a6fe-9272a202ed29>
Tue, 26 Dec 2006 03:04:27 +0000 (03:04 +0000)
committercantor <cantor@cb58f699-b61c-0410-a6fe-9272a202ed29>
Tue, 26 Dec 2006 03:04:27 +0000 (03:04 +0000)
git-svn-id: https://svn.middleware.georgetown.edu/cpp-sp/trunk@2092 cb58f699-b61c-0410-a6fe-9272a202ed29

26 files changed:
shar/test-client.cpp
shib-target/IListener.cpp [deleted file]
shib-target/Makefile.am
shib-target/XML.cpp
shib-target/ddf.h [deleted file]
shib-target/shib-ccache.cpp
shib-target/shib-config.cpp
shib-target/shib-handlers.cpp
shib-target/shib-ini.cpp
shib-target/shib-target.h
shib-target/shibtarget.vcproj
shibsp/ListenerService.cpp [new file with mode: 0644]
shibsp/ListenerService.h [new file with mode: 0644]
shibsp/Makefile.am
shibsp/SPConfig.cpp
shibsp/SPConfig.h
shibsp/SocketListener.cpp [moved from shib-target/SocketListener.cpp with 91% similarity]
shibsp/SocketListener.h [moved from shib-target/SocketListener.h with 75% similarity]
shibsp/TCPListener.cpp [moved from shib-target/TCPListener.cpp with 75% similarity]
shibsp/UnixListener.cpp [moved from shib-target/UnixListener.cpp with 63% similarity]
shibsp/ddf.cpp [moved from shib-target/ddf.cpp with 92% similarity]
shibsp/ddf.h [new file with mode: 0644]
shibsp/internal.h
shibsp/resource.h [new file with mode: 0644]
shibsp/shibsp.rc [new file with mode: 0644]
shibsp/shibsp.vcproj

index c22b912..e04b823 100644 (file)
 using namespace shibsp;
 using namespace shibtarget;
 using namespace saml;
+using namespace xmltooling;
 using namespace std;
 
 int main (int argc, char *argv[])
 {
+    if (argc<=1) {
+        cerr << "usage: testclient <integer>" << endl;
+        return -1;
+    }
   const char* config=getenv("SHIBCONFIG");
   if (!config)
     config=SHIB_CONFIG;
@@ -45,15 +50,15 @@ int main (int argc, char *argv[])
   try {
       DDF in("ping");
       DDFJanitor injan(in);
-      in.integer(0L);
+      in.integer(atol(argv[1]));
 
       DDF out=conf.getINI()->getListener()->send(in);
       DDFJanitor outjan(out);
 
-      cerr << 0 << " -> " << out.integer() << "\n";
+      cerr << argv[1] << " -> " << out.integer() << "\n";
   }
-  catch (SAMLException& e) {
-      cerr << "caught SAML exception: " << e.what() << "\n";
+  catch (exception& e) {
+      cerr << "caught exception: " << e.what() << "\n";
   }
   
   conf.shutdown();
diff --git a/shib-target/IListener.cpp b/shib-target/IListener.cpp
deleted file mode 100644 (file)
index 9187299..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- *  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
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-
-/*
- * IListener.cpp - basic functionality for remoting
- *
- * $Id$
- */
-
-#include "internal.h"
-
-using namespace std;
-using namespace log4cpp;
-using namespace saml;
-using namespace shibtarget;
-
-IRemoted* IListener::regListener(const char* address, IRemoted* listener)
-{
-    IRemoted* ret=NULL;
-    map<string,IRemoted*>::const_iterator i=m_listenerMap.find(address);
-    if (i!=m_listenerMap.end())
-        ret=i->second;
-    m_listenerMap[address]=listener;
-    Category::getInstance(SHIBT_LOGCAT".Listener").info("registered remoted message endpoint (%s)",address);
-    return ret;
-}
-
-bool IListener::unregListener(const char* address, IRemoted* current, IRemoted* restore)
-{
-    map<string,IRemoted*>::const_iterator i=m_listenerMap.find(address);
-    if (i!=m_listenerMap.end() && i->second==current) {
-        if (restore)
-            m_listenerMap[address]=restore;
-        else
-            m_listenerMap.erase(address);
-        Category::getInstance(SHIBT_LOGCAT".Listener").info("unregistered remoted message endpoint (%s)",address);
-        return true;
-    }
-    return false;
-}
-
-IRemoted* IListener::lookup(const char *address) const
-{
-    map<string,IRemoted*>::const_iterator i=m_listenerMap.find(address);
-    return (i==m_listenerMap.end()) ? NULL : i->second;
-}
-
-DDF IListener::receive(const DDF &in)
-{
-    if (!in.name())
-        throw ListenerException("Incoming message with no destination address rejected.");
-    IRemoted* dest=lookup(in.name());
-    if (!dest)
-        throw ListenerException("No destination registered for incoming message addressed to ($1).",params(1,in.name()));
-    return dest->receive(in);
-}
index f0b89ab..73a130f 100644 (file)
@@ -8,23 +8,17 @@ pkgxmldir = $(datadir)/xml/@PACKAGE@
 lib_LTLIBRARIES = libshib-target.la
 
 libshib_targetdir = $(includedir)/shib-target
-libshib_target_HEADERS = shib-target.h shib-paths.h hresult.h ddf.h
-noinst_HEADERS = internal.h SocketListener.h
+libshib_target_HEADERS = shib-target.h shib-paths.h hresult.h
+noinst_HEADERS = internal.h
 
 libshib_target_la_SOURCES = \
        ArtifactMapper.cpp \
-       CommonDomainCookie.cpp \
-       ddf.cpp \
-       IListener.cpp \
-       SocketListener.cpp \
     ShibHTTPHook.cpp \
        shib-ccache.cpp \
        shib-config.cpp \
        shib-handlers.cpp \
        shib-ini.cpp \
        shib-target.cpp \
-       TCPListener.cpp \
-       UnixListener.cpp \
        XML.cpp \
        XMLRequestMapper.cpp
 
index 8ed9427..15e88e6 100644 (file)
@@ -40,10 +40,6 @@ const char XML::LegacyRequestMapType[] =    "edu.internet2.middleware.shibboleth
 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 char XML::MemoryListenerType[] =      "edu.internet2.middleware.shibboleth.sp.provider.MemoryListener";
-
 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,
diff --git a/shib-target/ddf.h b/shib-target/ddf.h
deleted file mode 100644 (file)
index 9feac8f..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- *  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
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-
-/*
- * ddf.h - C++ DDF abstraction for interpretive RPC
- *
- * Created by:  Scott Cantor and Tom Sanfilippo, OSU
- *
- * $Id$
- */
-
-#ifndef __ddf_h__
-#define __ddf_h__
-
-#include <cstdio>
-#include <iostream>
-
-#ifdef WIN32
-# ifndef SHIBTARGET_EXPORTS
-#  define SHIBTARGET_EXPORTS __declspec(dllimport)
-# endif
-#else
-# define SHIBTARGET_EXPORTS
-#endif
-
-/**
- * DDF objects are implemented with a handle-body idiom and require explicit
- * destruction in order to allow stack objects to be freely mixed in structures
- * with heap objects. When stack objects leave scope, only the handle is freed.
- * Copying and assigning handle objects is a constant time operation equivalent
- * to a single pointer assignment, handled by compiler-generated behavior.
- */
-
-namespace shibtarget {
-
-class SHIBTARGET_EXPORTS DDF
-{
-public:
-    // constructors
-    DDF() : m_handle(NULL) {}
-    DDF(const char* n);
-    DDF(const char* n, const char* val);
-    DDF(const char* n, long val);
-    DDF(const char* n, double val);
-    DDF(const char* n, void* val);
-
-    DDF& destroy();         // deep destructor
-    DDF copy() const;       // deep copy routine
-
-    // property accessors
-    const char* name() const;           DDF& name(const char* n);
-
-    // basic type checking
-    bool isnull() const;
-    bool isempty() const;
-    bool isstring() const;
-    bool isint() const;
-    bool isfloat() const;
-    bool isstruct() const;
-    bool islist() const;
-    bool ispointer() const;
-
-    // type conversion and value extraction
-    const char* string() const;     // legal for str
-    long        integer() const;    // legal for all types
-    double      floating() const;   // legal for float
-    void*       pointer() const;    // legal for pointer
-
-    // string helper methods
-    size_t strlen() const;
-    bool operator==(const char* s) const;
-
-    // destructive node conversion methods
-    DDF& empty();
-    DDF& string(const char* val);
-    DDF& string(long val);
-    DDF& string(double val);
-    DDF& integer(long val);
-    DDF& integer(const char* val);
-    DDF& floating(double val);
-    DDF& floating(const char* val);
-    DDF& structure();
-    DDF& list();
-    DDF& pointer(void* val);
-
-    // list/struct methods
-    DDF& add(DDF& child);
-    DDF& addbefore(DDF& child, DDF& before);
-    DDF& addafter(DDF& child, DDF& after);
-    void swap(DDF& arg);
-    DDF& remove();
-
-    // C-style iterators
-    DDF parent() const;
-    DDF first();
-    DDF next();
-    DDF last();
-    DDF previous();
-    
-    // indexed operators
-    DDF operator[](unsigned long index) const;
-    DDF operator[](const char* path) const { return getmember(path); }
-
-    // named member access/creation
-    DDF addmember(const char* path);
-    DDF getmember(const char* path) const;
-
-    // debugging
-    void dump(FILE* f=NULL, int indent=0) const;
-
-    // serialization functions need private access
-    friend SHIBTARGET_EXPORTS std::ostream& operator<<(std::ostream& os, const DDF& obj);
-    friend SHIBTARGET_EXPORTS std::istream& operator>>(std::istream& is, DDF& obj);
-private:
-    struct ddf_body_t* m_handle;
-};
-
-// XML/WDDX serialization
-SHIBTARGET_EXPORTS std::ostream& operator<<(std::ostream& os, const DDF& obj);
-SHIBTARGET_EXPORTS std::istream& operator>>(std::istream& is, DDF& obj);
-
-/**
- * A "smart pointer" for disposing of DDF objects when they leave scope.
- */
-class SHIBTARGET_EXPORTS DDFJanitor
-{
-public:
-    DDFJanitor(DDF& obj) : m_obj(obj) {}
-    ~DDFJanitor() { m_obj.destroy(); }
-private:
-    DDF& m_obj;
-    DDFJanitor(const DDFJanitor&);
-    DDFJanitor& operator=(const DDFJanitor&);
-};
-
-}
-
-#endif // __ddf_h__
index 1cea2d1..fdf6e66 100644 (file)
@@ -328,7 +328,7 @@ private:
 /*
  * The actual in-memory session cache implementation.
  */
-class MemorySessionCache : public virtual ISessionCache, public virtual IRemoted
+class MemorySessionCache : public virtual ISessionCache, public virtual Remoted
 {
 public:
     MemorySessionCache(const DOMElement* e);
@@ -357,9 +357,9 @@ private:
     map<string,MemorySessionCacheEntry*> m_hashtable;
 
     Category* m_log;
-    IRemoted* restoreInsert;
-    IRemoted* restoreFind;
-    IRemoted* restoreRemove;
+    Remoted* restoreInsert;
+    Remoted* restoreFind;
+    Remoted* restoreRemove;
     ISessionCacheStore* m_sink;
 
     void dormant(const char* key);
@@ -1061,7 +1061,7 @@ MemorySessionCache::MemorySessionCache(const DOMElement* e)
     SAMLConfig::getConfig().conn_timeout = m_AAConnectTimeout;
 
     // Register for remoted messages.
-    IListener* listener=ShibTargetConfig::getConfig().getINI()->getListener();
+    ListenerService* listener=ShibTargetConfig::getConfig().getINI()->getListener();
     if (listener && SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess)) {
         restoreInsert=listener->regListener("SessionCache::insert",this);
         restoreFind=listener->regListener("SessionCache::find",this);
@@ -1083,7 +1083,7 @@ MemorySessionCache::~MemorySessionCache()
     cleanup_thread->join(NULL);
 
     // Unregister remoted messages.
-    IListener* listener=ShibTargetConfig::getConfig().getINI()->getListener();
+    ListenerService* listener=ShibTargetConfig::getConfig().getINI()->getListener();
     if (listener && SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess)) {
         listener->unregListener("SessionCache::insert",this,restoreInsert);
         listener->unregListener("SessionCache::find",this,restoreFind);
index 8f82e9e..46b7624 100644 (file)
@@ -98,11 +98,7 @@ bool STConfig::init(const char* schemadir)
     // Register built-in plugin types.
     REGISTER_EXCEPTION_FACTORY(ListenerException);
     REGISTER_EXCEPTION_FACTORY(ConfigurationException);
-#ifndef WIN32
-    samlConf.getPlugMgr().regFactory(shibtarget::XML::UnixListenerType,&UnixListenerFactory);
-#endif
-    samlConf.getPlugMgr().regFactory(shibtarget::XML::TCPListenerType,&TCPListenerFactory);
-    //samlConf.getPlugMgr().regFactory(shibtarget::XML::MemoryListenerType,&MemoryListenerFactory);
+
     samlConf.getPlugMgr().regFactory(shibtarget::XML::MemorySessionCacheType,&MemoryCacheFactory);
     samlConf.getPlugMgr().regFactory(shibtarget::XML::LegacyRequestMapType,&XMLRequestMapFactory);
     samlConf.getPlugMgr().regFactory(shibtarget::XML::XMLRequestMapType,&XMLRequestMapFactory);
index 51665b6..1fcac10 100644 (file)
@@ -59,7 +59,7 @@ namespace {
         ) const;
   };
 
-  class SAML1Consumer : virtual public IHandler, public virtual IRemoted
+  class SAML1Consumer : virtual public IHandler, public virtual Remoted
   {
   public:
     SAML1Consumer(const DOMElement* e);
@@ -243,7 +243,7 @@ SAML1Consumer::SAML1Consumer(const DOMElement* e)
 
     // Register for remoted messages.
     if (SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess)) {
-        IListener* listener=ShibTargetConfig::getConfig().getINI()->getListener();
+        ListenerService* listener=ShibTargetConfig::getConfig().getINI()->getListener();
         if (listener)
             listener->regListener(m_address.c_str(),this);
         else
@@ -253,7 +253,7 @@ SAML1Consumer::SAML1Consumer(const DOMElement* e)
 
 SAML1Consumer::~SAML1Consumer()
 {
-    IListener* listener=ShibTargetConfig::getConfig().getINI()->getListener();
+    ListenerService* listener=ShibTargetConfig::getConfig().getINI()->getListener();
     if (listener && SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess))
         listener->unregListener(m_address.c_str(),this);
     counter--;
index 06f8207..4ca58d8 100644 (file)
@@ -182,7 +182,7 @@ namespace shibtarget {
         const DOMElement* getElement() const {return static_cast<XMLConfigImpl*>(m_impl)->getElement();}
 
         // IConfig
-        IListener* getListener() const {return m_listener;}
+        ListenerService* getListener() const {return m_listener;}
         ISessionCache* getSessionCache() const {return m_sessionCache;}
         IReplayCache* getReplayCache() const {return m_replayCache;}
         IRequestMapper* getRequestMapper() const {return static_cast<XMLConfigImpl*>(m_impl)->m_requestMapper;}
@@ -198,7 +198,7 @@ namespace shibtarget {
 
     private:
         friend class XMLConfigImpl;
-        mutable IListener* m_listener;
+        mutable ListenerService* m_listener;
         mutable ISessionCache* m_sessionCache;
         mutable IReplayCache* m_replayCache;
     };
@@ -1117,26 +1117,25 @@ void XMLConfigImpl::init(bool first)
                 }
             }
             
-            // Instantiate the Listener and SessionCache objects.
+            // Instantiate the ListenerService and SessionCache objects.
             if (conf.isEnabled(SPConfig::Listener)) {
-                IPlugIn* plugin=NULL;
                 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);
+                    log.info("building Listener of type %s...",UNIX_LISTENER_SERVICE);
+                    m_outer->m_listener=conf.ListenerServiceManager.newPlugin(UNIX_LISTENER_SERVICE,exts);
                 }
                 else {
                     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);
+                        log.info("building Listener of type %s...",TCP_LISTENER_SERVICE);
+                        m_outer->m_listener=conf.ListenerServiceManager.newPlugin(TCP_LISTENER_SERVICE,exts);
                     }
                     else {
                         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());
-                            plugin=shibConf.getPlugMgr().newPlugin(type.get(),exts);
+                            m_outer->m_listener=conf.ListenerServiceManager.newPlugin(type.get(),exts);
                         }
                         else {
                             log.fatal("can't build Listener object, missing conf:Listener element?");
@@ -1144,16 +1143,6 @@ void XMLConfigImpl::init(bool first)
                         }
                     }
                 }
-                if (plugin) {
-                    IListener* listen=dynamic_cast<IListener*>(plugin);
-                    if (listen)
-                        m_outer->m_listener=listen;
-                    else {
-                        delete plugin;
-                        log.fatal("plugin was not a Listener object");
-                        throw UnsupportedExtensionException("plugin was not a Listener object");
-                    }
-                }
             }
 
             if (conf.isEnabled(SPConfig::Caching)) {
@@ -1328,6 +1317,10 @@ void XMLConfigImpl::init(bool first)
                 m_appmap[iapp->getId()]=iapp.release();
         }
     }
+    catch (xmltooling::XMLToolingException& e) {
+        log.errorStream() << "Error while loading SP configuration: " << e.what() << CategoryStream::ENDLINE;
+        throw ConfigurationException(e.what());
+    }
     catch (SAMLException& e) {
         log.errorStream() << "Error while loading SP configuration: " << e.what() << CategoryStream::ENDLINE;
         throw ConfigurationException(e.what());
index 1b5bc3f..08e1e1c 100644 (file)
@@ -27,7 +27,7 @@
 
 // New headers
 #include <saml/base.h>
-#include <xmltooling/PluginManager.h>
+#include <shibsp/ListenerService.h>
 
 // Old headers
 #include <saml/saml.h>
@@ -44,8 +44,6 @@
 # define SHIBTARGET_EXPORTS
 #endif
 
-#include <shib-target/ddf.h>
-
 namespace shibtarget {
   
     DECLARE_SAML_EXCEPTION(SHIBTARGET_EXPORTS,ListenerException,SAMLException);
@@ -273,53 +271,6 @@ namespace shibtarget {
     };
 
     /**
-     * Interface to a remoted service
-     * 
-     * Plugins that support remoted messages delivered by the IListener runtime
-     * support this interface and register themselves with the runtime to receive
-     * particular messages.
-     */
-    struct SHIBTARGET_EXPORTS IRemoted : public virtual saml::IPlugIn
-    {
-        virtual DDF receive(const DDF& in)=0;
-        virtual ~IRemoted() {}
-    };
-
-    /**
-     * Interface to the remoting engine
-     * 
-     * A listener supports the remoting of DDF objects, which are dynamic data trees
-     * that interface implementations can use to remote themselves by calling an
-     * out-of-process peer implementation with arbitrary data to carry out tasks
-     * on the implementation's behalf that require isolation from the dynamic process
-     * fluctuations that web servers are prone to. The ability to pass arbitrary data
-     * trees across the boundary allows arbitrary separation of duty between the
-     * in-process and out-of-process "halves". The implementation is responsible
-     * for marshalling and transmitting messages, as well as managing connections
-     * and communication errors.
-     */
-    class SHIBTARGET_EXPORTS IListener : public virtual IRemoted
-    {
-    public:
-        virtual DDF send(const DDF& in)=0;
-        virtual DDF receive(const DDF& in);
-        virtual ~IListener() {}
-
-        // Remoted classes register and unregister for messages using these methods.
-        // Registration returns any existing listeners, allowing message hooking.
-        virtual IRemoted* regListener(const char* address, IRemoted* listener);
-        virtual bool unregListener(const char* address, IRemoted* current, IRemoted* restore=NULL);
-        virtual IRemoted* lookup(const char* address) const;
-
-        // OutOfProcess servers can implement server-side transport handling by
-        // calling the run method and supplying a flag to monitor for shutdown.
-        virtual bool run(bool* shutdown)=0;
-
-    private:
-        std::map<std::string,IRemoted*> m_listenerMap;
-    };
-
-    /**
      * Interface to an access control plugin
      * 
      * Access control plugins return authorization decisions based on the intersection
@@ -350,7 +301,7 @@ namespace shibtarget {
         // loads initial configuration
         virtual void init()=0;
 
-        virtual IListener* getListener() const=0;
+        virtual shibsp::ListenerService* getListener() const=0;
         virtual ISessionCache* getSessionCache() const=0;
         virtual saml::IReplayCache* getReplayCache() const=0;
         virtual IRequestMapper* getRequestMapper() const=0;
@@ -590,11 +541,6 @@ namespace shibtarget {
         static const char htAccessControlType[];    // Apache-specific .htaccess authz module
         static const char XMLAccessControlType[];   // Proprietary but portable XML authz syntax
 
-        // Listener implementations
-        static const char TCPListenerType[];        // ONC RPC via TCP socket
-        static const char UnixListenerType[];       // ONC RPC via domain socker
-        static const char MemoryListenerType[];     // "faked" in-process marshalling
-    
         struct SHIBTARGET_EXPORTS Literals
         {
             static const XMLCh AAPProvider[];
index e091121..8ddaeac 100644 (file)
                        >
                </File>
                <File
-                       RelativePath=".\ddf.cpp"
-                       >
-               </File>
-               <File
-                       RelativePath=".\ddf.h"
-                       >
-               </File>
-               <File
                        RelativePath="hresult.h"
                        >
                </File>
                <File
-                       RelativePath=".\IListener.cpp"
-                       >
-               </File>
-               <File
                        RelativePath="internal.h"
                        >
                </File>
                <File
                        RelativePath="shib-handlers.cpp"
                        >
-                       </File>
+               </File>
                <File
                        RelativePath="shib-ini.cpp"
                        >
-                       </File>
+               </File>
                <File
                        RelativePath="shib-target.cpp"
                        >
                        >
                </File>
                <File
-                       RelativePath=".\SocketListener.cpp"
-                       >
-               </File>
-               <File
-                       RelativePath=".\SocketListener.h"
-                       >
-               </File>
-               <File
-                       RelativePath=".\TCPListener.cpp"
-                       >
-               </File>
-               <File
                        RelativePath="XML.cpp"
                        >
                </File>
diff --git a/shibsp/ListenerService.cpp b/shibsp/ListenerService.cpp
new file mode 100644 (file)
index 0000000..1caecd4
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ *  Copyright 2001-2006 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
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ */
+
+/**
+ * ListenerService.cpp
+ * 
+ * Interprocess remoting engine.
+ */
+
+#include "internal.h"
+#include "exceptions.h"
+#include "ListenerService.h"
+
+#include <log4cpp/Category.hh>
+#include <xercesc/dom/DOM.hpp>
+
+using namespace shibsp;
+using namespace xmltooling;
+using namespace log4cpp;
+using namespace xercesc;
+using namespace std;
+
+namespace shibsp {
+    //SHIBSP_DLLLOCAL PluginManager<ListenerService,const DOMElement*>::Factory MemoryListenerServiceFactory;
+    SHIBSP_DLLLOCAL PluginManager<ListenerService,const DOMElement*>::Factory TCPListenerServiceFactory;
+#ifndef WIN32
+    SHIBSP_DLLLOCAL PluginManager<ListenerService,const DOMElement*>::Factory UnixListenerServiceFactory;
+#endif
+};
+
+void SHIBSP_API shibsp::registerListenerServices()
+{
+    SPConfig& conf=SPConfig::getConfig();
+    //conf.ListenerServiceManager.registerFactory(MEMORY_LISTENER_SERVICE, MemoryListenerServiceFactory);
+    conf.ListenerServiceManager.registerFactory(TCP_LISTENER_SERVICE, TCPListenerServiceFactory);
+#ifndef WIN32
+    conf.ListenerServiceManager.registerFactory(UNIX_LISTENER_SERVICE, UnixListenerServiceFactory);
+#endif
+}
+
+Remoted* ListenerService::regListener(const char* address, Remoted* listener)
+{
+    Remoted* ret=NULL;
+    map<string,Remoted*>::const_iterator i=m_listenerMap.find(address);
+    if (i!=m_listenerMap.end())
+        ret=i->second;
+    m_listenerMap[address]=listener;
+    Category::getInstance(SHIBSP_LOGCAT".Listener").info("registered remoted message endpoint (%s)",address);
+    return ret;
+}
+
+bool ListenerService::unregListener(const char* address, Remoted* current, Remoted* restore)
+{
+    map<string,Remoted*>::const_iterator i=m_listenerMap.find(address);
+    if (i!=m_listenerMap.end() && i->second==current) {
+        if (restore)
+            m_listenerMap[address]=restore;
+        else
+            m_listenerMap.erase(address);
+        Category::getInstance(SHIBSP_LOGCAT".Listener").info("unregistered remoted message endpoint (%s)",address);
+        return true;
+    }
+    return false;
+}
+
+Remoted* ListenerService::lookup(const char *address) const
+{
+    map<string,Remoted*>::const_iterator i=m_listenerMap.find(address);
+    return (i==m_listenerMap.end()) ? NULL : i->second;
+}
+
+DDF ListenerService::receive(const DDF &in)
+{
+    if (!in.name())
+        throw ListenerException("Incoming message with no destination address rejected.");
+    else if (!strcmp("ping",in.name())) {
+        DDF out=DDF(NULL).integer(in.integer() + 1);
+        return out;
+    }
+
+    Remoted* dest=lookup(in.name());
+    if (!dest)
+        throw ListenerException("No destination registered for incoming message addressed to ($1).",params(1,in.name()));
+    
+    return dest->receive(in);
+}
diff --git a/shibsp/ListenerService.h b/shibsp/ListenerService.h
new file mode 100644 (file)
index 0000000..fa6dbd5
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ *  Copyright 2001-2006 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
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ */
+
+/**
+ * @file shibsp/ListenerService.h
+ * 
+ * Interprocess remoting engine.
+ */
+
+#ifndef __shibsp_listener_h__
+#define __shibsp_listener_h__
+
+#include <shibsp/ddf.h>
+#include <map>
+
+namespace shibsp {
+
+    /**
+     * Interface to a remoted service
+     * 
+     * Classes that support remoted messages delivered by the Listener runtime
+     * support this interface and register themselves with the runtime to receive
+     * particular messages.
+     */
+    class SHIBSP_API Remoted
+    {
+        MAKE_NONCOPYABLE(Remoted);
+    protected:
+        Remoted() {}
+    public:
+        virtual ~Remoted() {}
+
+        /**
+         * Remoted classes implement this method to process incoming messages.
+         * 
+         * @param in    incoming DDF message
+         * @return  DDF message response
+         */
+        virtual DDF receive(const DDF& in)=0;
+    };
+
+#if defined (_MSC_VER)
+    #pragma warning( push )
+    #pragma warning( disable : 4250 4251 )
+#endif
+
+    /**
+     * Interface to a remoting engine.
+     * 
+     * A ListenerService supports the remoting of DDF objects, which are dynamic data trees
+     * that other class implementations can use to remote themselves by calling an
+     * out-of-process peer implementation with arbitrary data to carry out tasks
+     * on the implementation's behalf that require isolation from the dynamic process
+     * fluctuations that web servers are prone to. The ability to pass arbitrary data
+     * trees across the boundary allows arbitrary separation of duty between the
+     * in-process and out-of-process "halves". The ListenerService is responsible
+     * for marshalling and transmitting messages, as well as managing connections
+     * and communication errors.
+     */
+    class SHIBSP_API ListenerService : public virtual Remoted
+    {
+    public:
+        virtual ~ListenerService() {}
+
+        /**
+         * Send a remoted message and return the response.
+         * 
+         * @param in    input message to send
+         * @return      response from remote service
+         */
+        virtual DDF send(const DDF& in)=0;
+        
+        virtual DDF receive(const DDF& in);
+
+        // Remoted classes register and unregister for messages using these methods.
+        // Registration returns any existing listeners, allowing message hooking.
+        
+        /**
+         * Register for a message. Returns existing remote service, allowing message hooking.
+         * 
+         * @param address   message address to register
+         * @param svc       pointer to remote service
+         * @return  previous service registered for message, if any
+         */
+        virtual Remoted* regListener(const char* address, Remoted* svc);
+        
+        /**
+         * Unregisters service from an address, possibly restoring an original.
+         * 
+         * @param address   message address to modify
+         * @param current   pointer to unregistering service
+         * @param restore   service to "restore" registration for
+         * @return  true iff the current service was still registered
+         */
+        virtual bool unregListener(const char* address, Remoted* current, Remoted* restore=NULL);
+        
+        /**
+         * Returns current service registered at an address, if any.
+         * 
+         * @param address message address to access
+         * @return  registered service, or NULL
+         */
+        virtual Remoted* lookup(const char* address) const;
+
+        /**
+         * OutOfProcess servers can implement server-side transport handling by
+         * calling the run method and supplying a flag to monitor for shutdown.
+         * 
+         * @param shutdown  pointer to flag that caller will set when shutdown is required
+         * @return true iff ListenerService initialization was successful
+         */
+        virtual bool run(bool* shutdown)=0;
+
+    private:
+        std::map<std::string,Remoted*> m_listenerMap;
+    };
+
+#if defined (_MSC_VER)
+    #pragma warning( pop )
+#endif
+
+    /**
+     * Registers ListenerService classes into the runtime.
+     */
+    void SHIBSP_API registerListenerServices();
+
+    /** Listener based on in-memory simulated remoting. */
+    #define MEMORY_LISTENER_SERVICE "edu.internet2.middleware.shibboleth.sp.provider.MemoryListener"
+
+    /** Listener based on TCP socket remoting. */
+    #define TCP_LISTENER_SERVICE "edu.internet2.middleware.shibboleth.sp.provider.TCPListener"
+
+    /** Listener based on UNIX domain socket remoting. */
+    #define UNIX_LISTENER_SERVICE "edu.internet2.middleware.shibboleth.sp.provider.UnixListener"
+};
+
+#endif /* __shibsp_listener_h__ */
index 5e8fc11..0c262db 100644 (file)
@@ -9,15 +9,23 @@ libshibspincludedir = $(includedir)/shibsp
 
 libshibspinclude_HEADERS = \
        base.h \
+       ddf.h \
        exceptions.h \
+       ListenerService.h \
        paths.h \
        version.h \
+       SocketListener.h \
        SPConfig.h
 
 noinst_HEADERS = \
        internal.h
 
 libshibsp_la_SOURCES = \
+       ddf.cpp \
+       ListenerService.cpp \
+       SocketListener.cpp \
+       TCPListener.cpp \
+       UnixListener.cpp \
        SPConfig.cpp
 
 # this is different from the project version
@@ -35,5 +43,5 @@ paths.h: ${srcdir}/paths.h.in Makefile ${top_builddir}/config.status
 install-exec-hook:
        for la in $(lib_LTLIBRARIES) ; do rm -f $(DESTDIR)$(libdir)/$$la ; done
 
-EXTRA_DIST = shibsp.vcproj paths.h.in
+EXTRA_DIST = shibsp.vcproj paths.h.in resource.h shibsp.rc
 BUILT_SOURCES = paths.h
index 125c995..90bd9c2 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "internal.h"
 #include "exceptions.h"
+#include "ListenerService.h"
 #include "SPConfig.h"
 
 #include <log4cpp/Category.hh>
@@ -84,6 +85,8 @@ bool SPInternalConfig::init(const char* catalog_path)
     
     REGISTER_XMLTOOLING_EXCEPTION_FACTORY(ConfigurationException,shibsp);
     REGISTER_XMLTOOLING_EXCEPTION_FACTORY(ListenerException,shibsp);
+    
+    registerListenerServices();
 
     log.info("library initialization complete");
     return true;
@@ -99,6 +102,8 @@ void SPInternalConfig::term()
 
     //delete m_serviceProvider;
     m_serviceProvider = NULL;
+    
+    ListenerServiceManager.deregisterFactories();
 
     SAMLConfig::getConfig().term();
     log.info("library shutdown complete");
index 44d32cc..ca29cb9 100644 (file)
@@ -24,6 +24,8 @@
 #define __shibsp_config_h__
 
 #include <shibsp/base.h>
+#include <xmltooling/PluginManager.h>
+#include <xercesc/dom/DOM.hpp>
 
 /**
  * @namespace shibsp
  */
 namespace shibsp {
 
+    class SHIBSP_API ListenerService;
     class SHIBSP_API ServiceProvider;
 
+#if defined (_MSC_VER)
+    #pragma warning( push )
+    #pragma warning( disable : 4250 4251 )
+#endif
+
     /**
      * Singleton object that manages library startup/shutdown.
      */
@@ -121,6 +129,11 @@ namespace shibsp {
             return m_serviceProvider;
         }
 
+        /**
+         * Manages factories for ListenerService plugins.
+         */
+        xmltooling::PluginManager<ListenerService,const xercesc::DOMElement*> ListenerServiceManager;
+
     protected:
         SPConfig() : m_serviceProvider(NULL) {}
         
@@ -131,6 +144,10 @@ namespace shibsp {
         unsigned long m_features;
     };
 
+#if defined (_MSC_VER)
+    #pragma warning( pop )
+#endif
+
 };
 
 #endif /* __shibsp_config_h__ */
similarity index 91%
rename from shib-target/SocketListener.cpp
rename to shibsp/SocketListener.cpp
index df0046d..baab25f 100644 (file)
 /**
  * SocketListener.cpp
  * 
- * Berkeley Socket-based Listener implementation
+ * Berkeley Socket-based ListenerService implementation
  */
 
+#include "internal.h"
+#include "exceptions.h"
 #include "SocketListener.h"
 
 #include <errno.h>
+#include <stack>
 #include <sstream>
 #include <shibsp/SPConfig.h>
+#include <xmltooling/util/NDC.h>
 
 #ifdef HAVE_UNISTD_H
 # include <unistd.h>
 #endif
 
 using namespace shibsp;
-using namespace shibtarget;
-using namespace saml;
 using namespace xmltooling;
 using namespace log4cpp;
 using namespace std;
+using xercesc::DOMElement;
 
-namespace shibtarget {
+namespace shibsp {
   
     // Manages the pool of connections
     class SocketPool
@@ -78,7 +81,7 @@ namespace shibtarget {
 SocketListener::ShibSocket SocketPool::connect()
 {
 #ifdef _DEBUG
-    saml::NDC ndc("connect");
+    NDC ndc("connect");
 #endif
 
     m_log.debug("trying to connect to listener");
@@ -112,7 +115,7 @@ SocketListener::ShibSocket SocketPool::connect()
     if (!connected) {
         m_log.crit("socket server unavailable, failing");
         m_listener->close(sock);
-        throw ListenerException("Cannot connect to listener process, a site adminstrator should be notified.");
+        throw ListenerException("Cannot connect to shibd process, a site adminstrator should be notified.");
     }
 
     m_log.debug("socket (%u) connected successfully", sock);
@@ -151,7 +154,7 @@ void SocketPool::put(SocketListener::ShibSocket s)
     m_lock->unlock();
 }
 
-SocketListener::SocketListener(const DOMElement* e) : log(&Category::getInstance(SHIBT_LOGCAT".Listener")),
+SocketListener::SocketListener(const DOMElement* e) : log(&Category::getInstance(SHIBSP_LOGCAT".Listener")),
     m_shutdown(NULL), m_child_lock(NULL), m_child_wait(NULL), m_socketpool(NULL), m_socket((ShibSocket)0)
 {
     // Are we a client?
@@ -175,7 +178,7 @@ SocketListener::~SocketListener()
 bool SocketListener::run(bool* shutdown)
 {
 #ifdef _DEBUG
-    saml::NDC ndc("run");
+    NDC ndc("run");
 #endif
 
     // Save flag to monitor for shutdown request.
@@ -246,7 +249,7 @@ bool SocketListener::run(bool* shutdown)
 DDF SocketListener::send(const DDF& in)
 {
 #ifdef _DEBUG
-    saml::NDC ndc("send");
+    NDC ndc("send");
 #endif
 
     log->debug("sending message: %s", in.name());
@@ -275,7 +278,7 @@ DDF SocketListener::send(const DDF& in)
             if (retry)
                 retry--;
             else
-                throw ListenerException("Failure sending remoted message ($1).", saml::params(1,in.name()));
+                throw ListenerException("Failure sending remoted message ($1).", params(1,in.name()));
         }
         else {
             // SUCCESS.
@@ -289,7 +292,7 @@ DDF SocketListener::send(const DDF& in)
     if (recv(sock,(char*)&len,sizeof(len)) != sizeof(len)) {
         log->error("error reading size of output message");
         this->close(sock);
-        throw ListenerException("Failure receiving response to remoted message ($1).", saml::params(1,in.name()));
+        throw ListenerException("Failure receiving response to remoted message ($1).", params(1,in.name()));
     }
     len = ntohl(len);
     
@@ -304,7 +307,7 @@ DDF SocketListener::send(const DDF& in)
     if (len) {
         log->error("error reading output message from socket");
         this->close(sock);
-        throw ListenerException("Failure receiving response to remoted message ($1).", saml::params(1,in.name()));
+        throw ListenerException("Failure receiving response to remoted message ($1).", params(1,in.name()));
     }
     
     m_socketpool->put(sock);
@@ -317,18 +320,17 @@ DDF SocketListener::send(const DDF& in)
     if (out.isstring() && out.name() && !strcmp(out.name(),"exception")) {
         // Reconstitute exception object.
         DDFJanitor jout(out);
-        SAMLException* except=NULL;
+        XMLToolingException* except=NULL;
         try { 
-            istringstream es(out.string());
-            except=SAMLException::getInstance(es);
+            except=XMLToolingException::fromString(out.string());
         }
-        catch (SAMLException& e) {
-            log->error("caught SAML Exception while building the SAMLException: %s", e.what());
+        catch (XMLToolingException& e) {
+            log->error("caught XMLToolingException while building the XMLToolingException: %s", e.what());
             log->error("XML was: %s", out.string());
             throw ListenerException("Remote call failed with an unparsable exception.");
         }
 
-        auto_ptr<SAMLException> wrapper(except);
+        auto_ptr<XMLToolingException> wrapper(except);
         wrapper->raise();
     }
 
@@ -398,7 +400,7 @@ ServerThread::~ServerThread()
 
 void ServerThread::run()
 {
-    saml::NDC ndc(m_id);
+    NDC ndc(m_id);
 
     // Before starting up, make sure we fully "own" this socket.
     m_listener->m_child_lock->lock();
@@ -453,10 +455,6 @@ bool ServerThread::job()
 #endif
 
     try {
-        // Lock the configuration.
-        IConfig* conf=ShibTargetConfig::getConfig().getINI();
-        Locker locker(conf);
-
         // Read the message.
         if (m_listener->recv(m_sock,(char*)&len,sizeof(len)) != sizeof(len)) {
             log.error("error reading size of input message");
@@ -484,19 +482,15 @@ bool ServerThread::job()
         // Dispatch the message.
         out=m_listener->receive(in);
     }
-    catch (SAMLException &e) {
+    catch (XMLToolingException &e) {
         log.error("error processing incoming message: %s", e.what());
-        ostringstream os;
-        os << e;
-        out=DDF("exception").string(os.str().c_str());
+        out=DDF("exception").string(e.toString().c_str());
     }
 #ifndef _DEBUG
     catch (...) {
         log.error("unexpected error processing incoming message");
         ListenerException ex("An unexpected error occurred while processing an incoming message.");
-        ostringstream os;
-        os << ex;
-        out=DDF("exception").string(os.str().c_str());
+        out=DDF("exception").string(ex.toString().c_str());
     }
 #endif
     
similarity index 75%
rename from shib-target/SocketListener.h
rename to shibsp/SocketListener.h
index b8b67c0..0dbcf9f 100644 (file)
  */
 
 /**
- * @file shib-target/SocketListener.h
+ * @file shibsp/SocketListener.h
  * 
- * Berkeley Socket-based Listener implementation
+ * Berkeley Socket-based ListenerService implementation
  */
 
-#ifndef __st_socklisten_h__
-#define __st_socklisten_h__
+#ifndef __shibsp_socklisten_h__
+#define __shibsp_socklisten_h__
 
 #ifndef FD_SETSIZE
 # define FD_SETSIZE 1024
 #endif
 
-#include "internal.h"
+#include <shibsp/ListenerService.h>
 
-#include <winsock.h>
+#include <log4cpp/Category.hh>
+#include <xercesc/dom/DOM.hpp>
+#include <xmltooling/util/Threads.h>
 
-namespace shibtarget {
+#ifdef WIN32
+# include <winsock.h>
+#endif
+
+namespace shibsp {
 
     class SocketPool;
     class ServerThread;
-    class SocketListener : public virtual IListener
+    
+    /**
+     * Berkeley Socket-based ListenerService implementation
+     */
+    class SocketListener : public virtual ListenerService
     {
     public:
-        SocketListener(const DOMElement* e);
+        /// @cond OFF
+        SocketListener(const xercesc::DOMElement* e);
         ~SocketListener();
 
         DDF send(const DDF& in);
@@ -61,6 +72,7 @@ namespace shibtarget {
     protected:
         bool log_error() const; // for OS-level errors
         log4cpp::Category* log;
+        /// @endcond
     
     private:
         mutable SocketPool* m_socketpool;
@@ -77,4 +89,4 @@ namespace shibtarget {
     };
 }
 
-#endif /* __st_socklisten_h__ */
+#endif /* __shibsp_socklisten_h__ */
similarity index 75%
rename from shib-target/TCPListener.cpp
rename to shibsp/TCPListener.cpp
index 089f56c..20c39a6 100644 (file)
  * TCP-based SocketListener implementation
  */
 
+#include "internal.h"
 #include "SocketListener.h"
 
+#include <xercesc/util/XMLUniDefs.hpp>
+#include <xmltooling/unicode.h>
+
 #ifdef HAVE_UNISTD_H
 # include <sys/socket.h>
 # include <sys/un.h>
 #include <stdlib.h>
 #include <errno.h>
 
+using namespace shibsp;
+using namespace xmltooling;
+using namespace xercesc;
 using namespace std;
-using namespace saml;
-using namespace shibboleth;
-using namespace shibtarget;
-using namespace log4cpp;
-
-static const XMLCh address[] = { chLatin_a, chLatin_d, chLatin_d, chLatin_r, chLatin_e, chLatin_s, chLatin_s, chNull };
-static const XMLCh port[] = { chLatin_p, chLatin_o, chLatin_r, chLatin_t, chNull };
 
-class TCPListener : virtual public SocketListener
-{
-public:
-    TCPListener(const DOMElement* e);
-    ~TCPListener() {}
-
-    bool create(ShibSocket& s) const;
-    bool bind(ShibSocket& s, bool force=false) const;
-    bool connect(ShibSocket& s) const;
-    bool close(ShibSocket& s) const;
-    bool accept(ShibSocket& listener, ShibSocket& s) const;
-    
-    int send(ShibSocket& s, const char* buf, int len) const {
-        return ::send(s, buf, len, 0);
-    }
-    
-    int recv(ShibSocket& s, char* buf, int buflen) const {
-        return ::recv(s, buf, buflen, 0);
+namespace shibsp {
+    static const XMLCh address[] = UNICODE_LITERAL_7(a,d,d,r,e,s,s);
+    static const XMLCh port[] = UNICODE_LITERAL_4(p,o,r,t);
+    static const XMLCh acl[] = UNICODE_LITERAL_3(a,c,l);
+
+    class TCPListener : virtual public SocketListener
+    {
+    public:
+        TCPListener(const DOMElement* e);
+        ~TCPListener() {}
+
+        bool create(ShibSocket& s) const;
+        bool bind(ShibSocket& s, bool force=false) const;
+        bool connect(ShibSocket& s) const;
+        bool close(ShibSocket& s) const;
+        bool accept(ShibSocket& listener, ShibSocket& s) const;
+        
+        int send(ShibSocket& s, const char* buf, int len) const {
+            return ::send(s, buf, len, 0);
+        }
+        
+        int recv(ShibSocket& s, char* buf, int buflen) const {
+            return ::recv(s, buf, buflen, 0);
+        }
+        
+    private:
+        void setup_tcp_sockaddr(struct sockaddr_in* addr) const;
+
+        string m_address;
+        unsigned short m_port;
+        vector<string> m_acl;
+    };
+
+    ListenerService* SHIBSP_DLLLOCAL TCPListenerServiceFactory(const DOMElement* const & e)
+    {
+        return new TCPListener(e);
     }
-    
-private:
-    void setup_tcp_sockaddr(struct sockaddr_in* addr) const;
-
-    string m_address;
-    unsigned short m_port;
-    vector<string> m_acl;
 };
 
-IPlugIn* TCPListenerFactory(const DOMElement* e)
-{
-    return new TCPListener(e);
-}
-
 TCPListener::TCPListener(const DOMElement* e) : SocketListener(e), m_address("127.0.0.1"), m_port(12345)
 {
     // We're stateless, but we need to load the configuration.
@@ -93,7 +99,7 @@ TCPListener::TCPListener(const DOMElement* e) : SocketListener(e), m_address("12
             m_port=12345;
     }
     
-    tag=e->getAttributeNS(NULL,SHIBT_L(acl));
+    tag=e->getAttributeNS(NULL,acl);
     if (tag && *tag) {
         auto_ptr_char temp(tag);
         string sockacl=temp.get();
similarity index 63%
rename from shib-target/UnixListener.cpp
rename to shibsp/UnixListener.cpp
index b837585..dd45509 100644 (file)
  * Unix Domain-based SocketListener implementation\r
  */\r
 \r
-#include "RPCListener.h"\r
+#include "internal.h"\r
+#include "SocketListener.h"\r
+\r
+#include <xercesc/util/XMLUniDefs.hpp>\r
+#include <xmltooling/unicode.h>\r
 \r
 #ifdef HAVE_UNISTD_H\r
 # include <sys/socket.h>\r
 #include <stdlib.h>\r
 #include <errno.h>\r
 \r
+using namespace shibsp;\r
+using namespace xmltooling;\r
+using namespace xercesc;\r
 using namespace std;\r
-using namespace saml;\r
-using namespace shibboleth;\r
-using namespace shibtarget;\r
-using namespace log4cpp;\r
 \r
-static const XMLCh address[] = { chLatin_a, chLatin_d, chLatin_d, chLatin_r, chLatin_e, chLatin_s, chLatin_s, chNull };\r
 \r
-class UnixListener : virtual public SocketListener\r
-{\r
-public:\r
-    UnixListener(const DOMElement* e);\r
-    ~UnixListener() {if (m_bound) unlink(m_address.c_str());}\r
-\r
-    bool create(ShibSocket& s) const;\r
-    bool bind(ShibSocket& s, bool force=false) const;\r
-    bool connect(ShibSocket& s) const;\r
-    bool close(ShibSocket& s) const;\r
-    bool accept(ShibSocket& listener, ShibSocket& s) const;\r
-\r
-    int send(ShibSocket& s, const char* buf, int len) const {\r
-        return ::send(s, buf, len, 0);\r
-    }\r
-    \r
-    int recv(ShibSocket& s, char* buf, int buflen) const {\r
-        return ::recv(s, buf, buflen, 0);\r
+namespace shibsp {\r
+    static const XMLCh address[] = UNICODE_LITERAL_7(a,d,d,r,e,s,s);\r
+\r
+    class UnixListener : virtual public SocketListener\r
+    {\r
+    public:\r
+        UnixListener(const DOMElement* e);\r
+        ~UnixListener() {if (m_bound) unlink(m_address.c_str());}\r
+\r
+        bool create(ShibSocket& s) const;\r
+        bool bind(ShibSocket& s, bool force=false) const;\r
+        bool connect(ShibSocket& s) const;\r
+        bool close(ShibSocket& s) const;\r
+        bool accept(ShibSocket& listener, ShibSocket& s) const;\r
+\r
+        int send(ShibSocket& s, const char* buf, int len) const {\r
+            return ::send(s, buf, len, 0);\r
+        }\r
+        \r
+        int recv(ShibSocket& s, char* buf, int buflen) const {\r
+            return ::recv(s, buf, buflen, 0);\r
+        }\r
+        \r
+    private:\r
+        string m_address;\r
+        mutable bool m_bound;\r
+    };\r
+\r
+    ListenerService* SHIBSP_DLLLOCAL UnixListenerServiceFactory(const DOMElement* const & e)\r
+    {\r
+        return new UnixListener(e);\r
     }\r
-    \r
-private:\r
-    string m_address;\r
-    mutable bool m_bound;\r
 };\r
 \r
-IPlugIn* UnixListenerFactory(const DOMElement* e)\r
-{\r
-    return new UnixListener(e);\r
-}\r
-\r
-UnixListener::UnixListener(const DOMElement* e) : RPCListener(e), m_address("/var/run/shar-socket"), m_bound(false)\r
+UnixListener::UnixListener(const DOMElement* e) : SocketListener(e), m_address("/var/run/shar-socket"), m_bound(false)\r
 {\r
     // We're stateless, but we need to load the configuration.\r
     const XMLCh* tag=e->getAttributeNS(NULL,address);\r
@@ -149,11 +155,3 @@ bool UnixListener::accept(ShibSocket& listener, ShibSocket& s) const
         return log_error();\r
     return true;\r
 }\r
-\r
-CLIENT* UnixListener::getClientHandle(ShibSocket& s, u_long program, u_long version) const\r
-{\r
-    struct sockaddr_in sin;\r
-    memset (&sin, 0, sizeof (sin));\r
-    sin.sin_port = 1;\r
-    return clnttcp_create(&sin, program, version, &s, 0, 0);\r
-}\r
similarity index 92%
rename from shib-target/ddf.cpp
rename to shibsp/ddf.cpp
index 2ae30ef..3716203 100644 (file)
  * limitations under the License.
  */
 
-/*
- * ddf.cpp - C++ DDF abstraction for interpretive RPC
- *
- * Created by:  Scott Cantor and Tom Sanfilippo, OSU
- *
- * $Id$
+/**
+ * ddf.cpp
+ * 
+ * C++ DDF abstraction for interpretive RPC
  */
 
+#include "internal.h"
+
 #ifdef WIN32
-# define _CRT_NONSTDC_NO_DEPRECATE 1
-# define _CRT_SECURE_NO_DEPRECATE 1
-# define SHIBTARGET_EXPORTS __declspec(dllexport)
 # define snprintf _snprintf
 #endif
 
-#include <saml/saml.h>
-#include <shib-target/ddf.h>
+#include <shibsp/ddf.h>
 
 #include <stdexcept>
-
-using namespace saml;
-using namespace shibtarget;
+#include <xercesc/dom/DOM.hpp>
+#include <xercesc/util/XMLUniDefs.hpp>
+#include <xmltooling/XMLToolingConfig.h>
+#include <xmltooling/util/ParserPool.h>
+#include <xmltooling/util/XMLHelper.h>
+
+using namespace shibsp;
+using namespace xmltooling;
+using namespace xercesc;
 using namespace std;
 
 // defensive string functions
@@ -85,7 +87,7 @@ char* ddf_token(const char** path, char* name)
 
 // body implementation
 
-struct shibtarget::ddf_body_t {
+struct shibsp::ddf_body_t {
     ddf_body_t() : name(NULL), parent(NULL), next(NULL), prev(NULL), type(DDF_EMPTY) {}
 
     char* name;                     // name of node
@@ -285,8 +287,6 @@ long DDF::integer() const
             case ddf_body_t::DDF_STRUCT:
             case ddf_body_t::DDF_LIST:
                 return m_handle->value.children.count;
-            case ddf_body_t::DDF_POINTER:
-                return reinterpret_cast<long>(m_handle->value.pointer);
         }
     }
     return 0;
@@ -885,7 +885,7 @@ void serialize(ddf_body_t* p, ostream& os, bool name_attr=true)
 
 // The stream insertion will work for any ostream-based object.
 
-SHIBTARGET_EXPORTS ostream& shibtarget::operator<<(ostream& os, const DDF& obj)
+SHIBSP_API ostream& shibsp::operator<<(ostream& os, const DDF& obj)
 {
     os.precision(15);
     os << "<wddxPacket version=\"1.0\" lowercase=\"no\">\n<header/>\n<data>\n";
@@ -924,15 +924,14 @@ static const char* g_DocType=
 // This function constructs a DDF object equivalent to the wddx data element rooted
 // by the input.
 
-static const XMLCh _no[] = { chLatin_n, chLatin_o, chNull };
-static const XMLCh _name[] = { chLatin_n, chLatin_a, chLatin_m, chLatin_e, chNull };
-static const XMLCh _var[] = { chLatin_v, chLatin_a, chLatin_r, chNull };
-static const XMLCh _string[] = { chLatin_s, chLatin_t, chLatin_r, chLatin_i, chLatin_n, chLatin_g, chNull };
-static const XMLCh _number[] = { chLatin_n, chLatin_u, chLatin_m, chLatin_b, chLatin_e, chLatin_r, chNull };
-static const XMLCh _array[] = { chLatin_a, chLatin_r, chLatin_r, chLatin_a, chLatin_y, chNull };
-static const XMLCh _struct[] = { chLatin_s, chLatin_t, chLatin_r, chLatin_u, chLatin_c, chLatin_t, chNull };
-static const XMLCh _lowercase[] =
-{ chLatin_l, chLatin_o, chLatin_w, chLatin_e, chLatin_r, chLatin_c, chLatin_a, chLatin_s, chLatin_e, chNull };
+static const XMLCh _no[] =      UNICODE_LITERAL_2(n,o);
+static const XMLCh _name[] =    UNICODE_LITERAL_4(n,a,m,e);
+static const XMLCh _var[] =     UNICODE_LITERAL_3(v,a,r);
+static const XMLCh _string[] =  UNICODE_LITERAL_6(s,t,r,i,n,g);
+static const XMLCh _number[] =  UNICODE_LITERAL_6(n,u,m,b,e,r);
+static const XMLCh _array[] =   UNICODE_LITERAL_5(a,r,r,a,y);
+static const XMLCh _struct[] =  UNICODE_LITERAL_6(s,t,r,u,c,t);
+static const XMLCh _lowercase[] = UNICODE_LITERAL_9(l,o,w,e,r,c,a,s,e);
 
 DDF deserialize(DOMElement* root, bool lowercase)
 {
@@ -946,7 +945,7 @@ DDF deserialize(DOMElement* root, bool lowercase)
 
     const XMLCh* tag=root->getTagName();
     if (!XMLString::compareString(tag,_var)) {
-        root=saml::XML::getFirstChildElement(root);
+        root=XMLHelper::getFirstChildElement(root);
         tag=(root ? root->getTagName() : &chNull);
     }
 
@@ -989,25 +988,14 @@ DDF deserialize(DOMElement* root, bool lowercase)
     return obj;
 }
 
-SHIBTARGET_EXPORTS istream& shibtarget::operator>>(istream& is, DDF& obj)
+SHIBSP_API istream& shibsp::operator>>(istream& is, DDF& obj)
 {
     // Parse the input stream into a DOM tree and construct the equivalent DDF.
-    DOMDocument* doc=NULL;
-    try {
-        XML::StreamInputSource src(is);
-        Wrapper4InputSource dsrc(&src,false);
-        saml::XML::Parser parser(false);    // non-validating
-        doc=parser.parse(dsrc);
-        const XMLCh* lowercase=doc->getDocumentElement()->getAttribute(_lowercase);
-        DOMElement* first=saml::XML::getFirstChildElement(saml::XML::getLastChildElement(doc->getDocumentElement()));
-        obj.destroy();
-        obj=deserialize(first,XMLString::compareString(lowercase,_no)!=0);
-        doc->release();
-    }
-    catch(...) {
-        if (doc)
-            doc->release();
-        throw;
-    }
+    DOMDocument* doc = XMLToolingConfig::getConfig().getParser().parse(is);
+    XercesJanitor<DOMDocument> docj(doc);
+    const XMLCh* lowercase=doc->getDocumentElement()->getAttribute(_lowercase);
+    DOMElement* first=XMLHelper::getFirstChildElement(XMLHelper::getLastChildElement(doc->getDocumentElement()));
+    obj.destroy();
+    obj=deserialize(first,XMLString::compareString(lowercase,_no)!=0);
     return is;
 }
diff --git a/shibsp/ddf.h b/shibsp/ddf.h
new file mode 100644 (file)
index 0000000..11700ad
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ *  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
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ */
+
+/**
+ * @file shibsp/ddf.h
+ * 
+ * C++ DDF abstraction for interpretive RPC
+ */
+
+#ifndef __ddf_h__
+#define __ddf_h__
+
+#include <shibsp/base.h>
+
+#include <cstdio>
+#include <iostream>
+
+namespace shibsp {
+
+    /**
+     * DDF objects are implemented with a handle-body idiom and require explicit
+     * destruction in order to allow stack objects to be freely mixed in structures
+     * with heap objects. When stack objects leave scope, only the handle is freed.
+     * Copying and assigning handle objects is a constant time operation equivalent
+     * to a single pointer assignment, handled by compiler-generated behavior.
+     */
+    class SHIBSP_API DDF
+    {
+    public:
+        /// @cond OFF
+        // constructors
+        DDF() : m_handle(NULL) {}
+        DDF(const char* n);
+        DDF(const char* n, const char* val);
+        DDF(const char* n, long val);
+        DDF(const char* n, double val);
+        DDF(const char* n, void* val);
+    
+        DDF& destroy();         // deep destructor
+        DDF copy() const;       // deep copy routine
+    
+        // property accessors
+        const char* name() const;           DDF& name(const char* n);
+    
+        // basic type checking
+        bool isnull() const;
+        bool isempty() const;
+        bool isstring() const;
+        bool isint() const;
+        bool isfloat() const;
+        bool isstruct() const;
+        bool islist() const;
+        bool ispointer() const;
+    
+        // type conversion and value extraction
+        const char* string() const;     // legal for str
+        long        integer() const;    // legal for all types
+        double      floating() const;   // legal for float
+        void*       pointer() const;    // legal for pointer
+    
+        // string helper methods
+        size_t strlen() const;
+        bool operator==(const char* s) const;
+    
+        // destructive node conversion methods
+        DDF& empty();
+        DDF& string(const char* val);
+        DDF& string(long val);
+        DDF& string(double val);
+        DDF& integer(long val);
+        DDF& integer(const char* val);
+        DDF& floating(double val);
+        DDF& floating(const char* val);
+        DDF& structure();
+        DDF& list();
+        DDF& pointer(void* val);
+    
+        // list/struct methods
+        DDF& add(DDF& child);
+        DDF& addbefore(DDF& child, DDF& before);
+        DDF& addafter(DDF& child, DDF& after);
+        void swap(DDF& arg);
+        DDF& remove();
+    
+        // C-style iterators
+        DDF parent() const;
+        DDF first();
+        DDF next();
+        DDF last();
+        DDF previous();
+        
+        // indexed operators
+        DDF operator[](unsigned long index) const;
+        DDF operator[](const char* path) const { return getmember(path); }
+    
+        // named member access/creation
+        DDF addmember(const char* path);
+        DDF getmember(const char* path) const;
+    
+        // debugging
+        void dump(FILE* f=NULL, int indent=0) const;
+    
+        // serialization functions need private access
+        friend SHIBSP_API std::ostream& operator<<(std::ostream& os, const DDF& obj);
+        friend SHIBSP_API std::istream& operator>>(std::istream& is, DDF& obj);
+        /// @endcond
+    private:
+        struct ddf_body_t* m_handle;
+    };
+
+    /**
+     * Serializes a DDF object to a stream.
+     * 
+     * @param os    output stream
+     * @param obj   DDF object to serialize
+     * @return reference to the output stream
+     */    
+    SHIBSP_API std::ostream& operator<<(std::ostream& os, const DDF& obj);
+
+    /**
+     * Reconstitutes a DDF object from a stream.
+     * 
+     * @param is    input stream
+     * @param obj   DDF object to reconstitute
+     * @return reference to the input stream
+     */
+    SHIBSP_API std::istream& operator>>(std::istream& is, DDF& obj);
+    
+    /**
+     * A "smart pointer" for disposing of DDF objects when they leave scope.
+     */
+    class SHIBSP_API DDFJanitor
+    {
+    public:
+        DDFJanitor(DDF& obj) : m_obj(obj) {}
+        ~DDFJanitor() { m_obj.destroy(); }
+    private:
+        DDF& m_obj;
+        DDFJanitor(const DDFJanitor&);
+        DDFJanitor& operator=(const DDFJanitor&);
+    };
+
+}
+
+#endif // __ddf_h__
index 13f2598..95ca5c2 100644 (file)
 #ifndef __shibsp_internal_h__
 #define __shibsp_internal_h__
 
+#ifndef FD_SETSIZE\r
+# define FD_SETSIZE 1024\r
+#endif\r
+
 #ifdef WIN32
 # define _CRT_SECURE_NO_DEPRECATE 1
 # define _CRT_NONSTDC_NO_DEPRECATE 1
diff --git a/shibsp/resource.h b/shibsp/resource.h
new file mode 100644 (file)
index 0000000..8df1c2f
--- /dev/null
@@ -0,0 +1,15 @@
+//{{NO_DEPENDENCIES}}\r
+// Microsoft Developer Studio generated include file.\r
+// Used by shibsp.rc\r
+//\r
+\r
+// Next default values for new objects\r
+// \r
+#ifdef APSTUDIO_INVOKED\r
+#ifndef APSTUDIO_READONLY_SYMBOLS\r
+#define _APS_NEXT_RESOURCE_VALUE        101\r
+#define _APS_NEXT_COMMAND_VALUE         40001\r
+#define _APS_NEXT_CONTROL_VALUE         1000\r
+#define _APS_NEXT_SYMED_VALUE           101\r
+#endif\r
+#endif\r
diff --git a/shibsp/shibsp.rc b/shibsp/shibsp.rc
new file mode 100644 (file)
index 0000000..c5cc32b
--- /dev/null
@@ -0,0 +1,117 @@
+//Microsoft Developer Studio generated resource script.\r
+//\r
+#include "resource.h"\r
+\r
+#define APSTUDIO_READONLY_SYMBOLS\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// Generated from the TEXTINCLUDE 2 resource.\r
+//\r
+#include "afxres.h"\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+#undef APSTUDIO_READONLY_SYMBOLS\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// English (U.S.) resources\r
+\r
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r
+#ifdef _WIN32\r
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US\r
+#pragma code_page(1252)\r
+#endif //_WIN32\r
+\r
+#ifndef _MAC\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// Version\r
+//\r
+\r
+VS_VERSION_INFO VERSIONINFO\r
+ FILEVERSION 1,0,0,0\r
+ PRODUCTVERSION 2,0,0,0\r
+ FILEFLAGSMASK 0x3fL\r
+#ifdef _DEBUG\r
+ FILEFLAGS 0x1L\r
+#else\r
+ FILEFLAGS 0x0L\r
+#endif\r
+ FILEOS 0x40004L\r
+ FILETYPE 0x2L\r
+ FILESUBTYPE 0x0L\r
+BEGIN\r
+    BLOCK "StringFileInfo"\r
+    BEGIN\r
+        BLOCK "040904b0"\r
+        BEGIN\r
+            VALUE "Comments", "\0"\r
+            VALUE "CompanyName", "Internet2\0"\r
+            VALUE "FileDescription", "Shibboleth SP Library\0"\r
+            VALUE "FileVersion", "1, 0, 0, 0\0"\r
+#ifdef _DEBUG\r
+            VALUE "InternalName", "shibsp1_0D\0"\r
+#else\r
+            VALUE "InternalName", "shibsp1_0\0"\r
+#endif\r
+            VALUE "LegalCopyright", "Copyright © 2006 Internet2\0"\r
+            VALUE "LegalTrademarks", "\0"\r
+#ifdef _DEBUG\r
+            VALUE "OriginalFilename", "shibsp1_0D.dll\0"\r
+#else\r
+            VALUE "OriginalFilename", "shibsp1_0.dll\0"\r
+#endif\r
+            VALUE "PrivateBuild", "\0"\r
+            VALUE "ProductName", "Shibboleth 2.0\0"\r
+            VALUE "ProductVersion", "2, 0, 0, 0\0"\r
+            VALUE "SpecialBuild", "\0"\r
+        END\r
+    END\r
+    BLOCK "VarFileInfo"\r
+    BEGIN\r
+        VALUE "Translation", 0x409, 1200\r
+    END\r
+END\r
+\r
+#endif    // !_MAC\r
+\r
+\r
+#ifdef APSTUDIO_INVOKED\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// TEXTINCLUDE\r
+//\r
+\r
+1 TEXTINCLUDE DISCARDABLE \r
+BEGIN\r
+    "resource.h\0"\r
+END\r
+\r
+2 TEXTINCLUDE DISCARDABLE \r
+BEGIN\r
+    "#include ""afxres.h""\r\n"\r
+    "\0"\r
+END\r
+\r
+3 TEXTINCLUDE DISCARDABLE \r
+BEGIN\r
+    "\r\n"\r
+    "\0"\r
+END\r
+\r
+#endif    // APSTUDIO_INVOKED\r
+\r
+#endif    // English (U.S.) resources\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+\r
+\r
+#ifndef APSTUDIO_INVOKED\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// Generated from the TEXTINCLUDE 3 resource.\r
+//\r
+\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+#endif    // not APSTUDIO_INVOKED\r
+\r
index 803a9a2..2ace6c5 100644 (file)
                        UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"\r
                        >\r
                        <File\r
+                               RelativePath=".\ddf.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\ListenerService.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\SocketListener.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath=".\SPConfig.cpp"\r
                                >\r
                        </File>\r
                                >\r
                        </File>\r
                        <File\r
+                               RelativePath=".\ddf.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath=".\exceptions.h"\r
                                >\r
                        </File>\r
                                >\r
                        </File>\r
                        <File\r
+                               RelativePath=".\ListenerService.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\resource.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\SocketListener.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath=".\SPConfig.h"\r
                                >\r
                        </File>\r
                        <File\r
+                               RelativePath=".\TCPListener.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath=".\version.h"\r
                                >\r
                        </File>\r
                        Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"\r
                        UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"\r
                        >\r
+                       <File\r
+                               RelativePath=".\shibsp.rc"\r
+                               >\r
+                       </File>\r
                </Filter>\r
        </Files>\r
        <Globals>\r