diff options
Diffstat (limited to 'Utilities/cmcurl/lib/pop3.c')
-rw-r--r-- | Utilities/cmcurl/lib/pop3.c | 84 |
1 files changed, 47 insertions, 37 deletions
diff --git a/Utilities/cmcurl/lib/pop3.c b/Utilities/cmcurl/lib/pop3.c index 0ed3d3e..d3f3de6 100644 --- a/Utilities/cmcurl/lib/pop3.c +++ b/Utilities/cmcurl/lib/pop3.c @@ -75,7 +75,6 @@ #include "strcase.h" #include "vtls/vtls.h" #include "connect.h" -#include "strerror.h" #include "select.h" #include "multiif.h" #include "url.h" @@ -131,6 +130,7 @@ const struct Curl_handler Curl_handler_pop3 = { pop3_disconnect, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_POP3, /* defport */ CURLPROTO_POP3, /* protocol */ CURLPROTO_POP3, /* family */ @@ -159,6 +159,7 @@ const struct Curl_handler Curl_handler_pop3s = { pop3_disconnect, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_POP3S, /* defport */ CURLPROTO_POP3S, /* protocol */ CURLPROTO_POP3, /* family */ @@ -306,7 +307,7 @@ static void state(struct Curl_easy *data, pop3state newstate) }; if(pop3c->state != newstate) - infof(data, "POP3 %p state change from %s to %s\n", + infof(data, "POP3 %p state change from %s to %s", (void *)pop3c, names[pop3c->state], names[newstate]); #endif @@ -368,8 +369,9 @@ static CURLcode pop3_perform_upgrade_tls(struct Curl_easy *data, { /* Start the SSL connection */ struct pop3_conn *pop3c = &conn->proto.pop3c; - CURLcode result = Curl_ssl_connect_nonblocking(data, conn, FIRSTSOCKET, - &pop3c->ssldone); + CURLcode result = + Curl_ssl_connect_nonblocking(data, conn, FALSE, FIRSTSOCKET, + &pop3c->ssldone); if(!result) { if(pop3c->state != POP3_UPGRADETLS) @@ -549,7 +551,7 @@ static CURLcode pop3_perform_authentication(struct Curl_easy *data, result = pop3_perform_user(data, conn); else { /* Other mechanisms not supported */ - infof(data, "No known authentication mechanisms supported!\n"); + infof(data, "No known authentication mechanisms supported!"); result = CURLE_LOGIN_DENIED; } } @@ -571,12 +573,12 @@ static CURLcode pop3_perform_command(struct Curl_easy *data) const char *command = NULL; /* Calculate the default command */ - if(pop3->id[0] == '\0' || data->set.ftp_list_only) { + if(pop3->id[0] == '\0' || data->set.list_only) { command = "LIST"; if(pop3->id[0] != '\0') /* Message specific LIST so skip the BODY transfer */ - pop3->transfer = FTPTRANSFER_INFO; + pop3->transfer = PPTRANSFER_INFO; } else command = "RETR"; @@ -709,7 +711,7 @@ static CURLcode pop3_state_capa_resp(struct Curl_easy *data, int pop3code, for(;;) { size_t llen; size_t wordlen; - unsigned int mechbit; + unsigned short mechbit; while(len && (*line == ' ' || *line == '\t' || @@ -738,28 +740,23 @@ static CURLcode pop3_state_capa_resp(struct Curl_easy *data, int pop3code, } } } - else if(pop3code == '+') { - 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_perform_starttls(data, conn); - else if(data->set.use_ssl == CURLUSESSL_TRY) - /* Fallback and carry on with authentication */ - result = pop3_perform_authentication(data, conn); - else { - failf(data, "STLS not supported."); - result = CURLE_USE_SSL_FAILED; - } - } - else - result = pop3_perform_authentication(data, conn); - } else { /* Clear text is supported when CAPA isn't recognised */ - pop3c->authtypes |= POP3_TYPE_CLEARTEXT; + if(pop3code != '+') + pop3c->authtypes |= POP3_TYPE_CLEARTEXT; - result = pop3_perform_authentication(data, conn); + if(!data->set.use_ssl || conn->ssl[FIRSTSOCKET].use) + result = pop3_perform_authentication(data, conn); + else if(pop3code == '+' && pop3c->tls_supported) + /* Switch to TLS connection now */ + result = pop3_perform_starttls(data, conn); + else if(data->set.use_ssl <= CURLUSESSL_TRY) + /* Fallback and carry on with authentication */ + result = pop3_perform_authentication(data, conn); + else { + failf(data, "STLS not supported."); + result = CURLE_USE_SSL_FAILED; + } } return result; @@ -774,6 +771,10 @@ static CURLcode pop3_state_starttls_resp(struct Curl_easy *data, CURLcode result = CURLE_OK; (void)instate; /* no use for this yet */ + /* Pipelining in response is forbidden. */ + if(data->conn->proto.pop3c.pp.cache_size) + return CURLE_WEIRD_SERVER_REPLY; + if(pop3code != '+') { if(data->set.use_ssl != CURLUSESSL_TRY) { failf(data, "STARTTLS denied"); @@ -916,7 +917,7 @@ static CURLcode pop3_state_command_resp(struct Curl_easy *data, the strip counter here so that these bytes won't be delivered. */ pop3c->strip = 2; - if(pop3->transfer == FTPTRANSFER_BODY) { + if(pop3->transfer == PPTRANSFER_BODY) { /* POP3 download */ Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1); @@ -1029,7 +1030,7 @@ static CURLcode pop3_multi_statemach(struct Curl_easy *data, bool *done) struct pop3_conn *pop3c = &conn->proto.pop3c; if((conn->handler->flags & PROTOPT_SSL) && !pop3c->ssldone) { - result = Curl_ssl_connect_nonblocking(data, conn, + result = Curl_ssl_connect_nonblocking(data, conn, FALSE, FIRSTSOCKET, &pop3c->ssldone); if(result || !pop3c->ssldone) return result; @@ -1150,7 +1151,7 @@ static CURLcode pop3_done(struct Curl_easy *data, CURLcode status, Curl_safefree(pop3->custom); /* Clear the transfer mode for the next request */ - pop3->transfer = FTPTRANSFER_BODY; + pop3->transfer = PPTRANSFER_BODY; return result; } @@ -1170,11 +1171,11 @@ static CURLcode pop3_perform(struct Curl_easy *data, bool *connected, struct connectdata *conn = data->conn; struct POP3 *pop3 = data->req.p.pop3; - DEBUGF(infof(data, "DO phase starts\n")); + DEBUGF(infof(data, "DO phase starts")); if(data->set.opt_no_body) { /* Requested no body means no transfer */ - pop3->transfer = FTPTRANSFER_INFO; + pop3->transfer = PPTRANSFER_INFO; } *dophase_done = FALSE; /* not done yet */ @@ -1189,7 +1190,7 @@ static CURLcode pop3_perform(struct Curl_easy *data, bool *connected, *connected = conn->bits.tcpconnect[FIRSTSOCKET]; if(*dophase_done) - DEBUGF(infof(data, "DO phase is complete\n")); + DEBUGF(infof(data, "DO phase is complete")); return result; } @@ -1272,11 +1273,11 @@ static CURLcode pop3_doing(struct Curl_easy *data, bool *dophase_done) CURLcode result = pop3_multi_statemach(data, dophase_done); if(result) - DEBUGF(infof(data, "DO phase failed\n")); + DEBUGF(infof(data, "DO phase failed")); else if(*dophase_done) { result = pop3_dophase_done(data, FALSE /* not connected */); - DEBUGF(infof(data, "DO phase is complete\n")); + DEBUGF(infof(data, "DO phase is complete")); } return result; @@ -1515,8 +1516,17 @@ CURLcode Curl_pop3_write(struct Curl_easy *data, char *str, size_t nread) if(prev) { /* If the partial match was the CRLF and dot then only write the CRLF as the server would have inserted the dot */ - result = Curl_client_write(data, CLIENTWRITE_BODY, (char *)POP3_EOB, - strip_dot ? prev - 1 : prev); + if(strip_dot && prev - 1 > 0) { + result = Curl_client_write(data, CLIENTWRITE_BODY, (char *)POP3_EOB, + prev - 1); + } + else if(!strip_dot) { + result = Curl_client_write(data, CLIENTWRITE_BODY, (char *)POP3_EOB, + prev); + } + else { + result = CURLE_OK; + } if(result) return result; |