pop3: Added support for the STLS capability (Part Two)

Added sending of initial CAPA command before STLS is sent. This allows
for the detection of the capability before trying to upgrade the
connection.
This commit is contained in:
Steve Holme
2013-02-10 15:45:01 +00:00
parent f6010d9a03
commit 2e0a295e3b

View File

@@ -393,14 +393,7 @@ static CURLcode pop3_state_capa(struct connectdata *conn)
pop3c->authmechs = 0; /* No known authentication mechanisms yet */ pop3c->authmechs = 0; /* No known authentication mechanisms yet */
pop3c->authused = 0; /* Clear the authentication mechanism used */ pop3c->authused = 0; /* Clear the authentication mechanism used */
pop3c->tls_supported = FALSE; /* Clear the TLS capability */
/* 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;
}
/* Send the CAPA command */ /* Send the CAPA command */
result = Curl_pp_sendf(&pop3c->pp, "CAPA"); result = Curl_pp_sendf(&pop3c->pp, "CAPA");
@@ -415,9 +408,17 @@ static CURLcode pop3_state_capa(struct connectdata *conn)
static CURLcode pop3_state_user(struct connectdata *conn) static CURLcode pop3_state_user(struct connectdata *conn)
{ {
CURLcode result; CURLcode result = CURLE_OK;
struct FTP *pop3 = conn->data->state.proto.pop3; struct FTP *pop3 = conn->data->state.proto.pop3;
/* 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;
}
/* Send the USER command */ /* Send the USER command */
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "USER %s", result = Curl_pp_sendf(&conn->proto.pop3c.pp, "USER %s",
pop3->user ? pop3->user : ""); pop3->user ? pop3->user : "");
@@ -439,6 +440,15 @@ static CURLcode pop3_state_apop(struct connectdata *conn)
unsigned char digest[MD5_DIGEST_LEN]; unsigned char digest[MD5_DIGEST_LEN];
char secret[2 * MD5_DIGEST_LEN + 1]; char secret[2 * MD5_DIGEST_LEN + 1];
/* 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;
}
/* Create the digest */
ctxt = Curl_MD5_init(Curl_DIGEST_MD5); ctxt = Curl_MD5_init(Curl_DIGEST_MD5);
if(!ctxt) if(!ctxt)
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
@@ -472,6 +482,14 @@ static CURLcode pop3_authenticate(struct connectdata *conn)
const char *mech = NULL; const char *mech = NULL;
pop3state authstate = POP3_STOP; 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 /* Calculate the supported authentication mechanism by decreasing order of
security */ security */
if(pop3c->authtypes & POP3_TYPE_SASL) { if(pop3c->authtypes & POP3_TYPE_SASL) {
@@ -563,13 +581,7 @@ static CURLcode pop3_state_servergreet_resp(struct connectdata *conn,
return CURLE_FTP_WEIRD_SERVER_REPLY; return CURLE_FTP_WEIRD_SERVER_REPLY;
} }
if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) { result = pop3_state_capa(conn);
/* We don't have a SSL/TLS connection yet, but SSL is requested. Switch
to TLS connection now */
result = pop3_state_starttls(conn);
}
else
result = pop3_state_capa(conn);
return result; return result;
} }
@@ -590,7 +602,7 @@ static CURLcode pop3_state_starttls_resp(struct connectdata *conn,
result = CURLE_USE_SSL_FAILED; result = CURLE_USE_SSL_FAILED;
} }
else else
result = pop3_state_capa(conn); result = pop3_authenticate(conn);
} }
else else
result = pop3_state_upgrade_tls(conn); result = pop3_state_upgrade_tls(conn);
@@ -623,13 +635,19 @@ static CURLcode pop3_state_capa_resp(struct connectdata *conn, int pop3code,
pop3state instate) pop3state instate)
{ {
CURLcode result = CURLE_OK; CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
(void)instate; /* no use for this yet */ (void)instate; /* no use for this yet */
if(pop3code == '+') if(pop3code != '+')
result = pop3_authenticate(conn);
else
result = pop3_state_user(conn); 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. Switch
to TLS connection now */
result = pop3_state_starttls(conn);
}
else
result = pop3_authenticate(conn);
return result; return result;
} }