int smtp_proxy_redirect_parse(const char *target, const char **destuser_r,
const char **host_r, struct ip_addr *ip_r,
- in_port_t *port_r)
+ in_port_t *port_r, const char **error_r)
{
const char *pend;
+ *error_r = NULL;
+
/* Skip <address> part of the reply if present (RCPT reply) */
pend = strchr(target, ' ');
if (*target == '<') {
- if (pend == NULL)
+ if (pend == NULL) {
+ *error_r = "Invalid path in redirect response";
return -1;
+ }
target = pend + 1;
pend = strchr(target, ' ');
}
if (pend != NULL)
target = t_strdup_until(target, pend);
- return (auth_proxy_parse_redirect(target, destuser_r, host_r,
- ip_r, port_r) ? 0 : -1);
+ if (!auth_proxy_parse_redirect(target, destuser_r, host_r,
+ ip_r, port_r)) {
+ *error_r = "Invalid redirect data";
+ return -1;
+ }
+ return 0;
}
static const char *
int smtp_proxy_redirect_parse(const char *target, const char **destuser_r,
const char **host_r, struct ip_addr *ip_r,
- in_port_t *port_r);
+ in_port_t *port_r, const char **error_r);
void smtp_server_reply_redirect(struct smtp_server_cmd_ctx *cmd,
in_port_t default_port,
lmtp_proxy_rcpt_parse_redirect(const struct smtp_reply *proxy_reply,
const char **destuser_r,
const char **host_r, struct ip_addr *ip_r,
- in_port_t *port_r)
+ in_port_t *port_r, const char **error_r)
{
if (proxy_reply->text_lines == NULL)
return -1;
return smtp_proxy_redirect_parse(*proxy_reply->text_lines, destuser_r,
- host_r, ip_r, port_r);
+ host_r, ip_r, port_r, error_r);
}
static void
struct smtp_server_recipient *rcpt = lrcpt->rcpt;
struct lmtp_proxy_connection *conn = lprcpt->conn;
struct lmtp_proxy_rcpt_settings set;
- const char *host, *destuser = lrcpt->username;
+ const char *host, *destuser = lrcpt->username, *error;
struct ip_addr ip;
in_port_t port;
if (lmtp_proxy_rcpt_parse_redirect(proxy_reply, &destuser,
- &host, &ip, &port) < 0) {
+ &host, &ip, &port, &error) < 0) {
e_error(rcpt->event,
- "Backend server returned invalid redirect: %s",
- smtp_reply_log(proxy_reply));
+ "Backend server returned invalid redirect '%s': %s",
+ smtp_reply_log(proxy_reply), error);
smtp_server_recipient_reply(rcpt, 451, "4.3.0",
"Temporary internal proxy error");
return;
}
static int
-submission_proxy_parse_redirect(const char *target, const char **userhostport_r)
+submission_proxy_parse_redirect(const char *target, const char **userhostport_r,
+ const char **error_r)
{
const char *destuser, *host;
struct ip_addr ip;
in_port_t port;
- if (smtp_proxy_redirect_parse(target, &destuser, &host, &ip, &port) < 0)
+ if (smtp_proxy_redirect_parse(target, &destuser, &host, &ip, &port,
+ error_r) < 0)
return -1;
string_t *str = t_str_new(128);
enum login_proxy_failure_type *failure_type_r,
const char **text_r)
{
+ const char *error;
+
if (!smtp_reply_code_is_proxy_redirect(status, enh_code))
return FALSE;
- if (submission_proxy_parse_redirect(target, text_r) < 0) {
+ if (submission_proxy_parse_redirect(target, text_r, &error) < 0) {
e_debug(login_proxy_get_event(client->login_proxy),
- "Backend server returned invalid redirect: %03u %s %s",
- status, enh_code, target);
+ "Backend server returned invalid redirect "
+ "'%03u %s %s': %s",
+ status, enh_code, target, error);
*failure_type_r = LOGIN_PROXY_FAILURE_TYPE_AUTH_TEMPFAIL;
*text_r = "Temporary internal proxy error";
return TRUE;