diff options
| author | Steve Holme <steve_holme@hotmail.com> | 2012-06-02 11:55:58 +0100 | 
|---|---|---|
| committer | Steve Holme <steve_holme@hotmail.com> | 2012-06-02 11:55:58 +0100 | 
| commit | 69f7156ad96877b18b1867f9adc29454774d7cf7 (patch) | |
| tree | d816e7977b755f6c70192cb67fb456d655f115c5 | |
| parent | 6f964e4f0625177d9fdef61cc72de9d46328ace5 (diff) | |
pop3: Added support for sasl ntlm authentication
| -rw-r--r-- | lib/pop3.c | 97 | ||||
| -rw-r--r-- | lib/pop3.h | 2 | 
2 files changed, 98 insertions, 1 deletions
diff --git a/lib/pop3.c b/lib/pop3.c index 9660bb57a..b212e9536 100644 --- a/lib/pop3.c +++ b/lib/pop3.c @@ -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; @@ -1069,7 +1161,7 @@ static CURLcode pop3_quit(struct connectdata *conn)   */  static CURLcode pop3_disconnect(struct connectdata *conn, bool dead_connection)  { -  struct pop3_conn *pop3c= &conn->proto.pop3c; +  struct pop3_conn *pop3c = &conn->proto.pop3c;    /* We cannot send quit unconditionally. If this connection is stale or       bad in any way, sending quit and waiting around here will make the @@ -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;  } diff --git a/lib/pop3.h b/lib/pop3.h index 75a208f4c..9306f9134 100644 --- a/lib/pop3.h +++ b/lib/pop3.h @@ -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,  | 
