commit 7e1c16ae02b9b880d72982205169adbd68c1a954
parent 058d01f1792d0e0bd1f90cae157c071127eded5f
Author: Oswald Buddenhagen <ossi@users.sf.net>
Date: Sun, 23 Jan 2011 13:35:56 +0100
make cram() sane
- don't silently fail in release mode (expression with side effects
inside assert())
- save some redundand strlen()s by not throwing away known lengths
- reorganize the code for legibility
Diffstat:
M | src/drv_imap.c | | | 55 | +++++++++++++++++++++++++------------------------------ |
1 file changed, 25 insertions(+), 30 deletions(-)
diff --git a/src/drv_imap.c b/src/drv_imap.c
@@ -1223,49 +1223,45 @@ hexchar( unsigned int b )
return 'a' + (b - 10);
}
-/* XXX merge into do_cram_auth? */
-static char *
-cram( const char *challenge, const char *user, const char *pass )
+static void
+cram( const char *challenge, const char *user, const char *pass, char **_final, int *_finallen )
{
+ unsigned char *response, *final;
+ unsigned hashlen;
+ int i, clen, rlen, blen, flen, olen;
+ unsigned char hash[16];
+ char buf[256], hex[33];
HMAC_CTX hmac;
- char hash[16];
- char hex[33];
- int i;
- unsigned int hashlen = sizeof(hash);
- char buf[256];
- int len = strlen( challenge );
- char *response = nfcalloc( 1 + len );
- char *final;
- /* response will always be smaller than challenge because we are
- * decoding.
- */
- len = EVP_DecodeBlock( (unsigned char *)response, (unsigned char *)challenge, strlen( challenge ) );
+ HMAC_Init( &hmac, (unsigned char *)pass, strlen( pass ), EVP_md5() );
- HMAC_Init( &hmac, (unsigned char *) pass, strlen( pass ), EVP_md5() );
- HMAC_Update( &hmac, (unsigned char *)response, strlen( response ) );
- HMAC_Final( &hmac, (unsigned char *)hash, &hashlen );
+ clen = strlen( challenge );
+ /* response will always be smaller than challenge because we are decoding. */
+ response = nfcalloc( 1 + clen );
+ rlen = EVP_DecodeBlock( response, (unsigned char *)challenge, clen );
+ HMAC_Update( &hmac, response, rlen );
+ free( response );
+ hashlen = sizeof(hash);
+ HMAC_Final( &hmac, hash, &hashlen );
assert( hashlen == sizeof(hash) );
- free( response );
-
hex[32] = 0;
for (i = 0; i < 16; i++) {
hex[2 * i] = hexchar( (hash[i] >> 4) & 0xf );
hex[2 * i + 1] = hexchar( hash[i] & 0xf );
}
- nfsnprintf( buf, sizeof(buf), "%s %s", user, hex );
-
- len = strlen( buf );
- len = ENCODED_SIZE( len ) + 1;
- final = nfmalloc( len );
- final[len - 1] = 0;
+ blen = nfsnprintf( buf, sizeof(buf), "%s %s", user, hex );
- assert( EVP_EncodeBlock( (unsigned char *)final, (unsigned char *)buf, strlen( buf ) ) == len - 1 );
+ flen = ENCODED_SIZE( blen );
+ final = nfmalloc( flen + 1 );
+ final[flen] = 0;
+ olen = EVP_EncodeBlock( (unsigned char *)final, (unsigned char *)buf, blen );
+ assert( olen == flen );
- return final;
+ *_final = (char *)final;
+ *_finallen = flen;
}
static int
@@ -1275,11 +1271,10 @@ do_cram_auth( imap_store_t *ctx, struct imap_cmd *cmdp, const char *prompt )
char *resp;
int n, l;
- resp = cram( prompt, srvc->user, srvc->pass );
+ cram( prompt, srvc->user, srvc->pass, &resp, &l );
if (DFlags & VERBOSE)
printf( ">+> %s\n", resp );
- l = strlen( resp );
n = socket_write( &ctx->buf.sock, resp, l );
free( resp );
if (n != l)