]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
doveadm: Add STARTTLS support
authorAki Tuomi <aki.tuomi@open-xchange.com>
Sun, 13 Oct 2019 17:38:12 +0000 (20:38 +0300)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Wed, 16 Oct 2019 09:33:52 +0000 (12:33 +0300)
src/doveadm/client-connection-tcp.c
src/doveadm/doveadm-util.h
src/doveadm/server-connection.c

index d7bb131ebb82f0275621896e7203cb961d717805..dca9d48bd502c87b7509bdc4540723395d6d17d9 100644 (file)
@@ -47,6 +47,8 @@ static void
 client_connection_tcp_send_auth_handshake(struct client_connection_tcp *conn);
 static void
 client_connection_tcp_destroy(struct client_connection_tcp **_conn);
+static int
+client_connection_tcp_init_ssl(struct client_connection_tcp *conn);
 
 static failure_callback_t *orig_error_callback, *orig_fatal_callback;
 static failure_callback_t *orig_info_callback, *orig_debug_callback = NULL;
@@ -446,6 +448,14 @@ client_connection_tcp_authenticate(struct client_connection_tcp *conn)
                return -1;
        }
 
+       if (strcmp(line, "STARTTLS") == 0) {
+               io_remove(&conn->io);
+               if (client_connection_tcp_init_ssl(conn) < 0)
+                       return -1;
+               conn->io = io_add_istream(conn->input, client_connection_tcp_input, conn);
+               return 0;
+       }
+
        /* FIXME: some day we should probably let auth process do this and
           support all kinds of authentication */
        if (!str_begins(line, "PLAIN\t")) {
index 11ec9afc272b6084f448a4007197514bae14bf92..8aefd92f34a67927e90e667fb41543bde1caa364 100644 (file)
@@ -4,9 +4,9 @@
 #include "net.h"
 
 #define DOVEADM_SERVER_PROTOCOL_VERSION_MAJOR 1
-#define DOVEADM_SERVER_PROTOCOL_VERSION_MINOR 1
-#define DOVEADM_SERVER_PROTOCOL_VERSION_LINE "VERSION\tdoveadm-server\t1\t1"
-#define DOVEADM_CLIENT_PROTOCOL_VERSION_LINE "VERSION\tdoveadm-client\t1\t1"
+#define DOVEADM_SERVER_PROTOCOL_VERSION_MINOR 2
+#define DOVEADM_SERVER_PROTOCOL_VERSION_LINE "VERSION\tdoveadm-server\t1\t2"
+#define DOVEADM_CLIENT_PROTOCOL_VERSION_LINE "VERSION\tdoveadm-client\t1\t2"
 
 extern bool doveadm_verbose, doveadm_debug, doveadm_server;
 
index 51a40380372a83e4c3a86c8d9865549936388aba..c0928b10d6a357029523a8367fb91b75a1a5a4d7 100644 (file)
@@ -63,6 +63,7 @@ struct server_connection {
        bool authenticate_sent:1;
        bool authenticated:1;
        bool streaming:1;
+       bool ssl_done:1;
 };
 
 static struct server_connection *printing_conn = NULL;
@@ -70,6 +71,8 @@ static ARRAY(struct doveadm_server *) print_pending_servers = ARRAY_INIT;
 
 static void server_connection_input(struct server_connection *conn);
 static bool server_connection_input_one(struct server_connection *conn);
+static int server_connection_init_ssl(struct server_connection *conn,
+                                     const char **error_r);
 
 static void server_set_print_pending(struct doveadm_server *server)
 {
@@ -341,6 +344,7 @@ static void server_connection_start_multiplex(struct server_connection *conn)
 static void server_connection_input(struct server_connection *conn)
 {
        const char *line;
+       const char *error;
 
        if (i_stream_read(conn->input) < 0) {
                /* disconnected */
@@ -383,6 +387,24 @@ static void server_connection_input(struct server_connection *conn)
                                server_connection_destroy(&conn);
                                return;
                        }
+                       if (!conn->ssl_done &&
+                           (conn->server->ssl_flags & PROXY_SSL_FLAG_STARTTLS) != 0) {
+                               io_remove(&conn->io);
+                               if (conn->minor < 2) {
+                                       i_error("doveadm STARTTLS failed: Server does not support it");
+                                       server_connection_destroy(&conn);
+                                       return;
+                               }
+                               /* send STARTTLS */
+                               o_stream_nsend_str(conn->output, "STARTTLS\n");
+                               if (server_connection_init_ssl(conn, &error) < 0) {
+                                       i_error("doveadm STARTTLS failed: %s", error);
+                                       server_connection_destroy(&conn);
+                                       return;
+                               }
+                               conn->ssl_done = TRUE;
+                               conn->io = io_add_istream(conn->input, server_connection_input, conn);
+                       }
                        if (server_connection_authenticate(conn) < 0) {
                                server_connection_destroy(&conn);
                                return;
@@ -553,7 +575,8 @@ int server_connection_create(struct doveadm_server *server,
        array_push_back(&conn->server->connections, &conn);
 
        if (server_connection_read_settings(conn, error_r) < 0 ||
-           server_connection_init_ssl(conn, error_r) < 0) {
+           ((server->ssl_flags & PROXY_SSL_FLAG_STARTTLS) == 0 &&
+            server_connection_init_ssl(conn, error_r) < 0)) {
                server_connection_destroy(&conn);
                return -1;
        }