Hi Kevin,

On 2026-04-19T15:24:10+0800, Kevin J. McCarthy wrote:
> On Sun, Apr 19, 2026 at 08:42:48AM +0200, Alejandro Colomar via Mutt-dev 
> wrote:
> > On 2026-04-19T07:48:40+0800, Kevin J. McCarthy wrote:
> > > On Sat, Apr 18, 2026 at 08:27:26PM +0200, Alejandro Colomar via Mutt-dev 
> > > wrote:
> > > 
> > > /etc/shadow stores a readable ascii encoding, (base64?)  not the raw bytes
> > > themselves.  In this case, md5_buffer() actually generates binary data and
> > > stores it into hash_passwd.
> > 
> > As far as I know (I could be wrong), it stores the raw bytes.  I've
> > checked the source code of the shadow project, and didn't find anything
> > that seems to encode the data in any way.  It stores directly whatever
> > that crypt(3) produces.  Unless crypt(3) itself already gives us an
> > encoded version of the hash, of course.
> 
> The output of md5 is a sequence of 16 bytes, each of which can have values
> 0-255, right?  So it would make sense that if the result of crypt(3) was not
> encoded somehow, `cat /etc/shadow` (as root of course) would generate
> garbage in the terminal.

Hmmm, I think crypt prints the hex values as text.  That is, where
mutt(1) would produce the value 0x1234, crypt would produce the string
"1234" (more or less).


Cheers,
Alex

> 
> If I have time I'll try to play with it more, but I can confirm that mutt's
> md5_buffer() generates raw data.  In places where mutt wants to use that
> data as a string, it encodes it, for example in hcache.c L642:
> 
>     md5_buffer(folder, strlen(folder), &md5sum);
>     mutt_buffer_printf(hcfile,
>                        "%02x%02x%02x%02x%02x%02x%02x%02x"
>                        "%02x%02x%02x%02x%02x%02x%02x%02x",
>                        md5sum[0], md5sum[1], md5sum[2], md5sum[3],
>                        md5sum[4], md5sum[5], md5sum[6], md5sum[7],
>                        md5sum[8], md5sum[9], md5sum[10], md5sum[11],
>                        md5sum[12], md5sum[13], md5sum[14], md5sum[15]);
> 
> In any case - even if I am completely wrong - there isn't anything wrong
> with using memcpy on the result in auth_cram().  The value of 'secret' is
> further memcpy() below into ipad and opad.  AFAIK, AUTH CRAM is supposed to
> be fed the raw bytes when the secret is md5 digested.  See imap/auth_cram.c:
> 
> 
>   secret_len = strlen (password);
>   chal_len = strlen (challenge);
> 
>   /* passwords longer than MD5_BLOCK_LEN bytes are substituted with their MD5
>    * digests */
>   if (secret_len > MD5_BLOCK_LEN)
>   {
>     md5_buffer (password, secret_len, hash_passwd);
>     memcpy(secret, hash_passwd, MD5_DIGEST_LEN);
>     secret_len = MD5_DIGEST_LEN;
>   }
>   else
>     strfcpy ((char *) secret, password, sizeof (secret));
> 
>   memset (ipad, 0, sizeof (ipad));
>   memset (opad, 0, sizeof (opad));
>   memcpy (ipad, secret, secret_len);
>   memcpy (opad, secret, secret_len);
> 
> 
> -- 
> Kevin J. McCarthy
> GPG Fingerprint: 8975 A9B3 3AA3 7910 385C  5308 ADEF 7684 8031 6BDA



-- 
<https://www.alejandro-colomar.es>

Attachment: signature.asc
Description: PGP signature

Reply via email to