]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
*-login: Change proxy_error() API to proxy_failed() API
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Wed, 6 May 2020 17:21:15 +0000 (20:21 +0300)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Mon, 25 May 2020 08:38:55 +0000 (08:38 +0000)
The protocol-specific code is now able to control better what kind of a
reply is sent to client on proxying failure.

12 files changed:
src/imap-login/imap-login-client.c
src/imap-login/imap-proxy.c
src/imap-login/imap-proxy.h
src/login-common/client-common-auth.c
src/login-common/client-common.h
src/login-common/login-proxy.h
src/pop3-login/client.c
src/pop3-login/pop3-proxy.c
src/pop3-login/pop3-proxy.h
src/submission-login/client.c
src/submission-login/submission-proxy.c
src/submission-login/submission-proxy.h

index 91b1c5afc7ed75b218cf6e80e7436430e6e7e4b7..e2af176309cc07861bcd622bd846d09d76124bbc 100644 (file)
@@ -546,7 +546,7 @@ static struct client_vfuncs imap_client_vfuncs = {
        .auth_result = imap_client_auth_result,
        .proxy_reset = imap_proxy_reset,
        .proxy_parse_line = imap_proxy_parse_line,
-       .proxy_error = imap_proxy_error,
+       .proxy_failed = imap_proxy_failed,
        .proxy_get_state = imap_proxy_get_state,
        .send_raw_data = client_common_send_raw_data,
        .input_next_cmd = imap_client_input_next_cmd,
index afcd8a6e9c1a414c27af14ec97fbc64da0eaa7e6..09c10b80b2e2914ec509243ba04b02435532b4d1 100644 (file)
@@ -449,10 +449,42 @@ void imap_proxy_reset(struct client *client)
        imap_client->proxy_rcvd_state = IMAP_PROXY_RCVD_STATE_NONE;
 }
 
-void imap_proxy_error(struct client *client, const char *text)
+static void
+imap_proxy_send_failure_reply(struct imap_client *imap_client,
+                             enum login_proxy_failure_type type,
+                             const char *reason ATTR_UNUSED)
+{
+       switch (type) {
+       case LOGIN_PROXY_FAILURE_TYPE_CONNECT:
+       case LOGIN_PROXY_FAILURE_TYPE_INTERNAL:
+       case LOGIN_PROXY_FAILURE_TYPE_REMOTE:
+       case LOGIN_PROXY_FAILURE_TYPE_PROTOCOL:
+               client_send_reply_code(&imap_client->common, IMAP_CMD_REPLY_NO,
+                                      IMAP_RESP_CODE_UNAVAILABLE,
+                                      LOGIN_PROXY_FAILURE_MSG);
+               break;
+       case LOGIN_PROXY_FAILURE_TYPE_REMOTE_CONFIG:
+       case LOGIN_PROXY_FAILURE_TYPE_INTERNAL_CONFIG:
+               client_send_reply_code(&imap_client->common, IMAP_CMD_REPLY_NO,
+                                      IMAP_RESP_CODE_SERVERBUG,
+                                      LOGIN_PROXY_FAILURE_MSG);
+               break;
+       case LOGIN_PROXY_FAILURE_TYPE_AUTH:
+               /* reply was already sent */
+               break;
+       }
+}
+
+void imap_proxy_failed(struct client *client,
+                      enum login_proxy_failure_type type,
+                      const char *reason, bool reconnecting)
 {
-       client_send_reply_code(client, IMAP_CMD_REPLY_NO,
-                              IMAP_RESP_CODE_UNAVAILABLE, text);
+       struct imap_client *imap_client =
+               container_of(client, struct imap_client, common);
+
+       if (!reconnecting)
+               imap_proxy_send_failure_reply(imap_client, type, reason);
+       client_common_proxy_failed(client, type, reason, reconnecting);
 }
 
 const char *imap_proxy_get_state(struct client *client)
