From f6e33cf66990c0c195c19d05a883361d5068da66 Mon Sep 17 00:00:00 2001 From: Steve Holme Date: Mon, 7 Jan 2013 02:47:12 +0000 Subject: [PATCH] imap: Added support for sasl ntlm authentication --- lib/imap.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/imap.h | 2 ++ 2 files changed, 103 insertions(+) diff --git a/lib/imap.c b/lib/imap.c index e24cc241c..c69295d71 100644 --- a/lib/imap.c +++ b/lib/imap.c @@ -435,6 +435,8 @@ static void state(struct connectdata *conn, "AUTHENTICATE_PLAIN", "AUTHENTICATE_LOGIN", "AUTHENTICATE_LOGIN_PASSWD", + "AUTHENTICATE_NTLM", + "AUTHENTICATE_NTLM_TYPE2MSG", "AUTHENTICATE", "LOGIN", "SELECT", @@ -513,6 +515,14 @@ static CURLcode imap_authenticate(struct connectdata *conn) /* Check supported authentication mechanisms by decreasing order of security */ +#ifdef USE_NTLM + if(imapc->authmechs & SASL_MECH_NTLM) { + mech = "NTLM"; + authstate = IMAP_AUTHENTICATE_NTLM; + imapc->authused = SASL_MECH_NTLM; + } + else +#endif if(imapc->authmechs & SASL_MECH_LOGIN) { mech = "LOGIN"; authstate = IMAP_AUTHENTICATE_LOGIN; @@ -764,6 +774,86 @@ static CURLcode imap_state_auth_login_password_resp(struct connectdata *conn, return result; } +#ifdef USE_NTLM +/* For AUTHENTICATE NTLM responses */ +static CURLcode imap_state_auth_ntlm_resp(struct connectdata *conn, + int imapcode, + imapstate instate) +{ + CURLcode result = CURLE_OK; + struct SessionHandle *data = conn->data; + size_t len = 0; + char *type1msg = NULL; + + (void)instate; /* no use for this yet */ + + if(imapcode != '+') { + failf(data, "Access denied: %d", imapcode); + result = CURLE_LOGIN_DENIED; + } + else { + /* Create the type-1 message */ + result = Curl_sasl_create_ntlm_type1_message(conn->user, conn->passwd, + &conn->ntlm, + &type1msg, &len); + + /* Send the message */ + if(!result) { + if(type1msg) { + result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", type1msg); + + if(!result) + state(conn, IMAP_AUTHENTICATE_NTLM_TYPE2MSG); + } + + Curl_safefree(type1msg); + } + } + + return result; +} + +/* For NTLM type-2 responses (sent in reponse to our type-1 message) */ +static CURLcode imap_state_auth_ntlm_type2msg_resp(struct connectdata *conn, + int imapcode, + imapstate instate) +{ + CURLcode result = CURLE_OK; + struct SessionHandle *data = conn->data; + size_t len = 0; + char *type3msg = NULL; + + (void)instate; /* no use for this yet */ + + if(imapcode != '+') { + failf(data, "Access denied: %d", imapcode); + result = CURLE_LOGIN_DENIED; + } + else { + /* Create the type-3 message */ + result = Curl_sasl_create_ntlm_type3_message(data, + data->state.buffer + 2, + conn->user, conn->passwd, + &conn->ntlm, + &type3msg, &len); + + /* Send the message */ + if(!result) { + if(type3msg) { + result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", type3msg); + + if(!result) + state(conn, IMAP_AUTHENTICATE); + } + + Curl_safefree(type3msg); + } + } + + return result; +} +#endif + /* For final responses to the AUTHENTICATE sequence */ static CURLcode imap_state_auth_final_resp(struct connectdata *conn, int imapcode, @@ -1002,6 +1092,17 @@ static CURLcode imap_statemach_act(struct connectdata *conn) imapc->state); break; +#ifdef USE_NTLM + case IMAP_AUTHENTICATE_NTLM: + result = imap_state_auth_ntlm_resp(conn, imapcode, imapc->state); + break; + + case IMAP_AUTHENTICATE_NTLM_TYPE2MSG: + result = imap_state_auth_ntlm_type2msg_resp(conn, imapcode, + imapc->state); + break; +#endif + 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 615bda374..19e595f2f 100644 --- a/lib/imap.h +++ b/lib/imap.h @@ -38,6 +38,8 @@ typedef enum { IMAP_AUTHENTICATE_PLAIN, IMAP_AUTHENTICATE_LOGIN, IMAP_AUTHENTICATE_LOGIN_PASSWD, + IMAP_AUTHENTICATE_NTLM, + IMAP_AUTHENTICATE_NTLM_TYPE2MSG, IMAP_AUTHENTICATE, IMAP_LOGIN, IMAP_SELECT,