From 8dfba1df083d4fc30f386b5e84748f9482f94485 Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan.bosch@open-xchange.com> Date: Sun, 10 Oct 2021 23:30:03 +0200 Subject: [PATCH] managesieve-login: proxy - Support parsing REFERRAL on remote auth failure. --- src/managesieve-login/managesieve-proxy.c | 32 +++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/managesieve-login/managesieve-proxy.c b/src/managesieve-login/managesieve-proxy.c index 184bae2fd..36b8c3cfe 100644 --- a/src/managesieve-login/managesieve-proxy.c +++ b/src/managesieve-login/managesieve-proxy.c @@ -20,6 +20,7 @@ #include "managesieve-quote.h" #include "managesieve-proxy.h" #include "managesieve-parser.h" +#include "managesieve-url.h" typedef enum { MANAGESIEVE_RESPONSE_NONE, @@ -442,6 +443,34 @@ managesieve_proxy_parse_auth_reply(const char *line, managesieve_parser_destroy(&parser); } +static bool +auth_resp_code_parse_referral(struct client *client, const char *resp_code, + const char **userhostport_r) +{ + struct managesieve_url *url; + const char *referral, *error; + + if (resp_code == NULL || strncasecmp(resp_code, "REFERRAL ", 9) != 0) + return FALSE; + referral = resp_code + 9; + + if (managesieve_url_parse(referral, MANAGESIEVE_URL_ALLOW_USERINFO_PART, + pool_datastack_create(), &url, &error) < 0) { + e_debug(login_proxy_get_event(client->login_proxy), + "Couldn't parse REFERRAL '%s': %s", referral, error); + return FALSE; + } + + string_t *str = t_str_new(128); + if (url->user != NULL) + str_printfa(str, "%s@", url->user); + str_append(str, url->host.name); + if (url->port != 0) + str_printfa(str, ":%u", url->port); + *userhostport_r = str_c(str); + return TRUE; +} + int managesieve_proxy_parse_line(struct client *client, const char *line) { struct managesieve_client *msieve_client = @@ -608,6 +637,9 @@ int managesieve_proxy_parse_line(struct client *client, const char *line) enum login_proxy_failure_type failure_type; if (null_strcasecmp(resp_code, "TRYLATER") == 0) failure_type = LOGIN_PROXY_FAILURE_TYPE_AUTH_TEMPFAIL; + else if (auth_resp_code_parse_referral(client, resp_code, + &reason)) + failure_type = LOGIN_PROXY_FAILURE_TYPE_AUTH_REDIRECT; else { failure_type = LOGIN_PROXY_FAILURE_TYPE_AUTH; client_send_no(client, AUTH_FAILED_MSG); -- GitLab