index b437ef509cf86485f0b2a7c24e14480117b52b10..71c2f64e783a077721b057f4b52f043f21873297 100644 (file)
@@ -4,7 +4,9 @@
 void imap_proxy_reset(struct client *client);
 int imap_proxy_parse_line(struct client *client, const char *line);
 
-void imap_proxy_error(struct client *client, const char *text);
+void imap_proxy_failed(struct client *client,
+                      enum login_proxy_failure_type type,
+                      const char *reason, bool reconnecting);
 const char *imap_proxy_get_state(struct client *client);
 
 #endif
index 57e2f082bcc1539e11562baf7a70da903971ddde..1cc9cce7f27baf2169bde5a6806bc23a7a79dc11 100644 (file)
@@ -16,8 +16,6 @@
 #include "master-service-ssl-settings.h"
 #include "client-common.h"
 
-#define PROXY_FAILURE_MSG "Account is temporarily unavailable."
-
 /* If we've been waiting auth server to respond for over this many milliseconds,
    send a "waiting" message. */
 #define AUTH_WAITING_TIMEOUT_MSECS (30*1000)
@@ -283,11 +281,6 @@ void client_proxy_finish_destroy_client(struct client *client)
        client_destroy_success(client, NULL);
 }
 
-static void client_proxy_error(struct client *client, const char *text)
-{
-       client->v.proxy_error(client, text);
-}
-
 const char *client_proxy_get_state(struct client *client)
 {
        return client->v.proxy_get_state(client);
@@ -361,10 +354,10 @@ static void proxy_input(struct client *client)
        o_stream_unref(&output);
 }
 
-static void proxy_failed(struct client *client,
-                        enum login_proxy_failure_type type,
-                        const char *reason ATTR_UNUSED,
-                        bool reconnecting)
+void client_common_proxy_failed(struct client *client,
+                               enum login_proxy_failure_type type,
+                               const char *reason ATTR_UNUSED,
+                               bool reconnecting)
 {
        if (client->proxy_sasl_client != NULL)
                dsasl_client_free(&client->proxy_sasl_client);
@@ -380,7 +373,6 @@ static void proxy_failed(struct client *client,
        case LOGIN_PROXY_FAILURE_TYPE_REMOTE:
        case LOGIN_PROXY_FAILURE_TYPE_REMOTE_CONFIG:
        case LOGIN_PROXY_FAILURE_TYPE_PROTOCOL:
-               client_proxy_error(client, PROXY_FAILURE_MSG);
                break;
        case LOGIN_PROXY_FAILURE_TYPE_AUTH:
                client->proxy_auth_failed = TRUE;
@@ -456,7 +448,9 @@ static int proxy_start(struct client *client,
                "proxy(%s): ", client->virtual_user));
 
        if (!proxy_check_start(client, event, reply, &sasl_mech, &ip)) {
-               client_proxy_error(client, PROXY_FAILURE_MSG);
+               client->v.proxy_failed(client,
+                       LOGIN_PROXY_FAILURE_TYPE_INTERNAL,
+                       LOGIN_PROXY_FAILURE_MSG, FALSE);
                event_unref(&event);
                return -1;
        }
@@ -486,7 +480,7 @@ static int proxy_start(struct client *client,
                net_ip2addr(&proxy_set.ip), proxy_set.port));
 
        if (login_proxy_new(client, event, &proxy_set, proxy_input,
-                           proxy_failed) < 0) {
+                           client->v.proxy_failed) < 0) {
                event_unref(&event);
                return -1;
        }
index 7bf5de4fd041b09730e7fc4ecbca2e6cef2700b0..cacd347049d11f6451d39e3eae354aef54c8d98f 100644 (file)
@@ -123,7 +123,9 @@ struct client_vfuncs {
                            const char *text);
        void (*proxy_reset)(struct client *client);
        int (*proxy_parse_line)(struct client *client, const char *line);
