reSIProcate
SIP stack, Dialog Usage Manager and related libraries
Loading...
Searching...
No Matches
TlsServer.cxx
Go to the documentation of this file.
1#if defined(HAVE_CONFIG_H)
2#include "config.h"
3#endif
4
5#ifdef USE_SSL
6
7#include "TlsServer.hxx"
8#include <functional>
9#include <rutil/Data.hxx>
11#include <rutil/Logger.hxx>
12#include "ReTurnSubsystem.hxx"
13
14#define RESIPROCATE_SUBSYSTEM ReTurnSubsystem::RETURN
15
16namespace reTurn {
17
18TlsServer::TlsServer(asio::io_context& ioService, RequestHandler& requestHandler, const asio::ip::address& address, unsigned short port)
19: mIOService(ioService),
20 mAcceptor(ioService),
21 mContext(asio::ssl::context::sslv23), // SSLv23 (actually chooses TLS version dynamically)
22 mConnectionManager(requestHandler.getTurnManager()),
23 mRequestHandler(requestHandler)
24{
25 // Set Context options
26 asio::error_code ec;
27 mContext.set_options(asio::ssl::context::default_workarounds | // Implement various bug workarounds.
28 asio::ssl::context::single_dh_use); // enforce recalculation of the DH key for eatch session
29 // OpenSSLCTXSetOptions / OpenSSLCTXClearOptions, eg. SSL_OP_NO_TLSv1 and SSL_OP_NO_TLSv1_1 to require TLS 1.2
30 SSL_CTX_set_options(mContext.native_handle(), mRequestHandler.getConfig().mOpenSSLCTXSetOptions);
31 SSL_CTX_clear_options(mContext.native_handle(), mRequestHandler.getConfig().mOpenSSLCTXClearOptions);
32
33 mContext.set_password_callback(std::bind(&TlsServer::getPassword, this));
34
35 // Use a certificate chain from a file.
36 mContext.use_certificate_chain_file(mRequestHandler.getConfig().mTlsServerCertificateFilename.c_str(), ec);
37 if(ec)
38 {
39 ErrLog(<< "Unable to load server cert chain file: " << mRequestHandler.getConfig().mTlsServerCertificateFilename << ", error=" << ec.value() << "(" << ec.message() << ")");
40 throw asio::system_error(ec);
41 }
42
43 // Use a private key from a file.
45 if(keyFilename.empty())
46 {
48 }
49 mContext.use_private_key_file(keyFilename.c_str(), asio::ssl::context::pem, ec);
50 if(ec)
51 {
52 ErrLog(<< "Unable to load server private key file: " << keyFilename << ", error=" << ec.value() << "(" << ec.message() << ")");
53 throw asio::system_error(ec);
54 }
55
56 // Use the specified file to obtain the temporary Diffie-Hellman parameters.
57 mContext.use_tmp_dh_file(mRequestHandler.getConfig().mTlsTempDhFilename.c_str(), ec);
58 if(ec)
59 {
60 ErrLog(<< "Unable to load temporary Diffie-Hellman parameters file: " << mRequestHandler.getConfig().mTlsTempDhFilename << ", error=" << ec.value() << "(" << ec.message() << ")");
61 throw asio::system_error(ec);
62 }
63
64 // Open the acceptor with the option to reuse the address (i.e. SO_REUSEADDR).
65 asio::ip::tcp::endpoint endpoint(address, port);
66
67 mAcceptor.open(endpoint.protocol());
68 mAcceptor.set_option(asio::ip::tcp::acceptor::reuse_address(true));
69#ifdef USE_IPV6
70#ifdef __linux__
71 if(address.is_v6())
72 {
73 asio::ip::v6_only v6_opt(true);
74 mAcceptor.set_option(v6_opt);
75 }
76#endif
77#endif
78 mAcceptor.bind(endpoint);
79 mAcceptor.listen();
80
81 InfoLog(<< "TlsServer started. Listening on " << address.to_string() << ":" << port);
82}
83
84void
86{
87 mNewConnection.reset(new TlsConnection(mIOService, mConnectionManager, mRequestHandler, mContext));
88 mAcceptor.async_accept(((TlsConnection*)mNewConnection.get())->socket(), std::bind(&TlsServer::handleAccept, this, std::placeholders::_1));
89}
90
91std::string
92TlsServer::getPassword() const
93{
94 return mRequestHandler.getConfig().mTlsPrivateKeyPassword.c_str();
95}
96
97void
98TlsServer::handleAccept(const asio::error_code& e)
99{
100 if (!e)
101 {
102 // Started if its client's address doesn't already have too many connections
103 asio::error_code ec;
104 const asio::ip::address remoteAddress = ((TlsConnection*)mNewConnection.get())->socket().remote_endpoint(ec).address();
105 if(!ec)
106 {
107 mConnectionManager.start(mNewConnection, remoteAddress);
108 }
109 else
110 {
111 mNewConnection->stop(); // eg. the client has gone already
112 }
113
114 mNewConnection.reset(new TlsConnection(mIOService, mConnectionManager, mRequestHandler, mContext));
115 mAcceptor.async_accept(((TlsConnection*)mNewConnection.get())->socket(), std::bind(&TlsServer::handleAccept, this, std::placeholders::_1));
116 }
117 else
118 {
119 ErrLog(<< "Error in handleAccept: " << e.value() << "-" << e.message());
120 if(e == asio::error::no_descriptors)
121 {
122 // Retry if too many open files (ie. out of socket descriptors)
123 mNewConnection.reset(new TlsConnection(mIOService, mConnectionManager, mRequestHandler, mContext));
124 mAcceptor.async_accept(((TlsConnection*)mNewConnection.get())->socket(), std::bind(&TlsServer::handleAccept, this, std::placeholders::_1));
125 }
126 }
127}
128
129}
130
131#endif
132
133/* ====================================================================
134
135 Copyright (c) 2008-2026 SIP Spectrum, Inc. https://www.sipspectrum.com
136 Copyright (c) 2007-2008, Plantronics, Inc.
137 All rights reserved.
138
139 Redistribution and use in source and binary forms, with or without
140 modification, are permitted provided that the following conditions are
141 met:
142
143 1. Redistributions of source code must retain the above copyright
144 notice, this list of conditions and the following disclaimer.
145
146 2. Redistributions in binary form must reproduce the above copyright
147 notice, this list of conditions and the following disclaimer in the
148 documentation and/or other materials provided with the distribution.
149
150 3. Neither the name of Plantronics nor the names of its contributors
151 may be used to endorse or promote products derived from this
152 software without specific prior written permission.
153
154 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
155 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
156 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
157 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
158 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
159 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
160 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
161 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
162 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
163 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
164 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
165
166 ==================================================================== */
#define InfoLog(args_)
Definition Logger.hxx:131
#define ErrLog(args_)
Definition Logger.hxx:137
void start(ConnectionPtr c, const asio::ip::address &remoteAddress)
Add the specified connection, from remoteAddress, to the manager and start it - or,...
resip::Data mTlsTempDhFilename
resip::Data mTlsPrivateKeyPassword
resip::Data mTlsServerCertificateFilename
resip::Data mTlsServerPrivateKeyFilename
The common handler for all incoming requests.
const ReTurnConfig & getConfig()
Represents a single connection from a client.
TlsServer(const TlsServer &)=delete
An alternative to std::string, encapsulates an arbitrary buffer of bytes.
Definition Data.hxx:90
const char * c_str() const
Returns a null-terminated string representing.
Definition Data.cxx:1097
void list()
Definition userAdmin.cxx:66