|
static CURLcode imap_state_capability_resp(struct Curl_easy *data, |
|
struct imap_conn *imapc, |
|
int imapcode, |
|
imapstate instate) |
|
{ |
|
CURLcode result = CURLE_OK; |
|
struct connectdata *conn = data->conn; |
|
const char *line = curlx_dyn_ptr(&imapc->pp.recvbuf); |
|
|
|
(void)instate; |
|
|
|
/* Do we have an untagged response? */ |
|
if(imapcode == '*') { |
|
line += 2; |
|
|
|
/* Loop through the data line */ |
|
for(;;) { |
|
size_t wordlen; |
|
while(*line && |
|
(*line == ' ' || *line == '\t' || |
|
*line == '\r' || *line == '\n')) { |
|
|
|
line++; |
|
} |
|
|
|
if(!*line) |
|
break; |
|
|
|
/* Extract the word */ |
|
for(wordlen = 0; line[wordlen] && line[wordlen] != ' ' && |
|
line[wordlen] != '\t' && line[wordlen] != '\r' && |
|
line[wordlen] != '\n';) |
|
wordlen++; |
|
|
|
/* Does the server support the STARTTLS capability? */ |
|
if(wordlen == 8 && !memcmp(line, "STARTTLS", 8)) |
|
imapc->tls_supported = TRUE; |
|
|
|
/* Has the server explicitly disabled clear text authentication? */ |
|
else if(wordlen == 13 && !memcmp(line, "LOGINDISABLED", 13)) |
|
imapc->login_disabled = TRUE; |
|
|
|
/* Does the server support the SASL-IR capability? */ |
|
else if(wordlen == 7 && !memcmp(line, "SASL-IR", 7)) |
|
imapc->ir_supported = TRUE; |
|
|
|
/* Do we have a SASL based authentication mechanism? */ |
|
else if(wordlen > 5 && !memcmp(line, "AUTH=", 5)) { |
|
size_t llen; |
|
unsigned short mechbit; |
|
|
|
line += 5; |
|
wordlen -= 5; |
|
|
|
/* Test the word for a matching authentication mechanism */ |
|
mechbit = Curl_sasl_decode_mech(line, wordlen, &llen); |
|
if(mechbit && llen == wordlen) |
|
imapc->sasl.authmechs |= mechbit; |
|
} |
|
|
|
line += wordlen; |
|
} |
|
} |
|
else if(data->set.use_ssl && !Curl_conn_is_ssl(conn, FIRSTSOCKET)) { |
|
/* PREAUTH is not compatible with STARTTLS. */ |
|
if(imapcode == IMAP_RESP_OK && imapc->tls_supported && !imapc->preauth) { |
|
/* Switch to TLS connection now */ |
|
result = imap_perform_starttls(data, imapc); |
|
} |
|
else if(data->set.use_ssl <= CURLUSESSL_TRY) |
|
result = imap_perform_authentication(data, imapc); |
|
else { |
|
failf(data, "STARTTLS not available."); |
|
result = CURLE_USE_SSL_FAILED; |
|
} |
|
} |
|
else |
|
result = imap_perform_authentication(data, imapc); |
|
|
|
return result; |
|
} |
I did this
Sorry, quick copy-paste because I'm in a rush but,
curl/lib/imap.c
Lines 1024 to 1104 in c37ed9a
(Chatgpt generated description):
IMAP keywords and atoms are case-insensitive by default. RFC 3501's formal syntax section states: "Except as noted otherwise, all alphabetic characters are case-insensitive... Implementations MUST accept these strings in a case-insensitive fashion." IETF Datatracker
The CAPABILITY response is a space-separated list of capability names. It must include
IMAP4rev1, and it uses atoms for items likeSTARTTLS,LOGINDISABLED, andAUTH=<mechanism>. Clients MUST NOT issueLOGINifLOGINDISABLEDis advertised. Since these are atoms, the case-insensitive rule applies when matching them. IETF DatatrackerThe grammar explicitly defines
auth-type = atom, which again inherits the case-insensitive rule. That meansAUTH=plainandAUTH=PLAINmust be treated the same by a client. IETF DatatrackerThe STARTTLS extension for IMAP is advertised as the
STARTTLScapability and invoked with theSTARTTLScommand. Whether a server printsSTARTTLSorstarttls, a conforming client has to recognize it. IETF DatatrackerThe
SASL-IRcapability (initial client response) is defined by RFC 4959. Like all capability atoms, it is matched case-insensitively.I expected the following
used a server which uses lowercase keywords in imap
curl/libcurl version
all
operating system
all