Line data Source code
1 : // Copyright (c) 2012-2024 Made to Order Software Corp. All Rights Reserved
2 : //
3 : // https://snapwebsites.org/project/eventdispatcher
4 : // contact@m2osw.com
5 : //
6 : // This program is free software; you can redistribute it and/or modify
7 : // it under the terms of the GNU General Public License as published by
8 : // the Free Software Foundation; either version 2 of the License, or
9 : // (at your option) any later version.
10 : //
11 : // This program is distributed in the hope that it will be useful,
12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : // GNU General Public License for more details.
15 : //
16 : // You should have received a copy of the GNU General Public License
17 : // along with this program; if not, write to the Free Software
18 : // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 :
20 : /** \file
21 : * \brief Event dispatch class.
22 : *
23 : * Class used to handle events.
24 : */
25 :
26 : // make sure we use OpenSSL with multi-thread support
27 : // (TODO: move to .cpp once we have the impl!)
28 : #define OPENSSL_THREAD_DEFINES
29 :
30 : // self
31 : //
32 : #include "eventdispatcher/tcp_bio_options.h"
33 :
34 : #include "eventdispatcher/tcp_private.h"
35 : #include "eventdispatcher/exception.h"
36 :
37 :
38 : // OpenSSL
39 : //
40 : #include <openssl/bio.h>
41 : #include <openssl/err.h>
42 :
43 :
44 : // C++
45 : //
46 : #include <memory>
47 :
48 :
49 : // last include
50 : //
51 : #include <snapdev/poison.h>
52 :
53 :
54 :
55 :
56 : #ifndef OPENSSL_THREADS
57 : #error "OPENSSL_THREADS is not defined. Snap! requires support for multiple threads in OpenSSL."
58 : #endif
59 :
60 : namespace ed
61 : {
62 :
63 :
64 :
65 : /** \brief Initialize the options object to the defaults.
66 : *
67 : * This constructor sets up the default options in this structure.
68 : */
69 108 : tcp_bio_options::tcp_bio_options()
70 : {
71 36 : }
72 :
73 :
74 : /** \brief Specify the depth of SSL certificate verification.
75 : *
76 : * When verifying a certificate, you may end up with a very long chain.
77 : * In most cases, a very long chain is not sensible and probably means
78 : * something fishy is going on. For this reason, this is verified here.
79 : *
80 : * The default is 4. Some people like to use 5 or 6. The full range
81 : * allows for way more, although really it should be very much
82 : * limited.
83 : *
84 : * \exception
85 : * This function accepts a number between 1 and 100. Any number outside
86 : * of that range and this exception is raised.
87 : *
88 : * \param[in] depth The depth for the verification of certificates.
89 : */
90 0 : void tcp_bio_options::set_verification_depth(size_t depth)
91 : {
92 0 : if(depth == 0
93 0 : || depth > MAX_VERIFICATION_DEPTH)
94 : {
95 0 : throw invalid_parameter("the depth parameter must be defined between 1 and 100 inclusive");
96 : }
97 :
98 0 : f_verification_depth = depth;
99 0 : }
100 :
101 :
102 : /** \brief Retrieve the verification maximum depth allowed.
103 : *
104 : * This function returns the verification depth parameter. This number
105 : * will always be between 1 and 100 inclusive.
106 : *
107 : * The inclusive maximum is actually defined as MAX_VERIFICATION_DEPTH.
108 : *
109 : * The default depth is 4.
110 : *
111 : * \return The current verification depth.
112 : */
113 0 : size_t tcp_bio_options::get_verification_depth() const
114 : {
115 0 : return f_verification_depth;
116 : }
117 :
118 :
119 : /** \brief Change the SSL options.
120 : *
121 : * This function sets the SSL options to the new \p ssl_options
122 : * values.
123 : *
124 : * By default the bio_client forbids:
125 : *
126 : * * SSL version 2
127 : * * SSL version 3
128 : * * TLS version 1.0
129 : * * SSL compression
130 : *
131 : * which are parameter that are known to create security issues.
132 : *
133 : * To make it easier to add options to the defaults, the class
134 : * offers the DEFAULT_SSL_OPTIONS option. Just add and remove
135 : * bits starting from that value.
136 : *
137 : * \param[in] ssl_options The new SSL options.
138 : */
139 0 : void tcp_bio_options::set_ssl_options(ssl_options_t ssl_options)
140 : {
141 0 : f_ssl_options = ssl_options;
142 0 : }
143 :
144 :
145 : /** \brief Retrieve the current SSL options.
146 : *
147 : * This function can be used to add and remove SSL options to
148 : * bio_client connections.
149 : *
150 : * For example, to also prevent TLS 1.1, add the new flag:
151 : *
152 : * \code
153 : * bio.set_ssl_options(bio.get_ssl_options() | SSL_OP_NO_TLSv1_1);
154 : * \endcode
155 : *
156 : * And to allow compression, remove a flag which is set by default:
157 : *
158 : * \code
159 : * bio.set_ssl_options(bio.get_ssl_options() & ~(SSL_OP_NO_COMPRESSION));
160 : * \endcode
161 : *
162 : * \return The current SSL options.
163 : */
164 0 : tcp_bio_options::ssl_options_t tcp_bio_options::get_ssl_options() const
165 : {
166 0 : return f_ssl_options;
167 : }
168 :
169 :
170 : /** \brief Change the default path to SSL certificates.
171 : *
172 : * By default, we define the path to the SSL certificate as defined
173 : * on Ubuntu. This is under "/etc/ssl/certs".
174 : *
175 : * This function let you change that path to another one. Maybe you
176 : * would prefer to not allow all certificates to work in your
177 : * circumstances.
178 : *
179 : * \param[in] path The new path to SSL certificates used to verify
180 : * secure connections.
181 : */
182 0 : void tcp_bio_options::set_ssl_certificate_path(std::string const path)
183 : {
184 0 : f_ssl_certificate_path = path;
185 0 : }
186 :
187 :
188 : /** \brief Return the current SSL certificate path.
189 : *
190 : * This function returns the path where the SSL interface will
191 : * look for the root certificates used to verify a connection's
192 : * security.
193 : *
194 : * \return The current SSL certificate path.
195 : */
196 0 : std::string const & tcp_bio_options::get_ssl_certificate_path() const
197 : {
198 0 : return f_ssl_certificate_path;
199 : }
200 :
201 :
202 : /** \brief Set whether the SO_KEEPALIVE should be set.
203 : *
204 : * By default this option is turned ON meaning that all BIO_client have their
205 : * SO_KEEPALIVE turned on when created.
206 : *
207 : * You may turn this off if you are creating a socket for a very short
208 : * period of time, such as to send a fast REST command to a server.
209 : *
210 : * \attention
211 : * As per the TCP RFC, you should only use keepalive on a server, not a
212 : * client. (The client can quit any time and if it tries to access the
213 : * server and it fails, it can either quit or reconnect then.) That being
214 : * said, at times a server does not set the Keep-Alive and the client may
215 : * want to use it to maintain the connection when not much happens for
216 : * long durations.
217 : *
218 : * https://tools.ietf.org/html/rfc1122#page-101
219 : *
220 : * Some numbers about Keep-Alive:
221 : *
222 : * https://www.veritas.com/support/en_US/article.100028680
223 : *
224 : * For Linux (in seconds):
225 : *
226 : * \code
227 : * tcp_keepalive_time = 7200
228 : * tcp_keepalive_intvl = 75
229 : * tcp_keepalive_probes = 9
230 : * \endcode
231 : *
232 : * These can be access through the /proc file system:
233 : *
234 : * \code
235 : * /proc/sys/net/ipv4/tcp_keepalive_time
236 : * /proc/sys/net/ipv4/tcp_keepalive_intvl
237 : * /proc/sys/net/ipv4/tcp_keepalive_probes
238 : * \endcode
239 : *
240 : * See: http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/usingkeepalive.html
241 : *
242 : * \warning
243 : * These numbers are used by all applications using TCP. Remember that
244 : * changing them will affect all your clients and servers.
245 : *
246 : * \param[in] keepalive true if you want the SO_KEEP_ALIVE turned on.
247 : *
248 : * \sa get_keepalive()
249 : */
250 0 : void tcp_bio_options::set_keepalive(bool keepalive)
251 : {
252 0 : f_keepalive = keepalive;
253 0 : }
254 :
255 :
256 : /** \brief Retrieve the SO_KEEPALIVE flag.
257 : *
258 : * This function returns the current value of the SO_KEEPALIVE flag. By
259 : * default this is true.
260 : *
261 : * Note that this function returns the flag status in the options, not
262 : * a connected socket.
263 : *
264 : * \return The current status of the SO_KEEPALIVE flag (true or false).
265 : *
266 : * \sa set_keepalive()
267 : */
268 35 : bool tcp_bio_options::get_keepalive() const
269 : {
270 35 : return f_keepalive;
271 : }
272 :
273 :
274 : /** \brief Set whether the SNI should be included in the SSL request.
275 : *
276 : * Whenever SSL connects a server, it has the option to include the
277 : * Server Name Indication, which is the server hostname to which
278 : * are think you are connecting. That way the server can verify that
279 : * you indeed were sent to the right server.
280 : *
281 : * The default is set to true, however, if you create a bio_client
282 : * object using an IP address (opposed to the hostname) then no
283 : * SNI will be included unless you also call the set_host() function
284 : * to setup the host.
285 : *
286 : * In other words, you can use the IP address on the bio_client
287 : * constructor and the hostname in the options and you will still
288 : * be able to get the SNI setup as expected.
289 : *
290 : * \param[in] sni true if you want the SNI to be included.
291 : *
292 : * \sa get_sni()
293 : * \sa set_host()
294 : */
295 0 : void tcp_bio_options::set_sni(bool sni)
296 : {
297 0 : f_sni = sni;
298 0 : }
299 :
300 :
301 : /** \brief Retrieve the SNI flag.
302 : *
303 : * This function returns the current value of the SNI flag. By
304 : * default this is true.
305 : *
306 : * Note that although the flag is true by default, the SSL request
307 : * may still not get to work if you don't include the host with
308 : * the set_host() and construct a bio_client object with an IP
309 : * address (opposed to a hostname.)
310 : *
311 : * \return The current status of the SNI (true or false).
312 : *
313 : * \sa set_sni()
314 : * \sa set_host()
315 : */
316 0 : bool tcp_bio_options::get_sni() const
317 : {
318 0 : return f_sni;
319 : }
320 :
321 :
322 : /** \brief Set the hostname.
323 : *
324 : * This function is used to setup the SNI hostname.
325 : *
326 : * The Server Name Indication is added to the SSL Hello message if
327 : * available (i.e. the host was specified here or the bio_client
328 : * constructor is called with the hostname and not an IP address.)
329 : *
330 : * If you construct the bio_client object with an IP address, you
331 : * can use this set_host() function to specify the hostname, but
332 : * you still need to make sure that both are a match.
333 : *
334 : * \param[in] host The host being accessed.
335 : */
336 0 : void tcp_bio_options::set_host(std::string const & host)
337 : {
338 0 : f_host = host;
339 0 : }
340 :
341 :
342 : /** \brief Retrieve the hostname.
343 : *
344 : * This function is used to retrieve the hostname. This name has
345 : * priority over the \p addr parameter specified to the
346 : * bio_client constructor.
347 : *
348 : * By default this name is empty in which case the bio_client
349 : * constructor checks the \p addr parameter and if it is
350 : * a hostname (opposed to direct IP addresses) then it uses
351 : * that \p addr parameter instead.
352 : *
353 : * If you do not want the Server Name Indication in the SSL
354 : * request, you must call set_sni(false) so even if the
355 : * bio_client constructor is called with a hostname, the
356 : * SNI won't be included in the request.
357 : *
358 : * \return A reference string with the hostname.
359 : */
360 0 : std::string const & tcp_bio_options::get_host() const
361 : {
362 0 : return f_host;
363 : }
364 :
365 :
366 :
367 : /** \brief Call the bio_cleanup() function.
368 : *
369 : * This can be used in the main() function of your tests so that way the
370 : * coverage tests do not detect any memory leaks from the OpenSSL libraries.
371 : *
372 : * It automatically calls the bio_cleanup() function.
373 : *
374 : * Note that this is not necessary in your standard tools and services
375 : * since those can have memory still allocated at the time you leave your
376 : * application. For tests, though, we verify memory leaks (through the
377 : * sanitizer) and if such are discovered, the test fails.
378 : *
379 : * Here is an example one can use to implement such. Note that the order
380 : * is probably not important (i.e. it just needs to get initialized
381 : * at some point before you quit). The tests/catch_main.cpp of this
382 : * very project (eventdispatcher) makes use of this feature.
383 : *
384 : * \code
385 : * int main(...)
386 : * {
387 : * ...
388 : * bio_auto_cleanup bio_cleanup;
389 : * ...
390 : * }
391 : * \endcode
392 : */
393 2 : bio_auto_cleanup::~bio_auto_cleanup()
394 : {
395 2 : detail::bio_cleanup();
396 2 : }
397 :
398 :
399 :
400 : } // namespace ed
401 : // vim: ts=4 sw=4 et
|