diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/imap.c | 64 | ||||
| -rw-r--r-- | lib/imap.h | 1 | 
2 files changed, 64 insertions, 1 deletions
| diff --git a/lib/imap.c b/lib/imap.c index a8d95190b..302cc73ca 100644 --- a/lib/imap.c +++ b/lib/imap.c @@ -26,6 +26,7 @@   * RFC4616 PLAIN authentication   * RFC4959 IMAP Extension for SASL Initial Client Response   * RFC5092 IMAP URL Scheme + * RFC6749 OAuth 2.0 Authorization Framework   *   ***************************************************************************/ @@ -344,6 +345,7 @@ static bool imap_endofresp(struct connectdata *conn, char *line, size_t len,        case IMAP_AUTHENTICATE_DIGESTMD5_RESP:        case IMAP_AUTHENTICATE_NTLM:        case IMAP_AUTHENTICATE_NTLM_TYPE2MSG: +      case IMAP_AUTHENTICATE_XOAUTH2:        case IMAP_AUTHENTICATE_FINAL:        case IMAP_APPEND:          *resp = '+'; @@ -386,6 +388,7 @@ static void state(struct connectdata *conn, imapstate newstate)      "AUTHENTICATE_DIGESTMD5_RESP",      "AUTHENTICATE_NTLM",      "AUTHENTICATE_NTLM_TYPE2MSG", +    "AUTHENTICATE_XOAUTH2",      "AUTHENTICATE_FINAL",      "LOGIN",      "LIST", @@ -575,7 +578,20 @@ static CURLcode imap_perform_authenticate(struct connectdata *conn)    }    else  #endif -  if((imapc->authmechs & SASL_MECH_LOGIN) && + +  if((imapc->authmechs & SASL_MECH_XOAUTH2) && +     (imapc->prefmech & SASL_MECH_XOAUTH2)) { +    mech = "XOAUTH2"; +    state1 = IMAP_AUTHENTICATE_XOAUTH2; +    state2 = IMAP_AUTHENTICATE_FINAL; +    imapc->authused = SASL_MECH_XOAUTH2; + +    if(imapc->ir_supported || data->set.sasl_ir) +      result = Curl_sasl_create_xoauth2_message(conn->data, conn->user, +                                                conn->xoauth2_bearer, +                                                &initresp, &len); +  } +  else if((imapc->authmechs & SASL_MECH_LOGIN) &&       (imapc->prefmech & SASL_MECH_LOGIN)) {      mech = "LOGIN";      state1 = IMAP_AUTHENTICATE_LOGIN; @@ -879,6 +895,8 @@ static CURLcode imap_state_capability_resp(struct connectdata *conn,            imapc->authmechs |= SASL_MECH_EXTERNAL;          else if(wordlen == 4 && !memcmp(line, "NTLM", 4))            imapc->authmechs |= SASL_MECH_NTLM; +        else if(wordlen == 7 && !memcmp(line, "XOAUTH2", 7)) +          imapc->authmechs |= SASL_MECH_XOAUTH2;        }        line += wordlen; @@ -1244,6 +1262,44 @@ static CURLcode imap_state_auth_ntlm_type2msg_resp(struct connectdata *conn,  }  #endif +/* For AUTH XOAUTH2 (without initial response) responses */ +static CURLcode imap_state_auth_xoauth2_resp(struct connectdata *conn, +                                             int imapcode, +                                             imapstate 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(imapcode != '+') { +    failf(data, "Access denied: %d", imapcode); +    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.imapc.pp, "%s", xoauth); + +        if(!result) +          state(conn, IMAP_AUTHENTICATE_FINAL); +      } + +      Curl_safefree(xoauth); +    } +  } + +  return result; +} +  /* For final responses to the AUTHENTICATE sequence */  static CURLcode imap_state_auth_final_resp(struct connectdata *conn,                                             int imapcode, @@ -1593,6 +1649,10 @@ static CURLcode imap_statemach_act(struct connectdata *conn)        break;  #endif +    case IMAP_AUTHENTICATE_XOAUTH2: +      result = imap_state_auth_xoauth2_resp(conn, imapcode, imapc->state); +      break; +      case IMAP_AUTHENTICATE_FINAL:        result = imap_state_auth_final_resp(conn, imapcode, imapc->state);        break; @@ -2221,6 +2281,8 @@ static CURLcode imap_parse_url_options(struct connectdata *conn)          imapc->prefmech = SASL_MECH_GSSAPI;        else if(strequal(value, "NTLM"))          imapc->prefmech = SASL_MECH_NTLM; +      else if(strequal(value, "XOAUTH2")) +        imapc->prefmech = SASL_MECH_XOAUTH2;        else          imapc->prefmech = SASL_AUTH_NONE;      } diff --git a/lib/imap.h b/lib/imap.h index bc0a83d48..1d4faabd7 100644 --- a/lib/imap.h +++ b/lib/imap.h @@ -43,6 +43,7 @@ typedef enum {    IMAP_AUTHENTICATE_DIGESTMD5_RESP,    IMAP_AUTHENTICATE_NTLM,    IMAP_AUTHENTICATE_NTLM_TYPE2MSG, +  IMAP_AUTHENTICATE_XOAUTH2,    IMAP_AUTHENTICATE_FINAL,    IMAP_LOGIN,    IMAP_LIST, | 
