aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Holme <steve_holme@hotmail.com>2013-10-27 12:34:56 +0000
committerSteve Holme <steve_holme@hotmail.com>2013-10-27 12:42:30 +0000
commit1e39b95682781fd9117eef094f6fd8c58b443610 (patch)
tree966e5f3f8645bcdcc56772e1dbac5cc8db54a0e0
parent8230af0b9420617f275bd4dea921610e960bb997 (diff)
email: Added support for canceling CRAM-MD5 authentication
-rw-r--r--lib/curl_sasl.c58
-rw-r--r--lib/curl_sasl.h6
-rw-r--r--lib/imap.c26
-rw-r--r--lib/pop3.c26
-rw-r--r--lib/smtp.c26
5 files changed, 98 insertions, 44 deletions
diff --git a/lib/curl_sasl.c b/lib/curl_sasl.c
index 044060ff8..15a197cab 100644
--- a/lib/curl_sasl.c
+++ b/lib/curl_sasl.c
@@ -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;
}
diff --git a/lib/curl_sasl.h b/lib/curl_sasl.h
index 2b6a5a26a..63888ffac 100644
--- a/lib/curl_sasl.h
+++ b/lib/curl_sasl.h
@@ -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,
diff --git a/lib/imap.c b/lib/imap.c
index b17b7e533..a4e61622f 100644
--- a/lib/imap.c
+++ b/lib/imap.c
@@ -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", "*");
- /* Send the response */
- if(!result) {
- if(rplyb64) {
+ 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 */
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;
}
diff --git a/lib/pop3.c b/lib/pop3.c
index f4dc5d1b3..d4075f4b3 100644
--- a/lib/pop3.c
+++ b/lib/pop3.c
@@ -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);
- /* 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.pop3c.pp, "%s", "*");
- /* Send the response */
- if(!result) {
- if(rplyb64) {
+ 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 */
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;
}
diff --git a/lib/smtp.c b/lib/smtp.c
index 7e07ba6d9..68537e74d 100644
--- a/lib/smtp.c
+++ b/lib/smtp.c
@@ -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);
- /* 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.smtpc.pp, "%s", "*");
- /* Send the response */
- if(!result) {
- if(rplyb64) {
+ 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 */
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;
}