diff options
author | Kyle L. Huff <kyle.huff@curetheitch.com> | 2013-08-25 13:17:58 -0400 |
---|---|---|
committer | Steve Holme <steve_holme@hotmail.com> | 2013-08-26 10:16:44 +0100 |
commit | 90ab65c632ec0405893466637c7971e327f1067a (patch) | |
tree | 860e561febb6b5e1c65efb175d0f1cd5a47308fc | |
parent | 34122800b898596f3657f89621dd6762f227653f (diff) |
smtp: added basic SASL XOAUTH2 support
Added the ability to use an XOAUTH2 bearer token [RFC6750] with SMTP for
authentication using RFC6749 "OAuth 2.0 Authorization Framework".
The bearer token is expected to be valid for the user specified in
conn->user. If CURLOPT_XOAUTH2_BEARER is defined and the connection has
an advertised auth mechanism of "XOAUTH2", the user and access token are
formatted as a base64 encoded string and sent to the server as
"AUTH XOAUTH2 <bearer token>".
-rw-r--r-- | lib/smtp.c | 62 | ||||
-rw-r--r-- | lib/smtp.h | 1 |
2 files changed, 62 insertions, 1 deletions
diff --git a/lib/smtp.c b/lib/smtp.c index a56f54921..f2c79794c 100644 --- a/lib/smtp.c +++ b/lib/smtp.c @@ -26,6 +26,7 @@ * RFC4616 PLAIN authentication * RFC4954 SMTP Authentication * RFC5321 SMTP protocol + * RFC6749 OAuth 2.0 Authorization Framework * Draft SMTP URL Interface * ***************************************************************************/ @@ -290,6 +291,8 @@ static bool smtp_endofresp(struct connectdata *conn, char *line, size_t len, smtpc->authmechs |= SASL_MECH_EXTERNAL; else if(wordlen == 4 && !memcmp(line, "NTLM", 4)) smtpc->authmechs |= SASL_MECH_NTLM; + else if(wordlen == 7 && !memcmp(line, "XOAUTH2", 7)) + smtpc->authmechs |= SASL_MECH_XOAUTH2; line += wordlen; len -= wordlen; @@ -326,6 +329,7 @@ static void state(struct connectdata *conn, smtpstate newstate) "AUTH_DIGESTMD5_RESP", "AUTH_NTLM", "AUTH_NTLM_TYPE2MSG", + "AUTH_XOAUTH2", "AUTH_FINAL", "MAIL", "RCPT", @@ -496,7 +500,20 @@ static CURLcode smtp_perform_authenticate(struct connectdata *conn) } else #endif - if((smtpc->authmechs & SASL_MECH_LOGIN) && + + if((smtpc->authmechs & SASL_MECH_XOAUTH2) && + (smtpc->prefmech & SASL_MECH_XOAUTH2)) { + mech = "XOAUTH2"; + state1 = SMTP_AUTH_XOAUTH2; + state2 = SMTP_AUTH_FINAL; + smtpc->authused = SASL_MECH_XOAUTH2; + + if(data->set.sasl_ir) + result = Curl_sasl_create_xoauth2_message(conn->data, conn->user, + conn->xoauth2_bearer, + &initresp, &len); + } + else if((smtpc->authmechs & SASL_MECH_LOGIN) && (smtpc->prefmech & SASL_MECH_LOGIN)) { mech = "LOGIN"; state1 = SMTP_AUTH_LOGIN; @@ -1088,6 +1105,43 @@ static CURLcode smtp_state_auth_ntlm_type2msg_resp(struct connectdata *conn, } #endif +/* For AUTH XOAUTH2 (without initial response) responses */ +static CURLcode smtp_state_auth_xoauth2_resp(struct connectdata *conn, + int smtpcode, smtpstate instate) +{ + CURLcode result = CURLE_OK; + struct SessionHandle *data = conn->data; + size_t len = 0; + char *xoauth = NULL; + + (void)instate; /* no use for this yet */ + + if(smtpcode != 334) { + failf(data, "Access denied: %d", smtpcode); + result = CURLE_LOGIN_DENIED; + } + else { + /* Create the authorisation message */ + result = Curl_sasl_create_xoauth2_message(conn->data, conn->user, + conn->xoauth2_bearer, + &xoauth, &len); + + /* Send the message */ + if(!result) { + if(xoauth) { + result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", xoauth); + + if(!result) + state(conn, SMTP_AUTH_FINAL); + } + + Curl_safefree(xoauth); + } + } + + return result; +} + /* For the final responses to the AUTH sequence */ static CURLcode smtp_state_auth_final_resp(struct connectdata *conn, int smtpcode, @@ -1296,6 +1350,10 @@ static CURLcode smtp_statemach_act(struct connectdata *conn) break; #endif + case SMTP_AUTH_XOAUTH2: + result = smtp_state_auth_xoauth2_resp(conn, smtpcode, smtpc->state); + break; + case SMTP_AUTH_FINAL: result = smtp_state_auth_final_resp(conn, smtpcode, smtpc->state); break; @@ -1738,6 +1796,8 @@ static CURLcode smtp_parse_url_options(struct connectdata *conn) smtpc->prefmech = SASL_MECH_GSSAPI; else if(strequal(value, "NTLM")) smtpc->prefmech = SASL_MECH_NTLM; + else if(strequal(value, "XOAUTH2")) + smtpc->prefmech = SASL_MECH_XOAUTH2; else smtpc->prefmech = SASL_AUTH_NONE; } diff --git a/lib/smtp.h b/lib/smtp.h index 4aff0c5f9..14429a5e7 100644 --- a/lib/smtp.h +++ b/lib/smtp.h @@ -44,6 +44,7 @@ typedef enum { SMTP_AUTH_DIGESTMD5_RESP, SMTP_AUTH_NTLM, SMTP_AUTH_NTLM_TYPE2MSG, + SMTP_AUTH_XOAUTH2, SMTP_AUTH_FINAL, SMTP_MAIL, /* MAIL FROM */ SMTP_RCPT, /* RCPT TO */ |