-       void (*proxy_error)(struct client *client, const char *text);
+       void (*proxy_failed)(struct client *client,
+                            enum login_proxy_failure_type type,
+                            const char *reason, bool reconnecting);
        const char *(*proxy_get_state)(struct client *client);
        void (*send_raw_data)(struct client *client,
                              const void *data, size_t size);
@@ -310,6 +312,9 @@ void client_send_raw(struct client *client, const char *data);
 void client_common_send_raw_data(struct client *client,
                                 const void *data, size_t size);
 void client_common_default_free(struct client *client);
+void client_common_proxy_failed(struct client *client,
+                               enum login_proxy_failure_type type,
+                               const char *reason, bool reconnecting);
 
 void client_set_auth_waiting(struct client *client);
 void client_auth_send_challenge(struct client *client, const char *data);
index ae460c32e9fea8056c4636fe16f7b57c1f0c9764..4729c70a84f4f489a2fb10f5f01483de5bd5e321 100644 (file)
@@ -10,6 +10,8 @@
    TTL extension feature. */
 #define LOGIN_PROXY_TTL 5
 
+#define LOGIN_PROXY_FAILURE_MSG "Account is temporarily unavailable."
+
 struct client;
 struct login_proxy;
 
index 267b6240e1c73a09f8ee7fabed95566eb79ae0fc..c687e37f24368aa0d1db4a13764160d5c477747d 100644 (file)
@@ -326,7 +326,7 @@ static struct client_vfuncs pop3_client_vfuncs = {
        .auth_result = pop3_client_auth_result,
        .proxy_reset = pop3_proxy_reset,
        .proxy_parse_line = pop3_proxy_parse_line,
-       .proxy_error = pop3_proxy_error,
+       .proxy_failed = pop3_proxy_failed,
        .proxy_get_state = pop3_proxy_get_state,
        .send_raw_data = client_common_send_raw_data,
        .input_next_cmd  = pop3_client_input_next_cmd,
index de04ae7c60a1744774df9e95025aea41015560a2..30ae5a8a4f671a9a19e6cd94f6f300d0e969114d 100644 (file)
@@ -270,9 +270,34 @@ void pop3_proxy_reset(struct client *client)
        pop3_client->proxy_state = POP3_PROXY_BANNER;
 }
 
-void pop3_proxy_error(struct client *client, const char *text)
+static void
+pop3_proxy_send_failure_reply(struct client *client,
+                             enum login_proxy_failure_type type,
+                             const char *reason ATTR_UNUSED)
 {
-       client_send_reply(client, POP3_CMD_REPLY_ERROR, text);
+       switch (type) {
+       case LOGIN_PROXY_FAILURE_TYPE_CONNECT:
+       case LOGIN_PROXY_FAILURE_TYPE_INTERNAL:
+       case LOGIN_PROXY_FAILURE_TYPE_INTERNAL_CONFIG:
+       case LOGIN_PROXY_FAILURE_TYPE_REMOTE:
+       case LOGIN_PROXY_FAILURE_TYPE_REMOTE_CONFIG:
+       case LOGIN_PROXY_FAILURE_TYPE_PROTOCOL:
+               client_send_reply(client, POP3_CMD_REPLY_ERROR,
+                                 LOGIN_PROXY_FAILURE_MSG);
+               break;
+       case LOGIN_PROXY_FAILURE_TYPE_AUTH:
+               /* reply was already sent */
+               break;
+       }
+}
+
+void pop3_proxy_failed(struct client *client,
+                      enum login_proxy_failure_type type,
+                      const char *reason, bool reconnecting)
+{
+       if (!reconnecting)
+               pop3_proxy_send_failure_reply(client, type, reason);
+       client_common_proxy_failed(client, type, reason, reconnecting);
 }
 
 const char *pop3_proxy_get_state(struct client *client)
