email: Added support for canceling CRAM-MD5 authentication

This commit is contained in:
Steve Holme 2013-10-27 12:34:56 +00:00
parent 8230af0b94
commit 1e39b95682
5 changed files with 98 additions and 44 deletions

View File

@ -168,7 +168,37 @@ CURLcode Curl_sasl_create_login_message(struct SessionHandle *data,
}
#ifndef CURL_DISABLE_CRYPTO_AUTH
/*
/*
* Curl_sasl_decode_cram_md5_message()
*
* This is used to decode an already encoded CRAM-MD5 challenge message.
*
* Parameters:
*
* chlg64 [in] - Pointer to the base64 encoded challenge message.
* outptr [in/out] - The address where a pointer to newly allocated memory
* holding the result will be stored upon completion.
* outlen [out] - The length of the output message.
*
* Returns CURLE_OK on success.
*/
CURLcode Curl_sasl_decode_cram_md5_message(const char *chlg64, char **outptr,
size_t *outlen)
{
CURLcode result = CURLE_OK;
size_t chlg64len = strlen(chlg64);
*outptr = NULL;
*outlen = 0;
/* Decode the challenge if necessary */
if(chlg64len && *chlg64 != '=')
result = Curl_base64_decode(chlg64, (unsigned char **) outptr, outlen);
return result;
}
/*
* Curl_sasl_create_cram_md5_message()
*
* This is used to generate an already encoded CRAM-MD5 response message ready
@ -177,7 +207,7 @@ CURLcode Curl_sasl_create_login_message(struct SessionHandle *data,
* Parameters:
*
* data [in] - The session handle.
* chlg64 [in] - Pointer to the base64 encoded challenge buffer.
* chlg [in] - The challenge.
* userp [in] - The user name.
* passdwp [in] - The user's password.
* outptr [in/out] - The address where a pointer to newly allocated memory
@ -187,42 +217,31 @@ CURLcode Curl_sasl_create_login_message(struct SessionHandle *data,
* Returns CURLE_OK on success.
*/
CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data,
const char *chlg64,
const char *chlg,
const char *userp,
const char *passwdp,
char **outptr, size_t *outlen)
{
CURLcode result = CURLE_OK;
size_t chlg64len = strlen(chlg64);
unsigned char *chlg = (unsigned char *) NULL;
size_t chlglen = 0;
HMAC_context *ctxt;
unsigned char digest[MD5_DIGEST_LEN];
char *response;
/* Decode the challenge if necessary */
if(chlg64len && *chlg64 != '=') {
result = Curl_base64_decode(chlg64, &chlg, &chlglen);
if(result)
return result;
}
if(chlg)
chlglen = strlen(chlg);
/* Compute the digest using the password as the key */
ctxt = Curl_HMAC_init(Curl_HMAC_MD5,
(const unsigned char *) passwdp,
curlx_uztoui(strlen(passwdp)));
if(!ctxt) {
Curl_safefree(chlg);
if(!ctxt)
return CURLE_OUT_OF_MEMORY;
}
/* Update the digest with the given challenge */
if(chlglen > 0)
Curl_HMAC_update(ctxt, chlg, curlx_uztoui(chlglen));
Curl_safefree(chlg);
Curl_HMAC_update(ctxt, (const unsigned char *) chlg,
curlx_uztoui(chlglen));
/* Finalise the digest */
Curl_HMAC_final(ctxt, digest);
@ -240,6 +259,7 @@ CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data,
result = Curl_base64_encode(data, response, 0, outptr, outlen);
Curl_safefree(response);
return result;
}

View File

@ -66,6 +66,10 @@ CURLcode Curl_sasl_create_login_message(struct SessionHandle *data,
size_t *outlen);
#ifndef CURL_DISABLE_CRYPTO_AUTH
/* This is used to decode a base64 encoded CRAM-MD5 challange message */
CURLcode Curl_sasl_decode_cram_md5_message(const char *chlg64, char **outptr,
size_t *outlen);
/* This is used to generate a base64 encoded CRAM-MD5 response message */
CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data,
const char *chlg64,
@ -75,7 +79,7 @@ CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data,
/* This is used to generate a base64 encoded DIGEST-MD5 response message */
CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
const char *chlg64,
const char *chlg,
const char *user,
const char *passwdp,
const char *service,

