~kevin8t8/mutt

9da4e6e11e7037668d0ca7e8f5d6773d26e379ac — Remco Rijnders 13 days ago b48233f
Change Message-ID to be more unique and leak less information

A Message-ID should be globally unique. Currently mutt generates this ID
based on the current date and time, followed by ".G", followed by a letter
A to Z (A for the 1st and 27th email sent, Z for the 26th, etc.), followed
by the pid of the active mutt process, followed by "@" and the configured
fqdn.

This can lead to information being leaked as to an users email habits and
activities, which might be undesirable.

By replacing everything left of the "@" in the Message-ID with a Base64
encoded timestamp and 64 bits of randomness, we no longer include this
information.
1 files changed, 19 insertions(+), 12 deletions(-)

M sendlib.c
M sendlib.c => sendlib.c +19 -12
@@ 80,8 80,6 @@ const char B64Chars[64] = {
  '8', '9', '+', '/'
};

static char MsgIdPfx = 'A';

static void transform_to_7bit (BODY *a, FILE *fpin);

static void encode_quoted (FGETCONV * fc, FILE *fout, int istext)


@@ 2415,19 2413,28 @@ const char *mutt_fqdn(short may_hide_host)
char *mutt_gen_msgid (void)
{
  char buf[SHORT_STRING];
  time_t now;
  struct tm *tm;
  time_t now = time (NULL);
  char random_bytes[8];
  char localpart[12]; /* = 32 bit timestamp, plus 64 bit randomness */
  unsigned char localpart_B64[16+1]; /* = Base64 encoded value of localpart plus
                                        terminating \0 */
  const char *fqdn;

  now = time (NULL);
  tm = gmtime (&now);
  if (!(fqdn = mutt_fqdn(0)))
    fqdn = NONULL(Hostname);
  mutt_random_bytes ((char *) &random_bytes, sizeof(random_bytes));

  /* Convert the four least significant bytes of our timestamp and put it in
     localpart, with proper endianness (for humans) taken into account. */
  for (int i = 0; i < 4; i++)
    localpart[i] = (uint8_t) (now >> (3-i)*8u);

  memcpy (&localpart[4], &random_bytes, 8);

  mutt_to_base64 (localpart_B64, (unsigned char *) localpart, 12, 17);

  if (!(fqdn = mutt_fqdn (0)))
    fqdn = NONULL (Hostname);

  snprintf (buf, sizeof (buf), "<%d%02d%02d%02d%02d%02d.G%c%u@%s>",
	    tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour,
	    tm->tm_min, tm->tm_sec, MsgIdPfx, (unsigned int)getpid (), fqdn);
  MsgIdPfx = (MsgIdPfx == 'Z') ? 'A' : MsgIdPfx + 1;
  snprintf (buf, sizeof (buf), "<%s@%s>", localpart_B64, fqdn);
  return (safe_strdup (buf));
}