diff options
Diffstat (limited to 'louloulibs/network/tcp_socket_handler.hpp')
-rw-r--r-- | louloulibs/network/tcp_socket_handler.hpp | 152 |
1 files changed, 64 insertions, 88 deletions
diff --git a/louloulibs/network/tcp_socket_handler.hpp b/louloulibs/network/tcp_socket_handler.hpp index 20a3e5a..600405d 100644 --- a/louloulibs/network/tcp_socket_handler.hpp +++ b/louloulibs/network/tcp_socket_handler.hpp @@ -1,6 +1,5 @@ #pragma once - #include "louloulibs.h" #include <network/socket_handler.hpp> @@ -19,13 +18,44 @@ #include <string> #include <list> +#ifdef BOTAN_FOUND + +# include <botan/types.h> +# include <botan/botan.h> +# include <botan/tls_session_manager.h> + +class BiboumiTLSPolicy: public Botan::TLS::Policy +{ +public: +# if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,33) + bool use_ecc_point_compression() const override + { + return true; + } + bool require_cert_revocation_info() const override + { + return false; + } +# endif +}; + +# if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,32) +# define BOTAN_TLS_CALLBACKS_OVERRIDE override final +# else +# define BOTAN_TLS_CALLBACKS_OVERRIDE +# endif +#endif + /** - * An interface, with a series of callbacks that should be implemented in - * subclasses that deal with a socket. These callbacks are called on various events - * (read/write/timeout, etc) when they are notified to a poller - * (select/poll/epoll etc) + * Does all the read/write, buffering etc. With optional tls. + * But doesn’t do any connect() or accept() or anything else. */ class TCPSocketHandler: public SocketHandler +#ifdef BOTAN_FOUND +# if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,32) + ,public Botan::TLS::Callbacks +# endif +#endif { protected: ~TCPSocketHandler(); @@ -37,13 +67,6 @@ public: TCPSocketHandler& operator=(TCPSocketHandler&&) = delete; /** - * Connect to the remote server, and call on_connected() if this - * succeeds. If tls is true, we set use_tls to true and will also call - * start_tls() when the connection succeeds. - */ - void connect(const std::string& address, const std::string& port, const bool tls); - void connect() override final; - /** * Reads raw data from the socket. And pass it to parse_in_buffer() * If we are using TLS on this connection, we call tls_recv() */ @@ -67,25 +90,7 @@ public: /** * Close the connection, remove us from the poller */ - void close(); - /** - * Called by a TimedEvent, when the connection did not succeed or fail - * after a given time. - */ - void on_connection_timeout(); - /** - * Called when the connection is successful. - */ - virtual void on_connected() = 0; - /** - * Called when the connection fails. Not when it is closed later, just at - * the connect() call. - */ - virtual void on_connection_failed(const std::string& reason) = 0; - /** - * Called when we detect a disconnection from the remote host. - */ - virtual void on_connection_close(const std::string& error) = 0; + virtual void close(); /** * Handle/consume (some of) the data received so far. The data to handle * may be in the in_buf buffer, or somewhere else, depending on what @@ -93,6 +98,9 @@ public: * should be truncated, only the unused data should be left untouched. * * The size argument is the size of the last chunk of data that was added to the buffer. + * + * The function should call consume_in_buffer, with the size that was consumed by the + * “parsing”, and thus to be removed from the input buffer. */ virtual void parse_in_buffer(const size_t size) = 0; #ifdef BOTAN_FOUND @@ -105,19 +113,10 @@ public: return true; } #endif - bool is_connected() const override final; - bool is_connecting() const; bool is_using_tls() const; - std::string get_port() const; - std::chrono::system_clock::time_point connection_date; private: /** - * Initialize the socket with the parameters contained in the given - * addrinfo structure. - */ - void init_socket(const struct addrinfo* rp); - /** * Reads from the socket into the provided buffer. If an error occurs * (read returns <= 0), the handling of the error is done here (close the * connection, log a message, etc). @@ -136,13 +135,16 @@ private: */ void raw_send(std::string&& data); + protected: + virtual bool is_connecting() const = 0; #ifdef BOTAN_FOUND /** * Create the TLS::Client object, with all the callbacks etc. This must be * called only when we know we are able to send TLS-encrypted data over * the socket. */ - void start_tls(); + void start_tls(const std::string& address, const std::string& port); + private: /** * An additional step to pass the data into our tls object to decrypt it * before passing it to parse_in_buffer. @@ -158,22 +160,31 @@ private: * Called by the tls object that some data has been decrypt. We call * parse_in_buffer() to handle that unencrypted data. */ - void tls_data_cb(const Botan::byte* data, size_t size); + void tls_record_received(uint64_t rec_no, const Botan::byte* data, size_t size) BOTAN_TLS_CALLBACKS_OVERRIDE; /** * Called by the tls object to indicate that some data has been encrypted * and is now ready to be sent on the socket as is. */ - void tls_output_fn(const Botan::byte* data, size_t size); + void tls_emit_data(const Botan::byte* data, size_t size) BOTAN_TLS_CALLBACKS_OVERRIDE; /** * Called by the tls object to indicate that a TLS alert has been * received. We don’t use it, we just log some message, at the moment. */ - void tls_alert_cb(Botan::TLS::Alert alert, const Botan::byte*, size_t); + void tls_alert(Botan::TLS::Alert alert) BOTAN_TLS_CALLBACKS_OVERRIDE; /** * Called by the tls object at the end of the TLS handshake. We don't do * anything here appart from logging the TLS session information. */ - bool tls_handshake_cb(const Botan::TLS::Session& session); + bool tls_session_established(const Botan::TLS::Session& session) BOTAN_TLS_CALLBACKS_OVERRIDE; + +#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,34) + void tls_verify_cert_chain(const std::vector<Botan::X509_Certificate>& cert_chain, + const std::vector<std::shared_ptr<const Botan::OCSP::Response>>& ocsp_responses, + const std::vector<Botan::Certificate_Store*>& trusted_roots, + Botan::Usage_Type usage, + const std::string& hostname, + const Botan::TLS::Policy& policy) BOTAN_TLS_CALLBACKS_OVERRIDE; +#endif /** * Called whenever the tls session goes from inactive to active. This * means that the handshake has just been successfully done, and we can @@ -185,20 +196,11 @@ private: * Where data is added, when we want to send something to the client. */ std::vector<std::string> out_buf; +protected: /** - * DNS resolver - */ - Resolver resolver; - /** - * Keep the details of the addrinfo returned by the resolver that - * triggered a EINPROGRESS error when connect()ing to it, to reuse it - * directly when connect() is called again. + * Whether we are using TLS on this connection or not. */ - struct addrinfo addrinfo; - struct sockaddr_in6 ai_addr; - socklen_t ai_addrlen; - -protected: + bool use_tls; /** * Where data read from the socket is added until we can extract a full * and meaningful “message” from it. @@ -207,9 +209,9 @@ protected: */ std::string in_buf; /** - * Whether we are using TLS on this connection or not. + * Remove the given “size” first bytes from our in_buf. */ - bool use_tls; + void consume_in_buffer(const std::size_t size); /** * Provide a buffer in which data can be directly received. This can be * used to avoid copying data into in_buf before using it. If no buffer @@ -219,38 +221,12 @@ protected: */ virtual void* get_receive_buffer(const size_t size) const; /** - * Hostname we are connected/connecting to - */ - std::string address; - /** - * Port we are connected/connecting to - */ - std::string port; - - bool connected; - bool connecting; - - bool hostname_resolution_failed; - - /** - * Address to bind the socket to, before calling connect(). - * If empty, it’s equivalent to binding to INADDR_ANY. - */ - std::string bind_addr; - -private: - /** - * Display the resolved IP, just for information purpose. + * Called when we detect a disconnection from the remote host. */ - void display_resolved_ip(struct addrinfo* rp) const; + virtual void on_connection_close(const std::string&) {} + virtual void on_connection_failed(const std::string&) {} #ifdef BOTAN_FOUND - /** - * Botan stuff to manipulate a TLS session. - */ - static Botan::AutoSeeded_RNG rng; - static Botan::TLS::Policy policy; - static Botan::TLS::Session_Manager_In_Memory session_manager; protected: BasicCredentialsManager credential_manager; private: |