mirror of
https://github.com/moparisthebest/curl
synced 2024-12-21 23:58:49 -05:00
imap: Changed response tag generation to be completely unique
Updated the automatic response tag generation to follow the examples given in RC3501, which list a 4 character string such as A001, A002, etc. As a unique identifier should be generated for each command the string generation is based on the connection id and the incrementing command id.
This commit is contained in:
parent
542507f316
commit
7704621f4c
68
lib/imap.c
68
lib/imap.c
@ -211,41 +211,33 @@ static const struct Curl_handler Curl_handler_imaps_proxy = {
|
||||
*
|
||||
* Designed to never block.
|
||||
*/
|
||||
static CURLcode imap_sendf(struct connectdata *conn,
|
||||
const char *idstr, /* command id to wait for */
|
||||
const char *fmt, ...)
|
||||
static CURLcode imap_sendf(struct connectdata *conn, const char *fmt, ...)
|
||||
{
|
||||
CURLcode result;
|
||||
struct imap_conn *imapc = &conn->proto.imapc;
|
||||
char *taggedfmt;
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
|
||||
imapc->resptag = idstr;
|
||||
/* Calculate the next command ID wrapping at 3 digits */
|
||||
imapc->cmdid = (imapc->cmdid + 1) % 1000;
|
||||
|
||||
result = Curl_pp_vsendf(&imapc->pp, fmt, ap);
|
||||
/* Calculate the tag based on the connection ID and command ID */
|
||||
snprintf(imapc->resptag, sizeof(imapc->resptag), "%c%03d",
|
||||
'A' + (conn->connection_id % 26), imapc->cmdid);
|
||||
|
||||
taggedfmt = aprintf("%s %s", imapc->resptag, fmt);
|
||||
if(!taggedfmt)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
result = Curl_pp_vsendf(&imapc->pp, taggedfmt, ap);
|
||||
|
||||
Curl_safefree(taggedfmt);
|
||||
va_end(ap);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static const char *getcmdid(struct connectdata *conn)
|
||||
{
|
||||
static const char * const ids[]= {
|
||||
"A",
|
||||
"B",
|
||||
"C",
|
||||
"D"
|
||||
};
|
||||
|
||||
struct imap_conn *imapc = &conn->proto.imapc;
|
||||
|
||||
/* Get the next id, but wrap at end of table */
|
||||
imapc->cmdid = (int)((imapc->cmdid + 1) % (sizeof(ids) / sizeof(ids[0])));
|
||||
|
||||
return ids[imapc->cmdid];
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* imap_atom()
|
||||
@ -462,10 +454,9 @@ static void state(struct connectdata *conn, imapstate newstate)
|
||||
static CURLcode imap_state_starttls(struct connectdata *conn)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
const char *str = getcmdid(conn);
|
||||
|
||||
/* Send the STARTTLS command */
|
||||
result = imap_sendf(conn, str, "%s STARTTLS", str);
|
||||
result = imap_sendf(conn, "STARTTLS");
|
||||
|
||||
if(!result)
|
||||
state(conn, IMAP_STARTTLS);
|
||||
@ -477,7 +468,6 @@ static CURLcode imap_state_capability(struct connectdata *conn)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct imap_conn *imapc = &conn->proto.imapc;
|
||||
const char *str;
|
||||
|
||||
imapc->authmechs = 0; /* No known authentication mechanisms yet */
|
||||
imapc->authused = 0; /* Clear the authentication mechanism used */
|
||||
@ -490,10 +480,8 @@ static CURLcode imap_state_capability(struct connectdata *conn)
|
||||
return result;
|
||||
}
|
||||
|
||||
str = getcmdid(conn);
|
||||
|
||||
/* Send the CAPABILITY command */
|
||||
result = imap_sendf(conn, str, "%s CAPABILITY", str);
|
||||
result = imap_sendf(conn, "CAPABILITY");
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
@ -507,13 +495,12 @@ static CURLcode imap_state_login(struct connectdata *conn)
|
||||
{
|
||||
CURLcode result;
|
||||
struct FTP *imap = conn->data->state.proto.imap;
|
||||
const char *str = getcmdid(conn);
|
||||
char *user = imap_atom(imap->user);
|
||||
char *passwd = imap_atom(imap->passwd);
|
||||
|
||||
/* Send USER and password */
|
||||
result = imap_sendf(conn, str, "%s LOGIN %s %s", str,
|
||||
user ? user : "", passwd ? passwd : "");
|
||||
result = imap_sendf(conn, "LOGIN %s %s", user ? user : "",
|
||||
passwd ? passwd : "");
|
||||
|
||||
Curl_safefree(user);
|
||||
Curl_safefree(passwd);
|
||||
@ -569,9 +556,7 @@ static CURLcode imap_authenticate(struct connectdata *conn)
|
||||
|
||||
if(mech) {
|
||||
/* Perform SASL based authentication */
|
||||
const char *str = getcmdid(conn);
|
||||
|
||||
result = imap_sendf(conn, str, "%s AUTHENTICATE %s", str, mech);
|
||||
result = imap_sendf(conn, "AUTHENTICATE %s", mech);
|
||||
|
||||
if(!result)
|
||||
state(conn, authstate);
|
||||
@ -1051,10 +1036,9 @@ static CURLcode imap_select(struct connectdata *conn)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct imap_conn *imapc = &conn->proto.imapc;
|
||||
const char *str = getcmdid(conn);
|
||||
|
||||
result = imap_sendf(conn, str, "%s SELECT %s", str,
|
||||
imapc->mailbox?imapc->mailbox:"");
|
||||
result = imap_sendf(conn, "SELECT %s",
|
||||
imapc->mailbox ? imapc->mailbox : "");
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
@ -1066,12 +1050,11 @@ static CURLcode imap_select(struct connectdata *conn)
|
||||
static CURLcode imap_fetch(struct connectdata *conn)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
const char *str = getcmdid(conn);
|
||||
|
||||
/* TODO: make this select the correct mail
|
||||
* Use "1 body[text]" to get the full mail body of mail 1
|
||||
*/
|
||||
result = imap_sendf(conn, str, "%s FETCH 1 BODY[TEXT]", str);
|
||||
result = imap_sendf(conn, "FETCH 1 BODY[TEXT]");
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
@ -1389,8 +1372,8 @@ static CURLcode imap_connect(struct connectdata *conn, bool *done)
|
||||
/* Start off waiting for the server greeting response */
|
||||
state(conn, IMAP_SERVERGREET);
|
||||
|
||||
/* Start off with an id of '*' */
|
||||
imapc->resptag = "*";
|
||||
/* Start off with an response id of '*' */
|
||||
strcpy(imapc->resptag, "*");
|
||||
|
||||
result = imap_multi_statemach(conn, done);
|
||||
|
||||
@ -1521,9 +1504,8 @@ static CURLcode imap_do(struct connectdata *conn, bool *done)
|
||||
static CURLcode imap_logout(struct connectdata *conn)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
const char *str = getcmdid(conn);
|
||||
|
||||
result = imap_sendf(conn, str, "%s LOGOUT", str, NULL);
|
||||
result = imap_sendf(conn, "LOGOUT", NULL);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
|
@ -60,7 +60,7 @@ struct imap_conn {
|
||||
unsigned int authused; /* Auth mechanism used for the connection */
|
||||
imapstate state; /* Always use imap.c:state() to change state! */
|
||||
int cmdid; /* Last used command ID */
|
||||
const char *resptag; /* Response tag to wait for */
|
||||
char resptag[5]; /* Response tag to wait for */
|
||||
bool ssldone; /* Is connect() over SSL done? */
|
||||
bool login_disabled; /* LOGIN command explicitly disabled by server */
|
||||
};
|
||||
|
@ -56,11 +56,11 @@ imap://%HOSTIP:%IMAPPORT/1321 -u user:secret -p -x %HOSTIP:%PROXYPORT
|
||||
^User-Agent: curl/.*
|
||||
</strip>
|
||||
<protocol>
|
||||
B CAPABILITY
|
||||
C LOGIN user secret
|
||||
D SELECT 1321
|
||||
A FETCH 1 BODY[TEXT]
|
||||
B LOGOUT
|
||||
A001 CAPABILITY
|
||||
A002 LOGIN user secret
|
||||
A003 SELECT 1321
|
||||
A004 FETCH 1 BODY[TEXT]
|
||||
A005 LOGOUT
|
||||
</protocol>
|
||||
<proxy>
|
||||
CONNECT %HOSTIP:%IMAPPORT HTTP/1.1
|
||||
|
@ -38,11 +38,11 @@ imap://%HOSTIP:%IMAPPORT/801 -u user:secret
|
||||
# Verify data after the test has been "shot"
|
||||
<verify>
|
||||
<protocol>
|
||||
B CAPABILITY
|
||||
C LOGIN user secret
|
||||
D SELECT 801
|
||||
A FETCH 1 BODY[TEXT]
|
||||
B LOGOUT
|
||||
A001 CAPABILITY
|
||||
A002 LOGIN user secret
|
||||
A003 SELECT 801
|
||||
A004 FETCH 1 BODY[TEXT]
|
||||
A005 LOGOUT
|
||||
</protocol>
|
||||
</verify>
|
||||
</testcase>
|
||||
|
Loading…
Reference in New Issue
Block a user