Loading lib/pop3.c +107 −5 Original line number Diff line number Diff line Loading @@ -18,9 +18,11 @@ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * * RFC1734 POP3 Authentication * RFC1939 POP3 protocol * RFC2384 POP URL Scheme * RFC2595 Using TLS with IMAP, POP3 and ACAP * RFC4616 PLAIN authentication * ***************************************************************************/ Loading Loading @@ -279,6 +281,8 @@ static void state(struct connectdata *conn, pop3state newstate) "SERVERGREET", "STARTTLS", "AUTH", "AUTH_PLAIN", "AUTH_FINAL", "USER", "PASS", "COMMAND", Loading @@ -301,6 +305,7 @@ static CURLcode pop3_state_auth(struct connectdata *conn) struct pop3_conn *pop3c = &conn->proto.pop3c; pop3c->authmechs = 0; /* No known authentication mechanisms yet */ pop3c->authused = 0; /* Clear the authentication mechanism used */ /* send AUTH */ result = Curl_pp_sendf(&pop3c->pp, "AUTH"); Loading Loading @@ -329,6 +334,35 @@ static CURLcode pop3_state_user(struct connectdata *conn) return CURLE_OK; } static CURLcode pop3_authenticate(struct connectdata *conn) { CURLcode result = CURLE_OK; struct pop3_conn *pop3c = &conn->proto.pop3c; const char *mech = NULL; pop3state authstate = POP3_STOP; /* Check supported authentication mechanisms by decreasing order of security */ if(pop3c->authmechs & SASL_AUTH_PLAIN) { mech = "PLAIN"; authstate = POP3_AUTH_PLAIN; pop3c->authused = SASL_AUTH_PLAIN; } else { infof(conn->data, "No known SASL auth mechanisms supported!\n"); result = CURLE_LOGIN_DENIED; /* Other mechanisms not supported */ } if(!result) { result = Curl_pp_sendf(&pop3c->pp, "AUTH %s", mech); if(!result) state(conn, authstate); } return result; } /* For the POP3 "protocol connect" and "doing" phases only */ static int pop3_getsock(struct connectdata *conn, curl_socket_t *socks, int numsocks) Loading Loading @@ -408,12 +442,72 @@ static CURLcode pop3_state_starttls_resp(struct connectdata *conn, } /* For AUTH responses */ static CURLcode pop3_state_auth_resp(struct connectdata *conn) static CURLcode pop3_state_auth_resp(struct connectdata *conn, int pop3code, pop3state instate) { CURLcode result = CURLE_OK; /* Proceed with clear text authentication as we used to for now */ (void)instate; /* no use for this yet */ if(pop3code != '+') result = pop3_state_user(conn); else result = pop3_authenticate(conn); return result; } /* For AUTH PLAIN responses */ static CURLcode pop3_state_auth_plain_resp(struct connectdata *conn, int pop3code, pop3state instate) { CURLcode result = CURLE_OK; struct SessionHandle *data = conn->data; size_t len = 0; char *plainauth = NULL; (void)instate; /* no use for this yet */ if(pop3code != '+') { failf(data, "Access denied. %c", pop3code); result = CURLE_LOGIN_DENIED; } else { result = Curl_sasl_create_plain_message(conn->data, conn->user, conn->passwd, &plainauth, &len); if(!result) { if(plainauth) { result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", plainauth); if(!result) state(conn, POP3_AUTH_FINAL); } Curl_safefree(plainauth); } } return result; } /* For final responses in the AUTH sequence */ static CURLcode pop3_state_auth_final_resp(struct connectdata *conn, int pop3code, pop3state instate) { CURLcode result = CURLE_OK; struct SessionHandle *data = conn->data; (void)instate; /* no use for this yet */ if(pop3code != '+') { failf(data, "Authentication failed: %d", pop3code); result = CURLE_LOGIN_DENIED; } state(conn, POP3_STOP); /* End of connect phase */ return result; } Loading Loading @@ -460,7 +554,7 @@ static CURLcode pop3_state_pass_resp(struct connectdata *conn, result = CURLE_LOGIN_DENIED; } state(conn, POP3_STOP); state(conn, POP3_STOP); /* End of connect phase */ return result; } Loading Loading @@ -587,7 +681,15 @@ static CURLcode pop3_statemach_act(struct connectdata *conn) break; case POP3_AUTH: result = pop3_state_auth_resp(conn); result = pop3_state_auth_resp(conn, pop3code, pop3c->state); break; case POP3_AUTH_PLAIN: result = pop3_state_auth_plain_resp(conn, pop3code, pop3c->state); break; case POP3_AUTH_FINAL: result = pop3_state_auth_final_resp(conn, pop3code, pop3c->state); break; case POP3_USER: Loading lib/pop3.h +3 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,8 @@ typedef enum { a connect */ POP3_STARTTLS, POP3_AUTH, POP3_AUTH_PLAIN, POP3_AUTH_FINAL, POP3_USER, POP3_PASS, POP3_COMMAND, Loading @@ -48,6 +50,7 @@ struct pop3_conn { received thus far */ size_t strip; /* number of bytes from the start to ignore as non-body */ unsigned int authmechs; /* Accepted authentication methods */ unsigned int authused; /* Authentication method used for the connection */ pop3state state; /* always use pop3.c:state() to change state! */ }; Loading Loading
lib/pop3.c +107 −5 Original line number Diff line number Diff line Loading @@ -18,9 +18,11 @@ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * * RFC1734 POP3 Authentication * RFC1939 POP3 protocol * RFC2384 POP URL Scheme * RFC2595 Using TLS with IMAP, POP3 and ACAP * RFC4616 PLAIN authentication * ***************************************************************************/ Loading Loading @@ -279,6 +281,8 @@ static void state(struct connectdata *conn, pop3state newstate) "SERVERGREET", "STARTTLS", "AUTH", "AUTH_PLAIN", "AUTH_FINAL", "USER", "PASS", "COMMAND", Loading @@ -301,6 +305,7 @@ static CURLcode pop3_state_auth(struct connectdata *conn) struct pop3_conn *pop3c = &conn->proto.pop3c; pop3c->authmechs = 0; /* No known authentication mechanisms yet */ pop3c->authused = 0; /* Clear the authentication mechanism used */ /* send AUTH */ result = Curl_pp_sendf(&pop3c->pp, "AUTH"); Loading Loading @@ -329,6 +334,35 @@ static CURLcode pop3_state_user(struct connectdata *conn) return CURLE_OK; } static CURLcode pop3_authenticate(struct connectdata *conn) { CURLcode result = CURLE_OK; struct pop3_conn *pop3c = &conn->proto.pop3c; const char *mech = NULL; pop3state authstate = POP3_STOP; /* Check supported authentication mechanisms by decreasing order of security */ if(pop3c->authmechs & SASL_AUTH_PLAIN) { mech = "PLAIN"; authstate = POP3_AUTH_PLAIN; pop3c->authused = SASL_AUTH_PLAIN; } else { infof(conn->data, "No known SASL auth mechanisms supported!\n"); result = CURLE_LOGIN_DENIED; /* Other mechanisms not supported */ } if(!result) { result = Curl_pp_sendf(&pop3c->pp, "AUTH %s", mech); if(!result) state(conn, authstate); } return result; } /* For the POP3 "protocol connect" and "doing" phases only */ static int pop3_getsock(struct connectdata *conn, curl_socket_t *socks, int numsocks) Loading Loading @@ -408,12 +442,72 @@ static CURLcode pop3_state_starttls_resp(struct connectdata *conn, } /* For AUTH responses */ static CURLcode pop3_state_auth_resp(struct connectdata *conn) static CURLcode pop3_state_auth_resp(struct connectdata *conn, int pop3code, pop3state instate) { CURLcode result = CURLE_OK; /* Proceed with clear text authentication as we used to for now */ (void)instate; /* no use for this yet */ if(pop3code != '+') result = pop3_state_user(conn); else result = pop3_authenticate(conn); return result; } /* For AUTH PLAIN responses */ static CURLcode pop3_state_auth_plain_resp(struct connectdata *conn, int pop3code, pop3state instate) { CURLcode result = CURLE_OK; struct SessionHandle *data = conn->data; size_t len = 0; char *plainauth = NULL; (void)instate; /* no use for this yet */ if(pop3code != '+') { failf(data, "Access denied. %c", pop3code); result = CURLE_LOGIN_DENIED; } else { result = Curl_sasl_create_plain_message(conn->data, conn->user, conn->passwd, &plainauth, &len); if(!result) { if(plainauth) { result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", plainauth); if(!result) state(conn, POP3_AUTH_FINAL); } Curl_safefree(plainauth); } } return result; } /* For final responses in the AUTH sequence */ static CURLcode pop3_state_auth_final_resp(struct connectdata *conn, int pop3code, pop3state instate) { CURLcode result = CURLE_OK; struct SessionHandle *data = conn->data; (void)instate; /* no use for this yet */ if(pop3code != '+') { failf(data, "Authentication failed: %d", pop3code); result = CURLE_LOGIN_DENIED; } state(conn, POP3_STOP); /* End of connect phase */ return result; } Loading Loading @@ -460,7 +554,7 @@ static CURLcode pop3_state_pass_resp(struct connectdata *conn, result = CURLE_LOGIN_DENIED; } state(conn, POP3_STOP); state(conn, POP3_STOP); /* End of connect phase */ return result; } Loading Loading @@ -587,7 +681,15 @@ static CURLcode pop3_statemach_act(struct connectdata *conn) break; case POP3_AUTH: result = pop3_state_auth_resp(conn); result = pop3_state_auth_resp(conn, pop3code, pop3c->state); break; case POP3_AUTH_PLAIN: result = pop3_state_auth_plain_resp(conn, pop3code, pop3c->state); break; case POP3_AUTH_FINAL: result = pop3_state_auth_final_resp(conn, pop3code, pop3c->state); break; case POP3_USER: Loading
lib/pop3.h +3 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,8 @@ typedef enum { a connect */ POP3_STARTTLS, POP3_AUTH, POP3_AUTH_PLAIN, POP3_AUTH_FINAL, POP3_USER, POP3_PASS, POP3_COMMAND, Loading @@ -48,6 +50,7 @@ struct pop3_conn { received thus far */ size_t strip; /* number of bytes from the start to ignore as non-body */ unsigned int authmechs; /* Accepted authentication methods */ unsigned int authused; /* Authentication method used for the connection */ pop3state state; /* always use pop3.c:state() to change state! */ }; Loading