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

pop3: Moved the calculation of SASL login details into a separate function

parent 933e6c9d
Loading
Loading
Loading
Loading
+93 −71
Original line number Diff line number Diff line
@@ -106,6 +106,10 @@ static CURLcode pop3_setup_connection(struct connectdata *conn);
static CURLcode pop3_parse_url_options(struct connectdata *conn);
static CURLcode pop3_parse_url_path(struct connectdata *conn);
static CURLcode pop3_parse_custom_request(struct connectdata *conn);
static CURLcode pop3_calc_sasl_details(struct connectdata *conn,
                                       const char **mech,
                                       char **initresp, size_t *len,
                                       pop3state *state1, pop3state *state2);

/*
 * POP3 protocol handler.
@@ -616,7 +620,6 @@ static CURLcode pop3_perform_auth(struct connectdata *conn,
static CURLcode pop3_perform_authentication(struct connectdata *conn)
{
  CURLcode result = CURLE_OK;
  struct SessionHandle *data = conn->data;
  struct pop3_conn *pop3c = &conn->proto.pop3c;
  const char *mech = NULL;
  char *initresp = NULL;
@@ -632,76 +635,10 @@ static CURLcode pop3_perform_authentication(struct connectdata *conn)
    return result;
  }

  /* Calculate the supported authentication mechanism, by decreasing order of
     security, as well as the initial response where appropriate */
  if(pop3c->authtypes & POP3_TYPE_SASL) {
#ifndef CURL_DISABLE_CRYPTO_AUTH
    if((pop3c->authmechs & SASL_MECH_DIGEST_MD5) &&
       (pop3c->prefmech & SASL_MECH_DIGEST_MD5)) {
      mech = SASL_MECH_STRING_DIGEST_MD5;
      state1 = POP3_AUTH_DIGESTMD5;
      pop3c->authused = SASL_MECH_DIGEST_MD5;
    }
    else if((pop3c->authmechs & SASL_MECH_CRAM_MD5) &&
            (pop3c->prefmech & SASL_MECH_CRAM_MD5)) {
      mech = SASL_MECH_STRING_CRAM_MD5;
      state1 = POP3_AUTH_CRAMMD5;
      pop3c->authused = SASL_MECH_CRAM_MD5;
    }
    else
#endif
#ifdef USE_NTLM
    if((pop3c->authmechs & SASL_MECH_NTLM) &&
       (pop3c->prefmech & SASL_MECH_NTLM)) {
      mech = SASL_MECH_STRING_NTLM;
      state1 = POP3_AUTH_NTLM;
      state2 = POP3_AUTH_NTLM_TYPE2MSG;
      pop3c->authused = SASL_MECH_NTLM;

      if(data->set.sasl_ir)
        result = Curl_sasl_create_ntlm_type1_message(conn->user, conn->passwd,
                                                     &conn->ntlm,
                                                     &initresp, &len);
    }
    else
#endif
    if(((pop3c->authmechs & SASL_MECH_XOAUTH2) &&
        (pop3c->prefmech & SASL_MECH_XOAUTH2) &&
        (pop3c->prefmech != SASL_AUTH_ANY)) || conn->xoauth2_bearer) {
      mech = SASL_MECH_STRING_XOAUTH2;
      state1 = POP3_AUTH_XOAUTH2;
      state2 = POP3_AUTH_FINAL;
      pop3c->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((pop3c->authmechs & SASL_MECH_LOGIN) &&
       (pop3c->prefmech & SASL_MECH_LOGIN)) {
      mech = SASL_MECH_STRING_LOGIN;
      state1 = POP3_AUTH_LOGIN;
      state2 = POP3_AUTH_LOGIN_PASSWD;
      pop3c->authused = SASL_MECH_LOGIN;

      if(data->set.sasl_ir)
        result = Curl_sasl_create_login_message(conn->data, conn->user,
                                                &initresp, &len);
    }
    else if((pop3c->authmechs & SASL_MECH_PLAIN) &&
            (pop3c->prefmech & SASL_MECH_PLAIN)) {
      mech = SASL_MECH_STRING_PLAIN;
      state1 = POP3_AUTH_PLAIN;
      state2 = POP3_AUTH_FINAL;
      pop3c->authused = SASL_MECH_PLAIN;

      if(data->set.sasl_ir)
        result = Curl_sasl_create_plain_message(conn->data, conn->user,
                                                conn->passwd, &initresp,
                                                &len);
    }
  }
  /* Calculate the SASL login details */
  if(pop3c->authtypes & POP3_TYPE_SASL)
    result = pop3_calc_sasl_details(conn, &mech, &initresp, &len, &state1,
                                    &state2);

  if(!result) {
    if(mech && (pop3c->preftype & POP3_TYPE_SASL)) {
@@ -1938,6 +1875,91 @@ static CURLcode pop3_parse_custom_request(struct connectdata *conn)
  return result;
}

/***********************************************************************
 *
 * pop3_calc_sasl_details()
 *
 * Calculate the required login details for SASL authentication.
 */
static CURLcode pop3_calc_sasl_details(struct connectdata *conn,
                                       const char **mech,
                                       char **initresp, size_t *len,
                                       pop3state *state1, pop3state *state2)
{
  CURLcode result = CURLE_OK;
  struct SessionHandle *data = conn->data;
  struct pop3_conn *pop3c = &conn->proto.pop3c;

  /* Calculate the supported authentication mechanism, by decreasing order of
     security, as well as the initial response where appropriate */
#ifndef CURL_DISABLE_CRYPTO_AUTH
  if((pop3c->authmechs & SASL_MECH_DIGEST_MD5) &&
      (pop3c->prefmech & SASL_MECH_DIGEST_MD5)) {
    *mech = SASL_MECH_STRING_DIGEST_MD5;
    *state1 = POP3_AUTH_DIGESTMD5;
    pop3c->authused = SASL_MECH_DIGEST_MD5;
  }
  else if((pop3c->authmechs & SASL_MECH_CRAM_MD5) &&
          (pop3c->prefmech & SASL_MECH_CRAM_MD5)) {
    *mech = SASL_MECH_STRING_CRAM_MD5;
    *state1 = POP3_AUTH_CRAMMD5;
    pop3c->authused = SASL_MECH_CRAM_MD5;
  }
  else
#endif
#ifdef USE_NTLM
  if((pop3c->authmechs & SASL_MECH_NTLM) &&
      (pop3c->prefmech & SASL_MECH_NTLM)) {
    *mech = SASL_MECH_STRING_NTLM;
    *state1 = POP3_AUTH_NTLM;
    *state2 = POP3_AUTH_NTLM_TYPE2MSG;
    pop3c->authused = SASL_MECH_NTLM;

    if(data->set.sasl_ir)
      result = Curl_sasl_create_ntlm_type1_message(conn->user, conn->passwd,
                                                    &conn->ntlm,
                                                    initresp, len);
  }
  else
#endif
  if(((pop3c->authmechs & SASL_MECH_XOAUTH2) &&
      (pop3c->prefmech & SASL_MECH_XOAUTH2) &&
      (pop3c->prefmech != SASL_AUTH_ANY)) || conn->xoauth2_bearer) {
    *mech = SASL_MECH_STRING_XOAUTH2;
    *state1 = POP3_AUTH_XOAUTH2;
    *state2 = POP3_AUTH_FINAL;
    pop3c->authused = SASL_MECH_XOAUTH2;

    if(data->set.sasl_ir)
      result = Curl_sasl_create_xoauth2_message(data, conn->user,
                                                conn->xoauth2_bearer,
                                                initresp, len);
  }
  else if((pop3c->authmechs & SASL_MECH_LOGIN) &&
          (pop3c->prefmech & SASL_MECH_LOGIN)) {
    *mech = SASL_MECH_STRING_LOGIN;
    *state1 = POP3_AUTH_LOGIN;
    *state2 = POP3_AUTH_LOGIN_PASSWD;
    pop3c->authused = SASL_MECH_LOGIN;

    if(data->set.sasl_ir)
      result = Curl_sasl_create_login_message(data, conn->user, initresp, len);
  }
  else if((pop3c->authmechs & SASL_MECH_PLAIN) &&
          (pop3c->prefmech & SASL_MECH_PLAIN)) {
    *mech = SASL_MECH_STRING_PLAIN;
    *state1 = POP3_AUTH_PLAIN;
    *state2 = POP3_AUTH_FINAL;
    pop3c->authused = SASL_MECH_PLAIN;

    if(data->set.sasl_ir)
      result = Curl_sasl_create_plain_message(data, conn->user, conn->passwd,
                                              initresp, len);
  }

  return result;
}

/***********************************************************************
 *
 * Curl_pop3_write()