/* * Curl_sasl_parse_url_auth_option() * * Parse the URL login options. */ CURLcode Curl_sasl_parse_url_auth_option(struct SASL *sasl, const char *value, size_t len) { CURLcode result = CURLE_OK; unsigned int mechbit; size_t mechlen; if(!len) return CURLE_URL_MALFORMAT; if(sasl->resetprefs) { sasl->resetprefs = FALSE; sasl->prefmech = SASL_AUTH_NONE; } if(strnequal(value, "*", len)) sasl->prefmech = SASL_AUTH_DEFAULT; else { mechbit = Curl_sasl_decode_mech(value, len, &mechlen); if(mechbit && mechlen == len) sasl->prefmech |= mechbit; else result = CURLE_URL_MALFORMAT; } return result; }
/* For EHLO responses */ static CURLcode smtp_state_ehlo_resp(struct connectdata *conn, int smtpcode, smtpstate instate) { CURLcode result = CURLE_OK; struct Curl_easy *data = conn->data; struct smtp_conn *smtpc = &conn->proto.smtpc; const char *line = data->state.buffer; size_t len = strlen(line); (void)instate; /* no use for this yet */ if(smtpcode/100 != 2 && smtpcode != 1) { if(data->set.use_ssl <= CURLUSESSL_TRY || conn->ssl[FIRSTSOCKET].use) result = smtp_perform_helo(conn); else { failf(data, "Remote access denied: %d", smtpcode); result = CURLE_REMOTE_ACCESS_DENIED; } } else { line += 4; len -= 4; /* Does the server support the STARTTLS capability? */ if(len >= 8 && !memcmp(line, "STARTTLS", 8)) smtpc->tls_supported = TRUE; /* Does the server support the SIZE capability? */ else if(len >= 4 && !memcmp(line, "SIZE", 4)) smtpc->size_supported = TRUE; /* Does the server support authentication? */ else if(len >= 5 && !memcmp(line, "AUTH ", 5)) { smtpc->auth_supported = TRUE; /* Advance past the AUTH keyword */ line += 5; len -= 5; /* Loop through the data line */ for(;;) { size_t llen; size_t wordlen; unsigned int mechbit; while(len && (*line == ' ' || *line == '\t' || *line == '\r' || *line == '\n')) { line++; len--; } if(!len) break; /* Extract the word */ for(wordlen = 0; wordlen < len && line[wordlen] != ' ' && line[wordlen] != '\t' && line[wordlen] != '\r' && line[wordlen] != '\n';) wordlen++; /* Test the word for a matching authentication mechanism */ mechbit = Curl_sasl_decode_mech(line, wordlen, &llen); if(mechbit && llen == wordlen) smtpc->sasl.authmechs |= mechbit; line += wordlen; len -= wordlen; } } if(smtpcode != 1) { if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) { /* We don't have a SSL/TLS connection yet, but SSL is requested */ if(smtpc->tls_supported) /* Switch to TLS connection now */ result = smtp_perform_starttls(conn); else if(data->set.use_ssl == CURLUSESSL_TRY) /* Fallback and carry on with authentication */ result = smtp_perform_authentication(conn); else { failf(data, "STARTTLS not supported."); result = CURLE_USE_SSL_FAILED; } } else result = smtp_perform_authentication(conn); } } return result; }
/* For CAPA responses */ static CURLcode pop3_state_capa_resp(struct connectdata *conn, int pop3code, pop3state instate) { CURLcode result = CURLE_OK; struct SessionHandle *data = conn->data; struct pop3_conn *pop3c = &conn->proto.pop3c; const char *line = data->state.buffer; size_t len = strlen(line); size_t wordlen; (void)instate; /* no use for this yet */ /* Do we have a untagged continuation response? */ if(pop3code == '*') { /* Does the server support the STLS capability? */ if(len >= 4 && !memcmp(line, "STLS", 4)) pop3c->tls_supported = TRUE; /* Does the server support clear text authentication? */ else if(len >= 4 && !memcmp(line, "USER", 4)) pop3c->authtypes |= POP3_TYPE_CLEARTEXT; /* Does the server support SASL based authentication? */ else if(len >= 5 && !memcmp(line, "SASL ", 5)) { pop3c->authtypes |= POP3_TYPE_SASL; /* Advance past the SASL keyword */ line += 5; len -= 5; /* Loop through the data line */ for(;;) { size_t llen; unsigned int mechbit; while(len && (*line == ' ' || *line == '\t' || *line == '\r' || *line == '\n')) { line++; len--; } if(!len) break; /* Extract the word */ for(wordlen = 0; wordlen < len && line[wordlen] != ' ' && line[wordlen] != '\t' && line[wordlen] != '\r' && line[wordlen] != '\n';) wordlen++; /* Test the word for a matching authentication mechanism */ if((mechbit = Curl_sasl_decode_mech(line, wordlen, &llen)) && llen == wordlen) pop3c->sasl.authmechs |= mechbit; line += wordlen; len -= wordlen; } } } else if(pop3code == '+') { if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) { /* We don't have a SSL/TLS connection yet, but SSL is requested */ if(pop3c->tls_supported) /* Switch to TLS connection now */ result = pop3_perform_starttls(conn); else if(data->set.use_ssl == CURLUSESSL_TRY) /* Fallback and carry on with authentication */ result = pop3_perform_authentication(conn); else { failf(data, "STLS not supported."); result = CURLE_USE_SSL_FAILED; } } else result = pop3_perform_authentication(conn); } else { /* Clear text is supported when CAPA isn't recognised */ pop3c->authtypes |= POP3_TYPE_CLEARTEXT; result = pop3_perform_authentication(conn); } return result; }