LCOV - code coverage report
Current view: top level - eventdispatcher - tcp_bio_options.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 18.4 % 38 7
Test Date: 2025-05-30 15:24:13 Functions: 21.4 % 14 3
Legend: Lines: hit not hit

            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
        

Generated by: LCOV version 2.0-1

Snap C++ | List of projects | List of versions