aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Noordhuis <info@bnoordhuis.nl>2011-02-16 00:56:46 +0100
committerBen Noordhuis <info@bnoordhuis.nl>2011-02-20 21:11:12 +0100
commitdd3760f2eb11745ea73d20bf7affe735f671fda5 (patch)
treedfb8af96dd3d9487585847ee6dd82a518e353756
parent45ca048f44f3c34441af225d9eae7605513db2c1 (diff)
IMAP in multi mode: use Curl_ssl_connect_nonblocking() when upgrading the connection to TLS/SSL.
-rw-r--r--lib/imap.c36
-rw-r--r--lib/imap.h1
2 files changed, 32 insertions, 5 deletions
diff --git a/lib/imap.c b/lib/imap.c
index 4e71fb3ed..16410c7d5 100644
--- a/lib/imap.c
+++ b/lib/imap.c
@@ -108,6 +108,7 @@ static int imap_getsock(struct connectdata *conn,
static CURLcode imap_doing(struct connectdata *conn,
bool *dophase_done);
static CURLcode imap_setup_connection(struct connectdata * conn);
+static CURLcode imap_state_upgrade_tls(struct connectdata *conn);
/*
* IMAP protocol handler.
@@ -342,17 +343,38 @@ static CURLcode imap_state_starttls_resp(struct connectdata *conn,
result = CURLE_LOGIN_DENIED;
}
else {
- /* Curl_ssl_connect is BLOCKING */
- result = Curl_ssl_connect(conn, FIRSTSOCKET);
- if(CURLE_OK == result) {
- conn->protocol |= PROT_IMAPS;
- result = imap_state_login(conn);
+ if(data->state.used_interface == Curl_if_multi) {
+ state(conn, IMAP_UPGRADETLS);
+ return imap_state_upgrade_tls(conn);
+ }
+ else {
+ result = Curl_ssl_connect(conn, FIRSTSOCKET);
+ if(CURLE_OK == result) {
+ conn->protocol |= PROT_IMAPS;
+ result = imap_state_login(conn);
+ }
}
}
state(conn, IMAP_STOP);
return result;
}
+static CURLcode imap_state_upgrade_tls(struct connectdata *conn)
+{
+ struct imap_conn *imapc = &conn->proto.imapc;
+ CURLcode result;
+
+ result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &imapc->ssldone);
+
+ if(imapc->ssldone) {
+ conn->protocol |= PROT_IMAPS;
+ result = imap_state_login(conn);
+ state(conn, IMAP_STOP);
+ }
+
+ return result;
+}
+
/* for LOGIN responses */
static CURLcode imap_state_login_resp(struct connectdata *conn,
int imapcode,
@@ -524,6 +546,10 @@ static CURLcode imap_statemach_act(struct connectdata *conn)
struct pingpong *pp = &imapc->pp;
size_t nread = 0;
+ /* busy upgrading the connection; right now all I/O is SSL/TLS, not IMAP */
+ if(imapc->state == IMAP_UPGRADETLS)
+ return imap_state_upgrade_tls(conn);
+
if(pp->sendleft)
return Curl_pp_flushsend(pp);
diff --git a/lib/imap.h b/lib/imap.h
index ab4cf2f09..c1395160a 100644
--- a/lib/imap.h
+++ b/lib/imap.h
@@ -33,6 +33,7 @@ typedef enum {
a connect */
IMAP_LOGIN,
IMAP_STARTTLS,
+ IMAP_UPGRADETLS, /* asynchronously upgrade the connection to SSL/TLS (multi mode only) */
IMAP_SELECT,
IMAP_FETCH,
IMAP_LOGOUT,