Fix memory override in smtp.c code. Fix ESMTP capability parsing.
* mailbox/base64.c (mu_base64_encode): Make sure output buffer is null-terminated. * imap4d/auth_gss.c (auth_gssapi): Assume buffer returned by mu_base64_encode is null-terminated. * libproto/mailer/smtp.c (cram_md5): Take challenge_len as argument. All callers updated. (smtp_auth): Fix eventual memory override. Assume buffer returned by mu_base64_encode is nul-terminated. (smtp_parse_ehlo_ack): Fix capability parsing: (a) do not depend on the continuation marker ('-' or ' ') and (b) fix parsing of the SIZE capablity. Move call to mu_rtrim_cset out of the internal loop.
Showing
3 changed files
with
29 additions
and
30 deletions
... | @@ -192,7 +192,7 @@ auth_gssapi (struct imap4d_command *command, | ... | @@ -192,7 +192,7 @@ auth_gssapi (struct imap4d_command *command, |
192 | if (outbuf.length) | 192 | if (outbuf.length) |
193 | { | 193 | { |
194 | mu_base64_encode (outbuf.value, outbuf.length, &tmp, &size); | 194 | mu_base64_encode (outbuf.value, outbuf.length, &tmp, &size); |
195 | util_send ("+ %*.*s\r\n", size, size, tmp); | 195 | util_send ("+ %s\r\n", tmp); |
196 | free (tmp); | 196 | free (tmp); |
197 | gss_release_buffer (&min_stat, &outbuf); | 197 | gss_release_buffer (&min_stat, &outbuf); |
198 | } | 198 | } |
... | @@ -212,7 +212,7 @@ auth_gssapi (struct imap4d_command *command, | ... | @@ -212,7 +212,7 @@ auth_gssapi (struct imap4d_command *command, |
212 | if (outbuf.length) | 212 | if (outbuf.length) |
213 | { | 213 | { |
214 | mu_base64_encode (outbuf.value, outbuf.length, &tmp, &size); | 214 | mu_base64_encode (outbuf.value, outbuf.length, &tmp, &size); |
215 | util_send ("+ %*.*s\r\n", size, size, tmp); | 215 | util_send ("+ %s\r\n", tmp); |
216 | free (tmp); | 216 | free (tmp); |
217 | gss_release_buffer (&min_stat, &outbuf); | 217 | gss_release_buffer (&min_stat, &outbuf); |
218 | imap4d_getline (&token_str, &token_size, &token_len); | 218 | imap4d_getline (&token_str, &token_size, &token_len); |
... | @@ -232,7 +232,7 @@ auth_gssapi (struct imap4d_command *command, | ... | @@ -232,7 +232,7 @@ auth_gssapi (struct imap4d_command *command, |
232 | } | 232 | } |
233 | 233 | ||
234 | mu_base64_encode (outbuf.value, outbuf.length, &tmp, &size); | 234 | mu_base64_encode (outbuf.value, outbuf.length, &tmp, &size); |
235 | util_send ("+ %*.*s\r\n", size, size, tmp); | 235 | util_send ("+ %s\r\n", tmp); |
236 | free (tmp); | 236 | free (tmp); |
237 | 237 | ||
238 | imap4d_getline (&token_str, &token_size, &token_len); | 238 | imap4d_getline (&token_str, &token_size, &token_len); | ... | ... |
... | @@ -630,13 +630,13 @@ smtp_starttls (smtp_t smtp) | ... | @@ -630,13 +630,13 @@ smtp_starttls (smtp_t smtp) |
630 | } | 630 | } |
631 | 631 | ||
632 | static void | 632 | static void |
633 | cram_md5 (char *secret, unsigned char *challenge, unsigned char *digest) | 633 | cram_md5 (char *secret, unsigned char *challenge, size_t challenge_len, |
634 | unsigned char *digest) | ||
634 | { | 635 | { |
635 | struct mu_md5_ctx context; | 636 | struct mu_md5_ctx context; |
636 | unsigned char ipad[64]; | 637 | unsigned char ipad[64]; |
637 | unsigned char opad[64]; | 638 | unsigned char opad[64]; |
638 | int secret_len; | 639 | int secret_len; |
639 | int challenge_len; | ||
640 | int i; | 640 | int i; |
641 | 641 | ||
642 | if (secret == 0 || challenge == 0) | 642 | if (secret == 0 || challenge == 0) |
... | @@ -766,7 +766,7 @@ smtp_auth (smtp_t smtp) | ... | @@ -766,7 +766,7 @@ smtp_auth (smtp_t smtp) |
766 | mu_rtrim_cset (p, "\r\n"); | 766 | mu_rtrim_cset (p, "\r\n"); |
767 | mu_base64_decode ((unsigned char*) p, strlen (p), &chl, &chlen); | 767 | mu_base64_decode ((unsigned char*) p, strlen (p), &chl, &chlen); |
768 | 768 | ||
769 | cram_md5 ((char *) mu_secret_password (secret), chl, digest); | 769 | cram_md5 ((char *) mu_secret_password (secret), chl, chlen, digest); |
770 | mu_secret_password_unref (secret); | 770 | mu_secret_password_unref (secret); |
771 | free (chl); | 771 | free (chl); |
772 | 772 | ||
... | @@ -776,7 +776,6 @@ smtp_auth (smtp_t smtp) | ... | @@ -776,7 +776,6 @@ smtp_auth (smtp_t smtp) |
776 | mu_asnprintf (&buf, &buflen, "%s %s", user, ascii_digest); | 776 | mu_asnprintf (&buf, &buflen, "%s %s", user, ascii_digest); |
777 | buflen = strlen (buf); | 777 | buflen = strlen (buf); |
778 | mu_base64_encode ((unsigned char*) buf, buflen, &b64buf, &b64buflen); | 778 | mu_base64_encode ((unsigned char*) buf, buflen, &b64buf, &b64buflen); |
779 | b64buf[b64buflen] = '\0'; | ||
780 | free (buf); | 779 | free (buf); |
781 | 780 | ||
782 | status = smtp_writeline (smtp, "%s\r\n", b64buf); | 781 | status = smtp_writeline (smtp, "%s\r\n", b64buf); |
... | @@ -818,7 +817,6 @@ smtp_auth (smtp_t smtp) | ... | @@ -818,7 +817,6 @@ smtp_auth (smtp_t smtp) |
818 | buf[c] = '\0'; | 817 | buf[c] = '\0'; |
819 | } | 818 | } |
820 | mu_base64_encode ((unsigned char*) buf, buflen, &b64buf, &b64buflen); | 819 | mu_base64_encode ((unsigned char*) buf, buflen, &b64buf, &b64buflen); |
821 | b64buf[b64buflen] = '\0'; | ||
822 | free (buf); | 820 | free (buf); |
823 | 821 | ||
824 | status = smtp_writeline (smtp, "AUTH PLAIN %s\r\n", b64buf); | 822 | status = smtp_writeline (smtp, "AUTH PLAIN %s\r\n", b64buf); |
... | @@ -1398,42 +1396,43 @@ smtp_parse_ehlo_ack (smtp_t smtp) | ... | @@ -1398,42 +1396,43 @@ smtp_parse_ehlo_ack (smtp_t smtp) |
1398 | status = smtp_readline (smtp); | 1396 | status = smtp_readline (smtp); |
1399 | if ((smtp->ptr - smtp->buffer) > 4 && smtp->buffer[3] == '-') | 1397 | if ((smtp->ptr - smtp->buffer) > 4 && smtp->buffer[3] == '-') |
1400 | multi = 1; | 1398 | multi = 1; |
1401 | if (status == 0) | 1399 | if (status == 0 && memcmp (smtp->buffer, "250", 3) == 0) |
1402 | { | 1400 | { |
1401 | char *capa_str = smtp->buffer + 4; | ||
1402 | |||
1403 | smtp->ptr = smtp->buffer; | 1403 | smtp->ptr = smtp->buffer; |
1404 | 1404 | ||
1405 | if (!mu_c_strncasecmp (smtp->buffer, "250-STARTTLS", 12)) | 1405 | if (!mu_c_strncasecmp (capa_str, "STARTTLS", 8)) |
1406 | smtp->capa |= CAPA_STARTTLS; | 1406 | smtp->capa |= CAPA_STARTTLS; |
1407 | else if (!mu_c_strncasecmp (smtp->buffer, "250-SIZE", 8)) | 1407 | else if (!mu_c_strncasecmp (capa_str, "SIZE", 4)) |
1408 | { | 1408 | { |
1409 | char *p; | ||
1410 | size_t n; | ||
1411 | |||
1409 | smtp->capa |= CAPA_SIZE; | 1412 | smtp->capa |= CAPA_SIZE; |
1410 | if (smtp->buffer[8] == '=') | 1413 | |
1411 | { | 1414 | n = strtoul (capa_str + 5, &p, 10); |
1412 | char *p; | 1415 | if (*p != '\n') |
1413 | size_t n = strtoul (smtp->buffer + 9, &p, 10); | 1416 | MU_DEBUG1 (smtp->mailer->debug, MU_DEBUG_ERROR, |
1414 | 1417 | "suspicious size capability: %s", | |
1415 | if (*p != '\n') | 1418 | smtp->buffer); |
1416 | MU_DEBUG1 (smtp->mailer->debug, MU_DEBUG_ERROR, | 1419 | else |
1417 | "suspicious size declaration: %s", | 1420 | smtp->max_size = n; |
1418 | smtp->buffer); | ||
1419 | else | ||
1420 | smtp->max_size = n; | ||
1421 | } | ||
1422 | } | 1421 | } |
1423 | else if (!mu_c_strncasecmp (smtp->buffer, "250-AUTH", 8)) | 1422 | else if (!mu_c_strncasecmp (capa_str, "AUTH", 4)) |
1424 | { | 1423 | { |
1425 | char *name, *s; | 1424 | char *name, *s; |
1426 | 1425 | ||
1427 | smtp->capa |= CAPA_AUTH; | 1426 | smtp->capa |= CAPA_AUTH; |
1428 | 1427 | ||
1429 | for (name = strtok_r (smtp->buffer + 8, " ", &s); name; | 1428 | for (name = strtok_r (capa_str + 5, " ", &s); name; |
1430 | name = strtok_r (NULL, " ", &s)) | 1429 | name = strtok_r (NULL, " ", &s)) |
1431 | { | 1430 | { |
1432 | struct auth_mech_record *mechs = auth_mech_list; | 1431 | struct auth_mech_record *mechs = auth_mech_list; |
1433 | 1432 | ||
1433 | mu_rtrim_cset (name, "\r\n"); | ||
1434 | for (; mechs->name; mechs++) | 1434 | for (; mechs->name; mechs++) |
1435 | { | 1435 | { |
1436 | mu_rtrim_cset (name, "\r\n"); | ||
1437 | if (!mu_c_strcasecmp (mechs->name, name)) | 1436 | if (!mu_c_strcasecmp (mechs->name, name)) |
1438 | { | 1437 | { |
1439 | smtp->auth_mechs |= mechs->id; | 1438 | smtp->auth_mechs |= mechs->id; | ... | ... |
... | @@ -26,11 +26,11 @@ | ... | @@ -26,11 +26,11 @@ |
26 | 26 | ||
27 | int | 27 | int |
28 | mu_base64_encode (const unsigned char *input, size_t input_len, | 28 | mu_base64_encode (const unsigned char *input, size_t input_len, |
29 | unsigned char **output, size_t * output_len) | 29 | unsigned char **output, size_t *output_len) |
30 | { | 30 | { |
31 | static char b64tab[] = | 31 | static char b64tab[] = |
32 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | 32 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
33 | size_t olen = 4 * (input_len + 2) / 3; | 33 | size_t olen = 4 * (input_len + 2) / 3 + 1; |
34 | unsigned char *out = malloc (olen); | 34 | unsigned char *out = malloc (olen); |
35 | 35 | ||
36 | if (!out) | 36 | if (!out) |
... | @@ -42,7 +42,6 @@ mu_base64_encode (const unsigned char *input, size_t input_len, | ... | @@ -42,7 +42,6 @@ mu_base64_encode (const unsigned char *input, size_t input_len, |
42 | *out++ = b64tab[((input[0] << 4) & 0x30) | (input[1] >> 4)]; | 42 | *out++ = b64tab[((input[0] << 4) & 0x30) | (input[1] >> 4)]; |
43 | *out++ = b64tab[((input[1] << 2) & 0x3c) | (input[2] >> 6)]; | 43 | *out++ = b64tab[((input[1] << 2) & 0x3c) | (input[2] >> 6)]; |
44 | *out++ = b64tab[input[2] & 0x3f]; | 44 | *out++ = b64tab[input[2] & 0x3f]; |
45 | olen -= 4; | ||
46 | input_len -= 3; | 45 | input_len -= 3; |
47 | input += 3; | 46 | input += 3; |
48 | } | 47 | } |
... | @@ -58,12 +57,13 @@ mu_base64_encode (const unsigned char *input, size_t input_len, | ... | @@ -58,12 +57,13 @@ mu_base64_encode (const unsigned char *input, size_t input_len, |
58 | *out++ = '='; | 57 | *out++ = '='; |
59 | } | 58 | } |
60 | *output_len = out - *output; | 59 | *output_len = out - *output; |
60 | *out = 0; | ||
61 | return 0; | 61 | return 0; |
62 | } | 62 | } |
63 | 63 | ||
64 | int | 64 | int |
65 | mu_base64_decode (const unsigned char *input, size_t input_len, | 65 | mu_base64_decode (const unsigned char *input, size_t input_len, |
66 | unsigned char **output, size_t * output_len) | 66 | unsigned char **output, size_t *output_len) |
67 | { | 67 | { |
68 | static int b64val[128] = { | 68 | static int b64val[128] = { |
69 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | 69 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ... | ... |
-
Please register or sign in to post a comment