diff --git a/lib/smtp.c b/lib/smtp.c index 8d24a628b..3b2179677 100644 --- a/lib/smtp.c +++ b/lib/smtp.c @@ -115,6 +115,7 @@ static int smtp_getsock(struct connectdata *conn, static CURLcode smtp_doing(struct connectdata *conn, bool *dophase_done); static CURLcode smtp_setup_connection(struct connectdata * conn); +static CURLcode smtp_state_upgrade_tls(struct connectdata *conn); /* @@ -290,6 +291,7 @@ static void state(struct connectdata *conn, "EHLO", "HELO", "STARTTLS", + "UPGRADETLS", "AUTHPLAIN", "AUTHLOGIN", "AUTHPASSWD", @@ -481,16 +483,36 @@ static CURLcode smtp_state_starttls_resp(struct connectdata *conn, result = smtp_authenticate(conn); } else { - /* Curl_ssl_connect is BLOCKING */ - result = Curl_ssl_connect(conn, FIRSTSOCKET); - if(CURLE_OK == result) { - smtp_to_smtps(conn); - result = smtp_state_ehlo(conn); + if(data->state.used_interface == Curl_if_multi) { + state(conn, SMTP_UPGRADETLS); + return smtp_state_upgrade_tls(conn); + } + else { + result = Curl_ssl_connect(conn, FIRSTSOCKET); + if(CURLE_OK == result) { + smtp_to_smtps(conn); + result = smtp_state_ehlo(conn); + } } } return result; } +static CURLcode smtp_state_upgrade_tls(struct connectdata *conn) +{ + struct smtp_conn *smtpc = &conn->proto.smtpc; + CURLcode result; + + result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &smtpc->ssldone); + + if(smtpc->ssldone) { + smtp_to_smtps(conn); + result = smtp_state_ehlo(conn); + } + + return result; +} + /* for EHLO responses */ static CURLcode smtp_state_ehlo_resp(struct connectdata *conn, int smtpcode, @@ -910,6 +932,9 @@ static CURLcode smtp_statemach_act(struct connectdata *conn) struct pingpong *pp = &smtpc->pp; size_t nread = 0; + if(smtpc->state == SMTP_UPGRADETLS) + return smtp_state_upgrade_tls(conn); + if(pp->sendleft) /* we have a piece of a command still left to send */ return Curl_pp_flushsend(pp); diff --git a/lib/smtp.h b/lib/smtp.h index e9050f868..0f527142c 100644 --- a/lib/smtp.h +++ b/lib/smtp.h @@ -34,6 +34,7 @@ typedef enum { SMTP_EHLO, SMTP_HELO, SMTP_STARTTLS, + SMTP_UPGRADETLS, /* asynchronously upgrade the connection to SSL/TLS (multi mode only) */ SMTP_AUTHPLAIN, SMTP_AUTHLOGIN, SMTP_AUTHPASSWD,