diff options
author | Steve Holme <steve_holme@hotmail.com> | 2013-01-06 23:14:18 +0000 |
---|---|---|
committer | Steve Holme <steve_holme@hotmail.com> | 2013-01-06 23:14:18 +0000 |
commit | 4e6265ea5ab440bdf62cebaa7e97358b20932441 (patch) | |
tree | 068a1f736610d810c7b9994727a38da3919b3f76 | |
parent | 494b8664dabf5abd0d1f0eb3995e92736f351dee (diff) |
imap: Added support for sasl login authentication
-rw-r--r-- | lib/imap.c | 91 | ||||
-rw-r--r-- | lib/imap.h | 2 |
2 files changed, 92 insertions, 1 deletions
diff --git a/lib/imap.c b/lib/imap.c index 4d587c782..e24cc241c 100644 --- a/lib/imap.c +++ b/lib/imap.c @@ -433,6 +433,8 @@ static void state(struct connectdata *conn, "UPGRADETLS", "CAPABILITY", "AUTHENTICATE_PLAIN", + "AUTHENTICATE_LOGIN", + "AUTHENTICATE_LOGIN_PASSWD", "AUTHENTICATE", "LOGIN", "SELECT", @@ -511,7 +513,12 @@ static CURLcode imap_authenticate(struct connectdata *conn) /* Check supported authentication mechanisms by decreasing order of security */ - if(imapc->authmechs & SASL_MECH_PLAIN) { + if(imapc->authmechs & SASL_MECH_LOGIN) { + mech = "LOGIN"; + authstate = IMAP_AUTHENTICATE_LOGIN; + imapc->authused = SASL_MECH_LOGIN; + } + else if(imapc->authmechs & SASL_MECH_PLAIN) { mech = "PLAIN"; authstate = IMAP_AUTHENTICATE_PLAIN; imapc->authused = SASL_MECH_PLAIN; @@ -683,6 +690,79 @@ static CURLcode imap_state_auth_plain_resp(struct connectdata *conn, return result; } +/* For AUTHENTICATE LOGIN responses */ +static CURLcode imap_state_auth_login_resp(struct connectdata *conn, + int imapcode, + imapstate instate) +{ + CURLcode result = CURLE_OK; + struct SessionHandle *data = conn->data; + size_t len = 0; + char *authuser = NULL; + + (void)instate; /* no use for this yet */ + + if(imapcode != '+') { + failf(data, "Access denied: %d", imapcode); + result = CURLE_LOGIN_DENIED; + } + else { + /* Create the user message */ + result = Curl_sasl_create_login_message(data, conn->user, + &authuser, &len); + + /* Send the user */ + if(!result) { + if(authuser) { + result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", authuser); + + if(!result) + state(conn, IMAP_AUTHENTICATE_LOGIN_PASSWD); + } + + Curl_safefree(authuser); + } + } + + return result; +} + +/* For AUTHENTICATE LOGIN user entry responses */ +static CURLcode imap_state_auth_login_password_resp(struct connectdata *conn, + int imapcode, + imapstate instate) +{ + CURLcode result = CURLE_OK; + struct SessionHandle *data = conn->data; + size_t len = 0; + char *authpasswd = NULL; + + (void)instate; /* no use for this yet */ + + if(imapcode != '+') { + failf(data, "Access denied: %d", imapcode); + result = CURLE_LOGIN_DENIED; + } + else { + /* Create the password message */ + result = Curl_sasl_create_login_message(data, conn->passwd, + &authpasswd, &len); + + /* Send the password */ + if(!result) { + if(authpasswd) { + result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", authpasswd); + + if(!result) + state(conn, IMAP_AUTHENTICATE); + } + + Curl_safefree(authpasswd); + } + } + + return result; +} /* For final responses to the AUTHENTICATE sequence */ static CURLcode imap_state_auth_final_resp(struct connectdata *conn, @@ -913,6 +993,15 @@ static CURLcode imap_statemach_act(struct connectdata *conn) result = imap_state_auth_plain_resp(conn, imapcode, imapc->state); break; + case IMAP_AUTHENTICATE_LOGIN: + result = imap_state_auth_login_resp(conn, imapcode, imapc->state); + break; + + case IMAP_AUTHENTICATE_LOGIN_PASSWD: + result = imap_state_auth_login_password_resp(conn, imapcode, + imapc->state); + break; + case IMAP_AUTHENTICATE: result = imap_state_auth_final_resp(conn, imapcode, imapc->state); break; diff --git a/lib/imap.h b/lib/imap.h index 896f35ad4..615bda374 100644 --- a/lib/imap.h +++ b/lib/imap.h @@ -36,6 +36,8 @@ typedef enum { (multi mode only) */ IMAP_CAPABILITY, IMAP_AUTHENTICATE_PLAIN, + IMAP_AUTHENTICATE_LOGIN, + IMAP_AUTHENTICATE_LOGIN_PASSWD, IMAP_AUTHENTICATE, IMAP_LOGIN, IMAP_SELECT, |