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
This commit is contained in:
parent
058d01f179
commit
7e1c16ae02
|
@ -1223,49 +1223,45 @@ hexchar( unsigned int b )
|
||||||
return 'a' + (b - 10);
|
return 'a' + (b - 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX merge into do_cram_auth? */
|
static void
|
||||||
static char *
|
cram( const char *challenge, const char *user, const char *pass, char **_final, int *_finallen )
|
||||||
cram( const char *challenge, const char *user, const char *pass )
|
|
||||||
{
|
{
|
||||||
|
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;
|
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 );
|
|
||||||
|
|
||||||
assert( hashlen == sizeof(hash) );
|
|
||||||
|
|
||||||
|
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 );
|
free( response );
|
||||||
|
|
||||||
|
hashlen = sizeof(hash);
|
||||||
|
HMAC_Final( &hmac, hash, &hashlen );
|
||||||
|
assert( hashlen == sizeof(hash) );
|
||||||
|
|
||||||
hex[32] = 0;
|
hex[32] = 0;
|
||||||
for (i = 0; i < 16; i++) {
|
for (i = 0; i < 16; i++) {
|
||||||
hex[2 * i] = hexchar( (hash[i] >> 4) & 0xf );
|
hex[2 * i] = hexchar( (hash[i] >> 4) & 0xf );
|
||||||
hex[2 * i + 1] = hexchar( hash[i] & 0xf );
|
hex[2 * i + 1] = hexchar( hash[i] & 0xf );
|
||||||
}
|
}
|
||||||
|
|
||||||
nfsnprintf( buf, sizeof(buf), "%s %s", user, hex );
|
blen = nfsnprintf( buf, sizeof(buf), "%s %s", user, hex );
|
||||||
|
|
||||||
len = strlen( buf );
|
flen = ENCODED_SIZE( blen );
|
||||||
len = ENCODED_SIZE( len ) + 1;
|
final = nfmalloc( flen + 1 );
|
||||||
final = nfmalloc( len );
|
final[flen] = 0;
|
||||||
final[len - 1] = 0;
|
olen = EVP_EncodeBlock( (unsigned char *)final, (unsigned char *)buf, blen );
|
||||||
|
assert( olen == flen );
|
||||||
|
|
||||||
assert( EVP_EncodeBlock( (unsigned char *)final, (unsigned char *)buf, strlen( buf ) ) == len - 1 );
|
*_final = (char *)final;
|
||||||
|
*_finallen = flen;
|
||||||
return final;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -1275,11 +1271,10 @@ do_cram_auth( imap_store_t *ctx, struct imap_cmd *cmdp, const char *prompt )
|
||||||
char *resp;
|
char *resp;
|
||||||
int n, l;
|
int n, l;
|
||||||
|
|
||||||
resp = cram( prompt, srvc->user, srvc->pass );
|
cram( prompt, srvc->user, srvc->pass, &resp, &l );
|
||||||
|
|
||||||
if (DFlags & VERBOSE)
|
if (DFlags & VERBOSE)
|
||||||
printf( ">+> %s\n", resp );
|
printf( ">+> %s\n", resp );
|
||||||
l = strlen( resp );
|
|
||||||
n = socket_write( &ctx->buf.sock, resp, l );
|
n = socket_write( &ctx->buf.sock, resp, l );
|
||||||
free( resp );
|
free( resp );
|
||||||
if (n != l)
|
if (n != l)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user