diff --git a/src/doveadm/client-connection.c b/src/doveadm/client-connection.c index 1641201631..839dba96e3 100644 --- a/src/doveadm/client-connection.c +++ b/src/doveadm/client-connection.c @@ -423,6 +423,11 @@ static void client_connection_input(struct client_connection *conn) conn->authenticated = TRUE; } + if (!conn->io_setup) { + conn->io_setup = TRUE; + doveadm_print_ostream = conn->output; + } + while (ok && !conn->input->closed && (line = i_stream_read_next_line(conn->input)) != NULL) { T_BEGIN { diff --git a/src/doveadm/client-connection.h b/src/doveadm/client-connection.h index 97e18711a8..172c082c59 100644 --- a/src/doveadm/client-connection.h +++ b/src/doveadm/client-connection.h @@ -18,6 +18,7 @@ struct client_connection { unsigned int handshaked:1; unsigned int authenticated:1; + unsigned int io_setup:1; }; struct client_connection * diff --git a/src/doveadm/doveadm-util.h b/src/doveadm/doveadm-util.h index b5bbf2df0d..54fdf60d7c 100644 --- a/src/doveadm/doveadm-util.h +++ b/src/doveadm/doveadm-util.h @@ -4,6 +4,8 @@ #include "net.h" #define DOVEADM_SERVER_PROTOCOL_VERSION_MAJOR 1 +#define DOVEADM_SERVER_PROTOCOL_VERSION_MINOR 0 +#define DOVEADM_SERVER_PROTOCOL_VERSION_LINE "VERSION\tdoveadm-server\t1\t0" extern bool doveadm_verbose, doveadm_debug, doveadm_server; diff --git a/src/doveadm/server-connection.c b/src/doveadm/server-connection.c index cc2badcf00..e0117c7b3b 100644 --- a/src/doveadm/server-connection.c +++ b/src/doveadm/server-connection.c @@ -296,30 +296,38 @@ static void server_connection_input(struct server_connection *conn) if (conn->to_input != NULL) timeout_remove(&conn->to_input); - if (!conn->handshaked) { - if ((line = i_stream_read_next_line(conn->input)) == NULL) { - if (conn->input->eof || conn->input->stream_errno != 0) { - server_log_disconnect_error(conn); + if (!conn->handshaked || !conn->authenticated) { + while((line = i_stream_read_next_line(conn->input)) != NULL) { + if (strcmp(line, "+") == 0) { + server_connection_authenticated(conn); + break; + } else if (strcmp(line, "-") == 0) { + if (!conn->handshaked && + server_connection_authenticate(conn) < 0) { + server_connection_destroy(&conn); + return; + } else if (conn->handshaked) { + i_error("doveadm authentication failed (%s)", + line+1); + server_connection_destroy(&conn); + return; + } + } else { + i_error("doveadm server sent invalid handshake: %s", + line); server_connection_destroy(&conn); + return; } - return; + conn->handshaked = TRUE; } - conn->handshaked = TRUE; - if (strcmp(line, "+") == 0) - server_connection_authenticated(conn); - else if (strcmp(line, "-") == 0) { - if (server_connection_authenticate(conn) < 0) { + if (line == NULL) { + if (conn->input->eof || conn->input->stream_errno != 0) { + server_log_disconnect_error(conn); server_connection_destroy(&conn); - return; } - return; - } else { - i_error("doveadm server sent invalid handshake: %s", - line); - server_connection_destroy(&conn); - return; } + return; } if (i_stream_read(conn->input) < 0) { @@ -329,18 +337,6 @@ static void server_connection_input(struct server_connection *conn) return; } - if (!conn->authenticated) { - if ((line = i_stream_next_line(conn->input)) == NULL) - return; - if (strcmp(line, "+") == 0) - server_connection_authenticated(conn); - else { - i_error("doveadm authentication failed (%s)", line+1); - server_connection_destroy(&conn); - return; - } - } - while (server_connection_input_one(conn)) ; }