index b6758d548479825f82d2a44e7ab1f6a59c2c6730..9e23475cd950187d932b7b75292a7ef8206a0c3e 100644 (file)
@@ -4,7 +4,9 @@
 void pop3_proxy_reset(struct client *client);
 int pop3_proxy_parse_line(struct client *client, const char *line);
 
-void pop3_proxy_error(struct client *client, const char *text);
+void pop3_proxy_failed(struct client *client,
+                      enum login_proxy_failure_type type,
+                      const char *reason, bool reconnecting);
 const char *pop3_proxy_get_state(struct client *client);
 
 #endif
index 673d3ce6e395288569204bf1f8e0f5ba0022f139..d2f03a0225c004e5c10d821830ba20c5d03d07d4 100644 (file)
@@ -292,7 +292,7 @@ static struct client_vfuncs submission_client_vfuncs = {
        .auth_result = submission_client_auth_result,
        .proxy_reset = submission_proxy_reset,
        .proxy_parse_line = submission_proxy_parse_line,
-       .proxy_error = submission_proxy_error,
+       .proxy_failed = submission_proxy_failed,
        .proxy_get_state = submission_proxy_get_state,
 };
 
index 652d041c44624d97c399c168f0748256f8b07b7e..c7548bc493d596f23990655f236a210595edca60 100644 (file)
@@ -456,16 +456,41 @@ void submission_proxy_reset(struct client *client)
        subm_client->proxy_reply = NULL;
 }
 
-void submission_proxy_error(struct client *client, const char *text)
+static void
+submission_proxy_send_failure_reply(struct submission_client *subm_client,
+                                   enum login_proxy_failure_type type,
+                                   const char *reason ATTR_UNUSED)
+{
+       struct smtp_server_cmd_ctx *cmd = subm_client->pending_auth;
+       if (cmd == NULL)
+               return;
+
+       subm_client->pending_auth = NULL;
+       switch (type) {
+       case LOGIN_PROXY_FAILURE_TYPE_CONNECT:
+       case LOGIN_PROXY_FAILURE_TYPE_INTERNAL:
+       case LOGIN_PROXY_FAILURE_TYPE_INTERNAL_CONFIG:
+       case LOGIN_PROXY_FAILURE_TYPE_REMOTE:
+       case LOGIN_PROXY_FAILURE_TYPE_REMOTE_CONFIG:
+       case LOGIN_PROXY_FAILURE_TYPE_PROTOCOL:
+               smtp_server_reply(cmd, 535, "5.7.8", LOGIN_PROXY_FAILURE_MSG);
+               break;
+       case LOGIN_PROXY_FAILURE_TYPE_AUTH:
+               /* reply was already sent */
+               break;
+       }
+}
+
+void submission_proxy_failed(struct client *client,
+                            enum login_proxy_failure_type type,
+                            const char *reason, bool reconnecting)
 {
        struct submission_client *subm_client =
                container_of(client, struct submission_client, common);
 
-       struct smtp_server_cmd_ctx *cmd = subm_client->pending_auth;
-       if (cmd != NULL) {
-               subm_client->pending_auth = NULL;
-               smtp_server_reply(cmd, 535, "5.7.8", "%s", text);
-       }
+       if (!reconnecting)
+               submission_proxy_send_failure_reply(subm_client, type, reason);
+       client_common_proxy_failed(client, type, reason, reconnecting);
 }
 
 const char *submission_proxy_get_state(struct client *client)
index b9370e6013258043b8b1c817df06052176722fb8..19342cf35d20f8cf637a0e5df104f05174612b4b 100644 (file)
@@ -4,7 +4,9 @@
 void submission_proxy_reset(struct client *client);
 int submission_proxy_parse_line(struct client *client, const char *line);
 
-void submission_proxy_error(struct client *client, const char *text);
+void submission_proxy_failed(struct client *client,
+                            enum login_proxy_failure_type type,
+                            const char *reason, bool reconnecting);
 const char *submission_proxy_get_state(struct client *client);
 
 #endif