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