]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-ssl-iostream: ssl_iostream_set_handshake_callback() API changed.
authorTimo Sirainen <tss@iki.fi>
Thu, 4 Apr 2013 12:21:00 +0000 (15:21 +0300)
committerTimo Sirainen <tss@iki.fi>
Thu, 4 Apr 2013 12:21:00 +0000 (15:21 +0300)
The callback can now return the error message to caller instead of having to
log it itself.

src/doveadm/server-connection.c
src/lib-http/http-client-connection.c
src/lib-imap-client/imapc-connection.c
src/lib-ssl-iostream/iostream-openssl.c
src/lib-ssl-iostream/iostream-openssl.h
src/lib-ssl-iostream/iostream-ssl-private.h
src/lib-ssl-iostream/iostream-ssl.c
src/lib-ssl-iostream/iostream-ssl.h
src/lib-storage/index/pop3c/pop3c-client.c

index 82332bf10d105e0a59d5517856c7bf77c7f238ff..a64bef4d6c2f91cb1118a578755d3c56d142e0bf 100644 (file)
@@ -315,7 +315,7 @@ static int server_connection_read_settings(struct server_connection *conn)
        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;
@@ -326,16 +326,14 @@ static int server_connection_ssl_handshaked(void *context)
                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",
index bf357ad7d7b9bb36a9911ffd158d9146e99c4d1c..3ea1b848be64de64acaa186941b19db9a18383d5 100644 (file)
@@ -652,7 +652,8 @@ http_client_connection_ready(struct http_client_connection *conn)
        (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;
 
@@ -661,23 +662,22 @@ static int http_client_connection_ssl_handshaked(void *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;
index dae7e023dd3ee969384eade587f7f021920a28b4..94f07b4c950399a41c6396005e9e2fb114606f75 100644 (file)
@@ -1126,7 +1126,7 @@ static void imapc_connection_input(struct imapc_connection *conn)
        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;
 
@@ -1134,17 +1134,15 @@ static int imapc_connection_ssl_handshaked(void *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",
index fc5d0eee571d22b5e963b5fcc8d222a41c546f8b..80ce04cd8c6c93a2cfd03142d9f1137ffc8e1dd7 100644 (file)
@@ -516,6 +516,7 @@ openssl_iostream_cert_match_name(struct ssl_iostream *ssl_io,
 
 static int openssl_iostream_handshake(struct ssl_iostream *ssl_io)
 {
+       const char *error = NULL;
        int ret;
 
        i_assert(!ssl_io->handshaked);
@@ -542,7 +543,9 @@ static int openssl_iostream_handshake(struct ssl_iostream *ssl_io)
        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;
                }
@@ -554,7 +557,7 @@ static int openssl_iostream_handshake(struct ssl_iostream *ssl_io)
 
 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;
index de02707b3cf1a68c1593bf610d5049ad1c676b5c..6fecde2edd1b779cd161c8e041530d9a30e6f59e 100644 (file)
@@ -38,7 +38,7 @@ struct ssl_iostream {
        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;
index 0747bfd04f1f4e5f88b7e256449e42b11289989f..f38ca7011e2bc83f8e383e3524ce1cb859b537aa 100644 (file)
@@ -25,7 +25,7 @@ struct iostream_ssl_vfuncs {
 
        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);
index c08743765c9da6574dbb02e9bd3a1af89455f647..13fd475cebf102a9c727ee7794dce3e498b9432e 100644 (file)
@@ -124,7 +124,7 @@ 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)
 {
        ssl_vfuncs->set_handshake_callback(ssl_io, callback, context);
index 0cbd72268a9198b674dcd77da8895acb43e4774b..c310bc33a5d873d67e97ee88b9910ded0ed84b84 100644 (file)
@@ -19,6 +19,11 @@ struct ssl_iostream_settings {
        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,
@@ -31,7 +36,7 @@ void ssl_iostream_destroy(struct ssl_iostream **ssl_io);
 
 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);
index d430b6be89cf12b9b02aea75b008ab802daac42f..8250ebdeb6db5568f14403f16d74d1c4925ae1b2 100644 (file)
@@ -409,7 +409,7 @@ static void pop3c_client_prelogin_input(struct pop3c_client *client)
        }
 }
 
-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;
 
@@ -417,16 +417,14 @@ static int pop3c_client_ssl_handshaked(void *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) {