View File

@ -1106,6 +1106,7 @@ static CURLcode imap_state_auth_cram_resp(struct connectdata *conn,
{
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
char *chlg = NULL;
char *chlg64 = NULL;
char *rplyb64 = NULL;
size_t len = 0;
@ -1120,22 +1121,31 @@ static CURLcode imap_state_auth_cram_resp(struct connectdata *conn,
/* Get the challenge message */
imap_get_message(data->state.buffer, &chlg64);
/* Create the response message */
result = Curl_sasl_create_cram_md5_message(data, chlg64, conn->user,
conn->passwd, &rplyb64, &len);
/* Decode the challenge message */
result = Curl_sasl_decode_cram_md5_message(chlg64, &chlg, &len);
if(result) {
/* Send the cancellation */
result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", "*");
if(!result)
state(conn, IMAP_AUTHENTICATE_CANCEL);
}
else {
/* Create the response message */
result = Curl_sasl_create_cram_md5_message(data, chlg, conn->user,
conn->passwd, &rplyb64, &len);
if(!result && rplyb64) {
/* Send the response */
if(!result) {
if(rplyb64) {
result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", rplyb64);
if(!result)
state(conn, IMAP_AUTHENTICATE_FINAL);
}
Curl_safefree(rplyb64);
}
Curl_safefree(chlg);
Curl_safefree(rplyb64);
return result;
}

View File

@ -964,6 +964,7 @@ static CURLcode pop3_state_auth_cram_resp(struct connectdata *conn,
{
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
char *chlg = NULL;
char *chlg64 = NULL;
char *rplyb64 = NULL;
size_t len = 0;
@ -978,22 +979,31 @@ static CURLcode pop3_state_auth_cram_resp(struct connectdata *conn,
/* Get the challenge message */
pop3_get_message(data->state.buffer, &chlg64);
/* Decode the challenge message */
result = Curl_sasl_decode_cram_md5_message(chlg64, &chlg, &len);
if(result) {
/* Send the cancellation */
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "*");
if(!result)
state(conn, POP3_AUTH_CANCEL);
}
else {
/* Create the response message */
result = Curl_sasl_create_cram_md5_message(data, chlg64, conn->user,
conn->passwd, &rplyb64, &len);
if(!result && rplyb64) {
/* Send the response */
if(!result) {
if(rplyb64) {
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", rplyb64);
if(!result)
state(conn, POP3_AUTH_FINAL);
}
Curl_safefree(rplyb64);
}
Curl_safefree(chlg);
Curl_safefree(rplyb64);
return result;
}

View File

@ -944,6 +944,7 @@ static CURLcode smtp_state_auth_cram_resp(struct connectdata *conn,
{
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
char *chlg = NULL;
char *chlg64 = NULL;
char *rplyb64 = NULL;
size_t len = 0;
@ -958,22 +959,31 @@ static CURLcode smtp_state_auth_cram_resp(struct connectdata *conn,
/* Get the challenge message */
smtp_get_message(data->state.buffer, &chlg64);
/* Decode the challenge message */
result = Curl_sasl_decode_cram_md5_message(chlg64, &chlg, &len);
if(result) {
/* Send the cancellation */
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "*");
if(!result)
state(conn, SMTP_AUTH_CANCEL);
}
else {
/* Create the response message */
result = Curl_sasl_create_cram_md5_message(data, chlg64, conn->user,
conn->passwd, &rplyb64, &len);
if(!result && rplyb64) {
/* Send the response */
if(!result) {
if(rplyb64) {
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", rplyb64);
if(!result)
state(conn, SMTP_AUTH_FINAL);
}
Curl_safefree(rplyb64);
}
Curl_safefree(chlg);
Curl_safefree(rplyb64);
return result;
}