/* Find the content encoding by name. */ static const content_encoding *find_encoding(const char *name, size_t len) { const content_encoding * const *cep; for(cep = encodings; *cep; cep++) { const content_encoding *ce = *cep; if((strncasecompare(name, ce->name, len) && !ce->name[len]) || (ce->alias && strncasecompare(name, ce->alias, len) && !ce->alias[len])) return ce; } return NULL; }
/*********************************************************************** * * pop3_parse_url_options() * * Parse the URL login options. */ static CURLcode pop3_parse_url_options(struct connectdata *conn) { CURLcode result = CURLE_OK; struct pop3_conn *pop3c = &conn->proto.pop3c; const char *ptr = conn->options; pop3c->sasl.resetprefs = TRUE; while(!result && ptr && *ptr) { const char *key = ptr; const char *value; while(*ptr && *ptr != '=') ptr++; value = ptr + 1; while(*ptr && *ptr != ';') ptr++; if(strncasecompare(key, "AUTH=", 5)) { result = Curl_sasl_parse_url_auth_option(&pop3c->sasl, value, ptr - value); if(result && strncasecompare(value, "+APOP", ptr - value)) { pop3c->preftype = POP3_TYPE_APOP; pop3c->sasl.prefmech = SASL_AUTH_NONE; result = CURLE_OK; } } else result = CURLE_URL_MALFORMAT; if(*ptr == ';') ptr++; } if(pop3c->preftype != POP3_TYPE_APOP) switch(pop3c->sasl.prefmech) { case SASL_AUTH_NONE: pop3c->preftype = POP3_TYPE_NONE; break; case SASL_AUTH_DEFAULT: pop3c->preftype = POP3_TYPE_ANY; break; default: pop3c->preftype = POP3_TYPE_SASL; break; } return result; }
/*********************************************************************** * * smtp_parse_url_options() * * Parse the URL login options. */ static CURLcode smtp_parse_url_options(struct connectdata *conn) { CURLcode result = CURLE_OK; struct smtp_conn *smtpc = &conn->proto.smtpc; const char *ptr = conn->options; smtpc->sasl.resetprefs = TRUE; while(!result && ptr && *ptr) { const char *key = ptr; const char *value; while(*ptr && *ptr != '=') ptr++; value = ptr + 1; while(*ptr && *ptr != ';') ptr++; if(strncasecompare(key, "AUTH=", 5)) result = Curl_sasl_parse_url_auth_option(&smtpc->sasl, value, ptr - value); else result = CURLE_URL_MALFORMAT; if(*ptr == ';') ptr++; } return result; }
/* Check if header matches. */ static char *match_header(struct curl_slist *hdr, const char *lbl, size_t len) { char *value = NULL; if(strncasecompare(hdr->data, lbl, len) && hdr->data[len] == ':') for(value = hdr->data + len + 1; *value == ' '; value++) ; return value; }
/* Set-up the unencoding stack from the Content-Encoding header value. * See RFC 7231 section 3.1.2.2. */ CURLcode Curl_build_unencoding_stack(struct connectdata *conn, const char *enclist, int maybechunked) { struct Curl_easy *data = conn->data; struct SingleRequest *k = &data->req; do { const char *name; size_t namelen; /* Parse a single encoding name. */ while(ISSPACE(*enclist) || *enclist == ',') enclist++; name = enclist; for(namelen = 0; *enclist && *enclist != ','; enclist++) if(!ISSPACE(*enclist)) namelen = enclist - name + 1; /* Special case: chunked encoding is handled at the reader level. */ if(maybechunked && namelen == 7 && strncasecompare(name, "chunked", 7)) { k->chunk = TRUE; /* chunks coming our way. */ Curl_httpchunk_init(conn); /* init our chunky engine. */ } else if(namelen) { const content_encoding *encoding = find_encoding(name, namelen); contenc_writer *writer; if(!k->writer_stack) { k->writer_stack = new_unencoding_writer(conn, &client_encoding, NULL); if(!k->writer_stack) return CURLE_OUT_OF_MEMORY; } if(!encoding) encoding = &error_encoding; /* Defer error at stack use. */ /* Stack the unencoding stage. */ writer = new_unencoding_writer(conn, encoding, k->writer_stack); if(!writer) return CURLE_OUT_OF_MEMORY; k->writer_stack = writer; } } while(*enclist); return CURLE_OK; }
static CURLcode set_ciphers(struct connectdata *conn, gsk_handle h, unsigned int *protoflags) { struct Curl_easy *data = conn->data; const char *cipherlist = SSL_CONN_CONFIG(cipher_list); const char *clp; const gskit_cipher *ctp; int i; int l; bool unsupported; CURLcode result; struct { char *buf; char *ptr; } ciphers[CURL_GSKPROTO_LAST]; /* Compile cipher list into GSKit-compatible cipher lists. */ if(!cipherlist) return CURLE_OK; while(is_separator(*cipherlist)) /* Skip initial separators. */ cipherlist++; if(!*cipherlist) return CURLE_OK; /* We allocate GSKit buffers of the same size as the input string: since GSKit tokens are always shorter than their cipher names, allocated buffers will always be large enough to accomodate the result. */ l = strlen(cipherlist) + 1; memset((char *) ciphers, 0, sizeof ciphers); for(i = 0; i < CURL_GSKPROTO_LAST; i++) { ciphers[i].buf = malloc(l); if(!ciphers[i].buf) { while(i--) free(ciphers[i].buf); return CURLE_OUT_OF_MEMORY; } ciphers[i].ptr = ciphers[i].buf; *ciphers[i].ptr = '\0'; } /* Process each cipher in input string. */ unsupported = FALSE; result = CURLE_OK; for(;;) { for(clp = cipherlist; *cipherlist && !is_separator(*cipherlist);) cipherlist++; l = cipherlist - clp; if(!l) break; /* Search the cipher in our table. */ for(ctp = ciphertable; ctp->name; ctp++) if(strncasecompare(ctp->name, clp, l) && !ctp->name[l]) break; if(!ctp->name) { failf(data, "Unknown cipher %.*s", l, clp); result = CURLE_SSL_CIPHER; } else { unsupported |= !(ctp->versions & (CURL_GSKPROTO_SSLV2_MASK | CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK)); for(i = 0; i < CURL_GSKPROTO_LAST; i++) { if(ctp->versions & (1 << i)) { strcpy(ciphers[i].ptr, ctp->gsktoken); ciphers[i].ptr += strlen(ctp->gsktoken); } } } /* Advance to next cipher name or end of string. */ while(is_separator(*cipherlist)) cipherlist++; } /* Disable protocols with empty cipher lists. */ for(i = 0; i < CURL_GSKPROTO_LAST; i++) { if(!(*protoflags & (1 << i)) || !ciphers[i].buf[0]) { *protoflags &= ~(1 << i); ciphers[i].buf[0] = '\0'; } } /* Try to set-up TLSv1.1 and TLSv2.1 ciphers. */ if(*protoflags & CURL_GSKPROTO_TLSV11_MASK) { result = set_buffer(data, h, GSK_TLSV11_CIPHER_SPECS, ciphers[CURL_GSKPROTO_TLSV11].buf, TRUE); if(result == CURLE_UNSUPPORTED_PROTOCOL) { result = CURLE_OK; if(unsupported) { failf(data, "TLSv1.1-only ciphers are not yet supported"); result = CURLE_SSL_CIPHER; } } } if(!result && (*protoflags & CURL_GSKPROTO_TLSV12_MASK)) { result = set_buffer(data, h, GSK_TLSV12_CIPHER_SPECS, ciphers[CURL_GSKPROTO_TLSV12].buf, TRUE); if(result == CURLE_UNSUPPORTED_PROTOCOL) { result = CURLE_OK; if(unsupported) { failf(data, "TLSv1.2-only ciphers are not yet supported"); result = CURLE_SSL_CIPHER; } } } /* Try to set-up TLSv1.0 ciphers. If not successful, concatenate them to the SSLv3 ciphers. OS/400 prior to version 7.1 will understand it. */ if(!result && (*protoflags & CURL_GSKPROTO_TLSV10_MASK)) { result = set_buffer(data, h, GSK_TLSV10_CIPHER_SPECS, ciphers[CURL_GSKPROTO_TLSV10].buf, TRUE); if(result == CURLE_UNSUPPORTED_PROTOCOL) { result = CURLE_OK; strcpy(ciphers[CURL_GSKPROTO_SSLV3].ptr, ciphers[CURL_GSKPROTO_TLSV10].ptr); } } /* Set-up other ciphers. */ if(!result && (*protoflags & CURL_GSKPROTO_SSLV3_MASK)) result = set_buffer(data, h, GSK_V3_CIPHER_SPECS, ciphers[CURL_GSKPROTO_SSLV3].buf, FALSE); if(!result && (*protoflags & CURL_GSKPROTO_SSLV2_MASK)) result = set_buffer(data, h, GSK_V2_CIPHER_SPECS, ciphers[CURL_GSKPROTO_SSLV2].buf, FALSE); /* Clean-up. */ for(i = 0; i < CURL_GSKPROTO_LAST; i++) free(ciphers[i].buf); return result; }