2 * Licensed to the University Corporation for Advanced Internet
3 * Development, Inc. (UCAID) under one or more contributor license
4 * agreements. See the NOTICE file distributed with this work for
5 * additional information regarding copyright ownership.
7 * UCAID licenses this file to you under the Apache License,
8 * Version 2.0 (the "License"); you may not use this file except
9 * in compliance with the License. You may obtain a copy of the
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
17 * either express or implied. See the License for the specific
18 * language governing permissions and limitations under the License.
24 * Interprocess remoting engine.
28 #include "exceptions.h"
29 #include "ServiceProvider.h"
30 #include "remoting/ListenerService.h"
32 #include <xercesc/dom/DOM.hpp>
33 #include <xmltooling/security/SecurityHelper.h>
35 using namespace shibsp;
36 using namespace xmltooling;
37 using namespace xercesc;
41 SHIBSP_DLLLOCAL PluginManager<ListenerService,string,const DOMElement*>::Factory TCPListenerServiceFactory;
43 SHIBSP_DLLLOCAL PluginManager<ListenerService,string,const DOMElement*>::Factory UnixListenerServiceFactory;
47 void SHIBSP_API shibsp::registerListenerServices()
49 SPConfig& conf=SPConfig::getConfig();
50 conf.ListenerServiceManager.registerFactory(TCP_LISTENER_SERVICE, TCPListenerServiceFactory);
52 conf.ListenerServiceManager.registerFactory(UNIX_LISTENER_SERVICE, UnixListenerServiceFactory);
64 ListenerService::ListenerService()
68 ListenerService::~ListenerService()
72 Remoted* ListenerService::regListener(const char* address, Remoted* listener)
75 map<string,Remoted*>::const_iterator i=m_listenerMap.find(address);
76 if (i!=m_listenerMap.end())
78 m_listenerMap[address]=listener;
79 Category::getInstance(SHIBSP_LOGCAT ".Listener").info("registered remoted message endpoint (%s)",address);
83 bool ListenerService::unregListener(const char* address, Remoted* current, Remoted* restore)
85 map<string,Remoted*>::const_iterator i=m_listenerMap.find(address);
86 if (i!=m_listenerMap.end() && i->second==current) {
88 m_listenerMap[address]=restore;
90 m_listenerMap.erase(address);
91 Category::getInstance(SHIBSP_LOGCAT ".Listener").info("unregistered remoted message endpoint (%s)",address);
97 Remoted* ListenerService::lookup(const char *address) const
99 map<string,Remoted*>::const_iterator i=m_listenerMap.find(address);
100 return (i==m_listenerMap.end()) ? nullptr : i->second;
103 void ListenerService::receive(DDF &in, ostream& out)
106 throw ListenerException("Incoming message with no destination address rejected.");
107 else if (!strcmp("ping", in.name())) {
108 DDF outmsg = DDF(nullptr).integer(in.integer() + 1);
109 DDFJanitor jan(outmsg);
113 else if (!strcmp("hash", in.name())) {
115 const char* hashAlg = in["alg"].string();
116 const char* data = in["data"].string();
117 if (!hashAlg || !*hashAlg || !data || !*data)
118 throw ListenerException("Hash request missing algorithm or data parameters.");
120 DDFJanitor jan(outmsg);
121 outmsg.string(SecurityHelper::doHash(hashAlg, data, strlen(data)).c_str());
125 throw ListenerException("Hash algorithms unavailable in lite build of library.");
129 // Two stage lookup, on the listener itself, and the SP interface.
130 ServiceProvider* sp = SPConfig::getConfig().getServiceProvider();
132 Remoted* dest = lookup(in.name());
134 dest = sp->lookupListener(in.name());
136 throw ListenerException("No destination registered for incoming message addressed to ($1).", params(1,in.name()));
139 dest->receive(in, out);
142 bool ListenerService::init(bool force)
147 void ListenerService::term()