SSL -> TLS; fix error handling
This commit is contained in:
parent
c8496a83d8
commit
6f3b48e4eb
29
degesch.c
29
degesch.c
@ -1067,7 +1067,7 @@ enum transport_io_result
|
|||||||
TRANSPORT_IO_ERROR ///< Connection error
|
TRANSPORT_IO_ERROR ///< Connection error
|
||||||
};
|
};
|
||||||
|
|
||||||
// The only real purpose of this is to abstract away TLS/SSL
|
// The only real purpose of this is to abstract away TLS
|
||||||
struct transport
|
struct transport
|
||||||
{
|
{
|
||||||
/// Initialize the transport
|
/// Initialize the transport
|
||||||
@ -1530,11 +1530,11 @@ static struct config_schema g_config_server[] =
|
|||||||
.validate = config_validate_nonjunk_string },
|
.validate = config_validate_nonjunk_string },
|
||||||
|
|
||||||
{ .name = "ssl",
|
{ .name = "ssl",
|
||||||
.comment = "Whether to use SSL/TLS",
|
.comment = "Whether to use TLS",
|
||||||
.type = CONFIG_ITEM_BOOLEAN,
|
.type = CONFIG_ITEM_BOOLEAN,
|
||||||
.default_ = "off" },
|
.default_ = "off" },
|
||||||
{ .name = "ssl_cert",
|
{ .name = "ssl_cert",
|
||||||
.comment = "Client SSL certificate (PEM)",
|
.comment = "Client TLS certificate (PEM)",
|
||||||
.type = CONFIG_ITEM_STRING },
|
.type = CONFIG_ITEM_STRING },
|
||||||
{ .name = "ssl_verify",
|
{ .name = "ssl_verify",
|
||||||
.comment = "Whether to verify certificates",
|
.comment = "Whether to verify certificates",
|
||||||
@ -3866,12 +3866,12 @@ static struct transport g_transport_plain =
|
|||||||
.get_poll_events = transport_plain_get_poll_events,
|
.get_poll_events = transport_plain_get_poll_events,
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- SSL/TLS transport -------------------------------------------------------
|
// --- TLS transport -----------------------------------------------------------
|
||||||
|
|
||||||
struct transport_tls_data
|
struct transport_tls_data
|
||||||
{
|
{
|
||||||
SSL_CTX *ssl_ctx; ///< SSL context
|
SSL_CTX *ssl_ctx; ///< SSL context
|
||||||
SSL *ssl; ///< SSL/TLS connection
|
SSL *ssl; ///< SSL connection
|
||||||
bool ssl_rx_want_tx; ///< SSL_read() wants to write
|
bool ssl_rx_want_tx; ///< SSL_read() wants to write
|
||||||
bool ssl_tx_want_rx; ///< SSL_write() wants to read
|
bool ssl_tx_want_rx; ///< SSL_write() wants to read
|
||||||
};
|
};
|
||||||
@ -3931,6 +3931,8 @@ transport_tls_init_ctx (struct server *s, SSL_CTX *ssl_ctx, struct error **e)
|
|||||||
const char *ca_file = get_config_string (s->config, "ssl_ca_file");
|
const char *ca_file = get_config_string (s->config, "ssl_ca_file");
|
||||||
const char *ca_path = get_config_string (s->config, "ssl_ca_path");
|
const char *ca_path = get_config_string (s->config, "ssl_ca_path");
|
||||||
|
|
||||||
|
ERR_clear_error ();
|
||||||
|
|
||||||
struct error *error = NULL;
|
struct error *error = NULL;
|
||||||
if (ca_file || ca_path)
|
if (ca_file || ca_path)
|
||||||
{
|
{
|
||||||
@ -3972,6 +3974,8 @@ transport_tls_init_cert (struct server *s, SSL *ssl, struct error **e)
|
|||||||
if (!ssl_cert)
|
if (!ssl_cert)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
ERR_clear_error ();
|
||||||
|
|
||||||
bool result = false;
|
bool result = false;
|
||||||
char *path = resolve_filename (ssl_cert, resolve_relative_config_filename);
|
char *path = resolve_filename (ssl_cert, resolve_relative_config_filename);
|
||||||
if (!path)
|
if (!path)
|
||||||
@ -3990,18 +3994,19 @@ transport_tls_init_cert (struct server *s, SSL *ssl, struct error **e)
|
|||||||
static bool
|
static bool
|
||||||
transport_tls_init (struct server *s, struct error **e)
|
transport_tls_init (struct server *s, struct error **e)
|
||||||
{
|
{
|
||||||
const char *error_info = NULL;
|
ERR_clear_error ();
|
||||||
|
|
||||||
|
struct error *error = NULL;
|
||||||
SSL_CTX *ssl_ctx = SSL_CTX_new (SSLv23_client_method ());
|
SSL_CTX *ssl_ctx = SSL_CTX_new (SSLv23_client_method ());
|
||||||
if (!ssl_ctx)
|
if (!ssl_ctx)
|
||||||
goto error_ssl_1;
|
goto error_ssl_1;
|
||||||
if (!transport_tls_init_ctx (s, ssl_ctx, e))
|
if (!transport_tls_init_ctx (s, ssl_ctx, &error))
|
||||||
goto error_ssl_2;
|
goto error_ssl_2;
|
||||||
|
|
||||||
SSL *ssl = SSL_new (ssl_ctx);
|
SSL *ssl = SSL_new (ssl_ctx);
|
||||||
if (!ssl)
|
if (!ssl)
|
||||||
goto error_ssl_2;
|
goto error_ssl_2;
|
||||||
|
|
||||||
struct error *error = NULL;
|
|
||||||
if (!transport_tls_init_cert (s, ssl, &error))
|
if (!transport_tls_init_cert (s, ssl, &error))
|
||||||
{
|
{
|
||||||
// XXX: is this a reason to abort the connection?
|
// XXX: is this a reason to abort the connection?
|
||||||
@ -4028,9 +4033,11 @@ error_ssl_3:
|
|||||||
error_ssl_2:
|
error_ssl_2:
|
||||||
SSL_CTX_free (ssl_ctx);
|
SSL_CTX_free (ssl_ctx);
|
||||||
error_ssl_1:
|
error_ssl_1:
|
||||||
if (!error_info)
|
if (!error)
|
||||||
error_info = ERR_reason_error_string (ERR_get_error ());
|
error_set (&error, "%s: %s", "Could not initialize TLS",
|
||||||
error_set (e, "%s: %s", "could not initialize SSL/TLS", error_info);
|
ERR_reason_error_string (ERR_get_error ()));
|
||||||
|
|
||||||
|
error_propagate (e, error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
42
kike.c
42
kike.c
@ -44,11 +44,11 @@ static struct config_item g_config_table[] =
|
|||||||
|
|
||||||
{ "bind_host", NULL, "Address of the IRC server" },
|
{ "bind_host", NULL, "Address of the IRC server" },
|
||||||
{ "bind_port", "6667", "Port of the IRC server" },
|
{ "bind_port", "6667", "Port of the IRC server" },
|
||||||
{ "ssl_cert", NULL, "Server SSL certificate (PEM)" },
|
{ "ssl_cert", NULL, "Server TLS certificate (PEM)" },
|
||||||
{ "ssl_key", NULL, "Server SSL private key (PEM)" },
|
{ "ssl_key", NULL, "Server TLS private key (PEM)" },
|
||||||
{ "ssl_ciphers", DEFAULT_CIPHERS, "OpenSSL cipher list" },
|
{ "ssl_ciphers", DEFAULT_CIPHERS, "OpenSSL cipher list" },
|
||||||
|
|
||||||
{ "operators", NULL, "IRCop SSL cert. fingerprints" },
|
{ "operators", NULL, "IRCop TLS cert. fingerprints" },
|
||||||
|
|
||||||
{ "max_connections", "0", "Global connection limit" },
|
{ "max_connections", "0", "Global connection limit" },
|
||||||
{ "ping_interval", "180", "Interval between PING's (sec)" },
|
{ "ping_interval", "180", "Interval between PING's (sec)" },
|
||||||
@ -624,7 +624,7 @@ struct server_context
|
|||||||
unsigned max_connections; ///< Max. connections allowed or 0
|
unsigned max_connections; ///< Max. connections allowed or 0
|
||||||
struct str_vector motd; ///< MOTD (none if empty)
|
struct str_vector motd; ///< MOTD (none if empty)
|
||||||
nl_catd catalog; ///< Message catalog for server msgs
|
nl_catd catalog; ///< Message catalog for server msgs
|
||||||
struct str_map operators; ///< SSL cert. fingerprints for IRCops
|
struct str_map operators; ///< TLS cert. fingerprints for IRCops
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1206,7 +1206,7 @@ irc_try_finish_registration (struct client *c)
|
|||||||
hard_assert (c->ssl_cert_fingerprint == NULL);
|
hard_assert (c->ssl_cert_fingerprint == NULL);
|
||||||
if ((c->ssl_cert_fingerprint = client_get_ssl_cert_fingerprint (c)))
|
if ((c->ssl_cert_fingerprint = client_get_ssl_cert_fingerprint (c)))
|
||||||
client_send (c, ":%s NOTICE %s :"
|
client_send (c, ":%s NOTICE %s :"
|
||||||
"Your SSL client certificate fingerprint is %s",
|
"Your TLS client certificate fingerprint is %s",
|
||||||
ctx->server_name, c->nickname, c->ssl_cert_fingerprint);
|
ctx->server_name, c->nickname, c->ssl_cert_fingerprint);
|
||||||
|
|
||||||
str_map_set (&ctx->whowas, c->nickname, NULL);
|
str_map_set (&ctx->whowas, c->nickname, NULL);
|
||||||
@ -1394,7 +1394,7 @@ irc_handle_pass (const struct irc_message *msg, struct client *c)
|
|||||||
else if (msg->params.len < 1)
|
else if (msg->params.len < 1)
|
||||||
irc_send_reply (c, IRC_ERR_NEEDMOREPARAMS, msg->command);
|
irc_send_reply (c, IRC_ERR_NEEDMOREPARAMS, msg->command);
|
||||||
|
|
||||||
// We have SSL client certificates for this purpose; ignoring
|
// We have TLS client certificates for this purpose; ignoring
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1653,7 +1653,7 @@ irc_handle_user_mode_change (struct client *c, const char *mode_string)
|
|||||||
&& str_map_find (&c->ctx->operators, c->ssl_cert_fingerprint))
|
&& str_map_find (&c->ctx->operators, c->ssl_cert_fingerprint))
|
||||||
new_mode |= IRC_USER_MODE_OPERATOR;
|
new_mode |= IRC_USER_MODE_OPERATOR;
|
||||||
else
|
else
|
||||||
client_send (c, ":%s NOTICE %s :Either you're not using an SSL"
|
client_send (c, ":%s NOTICE %s :Either you're not using an TLS"
|
||||||
" client certificate, or the fingerprint doesn't match",
|
" client certificate, or the fingerprint doesn't match",
|
||||||
c->ctx->server_name, c->nickname);
|
c->ctx->server_name, c->nickname);
|
||||||
break;
|
break;
|
||||||
@ -3256,26 +3256,28 @@ client_initialize_ssl (struct client *c)
|
|||||||
const char *error_info = NULL;
|
const char *error_info = NULL;
|
||||||
if (!c->ctx->ssl_ctx)
|
if (!c->ctx->ssl_ctx)
|
||||||
{
|
{
|
||||||
error_info = "SSL support disabled";
|
error_info = "TLS support disabled";
|
||||||
goto error_ssl_1;
|
goto error_ssl_1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ERR_clear_error ();
|
||||||
|
|
||||||
c->ssl = SSL_new (c->ctx->ssl_ctx);
|
c->ssl = SSL_new (c->ctx->ssl_ctx);
|
||||||
if (!c->ssl)
|
if (!c->ssl)
|
||||||
goto error_ssl_1;
|
|
||||||
if (!SSL_set_fd (c->ssl, c->socket_fd))
|
|
||||||
goto error_ssl_2;
|
goto error_ssl_2;
|
||||||
|
if (!SSL_set_fd (c->ssl, c->socket_fd))
|
||||||
|
goto error_ssl_3;
|
||||||
|
|
||||||
SSL_set_accept_state (c->ssl);
|
SSL_set_accept_state (c->ssl);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
error_ssl_2:
|
error_ssl_3:
|
||||||
SSL_free (c->ssl);
|
SSL_free (c->ssl);
|
||||||
c->ssl = NULL;
|
c->ssl = NULL;
|
||||||
|
error_ssl_2:
|
||||||
|
error_info = ERR_reason_error_string (ERR_get_error ());
|
||||||
error_ssl_1:
|
error_ssl_1:
|
||||||
if (!error_info)
|
print_debug ("could not initialize TLS for %s: %s", c->address, error_info);
|
||||||
error_info = ERR_reason_error_string (ERR_get_error ());
|
|
||||||
print_debug ("could not initialize SSL for %s: %s", c->address, error_info);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3480,10 +3482,12 @@ static bool
|
|||||||
irc_initialize_ssl_ctx (struct server_context *ctx,
|
irc_initialize_ssl_ctx (struct server_context *ctx,
|
||||||
const char *cert_path, const char *key_path, struct error **e)
|
const char *cert_path, const char *key_path, struct error **e)
|
||||||
{
|
{
|
||||||
|
ERR_clear_error ();
|
||||||
|
|
||||||
ctx->ssl_ctx = SSL_CTX_new (SSLv23_server_method ());
|
ctx->ssl_ctx = SSL_CTX_new (SSLv23_server_method ());
|
||||||
if (!ctx->ssl_ctx)
|
if (!ctx->ssl_ctx)
|
||||||
{
|
{
|
||||||
error_set (e, "%s: %s", "could not initialize SSL",
|
error_set (e, "%s: %s", "could not initialize TLS",
|
||||||
ERR_reason_error_string (ERR_get_error ()));
|
ERR_reason_error_string (ERR_get_error ()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -3510,11 +3514,11 @@ irc_initialize_ssl_ctx (struct server_context *ctx,
|
|||||||
if (!SSL_CTX_set_cipher_list (ctx->ssl_ctx, ciphers))
|
if (!SSL_CTX_set_cipher_list (ctx->ssl_ctx, ciphers))
|
||||||
error_set (e, "failed to select any cipher from the cipher list");
|
error_set (e, "failed to select any cipher from the cipher list");
|
||||||
else if (!SSL_CTX_use_certificate_chain_file (ctx->ssl_ctx, cert_path))
|
else if (!SSL_CTX_use_certificate_chain_file (ctx->ssl_ctx, cert_path))
|
||||||
error_set (e, "%s: %s", "setting the SSL client certificate failed",
|
error_set (e, "%s: %s", "setting the TLS certificate failed",
|
||||||
ERR_reason_error_string (ERR_get_error ()));
|
ERR_reason_error_string (ERR_get_error ()));
|
||||||
else if (!SSL_CTX_use_PrivateKey_file
|
else if (!SSL_CTX_use_PrivateKey_file
|
||||||
(ctx->ssl_ctx, key_path, SSL_FILETYPE_PEM))
|
(ctx->ssl_ctx, key_path, SSL_FILETYPE_PEM))
|
||||||
error_set (e, "%s: %s", "setting the SSL private key failed",
|
error_set (e, "%s: %s", "setting the TLS private key failed",
|
||||||
ERR_reason_error_string (ERR_get_error ()));
|
ERR_reason_error_string (ERR_get_error ()));
|
||||||
else
|
else
|
||||||
// TODO: SSL_CTX_check_private_key()? It has probably already been
|
// TODO: SSL_CTX_check_private_key()? It has probably already been
|
||||||
@ -3538,9 +3542,9 @@ irc_initialize_ssl (struct server_context *ctx, struct error **e)
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (!ssl_cert)
|
if (!ssl_cert)
|
||||||
error_set (e, "no SSL certificate set");
|
error_set (e, "no TLS certificate set");
|
||||||
else if (!ssl_key)
|
else if (!ssl_key)
|
||||||
error_set (e, "no SSL private key set");
|
error_set (e, "no TLS private key set");
|
||||||
if (!ssl_cert || !ssl_key)
|
if (!ssl_cert || !ssl_key)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user