return 0;
}
-static int server_connection_ssl_handshaked(void *context)
+static int server_connection_ssl_handshaked(const char **error_r, void *context)
{
struct server_connection *conn = context;
const char *host, *p;
host = t_strdup_until(host, p);
if (!ssl_iostream_has_valid_client_cert(conn->ssl_iostream)) {
- if (!ssl_iostream_has_broken_client_cert(conn->ssl_iostream)) {
- i_error("%s: SSL certificate not received",
- conn->server->name);
- } else {
- i_error("%s: Received invalid SSL certificate",
- conn->server->name);
- }
+ if (!ssl_iostream_has_broken_client_cert(conn->ssl_iostream))
+ *error_r = "SSL certificate not received";
+ else
+ *error_r = "Received invalid SSL certificate";
} else if (ssl_iostream_cert_match_name(conn->ssl_iostream, host) < 0) {
- i_error("%s: SSL certificate doesn't match host name",
- conn->server->name);
+ *error_r = t_strdup_printf(
+ "SSL certificate doesn't match expected host name %s",
+ host);
} else {
if (doveadm_debug) {
i_debug("%s: SSL handshake successful",
(void)http_client_connection_next_request(conn);
}
-static int http_client_connection_ssl_handshaked(void *context)
+static int
+http_client_connection_ssl_handshaked(const char **error_r, void *context)
{
struct http_client_connection *conn = context;
http_client_connection_debug(conn, "SSL handshake successful");
return 0;
} else if (!ssl_iostream_has_valid_client_cert(conn->ssl_iostream)) {
- if (!ssl_iostream_has_broken_client_cert(conn->ssl_iostream)) {
- http_client_connection_error(conn, "SSL certificate not received");
- } else {
- http_client_connection_error(conn, "Received invalid SSL certificate");
- }
+ if (!ssl_iostream_has_broken_client_cert(conn->ssl_iostream))
+ *error_r = "SSL certificate not received";
+ else
+ *error_r = "Received invalid SSL certificate";
} else {
const char *host = http_client_peer_get_hostname(conn->peer);
i_assert(host != NULL);
- if (ssl_iostream_cert_match_name(conn->ssl_iostream, host) < 0) {
- http_client_connection_error(conn,
- "SSL certificate doesn't match host name");
- } else {
+ if (ssl_iostream_cert_match_name(conn->ssl_iostream, host) == 0) {
http_client_connection_debug(conn, "SSL handshake successful");
return 0;
}
+
+ *error_r = t_strdup_printf(
+ "SSL certificate doesn't match expected host name %s", host);
}
i_stream_close(conn->conn.input);
return -1;
imapc_connection_unref(&conn);
}
-static int imapc_connection_ssl_handshaked(void *context)
+static int imapc_connection_ssl_handshaked(const char **error_r, void *context)
{
struct imapc_connection *conn = context;
/* skip certificate checks */
return 0;
} else if (!ssl_iostream_has_valid_client_cert(conn->ssl_iostream)) {
- if (!ssl_iostream_has_broken_client_cert(conn->ssl_iostream)) {
- i_error("imapc(%s): SSL certificate not received",
- conn->name);
- } else {
- i_error("imapc(%s): Received invalid SSL certificate",
- conn->name);
- }
+ if (!ssl_iostream_has_broken_client_cert(conn->ssl_iostream))
+ *error_r = "SSL certificate not received";
+ else
+ *error_r = "Received invalid SSL certificate";
} else if (ssl_iostream_cert_match_name(conn->ssl_iostream,
conn->client->set.host) < 0) {
- i_error("imapc(%s): SSL certificate doesn't match host name",
- conn->name);
+ *error_r = t_strdup_printf(
+ "SSL certificate doesn't match expected host name %s",
+ conn->client->set.host);
} else {
if (conn->client->set.debug) {
i_debug("imapc(%s): SSL handshake successful",
static int openssl_iostream_handshake(struct ssl_iostream *ssl_io)
{
+ const char *error = NULL;
int ret;
i_assert(!ssl_io->handshaked);
ssl_io->handshaked = TRUE;
if (ssl_io->handshake_callback != NULL) {
- if (ssl_io->handshake_callback(ssl_io->handshake_context) < 0) {
+ if (ssl_io->handshake_callback(&error, ssl_io->handshake_context) < 0) {
+ i_assert(error != NULL);
+ openssl_iostream_set_error(ssl_io, error);
errno = EINVAL;
return -1;
}
static void
openssl_iostream_set_handshake_callback(struct ssl_iostream *ssl_io,
- int (*callback)(void *context),
+ ssl_iostream_handshake_callback_t *callback,
void *context)
{
ssl_io->handshake_callback = callback;
bool verbose, verbose_invalid_cert, require_valid_cert;
int username_nid;
- int (*handshake_callback)(void *context);
+ ssl_iostream_handshake_callback_t *handshake_callback;
void *handshake_context;
unsigned int handshaked:1;
int (*handshake)(struct ssl_iostream *ssl_io);
void (*set_handshake_callback)(struct ssl_iostream *ssl_io,
- int (*callback)(void *context),
+ ssl_iostream_handshake_callback_t *callback,
void *context);
bool (*is_handshaked)(const struct ssl_iostream *ssl_io);
}
void ssl_iostream_set_handshake_callback(struct ssl_iostream *ssl_io,
- int (*callback)(void *context),
+ ssl_iostream_handshake_callback_t *callback,
void *context)
{
ssl_vfuncs->set_handshake_callback(ssl_io, callback, context);
bool require_valid_cert; /* stream-only */
};
+/* Returns 0 if ok, -1 and sets error_r if failed. The returned error string
+ becomes available via ssl_iostream_get_last_error() */
+typedef int
+ssl_iostream_handshake_callback_t(const char **error_r, void *context);
+
int io_stream_create_ssl(struct ssl_iostream_context *ctx, const char *source,
const struct ssl_iostream_settings *set,
struct istream **input, struct ostream **output,
int ssl_iostream_handshake(struct ssl_iostream *ssl_io);
void ssl_iostream_set_handshake_callback(struct ssl_iostream *ssl_io,
- int (*callback)(void *context),
+ ssl_iostream_handshake_callback_t *callback,
void *context);
bool ssl_iostream_is_handshaked(const struct ssl_iostream *ssl_io);
}
}
-static int pop3c_client_ssl_handshaked(void *context)
+static int pop3c_client_ssl_handshaked(const char **error_r, void *context)
{
struct pop3c_client *client = context;
/* skip certificate checks */
return 0;
} else if (!ssl_iostream_has_valid_client_cert(client->ssl_iostream)) {
- if (!ssl_iostream_has_broken_client_cert(client->ssl_iostream)) {
- i_error("pop3c(%s): SSL certificate not received",
- client->set.host);
- } else {
- i_error("pop3c(%s): Received invalid SSL certificate",
- client->set.host);
- }
+ if (!ssl_iostream_has_broken_client_cert(client->ssl_iostream))
+ *error_r = "SSL certificate not received";
+ else
+ *error_r = "Received invalid SSL certificate";
} else if (ssl_iostream_cert_match_name(client->ssl_iostream,
client->set.host) < 0) {
- i_error("pop3c(%s): SSL certificate doesn't match host name",
+ *error_r = t_strdup_printf(
+ "SSL certificate doesn't match expected host name %s",
client->set.host);
} else {
if (client->set.debug) {