Commit 4ffb8a63 authored by Steve Holme's avatar Steve Holme
Browse files

pop3: Added support for non-blocking SSL upgrade

Added support for asynchronous SSL upgrade when using the
multi-interface.
parent 7a6d8b1b
Loading
Loading
Loading
Loading
+32 −6
Original line number Diff line number Diff line
@@ -103,6 +103,7 @@ static int pop3_getsock(struct connectdata *conn,
                        int numsocks);
static CURLcode pop3_doing(struct connectdata *conn, bool *dophase_done);
static CURLcode pop3_setup_connection(struct connectdata *conn);
static CURLcode pop3_state_upgrade_tls(struct connectdata *conn);

/*
 * POP3 protocol handler.
@@ -227,7 +228,7 @@ static int pop3_endofresp(struct pingpong *pp, int *resp)
    return FALSE;
  }

  /* Are we processing servergreet responses */
  /* Are we processing servergreet responses? */
  if(pop3c->state == POP3_SERVERGREET) {
    /* Look for the APOP timestamp */
    if(len >= 3 && line[len - 3] == '>') {
@@ -345,6 +346,7 @@ static void state(struct connectdata *conn, pop3state newstate)
    "STOP",
    "SERVERGREET",
    "STARTTLS",
    "UPGRADETLS",
    "CAPA",
    "AUTH_PLAIN",
    "AUTH_LOGIN",
@@ -568,13 +570,33 @@ static CURLcode pop3_state_starttls_resp(struct connectdata *conn,
      result = pop3_state_capa(conn);
  }
  else {
    /* Curl_ssl_connect is BLOCKING */
    if(data->state.used_interface == Curl_if_multi) {
      state(conn, POP3_UPGRADETLS);
      result = pop3_state_upgrade_tls(conn);
    }
    else {
      result = Curl_ssl_connect(conn, FIRSTSOCKET);
      if(CURLE_OK == result) {
        pop3_to_pop3s(conn);
        result = pop3_state_capa(conn);
      }
    }
  }

  return result;
}

static CURLcode pop3_state_upgrade_tls(struct connectdata *conn)
{
  struct pop3_conn *pop3c = &conn->proto.pop3c;
  CURLcode result;

  result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &pop3c->ssldone);

  if(pop3c->ssldone) {
    pop3_to_pop3s(conn);
    result = pop3_state_capa(conn);
  }

  return result;
}
@@ -1114,6 +1136,10 @@ static CURLcode pop3_statemach_act(struct connectdata *conn)
  struct pingpong *pp = &pop3c->pp;
  size_t nread = 0;

  /* Busy upgrading the connection; right now all I/O is SSL/TLS, not POP3 */
  if(pop3c->state == POP3_UPGRADETLS)
    return pop3_state_upgrade_tls(conn);

  /* Flush any data that needs to be sent */
  if(pp->sendleft)
    return Curl_pp_flushsend(pp);
+5 −1
Original line number Diff line number Diff line
@@ -7,7 +7,7 @@
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 2009 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
 * Copyright (C) 2009 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
@@ -30,6 +30,8 @@ typedef enum {
  POP3_SERVERGREET,  /* waiting for the initial greeting immediately after
                        a connect */
  POP3_STARTTLS,
  POP3_UPGRADETLS,   /* asynchronously upgrade the connection to SSL/TLS
                       (multi mode only) */
  POP3_CAPA,
  POP3_AUTH_PLAIN,
  POP3_AUTH_LOGIN,
@@ -63,6 +65,8 @@ struct pop3_conn {
  unsigned int authused;  /* SASL auth mechanism used for the connection */
  char *apoptimestamp;    /* APOP timestamp from the server greeting */
  pop3state state;        /* Always use pop3.c:state() to change state! */
  bool ssldone;           /* Is connect() over SSL done? Only relevant in
                             multi mode */
};

extern const struct Curl_handler Curl_handler_pop3;