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;
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();
+++ /dev/null
-/*
- * 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);
-}
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
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,
+++ /dev/null
-/*
- * 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__
/*
* 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);
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);
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);
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);
// 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);
) const;
};
- class SAML1Consumer : virtual public IHandler, public virtual IRemoted
+ class SAML1Consumer : virtual public IHandler, public virtual Remoted
{
public:
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
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--;
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;}
private:
friend class XMLConfigImpl;
- mutable IListener* m_listener;
+ mutable ListenerService* m_listener;
mutable ISessionCache* m_sessionCache;
mutable IReplayCache* m_replayCache;
};
}
}
- // 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?");
}
}
}
- 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)) {
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());
// New headers
#include <saml/base.h>
-#include <xmltooling/PluginManager.h>
+#include <shibsp/ListenerService.h>
// Old headers
#include <saml/saml.h>
# define SHIBTARGET_EXPORTS
#endif
-#include <shib-target/ddf.h>
-
namespace shibtarget {
DECLARE_SAML_EXCEPTION(SHIBTARGET_EXPORTS,ListenerException,SAMLException);
};
/**
- * 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
// 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;
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[];
>
</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>
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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__ */
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
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
#include "internal.h"
#include "exceptions.h"
+#include "ListenerService.h"
#include "SPConfig.h"
#include <log4cpp/Category.hh>
REGISTER_XMLTOOLING_EXCEPTION_FACTORY(ConfigurationException,shibsp);
REGISTER_XMLTOOLING_EXCEPTION_FACTORY(ListenerException,shibsp);
+
+ registerListenerServices();
log.info("library initialization complete");
return true;
//delete m_serviceProvider;
m_serviceProvider = NULL;
+
+ ListenerServiceManager.deregisterFactories();
SAMLConfig::getConfig().term();
log.info("library shutdown complete");
#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.
*/
return m_serviceProvider;
}
+ /**
+ * Manages factories for ListenerService plugins.
+ */
+ xmltooling::PluginManager<ListenerService,const xercesc::DOMElement*> ListenerServiceManager;
+
protected:
SPConfig() : m_serviceProvider(NULL) {}
unsigned long m_features;
};
+#if defined (_MSC_VER)
+ #pragma warning( pop )
+#endif
+
};
#endif /* __shibsp_config_h__ */
/**
* 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
SocketListener::ShibSocket SocketPool::connect()
{
#ifdef _DEBUG
- saml::NDC ndc("connect");
+ NDC ndc("connect");
#endif
m_log.debug("trying to connect to listener");
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);
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?
bool SocketListener::run(bool* shutdown)
{
#ifdef _DEBUG
- saml::NDC ndc("run");
+ NDC ndc("run");
#endif
// Save flag to monitor for shutdown request.
DDF SocketListener::send(const DDF& in)
{
#ifdef _DEBUG
- saml::NDC ndc("send");
+ NDC ndc("send");
#endif
log->debug("sending message: %s", in.name());
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.
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);
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);
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();
}
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();
#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");
// 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
*/
/**
- * @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);
protected:
bool log_error() const; // for OS-level errors
log4cpp::Category* log;
+ /// @endcond
private:
mutable SocketPool* m_socketpool;
};
}
-#endif /* __st_socklisten_h__ */
+#endif /* __shibsp_socklisten_h__ */
* 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.
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();
* 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
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
* 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
// 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
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;
// 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";
// 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)
{
const XMLCh* tag=root->getTagName();
if (!XMLString::compareString(tag,_var)) {
- root=saml::XML::getFirstChildElement(root);
+ root=XMLHelper::getFirstChildElement(root);
tag=(root ? root->getTagName() : &chNull);
}
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;
}
--- /dev/null
+/*
+ * 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__
#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
--- /dev/null
+//{{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
--- /dev/null
+//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
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