Commit f6e33cf6 authored by Steve Holme's avatar Steve Holme
Browse files

imap: Added support for sasl ntlm authentication

parent 4e6265ea
Loading
Loading
Loading
Loading
+101 −0
Original line number Diff line number Diff line
@@ -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;
+2 −0
Original line number Diff line number Diff line
@@ -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,