mirror of https://github.com/moparisthebest/curl
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:
parent
fd00b382b2
commit
e882416e75
69
lib/smtp.c
69
lib/smtp.c
|
@ -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 */
|
||||||
|
|
Loading…
Reference in New Issue