// Matrix Construct // // Copyright (C) Matrix Construct Developers, Authors & Contributors // Copyright (C) 2016-2018 Jason Volk <jason@zemos.net> // // Permission to use, copy, modify, and/or distribute this software for any // purpose with or without fee is hereby granted, provided that the above // copyright notice and this permission notice is present in all copies. The // full license for this software is available in the LICENSE file. #pragma once #define HAVE_IRCD_NET_OPEN_H namespace ircd::net { struct open_opts; using open_callback = std::function<void (std::exception_ptr)>; string_view common_name(const open_opts &); string_view server_name(const open_opts &); // Open existing socket with callback. void open(socket &, const open_opts &, open_callback); // Open new socket with callback. std::shared_ptr<socket> open(const open_opts &, open_callback); // Open new socket with future. ctx::future<std::shared_ptr<socket>> open(const open_opts &); } /// Connection options structure. This is provided when making a client /// connection with a socket. The structure itself is copied when passed /// to open() but for any members that are string_views or pointers they /// will have to remain valid for the duration of the open(). struct ircd::net::open_opts { static conf::item<milliseconds> default_connect_timeout; static conf::item<milliseconds> default_handshake_timeout; static conf::item<bool> default_verify_certificate; static conf::item<bool> default_allow_self_signed; static conf::item<bool> default_allow_self_chain; static conf::item<bool> default_allow_expired; // Get the proper target CN from the options structure friend string_view common_name(const open_opts &); open_opts() = default; explicit open_opts(const net::ipport &ipport, const net::hostport & = {}); open_opts(const net::hostport &hostport); /// Remote's hostname and port. This will be used for address resolution /// if an ipport is not also provided later. The hostname will also be used /// for certificate /CN verification if common_name is not provided later. net::hostport hostport; /// Remote's resolved IP and port. Providing this skips DNS resolution if /// hostport is not given; required if so. net::ipport ipport; /// The duration allowed for the TCP connection. milliseconds connect_timeout { default_connect_timeout }; /// Pointer to a sock_opts structure which will be applied to this socket /// if given. Defaults to null; no application is made. const sock_opts *sopts { nullptr }; /// Option to toggle whether to perform the SSL handshake; you want true. bool handshake { true }; /// The duration allowed for the SSL handshake milliseconds handshake_timeout { default_handshake_timeout }; /// Option to toggle whether to perform any certificate verification; if /// false, everything no matter what is considered valid; you want true. bool verify_certificate { default_verify_certificate }; /// Option to toggle whether to perform CN verification to ensure the /// certificate is signed to the actual host we want to talk to. When /// true, see the comments for `common_name`. Otherwise if false, any /// common_name will pass muster. bool verify_common_name { true }; /// Option to toggle whether to perform CN verification for self-signed /// certificates. This is set to false for compatibility purposes as many /// self-signed certificates have either no CN or CN=localhost and none /// of that really matters anyway. bool verify_self_signed_common_name { false }; /// The expected /CN of the target. This should be the remote's hostname, /// If it is empty then `hostport.host` is used. If the signed /CN has /// some rfc2818/rfc2459 wildcard we will properly match that for you. string_view common_name; /// The server name identification string to send in the ClientHello. /// If this is not set, then common_name is used (or if common_name is /// empty, the value that is eventually used for common_name). string_view server_name; /// Option to toggle whether server name identification is sent. If /// false, it will not be sent regardless of the string values having /// been set. If true, it will be sent regardless. bool send_sni { true }; /// Option to toggle whether to allow self-signed certificates. This /// currently defaults to true to not break Matrix development but will /// likely change later and require setting to true for specific conns. bool allow_self_signed { default_allow_self_signed }; /// Option to toggle whether to allow self-signed certificate authorities /// in the chain. This is what corporate network nanny's may use to spy. bool allow_self_chain { default_allow_self_chain }; /// Option to allow expired certificates. bool allow_expired { default_allow_expired }; }; /// Constructor intended to provide implicit conversions (no-brackets required) /// in arguments to open(); i.e open(hostport) rather than open({hostport}); inline ircd::net::open_opts::open_opts(const net::hostport &hostport) :hostport{hostport} {} /// Constructor intended to provide implicit conversions (no-brackets required) /// in arguments to open(); i.e open(ipport) rather than open({ipport}); inline ircd::net::open_opts::open_opts(const net::ipport &ipport, const net::hostport &hostport) :hostport{hostport} ,ipport{ipport} {} inline ircd::string_view ircd::net::server_name(const open_opts &opts) { return opts.server_name?: common_name(opts); } inline ircd::string_view ircd::net::common_name(const open_opts &opts) { return opts.common_name?: opts.hostport.host; }