SMTP authentication: fix ordering of preferred authentication method

Fixed the order of the preferred SMTP authentication method to:
AUTH CRAM-MD5, AUTH LOGIN then AUTH PLAIN.

AUTH PLAIN should be the last as it slightly more insecure than AUTH LOGIN
as the username and password are sent together - there is no handshaking
between the client and server like there is with AUTH LOGIN.
This commit is contained in:
Steve Holme 2011-08-24 08:55:25 +02:00 committed by Yang Tse
parent fd00b382b2
commit e882416e75
1 changed files with 35 additions and 34 deletions

View File

@ -283,7 +283,7 @@ static void state(struct connectdata *conn,
struct smtp_conn *smtpc = &conn->proto.smtpc; struct smtp_conn *smtpc = &conn->proto.smtpc;
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
/* for debug purposes */ /* for debug purposes */
static const char * const names[]={ static const char * const names[] = {
"STOP", "STOP",
"SERVERGREET", "SERVERGREET",
"EHLO", "EHLO",
@ -401,7 +401,7 @@ static CURLcode smtp_authenticate(struct connectdata *conn)
l = 1; l = 1;
/* Check supported authentication mechanisms by decreasing order of /* Check supported authentication mechanisms by decreasing order of
preference. */ security. */
mech = (const char *) NULL; /* Avoid compiler warnings. */ mech = (const char *) NULL; /* Avoid compiler warnings. */
state1 = SMTP_STOP; state1 = SMTP_STOP;
state2 = SMTP_STOP; state2 = SMTP_STOP;
@ -413,18 +413,18 @@ static CURLcode smtp_authenticate(struct connectdata *conn)
} }
else else
#endif #endif
if(smtpc->authmechs & SMTP_AUTH_PLAIN) { if(smtpc->authmechs & SMTP_AUTH_LOGIN) {
mech = "PLAIN";
state1 = SMTP_AUTHPLAIN;
state2 = SMTP_AUTH;
result = smtp_auth_plain_data(conn, &initresp, &l);
}
else if(smtpc->authmechs & SMTP_AUTH_LOGIN) {
mech = "LOGIN"; mech = "LOGIN";
state1 = SMTP_AUTHLOGIN; state1 = SMTP_AUTHLOGIN;
state2 = SMTP_AUTHPASSWD; state2 = SMTP_AUTHPASSWD;
result = smtp_auth_login_user(conn, &initresp, &l); result = smtp_auth_login_user(conn, &initresp, &l);
} }
else if(smtpc->authmechs & SMTP_AUTH_PLAIN) {
mech = "PLAIN";
state1 = SMTP_AUTHPLAIN;
state2 = SMTP_AUTH;
result = smtp_auth_plain_data(conn, &initresp, &l);
}
else { else {
infof(conn->data, "No known auth mechanisms supported!\n"); infof(conn->data, "No known auth mechanisms supported!\n");
result = CURLE_LOGIN_DENIED; /* Other mechanisms not supported. */ result = CURLE_LOGIN_DENIED; /* Other mechanisms not supported. */
@ -927,7 +927,7 @@ static CURLcode smtp_statemach_act(struct connectdata *conn)
{ {
CURLcode result; CURLcode result;
curl_socket_t sock = conn->sock[FIRSTSOCKET]; curl_socket_t sock = conn->sock[FIRSTSOCKET];
struct SessionHandle *data=conn->data; struct SessionHandle *data = conn->data;
int smtpcode; int smtpcode;
struct smtp_conn *smtpc = &conn->proto.smtpc; struct smtp_conn *smtpc = &conn->proto.smtpc;
struct pingpong *pp = &smtpc->pp; struct pingpong *pp = &smtpc->pp;
@ -1083,17 +1083,17 @@ static CURLcode smtp_init(struct connectdata *conn)
* smtp_connect() should do everything that is to be considered a part of * smtp_connect() should do everything that is to be considered a part of
* the connection phase. * the connection phase.
* *
* The variable 'done' points to will be TRUE if the protocol-layer connect * The variable pointed to by 'done' will be TRUE if the protocol-layer
* phase is done when this function returns, or FALSE is not. When called as * connect phase is done when this function returns, or FALSE if not. When
* a part of the easy interface, it will always be TRUE. * called as a part of the easy interface, it will always be TRUE.
*/ */
static CURLcode smtp_connect(struct connectdata *conn, static CURLcode smtp_connect(struct connectdata *conn,
bool *done) /* see description above */ bool *done) /* see description above */
{ {
CURLcode result; CURLcode result;
struct smtp_conn *smtpc = &conn->proto.smtpc; struct smtp_conn *smtpc = &conn->proto.smtpc;
struct SessionHandle *data=conn->data; struct SessionHandle *data = conn->data;
struct pingpong *pp=&smtpc->pp; struct pingpong *pp = &smtpc->pp;
const char *path = conn->data->state.path; const char *path = conn->data->state.path;
int len; int len;
char localhost[1024 + 1]; char localhost[1024 + 1];
@ -1200,7 +1200,7 @@ static CURLcode smtp_done(struct connectdata *conn, CURLcode status,
{ {
struct SessionHandle *data = conn->data; struct SessionHandle *data = conn->data;
struct FTP *smtp = data->state.proto.smtp; struct FTP *smtp = data->state.proto.smtp;
CURLcode result=CURLE_OK; CURLcode result = CURLE_OK;
ssize_t bytes_written; ssize_t bytes_written;
(void)premature; (void)premature;
@ -1230,7 +1230,7 @@ static CURLcode smtp_done(struct connectdata *conn, CURLcode status,
if(status == CURLE_OK) { if(status == CURLE_OK) {
struct smtp_conn *smtpc = &conn->proto.smtpc; struct smtp_conn *smtpc = &conn->proto.smtpc;
struct pingpong *pp= &smtpc->pp; struct pingpong *pp = &smtpc->pp;
pp->response = Curl_tvnow(); /* timeout relative now */ pp->response = Curl_tvnow(); /* timeout relative now */
state(conn, SMTP_POSTDATA); state(conn, SMTP_POSTDATA);
@ -1264,7 +1264,7 @@ CURLcode smtp_perform(struct connectdata *conn,
bool *dophase_done) bool *dophase_done)
{ {
/* this is SMTP and no proxy */ /* this is SMTP and no proxy */
CURLcode result=CURLE_OK; CURLcode result = CURLE_OK;
DEBUGF(infof(conn->data, "DO phase starts\n")); DEBUGF(infof(conn->data, "DO phase starts\n"));
@ -1357,9 +1357,10 @@ static CURLcode smtp_quit(struct connectdata *conn)
* Disconnect from an SMTP server. Cleanup protocol-specific per-connection * Disconnect from an SMTP server. Cleanup protocol-specific per-connection
* resources. BLOCKING. * resources. BLOCKING.
*/ */
static CURLcode smtp_disconnect(struct connectdata *conn, bool dead_connection) static CURLcode smtp_disconnect(struct connectdata *conn,
bool dead_connection)
{ {
struct smtp_conn *smtpc= &conn->proto.smtpc; struct smtp_conn *smtpc = &conn->proto.smtpc;
/* We cannot send quit unconditionally. If this connection is stale or /* We cannot send quit unconditionally. If this connection is stale or
bad in any way, sending quit and waiting around here will make the bad in any way, sending quit and waiting around here will make the
@ -1385,7 +1386,7 @@ static CURLcode smtp_dophase_done(struct connectdata *conn,
bool connected) bool connected)
{ {
struct FTP *smtp = conn->data->state.proto.smtp; struct FTP *smtp = conn->data->state.proto.smtp;
struct smtp_conn *smtpc= &conn->proto.smtpc; struct smtp_conn *smtpc = &conn->proto.smtpc;
(void)connected; (void)connected;
if(smtp->transfer != FTPTRANSFER_BODY) if(smtp->transfer != FTPTRANSFER_BODY)
@ -1400,7 +1401,7 @@ static CURLcode smtp_dophase_done(struct connectdata *conn,
/* called from multi.c while DOing */ /* called from multi.c while DOing */
static CURLcode smtp_doing(struct connectdata *conn, static CURLcode smtp_doing(struct connectdata *conn,
bool *dophase_done) bool *dophase_done)
{ {
CURLcode result; CURLcode result;
result = smtp_multi_statemach(conn, dophase_done); result = smtp_multi_statemach(conn, dophase_done);
@ -1424,10 +1425,10 @@ static CURLcode smtp_doing(struct connectdata *conn,
*/ */
static static
CURLcode smtp_regular_transfer(struct connectdata *conn, CURLcode smtp_regular_transfer(struct connectdata *conn,
bool *dophase_done) bool *dophase_done)
{ {
CURLcode result=CURLE_OK; CURLcode result = CURLE_OK;
bool connected=FALSE; bool connected = FALSE;
struct SessionHandle *data = conn->data; struct SessionHandle *data = conn->data;
data->req.size = -1; /* make sure this is unknown at this point */ data->req.size = -1; /* make sure this is unknown at this point */
@ -1454,7 +1455,7 @@ CURLcode smtp_regular_transfer(struct connectdata *conn,
return result; return result;
} }
static CURLcode smtp_setup_connection(struct connectdata * conn) static CURLcode smtp_setup_connection(struct connectdata *conn)
{ {
struct SessionHandle *data = conn->data; struct SessionHandle *data = conn->data;
@ -1501,7 +1502,7 @@ CURLcode Curl_smtp_escape_eob(struct connectdata *conn, ssize_t nread)
struct SessionHandle *data = conn->data; struct SessionHandle *data = conn->data;
if(data->state.scratch == NULL) if(data->state.scratch == NULL)
data->state.scratch = malloc(2*BUFSIZE); data->state.scratch = malloc(2 * BUFSIZE);
if(data->state.scratch == NULL) { if(data->state.scratch == NULL) {
failf (data, "Failed to alloc scratch buffer!"); failf (data, "Failed to alloc scratch buffer!");
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
@ -1511,9 +1512,9 @@ CURLcode Curl_smtp_escape_eob(struct connectdata *conn, ssize_t nread)
for(i = 0, si = 0; i < nread; i++, si++) { for(i = 0, si = 0; i < nread; i++, si++) {
ssize_t left = nread - i; ssize_t left = nread - i;
if(left>= (ssize_t)(SMTP_EOB_LEN-smtpc->eob)) { if(left >= (ssize_t)(SMTP_EOB_LEN - smtpc->eob)) {
if(!memcmp(SMTP_EOB+smtpc->eob, &data->req.upload_fromhere[i], if(!memcmp(SMTP_EOB + smtpc->eob, &data->req.upload_fromhere[i],
SMTP_EOB_LEN-smtpc->eob)) { SMTP_EOB_LEN - smtpc->eob)) {
/* It matched, copy the replacement data to the target buffer /* It matched, copy the replacement data to the target buffer
instead. Note that the replacement does not contain the instead. Note that the replacement does not contain the
trailing CRLF but we instead continue to match on that one trailing CRLF but we instead continue to match on that one
@ -1521,14 +1522,14 @@ CURLcode Curl_smtp_escape_eob(struct connectdata *conn, ssize_t nread)
*/ */
memcpy(&data->state.scratch[si], SMTP_EOB_REPL, memcpy(&data->state.scratch[si], SMTP_EOB_REPL,
SMTP_EOB_REPL_LEN); SMTP_EOB_REPL_LEN);
si+=SMTP_EOB_REPL_LEN-1; /* minus one since the for() increments si += SMTP_EOB_REPL_LEN - 1; /* minus one since the for() increments
it */ it */
i+=SMTP_EOB_LEN-smtpc->eob-1-2; i += SMTP_EOB_LEN - smtpc->eob - 1 - 2;
smtpc->eob = 0; /* start over */ smtpc->eob = 0; /* start over */
continue; continue;
} }
} }
else if(!memcmp(SMTP_EOB+smtpc->eob, &data->req.upload_fromhere[i], else if(!memcmp(SMTP_EOB + smtpc->eob, &data->req.upload_fromhere[i],
left)) { left)) {
/* the last piece of the data matches the EOB so we can't send that /* the last piece of the data matches the EOB so we can't send that
until we know the rest of it */ until we know the rest of it */