1//
2// DialogServer.cpp
3//
4// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
5// and Contributors.
6//
7// SPDX-License-Identifier: BSL-1.0
8//
9
10
11#include "DialogServer.h"
12#include "Poco/Net/DialogSocket.h"
13#include "Poco/Net/SocketAddress.h"
14#include "Poco/Timespan.h"
15#include <iostream>
16#include "Poco/Net/SecureStreamSocket.h"
17#include "Poco/Net/SSLManager.h"
18#include "Poco/Net/Context.h"
19#include "Poco/Net/SecureStreamSocketImpl.h"
20
21using Poco::Net::Socket;
22using Poco::Net::DialogSocket;
23using Poco::Net::SocketAddress;
24using Poco::FastMutex;
25using Poco::Thread;
26using Poco::Net::SecureStreamSocket;
27using Poco::Net::SSLManager;
28using Poco::Exception;
29using Poco::Net::Context;
30using Poco::Net::Session;
31using Poco::Net::SecureStreamSocketImpl;
32
33DialogServer::DialogServer(bool acceptCommands, bool ssl):
34 _socket(SocketAddress()),
35 _thread("DialogServer"),
36 _stop(false),
37 _acceptCommands(acceptCommands),
38 _log(false),
39 _ssl(ssl)
40{
41 _thread.start(*this);
42 _ready.wait();
43}
44
45
46DialogServer::~DialogServer()
47{
48 _stop = true;
49 _thread.join();
50}
51
52
53Poco::UInt16 DialogServer::port() const
54{
55 return _socket.address().port();
56}
57
58
59void handleDataSSLrequest(DialogSocket& ds, bool ssl, Session::Ptr& sslSession)
60{
61 if (ssl)
62 {
63 try
64 {
65 Context::Ptr cDefaultServerContext = SSLManager::instance().defaultServerContext();
66 SecureStreamSocket sss(SecureStreamSocket::attach(ds, cDefaultServerContext, sslSession));
67 sss.setLazyHandshake(true);
68 if (sss.completeHandshake() == 1)
69 {
70 ds = sss;
71 }
72 }
73 catch (Exception&) {
74 }
75 }
76}
77
78void handleSSLrequest(DialogSocket& ds, bool ssl, Session::Ptr& sslSession)
79{
80 if (ssl)
81 {
82 try
83 {
84 Context::Ptr cDefaultServerContext = SSLManager::instance().defaultServerContext();
85 ds.sendMessage("200 OK");
86 SecureStreamSocket sss(SecureStreamSocket::attach(ds, cDefaultServerContext));
87 sss.setLazyHandshake(true);
88 if (sss.completeHandshake() == 1)
89 {
90 ds = sss;
91
92 SecureStreamSocketImpl* pSecure = dynamic_cast<SecureStreamSocketImpl*>(sss.impl());
93 if (pSecure != nullptr)
94 sslSession = pSecure->currentSession();
95 }
96 else
97 {
98 ds.sendMessage("501 Explicit TLS authentication not available");
99 }
100 }
101 catch (Exception&) {
102 ds.sendMessage("501 Explicit TLS authentication not available");
103 }
104 }
105 else
106 {
107 ds.sendMessage("501 Explicit TLS authentication not available");
108 }
109}
110
111void DialogServer::run()
112{
113 _ready.set();
114 Poco::Timespan span(250000);
115 while (!_stop)
116 {
117 if (_socket.poll(span, Socket::SELECT_READ))
118 {
119 DialogSocket ds = _socket.acceptConnection();
120 if (!_SSLsession.isNull()) {
121 handleDataSSLrequest(ds, _ssl, _SSLsession);
122 }
123 {
124 FastMutex::ScopedLock lock(_mutex);
125 if (!_nextResponses.empty())
126 {
127 ds.sendMessage(_nextResponses.front());
128 _nextResponses.erase(_nextResponses.begin());
129 }
130 }
131 if (_acceptCommands)
132 {
133 try
134 {
135
136 std::string command;
137 while (ds.receiveMessage(command))
138 {
139 if ((command == "AUTH TLS") || (command == "AUTH SSL"))
140 {
141 handleSSLrequest(ds, _ssl, _SSLsession);
142 continue;
143 }
144 else if ((command == "PBSZ 0") || (command == "PROT P"))
145 {
146 ds.sendMessage("200 OK");
147 continue;
148 }
149
150 if (_log) std::cout << ">> " << command << std::endl;
151 {
152 FastMutex::ScopedLock lock(_mutex);
153 _lastCommands.push_back(command);
154 if (!_nextResponses.empty())
155 {
156 if (_log) std::cout << "<< " << _nextResponses.front() << std::endl;
157 ds.sendMessage(_nextResponses.front());
158 _nextResponses.erase(_nextResponses.begin());
159 }
160 }
161 }
162 }
163 catch (Poco::Exception& exc)
164 {
165 std::cerr << "DialogServer: " << exc.displayText() << std::endl;
166 }
167 }
168 }
169 }
170}
171
172
173const std::string& DialogServer::lastCommand() const
174{
175 FastMutex::ScopedLock lock(_mutex);
176
177 static const std::string EMPTY;
178 if (_lastCommands.empty())
179 return EMPTY;
180 else
181 return _lastCommands.back();
182}
183
184
185const std::vector<std::string>& DialogServer::lastCommands() const
186{
187 return _lastCommands;
188}
189
190
191std::string DialogServer::popCommand()
192{
193 FastMutex::ScopedLock lock(_mutex);
194
195 std::string command;
196 if (!_lastCommands.empty())
197 {
198 command = _lastCommands.front();
199 _lastCommands.erase(_lastCommands.begin());
200 }
201 return command;
202}
203
204
205std::string DialogServer::popCommandWait()
206{
207 std::string result(popCommand());
208 while (result.empty())
209 {
210 Thread::sleep(100);
211 result = popCommand();
212 }
213 return result;
214}
215
216
217void DialogServer::addResponse(const std::string& response)
218{
219 FastMutex::ScopedLock lock(_mutex);
220
221 _nextResponses.push_back(response);
222}
223
224
225void DialogServer::clearCommands()
226{
227 FastMutex::ScopedLock lock(_mutex);
228
229 _lastCommands.clear();
230}
231
232
233void DialogServer::clearResponses()
234{
235 FastMutex::ScopedLock lock(_mutex);
236
237 _nextResponses.clear();
238}
239
240
241void DialogServer::log(bool flag)
242{
243 _log = flag;
244}
245
246void DialogServer::setSslSession(Session::Ptr cSession)
247{
248 _SSLsession = cSession;
249}
250
251Session::Ptr DialogServer::getSslSession()
252{
253 return _SSLsession;
254}
255