diff options
author | Sebastian Andrzej Siewior <sebastian@breakpoint.cc> | 2023-03-04 18:33:35 +0100 |
---|---|---|
committer | Kevin McCarthy <kevin@8t8.us> | 2023-03-04 18:11:15 -0800 |
commit | 5df86199463b5cf893fb6a37457fa02804d3b02a (patch) | |
tree | 3e3bc9bdf4449d94bfbc3c19d608e1673be9d224 | |
parent | cecddeac3be3d37a3418f01a02c9c0fbdd9f6d8c (diff) |
Use base64 URL safe alphabet for message id generation.
The character '/' from base64 alphabet breaks web redirectors if the
message-id from an email is used as part of the URL for redirectors and/
or automatic pointers to an email.
Use the URL safe alphabet from RFC4648 section 5 for message id
generation.
Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
-rw-r--r-- | base64.c | 33 | ||||
-rw-r--r-- | messageid.c | 4 | ||||
-rw-r--r-- | mime.h | 1 | ||||
-rw-r--r-- | protos.h | 1 | ||||
-rw-r--r-- | sendlib.c | 9 |
5 files changed, 36 insertions, 12 deletions
@@ -56,16 +56,15 @@ void mutt_buffer_to_base64 (BUFFER *out, const unsigned char *in, size_t len) mutt_buffer_fix_dptr (out); } -/* raw bytes to null-terminated base 64 string */ -void mutt_to_base64 (unsigned char *out, const unsigned char *in, size_t len, - size_t olen) +static void to_base64 (unsigned char *out, const unsigned char *in, size_t len, + size_t olen, const char *dict) { while (len >= 3 && olen > 4) { - *out++ = B64Chars[in[0] >> 2]; - *out++ = B64Chars[((in[0] << 4) & 0x30) | (in[1] >> 4)]; - *out++ = B64Chars[((in[1] << 2) & 0x3c) | (in[2] >> 6)]; - *out++ = B64Chars[in[2] & 0x3f]; + *out++ = dict[in[0] >> 2]; + *out++ = dict[((in[0] << 4) & 0x30) | (in[1] >> 4)]; + *out++ = dict[((in[1] << 2) & 0x3c) | (in[2] >> 6)]; + *out++ = dict[in[2] & 0x3f]; olen -= 4; len -= 3; in += 3; @@ -76,15 +75,29 @@ void mutt_to_base64 (unsigned char *out, const unsigned char *in, size_t len, { unsigned char fragment; - *out++ = B64Chars[in[0] >> 2]; + *out++ = dict[in[0] >> 2]; fragment = (in[0] << 4) & 0x30; if (len > 1) fragment |= in[1] >> 4; - *out++ = B64Chars[fragment]; - *out++ = (len < 2) ? '=' : B64Chars[(in[1] << 2) & 0x3c]; + *out++ = dict[fragment]; + *out++ = (len < 2) ? '=' : dict[(in[1] << 2) & 0x3c]; *out++ = '='; } *out = '\0'; + +} + +/* raw bytes to null-terminated base 64 string */ +void mutt_to_base64 (unsigned char *out, const unsigned char *in, size_t len, + size_t olen) +{ + to_base64 (out, in, len, olen, B64Chars); +} + +void mutt_to_base64_safeurl (unsigned char *out, const unsigned char *in, + size_t len, size_t olen) +{ + to_base64 (out, in, len, olen, B64Chars_urlsafe); } int mutt_buffer_from_base64 (BUFFER *out, const char *in) diff --git a/messageid.c b/messageid.c index e4ac4410..d96a5d44 100644 --- a/messageid.c +++ b/messageid.c @@ -49,7 +49,7 @@ static const char *id_format_str (char *dest, size_t destlen, size_t col, { case 'r': mutt_random_bytes ((char *)r_raw, sizeof(r_raw)); - mutt_to_base64 (r_out, r_raw, sizeof(r_raw), sizeof(r_out)); + mutt_to_base64_safeurl (r_out, r_raw, sizeof(r_raw), sizeof(r_out)); mutt_format_s (dest, destlen, fmt, (const char *)r_out); break; @@ -65,7 +65,7 @@ static const char *id_format_str (char *dest, size_t destlen, size_t col, for (int i = 0; i < 4; i++) z_raw[i] = (uint8_t) (id_data->now >> (3-i)*8u); mutt_random_bytes ((char *)z_raw + 4, sizeof(z_raw) - 4); - mutt_to_base64 (z_out, z_raw, sizeof(z_raw), sizeof(z_out)); + mutt_to_base64_safeurl (z_out, z_raw, sizeof(z_raw), sizeof(z_out)); mutt_format_s (dest, destlen, fmt, (const char *)z_out); break; @@ -63,6 +63,7 @@ enum extern const int Index_hex[]; extern const int Index_64[]; extern const char B64Chars[]; +extern const char B64Chars_urlsafe[]; #endif #define hexval(c) Index_hex[(unsigned int)(c)] @@ -432,6 +432,7 @@ int safe_symlink (const char *, const char *); /* base64.c */ void mutt_to_base64 (unsigned char*, const unsigned char*, size_t, size_t); +void mutt_to_base64_safeurl (unsigned char*, const unsigned char*, size_t, size_t); int mutt_from_base64 (char*, const char*, size_t); void mutt_buffer_to_base64 (BUFFER *, const unsigned char *, size_t); int mutt_buffer_from_base64 (BUFFER *, const char *); @@ -84,6 +84,15 @@ const char B64Chars[64] = { '8', '9', '+', '/' }; +/* RFC4648 section 5 Base 64 Encoding with URL and Filename Safe Alphabet */ +const char B64Chars_urlsafe[64] = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', + 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', + 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', '-', '_' +}; + static void transform_to_7bit (BODY *a, FILE *fpin); static void encode_quoted (FGETCONV * fc, FILE *fout, int istext) |