Пример #1
0
Файл: pop3.c Проект: dinny/curl
/* for STARTTLS responses */
static CURLcode pop3_state_starttls_resp(struct connectdata *conn,
                                         int pop3code,
                                         pop3state instate)
{
  CURLcode result = CURLE_OK;
  struct SessionHandle *data = conn->data;
  (void)instate; /* no use for this yet */

  if(pop3code != 'O') {
    if(data->set.use_ssl != CURLUSESSL_TRY) {
      failf(data, "STARTTLS denied. %c", pop3code);
      result = CURLE_USE_SSL_FAILED;
      state(conn, POP3_STOP);
    }
    else
      result = pop3_state_user(conn);
  }
  else {
    /* Curl_ssl_connect is BLOCKING */
    result = Curl_ssl_connect(conn, FIRSTSOCKET);
    if(CURLE_OK == result) {
      pop3_to_pop3s(conn);
      result = pop3_state_user(conn);
    }
    else {
      state(conn, POP3_STOP);
    }
  }
  return result;
}
Пример #2
0
/* For CAPA responses */
static CURLcode pop3_state_capa_resp(struct connectdata *conn, int pop3code,
                                     pop3state instate)
{
  CURLcode result = CURLE_OK;

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

  if(pop3code == '+' && conn->proto.pop3c.authtypes) {
    /* Check supported authentication types by decreasing order of security */
    if(conn->proto.pop3c.authtypes & POP3_TYPE_SASL)
      result = pop3_authenticate(conn);
#ifndef CURL_DISABLE_CRYPTO_AUTH
    else if(conn->proto.pop3c.authtypes & POP3_TYPE_APOP)
      result = pop3_state_apop(conn);
#endif
    else if(conn->proto.pop3c.authtypes & POP3_TYPE_CLEARTEXT)
      result = pop3_state_user(conn);
    else {
      infof(conn->data, "No known authentication types supported!\n");
      result = CURLE_LOGIN_DENIED; /* Other types not supported */
    }
  }
  else
    result = pop3_state_user(conn);

  return result;
}
Пример #3
0
/* For CAPA responses */
static CURLcode pop3_state_capa_resp(struct connectdata *conn, int pop3code,
                                     pop3state instate)
{
  CURLcode result = CURLE_OK;
  struct SessionHandle *data = conn->data;
  struct pop3_conn *pop3c = &conn->proto.pop3c;

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

  if(pop3code != '+')
    result = pop3_state_user(conn);
  else if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) {
    /* We don't have a SSL/TLS connection yet, but SSL is requested */
    if(pop3c->tls_supported)
      /* Switch to TLS connection now */
      result = pop3_state_starttls(conn);
    else if(data->set.use_ssl == CURLUSESSL_TRY)
      /* Fallback and carry on with authentication */
      result = pop3_authenticate(conn);
    else {
      failf(data, "STLS not supported.");
      result = CURLE_USE_SSL_FAILED;
    }
  }
  else
    result = pop3_authenticate(conn);

  return result;
}
Пример #4
0
/* For CAPA responses */
static CURLcode pop3_state_capa_resp(struct connectdata *conn, int pop3code,
                                     pop3state instate)
{
  CURLcode result = CURLE_OK;

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

  if(pop3code == '+')
    result = pop3_authenticate(conn);
  else
    result = pop3_state_user(conn);

  return result;
}
Пример #5
0
/* for STARTTLS responses */
static CURLcode pop3_state_starttls_resp(struct connectdata *conn,
                                         int pop3code,
                                         pop3state instate)
{
  CURLcode result = CURLE_OK;
  struct SessionHandle *data = conn->data;
  (void)instate; /* no use for this yet */

  if(pop3code != 'O') {
    failf(data, "STARTTLS denied. %c", pop3code);
    result = CURLE_LOGIN_DENIED;
  }
  else {
    /* Curl_ssl_connect is BLOCKING */
    result = Curl_ssl_connect(conn, FIRSTSOCKET);
    if(CURLE_OK == result) {
      conn->protocol |= PROT_POP3S;
      result = pop3_state_user(conn);
    }
  }
  state(conn, POP3_STOP);
  return result;
}
Пример #6
0
Файл: pop3.c Проект: dinny/curl
static CURLcode pop3_statemach_act(struct connectdata *conn)
{
  CURLcode result;
  curl_socket_t sock = conn->sock[FIRSTSOCKET];
  struct SessionHandle *data=conn->data;
  int pop3code;
  struct pop3_conn *pop3c = &conn->proto.pop3c;
  struct pingpong *pp = &pop3c->pp;
  size_t nread = 0;

  if(pp->sendleft)
    return Curl_pp_flushsend(pp);

  /* we read a piece of response */
  result = Curl_pp_readresp(sock, pp, &pop3code, &nread);
  if(result)
    return result;

  if(pop3code) {
    /* we have now received a full POP3 server response */
    switch(pop3c->state) {
    case POP3_SERVERGREET:
      if(pop3code != 'O') {
        failf(data, "Got unexpected pop3-server response");
        return CURLE_FTP_WEIRD_SERVER_REPLY;
      }

      if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) {
        /* We don't have a SSL/TLS connection yet, but SSL is requested. Switch
           to TLS connection now */
        result = Curl_pp_sendf(&pop3c->pp, "STLS");
        state(conn, POP3_STARTTLS);
      }
      else
        result = pop3_state_user(conn);
      if(result)
        return result;
      break;

    case POP3_USER:
      result = pop3_state_user_resp(conn, pop3code, pop3c->state);
      break;

    case POP3_PASS:
      result = pop3_state_pass_resp(conn, pop3code, pop3c->state);
      break;

    case POP3_STARTTLS:
      result = pop3_state_starttls_resp(conn, pop3code, pop3c->state);
      break;

    case POP3_RETR:
      result = pop3_state_retr_resp(conn, pop3code, pop3c->state);
      break;

    case POP3_LIST:
      result = pop3_state_list_resp(conn, pop3code, pop3c->state);
      break;

    case POP3_LIST_SINGLE:
      result = pop3_state_list_single_resp(conn, pop3code, pop3c->state);
      break;

    case POP3_QUIT:
      /* fallthrough, just stop! */
    default:
      /* internal error */
      state(conn, POP3_STOP);
      break;
    }
  }
  return result;
}
Пример #7
0
static CURLcode pop3_authenticate(struct connectdata *conn)
{
  CURLcode result = CURLE_OK;
  struct pop3_conn *pop3c = &conn->proto.pop3c;
  const char *mech = NULL;
  pop3state authstate = POP3_STOP;

  /* Check we have a username and password to authenticate with and end the
     connect phase if we don't */
  if(!conn->bits.user_passwd) {
    state(conn, POP3_STOP);

    return result;
  }

  /* Calculate the supported authentication mechanism by decreasing order of
     security */
  if(pop3c->authtypes & POP3_TYPE_SASL) {
#ifndef CURL_DISABLE_CRYPTO_AUTH
    if(pop3c->authmechs & SASL_MECH_DIGEST_MD5) {
      mech = "DIGEST-MD5";
      authstate = POP3_AUTH_DIGESTMD5;
      pop3c->authused = SASL_MECH_DIGEST_MD5;
    }
    else if(pop3c->authmechs & SASL_MECH_CRAM_MD5) {
      mech = "CRAM-MD5";
      authstate = POP3_AUTH_CRAMMD5;
      pop3c->authused = SASL_MECH_CRAM_MD5;
    }
    else
#endif
#ifdef USE_NTLM
    if(pop3c->authmechs & SASL_MECH_NTLM) {
      mech = "NTLM";
      authstate = POP3_AUTH_NTLM;
      pop3c->authused = SASL_MECH_NTLM;
    }
    else
#endif
    if(pop3c->authmechs & SASL_MECH_LOGIN) {
      mech = "LOGIN";
      authstate = POP3_AUTH_LOGIN;
      pop3c->authused = SASL_MECH_LOGIN;
    }
    else if(pop3c->authmechs & SASL_MECH_PLAIN) {
      mech = "PLAIN";
      authstate = POP3_AUTH_PLAIN;
      pop3c->authused = SASL_MECH_PLAIN;
    }
  }

  if(mech) {
    /* Perform SASL based authentication */
    result = Curl_pp_sendf(&pop3c->pp, "AUTH %s", mech);

    if(!result)
      state(conn, authstate);
  }
#ifndef CURL_DISABLE_CRYPTO_AUTH
  else if(pop3c->authtypes & POP3_TYPE_APOP)
    /* Perform APOP authentication */
    result = pop3_state_apop(conn);
#endif
  else if(pop3c->authtypes & POP3_TYPE_CLEARTEXT)
    /* Perform clear text authentication */
    result = pop3_state_user(conn);
  else {
    /* Other mechanisms not supported */
    infof(conn->data, "No known authentication mechanisms supported!\n");
    result = CURLE_LOGIN_DENIED;
  }

  return result;
}