Bläddra i källkod

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
Oswald Buddenhagen 14 år sedan
förälder
incheckning
7e1c16ae02
1 ändrade filer med 25 tillägg och 30 borttagningar
  1. 25 30
      src/drv_imap.c

+ 25 - 30
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)