SSPCPP-616 - clean up concatenated string literals
[shibboleth/cpp-sp.git] / shibsp / remoting / impl / ListenerService.cpp
1 /**
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.
6  *
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
10  * License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
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.
19  */
20
21 /**
22  * ListenerService.cpp
23  *
24  * Interprocess remoting engine.
25  */
26
27 #include "internal.h"
28 #include "exceptions.h"
29 #include "ServiceProvider.h"
30 #include "remoting/ListenerService.h"
31
32 #include <xercesc/dom/DOM.hpp>
33 #include <xmltooling/security/SecurityHelper.h>
34
35 using namespace shibsp;
36 using namespace xmltooling;
37 using namespace xercesc;
38 using namespace std;
39
40 namespace shibsp {
41     SHIBSP_DLLLOCAL PluginManager<ListenerService,string,const DOMElement*>::Factory TCPListenerServiceFactory;
42 #ifndef WIN32
43     SHIBSP_DLLLOCAL PluginManager<ListenerService,string,const DOMElement*>::Factory UnixListenerServiceFactory;
44 #endif
45 };
46
47 void SHIBSP_API shibsp::registerListenerServices()
48 {
49     SPConfig& conf=SPConfig::getConfig();
50     conf.ListenerServiceManager.registerFactory(TCP_LISTENER_SERVICE, TCPListenerServiceFactory);
51 #ifndef WIN32
52     conf.ListenerServiceManager.registerFactory(UNIX_LISTENER_SERVICE, UnixListenerServiceFactory);
53 #endif
54 }
55
56 Remoted::Remoted()
57 {
58 }
59
60 Remoted::~Remoted()
61 {
62 }
63
64 ListenerService::ListenerService()
65 {
66 }
67
68 ListenerService::~ListenerService()
69 {
70 }
71
72 Remoted* ListenerService::regListener(const char* address, Remoted* listener)
73 {
74     Remoted* ret=nullptr;
75     map<string,Remoted*>::const_iterator i=m_listenerMap.find(address);
76     if (i!=m_listenerMap.end())
77         ret=i->second;
78     m_listenerMap[address]=listener;
79     Category::getInstance(SHIBSP_LOGCAT ".Listener").info("registered remoted message endpoint (%s)",address);
80     return ret;
81 }
82
83 bool ListenerService::unregListener(const char* address, Remoted* current, Remoted* restore)
84 {
85     map<string,Remoted*>::const_iterator i=m_listenerMap.find(address);
86     if (i!=m_listenerMap.end() && i->second==current) {
87         if (restore)
88             m_listenerMap[address]=restore;
89         else
90             m_listenerMap.erase(address);
91         Category::getInstance(SHIBSP_LOGCAT ".Listener").info("unregistered remoted message endpoint (%s)",address);
92         return true;
93     }
94     return false;
95 }
96
97 Remoted* ListenerService::lookup(const char *address) const
98 {
99     map<string,Remoted*>::const_iterator i=m_listenerMap.find(address);
100     return (i==m_listenerMap.end()) ? nullptr : i->second;
101 }
102
103 void ListenerService::receive(DDF &in, ostream& out)
104 {
105     if (!in.name())
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);
110         out << outmsg;
111         return;
112     }
113     else if (!strcmp("hash", in.name())) {
114 #ifndef SHIBSP_LITE
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.");
119         DDF outmsg(nullptr);
120         DDFJanitor jan(outmsg);
121         outmsg.string(SecurityHelper::doHash(hashAlg, data, strlen(data)).c_str());
122         out << outmsg;
123         return;
124 #else
125         throw ListenerException("Hash algorithms unavailable in lite build of library.");
126 #endif
127     }
128
129     // Two stage lookup, on the listener itself, and the SP interface.
130     ServiceProvider* sp = SPConfig::getConfig().getServiceProvider();
131     Locker locker(sp);
132     Remoted* dest = lookup(in.name());
133     if (!dest) {
134         dest = sp->lookupListener(in.name());
135         if (!dest)
136             throw ListenerException("No destination registered for incoming message addressed to ($1).", params(1,in.name()));
137     }
138
139     dest->receive(in, out);
140 }
141
142 bool ListenerService::init(bool force)
143 {
144     return true;
145 }
146
147 void ListenerService::term()
148 {
149 }