Commit 69f7156a authored by Steve Holme's avatar Steve Holme
Browse files

pop3: Added support for sasl ntlm authentication

parent 6f964e4f
Loading
Loading
Loading
Loading
+96 −1
Original line number Diff line number Diff line
@@ -284,6 +284,8 @@ static void state(struct connectdata *conn, pop3state newstate)
    "AUTH_PLAIN",
    "AUTH_LOGIN",
    "AUTH_LOGIN_PASSWD",
    "AUTH_NTLM",
    "AUTH_NTLM_TYPE2MSG",
    "AUTH_FINAL",
    "USER",
    "PASS",
@@ -345,6 +347,14 @@ static CURLcode pop3_authenticate(struct connectdata *conn)

  /* Check supported authentication mechanisms by decreasing order of
     security */
#ifdef USE_NTLM
  if(pop3c->authmechs & SASL_AUTH_NTLM) {
    mech = "NTLM";
    authstate = POP3_AUTH_NTLM;
    pop3c->authused = SASL_AUTH_NTLM;
  }
  else
#endif
  if(pop3c->authmechs & SASL_AUTH_LOGIN) {
    mech = "LOGIN";
    authstate = POP3_AUTH_LOGIN;
@@ -567,6 +577,80 @@ static CURLcode pop3_state_auth_login_password_resp(struct connectdata *conn,
  return result;
}

#ifdef USE_NTLM
/* For AUTH NTLM responses */
static CURLcode pop3_state_auth_ntlm_resp(struct connectdata *conn,
                                          int pop3code,
                                          pop3state instate)
{
  CURLcode result = CURLE_OK;
  struct SessionHandle *data = conn->data;
  char *type1msg = NULL;
  size_t len = 0;

  (void)instate; /* no use for this yet */

  if(pop3code != '+') {
    failf(data, "Access denied: %d", pop3code);
    result = CURLE_LOGIN_DENIED;
  }
  else {
    result = Curl_sasl_create_ntlm_type1_message(conn->user, conn->passwd,
                                                 &conn->ntlm, &type1msg, &len);

    if(!result) {
      if(type1msg) {
        result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", type1msg);

        if(!result)
          state(conn, POP3_AUTH_NTLM_TYPE2MSG);
      }

      Curl_safefree(type1msg);
    }
  }

  return result;
}

/* For the NTLM type-2 response (sent in reponse to our type-1 message) */
static CURLcode pop3_state_auth_ntlm_type2msg_resp(struct connectdata *conn,
                                                   int pop3code,
                                                   pop3state instate)
{
  CURLcode result = CURLE_OK;
  struct SessionHandle *data = conn->data;
  char *type3msg = NULL;
  size_t len = 0;

  (void)instate; /* no use for this yet */

  if(pop3code != '+') {
    failf(data, "Access denied: %d", pop3code);
    result = CURLE_LOGIN_DENIED;
  }
  else {
    result = Curl_sasl_decode_ntlm_type2_message(data,
                                                 data->state.buffer + 2,
                                                 conn->user, conn->passwd,
                                                 &conn->ntlm,
                                                 &type3msg, &len);
    if(!result) {
      if(type3msg) {
        result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", type3msg);

        if(!result)
          state(conn, POP3_AUTH_FINAL);
      }

      Curl_safefree(type3msg);
    }
  }

  return result;
}
#endif

/* For final responses to the AUTH sequence */
static CURLcode pop3_state_auth_final_resp(struct connectdata *conn,
                                           int pop3code,
@@ -771,6 +855,14 @@ static CURLcode pop3_statemach_act(struct connectdata *conn)
      result = pop3_state_auth_login_password_resp(conn, pop3code, pop3c->state);
      break;

    case POP3_AUTH_NTLM:
      result = pop3_state_auth_ntlm_resp(conn, pop3code, pop3c->state);
      break;

    case POP3_AUTH_NTLM_TYPE2MSG:
      result = pop3_state_auth_ntlm_type2msg_resp(conn, pop3code, pop3c->state);
      break;

    case POP3_AUTH_FINAL:
      result = pop3_state_auth_final_resp(conn, pop3code, pop3c->state);
      break;
@@ -1083,6 +1175,9 @@ static CURLcode pop3_disconnect(struct connectdata *conn, bool dead_connection)

  Curl_pp_disconnect(&pop3c->pp);

  /* Cleanup the sasl module */
  Curl_sasl_cleanup(conn, pop3c->authused);

  return CURLE_OK;
}

+2 −0
Original line number Diff line number Diff line
@@ -34,6 +34,8 @@ typedef enum {
  POP3_AUTH_PLAIN,
  POP3_AUTH_LOGIN,
  POP3_AUTH_LOGIN_PASSWD,
  POP3_AUTH_NTLM,
  POP3_AUTH_NTLM_TYPE2MSG,
  POP3_AUTH_FINAL,
  POP3_USER,
  POP3_PASS,