Skip to content

Commit

Permalink
submission-login: submission-proxy - Do not include initial response …
Browse files Browse the repository at this point in the history
…in AUTH command if it is too long.
  • Loading branch information
stephanbosch authored and cmouse committed Feb 24, 2022
1 parent 161377b commit 667e206
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 9 deletions.
1 change: 1 addition & 0 deletions src/submission-login/client.h
Expand Up @@ -29,6 +29,7 @@ struct submission_client {

enum submission_proxy_state proxy_state;
enum smtp_capability proxy_capability;
char *proxy_sasl_ir;
unsigned int proxy_reply_status;
struct smtp_server_reply *proxy_reply;
const char **proxy_xclient;
Expand Down
74 changes: 65 additions & 9 deletions src/submission-login/submission-proxy.c
Expand Up @@ -234,7 +234,7 @@ proxy_send_login(struct submission_client *client, struct ostream *output)
dsasl_client_new(client->common.proxy_mech, &sasl_set);
mech_name = dsasl_client_mech_get_name(client->common.proxy_mech);

str_printfa(str, "AUTH %s ", mech_name);
str_printfa(str, "AUTH %s", mech_name);
if (dsasl_client_output(client->common.proxy_sasl_client,
&sasl_output, &sasl_output_len, &error) < 0) {
const char *reason = t_strdup_printf(
Expand All @@ -245,10 +245,35 @@ proxy_send_login(struct submission_client *client, struct ostream *output)
LOGIN_PROXY_FAILURE_TYPE_INTERNAL, reason);
return -1;
}
if (sasl_output_len == 0)
str_append_c(str, '=');
else
base64_encode(sasl_output, sasl_output_len, str);

string_t *sasl_output_base64 = t_str_new(
MAX_BASE64_ENCODED_SIZE(sasl_output_len));
base64_encode(sasl_output, sasl_output_len, sasl_output_base64);

/* RFC 4954, Section 4:
Note that the AUTH command is still subject to the line length
limitations defined in [SMTP]. If use of the initial response
argument would cause the AUTH command to exceed this length, the
client MUST NOT use the initial response parameter (and instead
proceed as defined in Section 5.1 of [SASL]).
If the client is transmitting an initial response of zero length, it
MUST instead transmit the response as a single equals sign ("=").
This indicates that the response is present, but contains no data.
*/

i_assert(client->proxy_sasl_ir == NULL);
if (str_len(sasl_output_base64) == 0)
str_append(str, " =");
else if ((5 + strlen(mech_name) + 1 + str_len(sasl_output_base64)) >
SMTP_BASE_LINE_LENGTH_LIMIT)
client->proxy_sasl_ir = i_strdup(str_c(sasl_output_base64));
else {
str_append_c(str, ' ');
str_append_str(str, sasl_output_base64);
}

str_append(str, "\r\n");
o_stream_nsend(output, str_data(str), str_len(str));

Expand Down Expand Up @@ -306,15 +331,45 @@ proxy_handle_ehlo_reply(struct submission_client *client,
}

static int
submission_proxy_continue_sasl_auth(struct client *client, struct ostream *output,
const char *line)
submission_proxy_continue_sasl_auth(struct client *client,
struct ostream *output, const char *line,
bool last_line)
{
struct submission_client *subm_client =
container_of(client, struct submission_client, common);
string_t *str;
const unsigned char *data;
size_t data_len;
const char *error;
int ret;

if (!last_line) {
const char *reason = t_strdup_printf(
"Server returned multi-line challenge: 334 %s",
str_sanitize(line, 1024));
login_proxy_failed(client->login_proxy,
login_proxy_get_event(client->login_proxy),
LOGIN_PROXY_FAILURE_TYPE_PROTOCOL, reason);
return -1;
}
if (subm_client->proxy_sasl_ir != NULL) {
if (*line == '\0') {
/* Send initial response */
o_stream_nsend(output, subm_client->proxy_sasl_ir,
strlen(subm_client->proxy_sasl_ir));
o_stream_nsend_str(output, "\r\n");
i_free(subm_client->proxy_sasl_ir);
return 0;
}
const char *reason = t_strdup_printf(
"Server sent unexpected server-first challenge: "
"334 %s", str_sanitize(line, 1024));
login_proxy_failed(client->login_proxy,
login_proxy_get_event(client->login_proxy),
LOGIN_PROXY_FAILURE_TYPE_PROTOCOL, reason);
return -1;
}

str = t_str_new(128);
if (base64_decode(line, strlen(line), NULL, str) < 0) {
login_proxy_failed(client->login_proxy,
Expand Down Expand Up @@ -576,8 +631,8 @@ int submission_proxy_parse_line(struct client *client, const char *line)
break;
if (status == 334 && client->proxy_sasl_client != NULL) {
/* continue SASL authentication */
if (submission_proxy_continue_sasl_auth(client, output,
text) < 0)
if (submission_proxy_continue_sasl_auth(
client, output, text, last_line) < 0)
return -1;
return 0;
}
Expand Down Expand Up @@ -649,6 +704,7 @@ void submission_proxy_reset(struct client *client)
subm_client->proxy_state = SUBMISSION_PROXY_BANNER;
subm_client->proxy_capability = 0;
i_free_and_null(subm_client->proxy_xclient);
i_free(subm_client->proxy_sasl_ir);
subm_client->proxy_reply_status = 0;
subm_client->proxy_reply = NULL;
}
Expand Down

0 comments on commit 667e206

Please sign in to comment.